⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 aic7xxx.seq

📁 linux-2.6.15.6
💻 SEQ
📖 第 1 页 / 共 4 页
字号:
 * the SCB cannot be found, SINDEX will be SCB_LIST_NULL, otherwise, SCBPTR * is set to the proper SCB. */findSCB:	mov	SCBPTR,SINDEX;			/* Initialize SCBPTR */	cmp	ARG_1, SCB_LIST_NULL	jne findSCB_by_SCBID;	mov	A, SAVED_TCL;	mvi	SCB_TCL	jmp findSCB_loop;	/* &SCB_TCL -> SINDEX */findSCB_by_SCBID:	mov	A, ARG_1;			/* Tag passed in ARG_1 */	mvi	SCB_TAG	jmp findSCB_loop;	/* &SCB_TAG -> SINDEX */findSCB_next:	mov     ARG_2, SCBPTR;	cmp	SCB_NEXT, SCB_LIST_NULL je notFound;	mov	SCBPTR,SCB_NEXT;	dec	SINDEX;		/* Last comparison moved us too far */findSCB_loop:	cmp	SINDIR, A	jne findSCB_next;	mov	SINDEX, SCBPTR 	ret;notFound:	mvi	SINDEX, SCB_LIST_NULL	ret;/* * Retrieve an SCB by SCBID first searching the disconnected list falling * back to DMA'ing the SCB down from the host.  This routine assumes that * ARG_1 is the SCBID of interrest and that SINDEX is the position in the * disconnected list to start the search from.  If SINDEX is SCB_LIST_NULL, * we go directly to the host for the SCB. */retrieveSCB:	test	SEQ_FLAGS, SCBPTR_VALID	jz retrieve_from_host;	mov	SCBPTR	call findSCB;	/* Continue the search */	cmp	SINDEX, SCB_LIST_NULL	je retrieve_from_host;/* * This routine expects SINDEX to contain the index of the SCB to be * removed, SCBPTR to be pointing to that SCB, and ARG_2 to be the * SCBID of the SCB just previous to this one in the list or SCB_LIST_NULL * if it is at the head. */rem_scb_from_disc_list:/* Remove this SCB from the disconnection list */	cmp     ARG_2, SCB_LIST_NULL    je rHead;	mov	DINDEX, SCB_NEXT;	mov	SCBPTR, ARG_2;	mov	SCB_NEXT, DINDEX;	mov	SCBPTR, SINDEX ret;rHead:	mov	DISCONNECTED_SCBH,SCB_NEXT ret;retrieve_from_host:/* * We didn't find it.  Pull an SCB and DMA down the one we want. * We should never get here in the non-paging case. */	mov	ALLZEROS	call	get_free_or_disc_scb;	mvi	DMAPARAMS, HDMAEN|DIRECTION|FIFORESET;	/* Jump instead of call as we want to return anyway */	mov	ARG_1	jmp dma_scb;/* * Determine whether a target is using tagged or non-tagged transactions * by first looking for a matching transaction based on the TCL and if * that fails, looking up this device in the host's untagged SCB array. * The TCL to search for is assumed to be in SAVED_TCL.  The value is * returned in ARG_1 (SCB_LIST_NULL for tagged, SCBID for non-tagged). * The SCBPTR_VALID bit is set in SEQ_FLAGS if we found the information * in an SCB instead of having to go to the host. */get_untagged_SCBID:	cmp	DISCONNECTED_SCBH, SCB_LIST_NULL je get_SCBID_from_host;	mvi	ARG_1, SCB_LIST_NULL;	mov	DISCONNECTED_SCBH call findSCB;	cmp	SINDEX, SCB_LIST_NULL	je get_SCBID_from_host;	or	SEQ_FLAGS, SCBPTR_VALID;/* Was in disconnected list */	test	SCB_CONTROL, TAG_ENB	jnz . + 2;	mov	ARG_1, SCB_TAG	ret;	mvi	ARG_1, SCB_LIST_NULL ret;/* * Fetch a byte from host memory given an index of (A + (256 * SINDEX)) * and a base address of SCBID_ADDR.  The byte is returned in RETURN_2. */fetch_byte:	mov	ARG_2, SINDEX;	if ((p->features & AHC_CMD_CHAN) != 0) {		mvi	DINDEX, CCHADDR;		mvi	SCBID_ADDR call set_1byte_addr;		mvi	CCHCNT, 1;		mvi	CCSGCTL, CCSGEN|CCSGRESET;		test	CCSGCTL, CCSGDONE jz .;		mvi	CCSGCTL, CCSGRESET;		bmov	RETURN_2, CCSGRAM, 1 ret;	} else {		mvi	DINDEX, HADDR;		mvi	SCBID_ADDR call set_1byte_addr;		mvi	HCNT[0], 1;		clr	HCNT[1];		clr	HCNT[2];		mvi	DFCNTRL, HDMAEN|DIRECTION|FIFORESET;		call	dma_finish;		mov	RETURN_2, DFDAT ret;	}/* * Prepare the hardware to post a byte to host memory given an * index of (A + (256 * SINDEX)) and a base address of SCBID_ADDR. */post_byte_setup:	mov	ARG_2, SINDEX;	if ((p->features & AHC_CMD_CHAN) != 0) {		mvi	DINDEX, CCHADDR;		mvi	SCBID_ADDR call	set_1byte_addr;		mvi	CCHCNT, 1;		mvi	CCSCBCTL, CCSCBRESET ret;	} else {		mvi	DINDEX, HADDR;		mvi	SCBID_ADDR call	set_1byte_addr;		mvi	HCNT[0], 1;		clr	HCNT[1];		clr	HCNT[2];		mvi	DFCNTRL, FIFORESET ret;	}post_byte:	if ((p->features & AHC_CMD_CHAN) != 0) {		bmov	CCSCBRAM, SINDEX, 1;		or	CCSCBCTL, CCSCBEN|CCSCBRESET;		test	CCSCBCTL, CCSCBDONE jz .;		clr	CCSCBCTL ret;	} else {		mov	DFDAT, SINDEX;		or	DFCNTRL, HDMAEN|FIFOFLUSH;		jmp	dma_finish;	}get_SCBID_from_host:	mov	A, SAVED_TCL;	mvi	UNTAGGEDSCB_OFFSET call fetch_byte;	mov	RETURN_1,  RETURN_2 ret;phase_lock:     	test	SSTAT1, REQINIT jz phase_lock;	test	SSTAT1, SCSIPERR jnz phase_lock;	and	SCSISIGO, PHASE_MASK, SCSISIGI;	and	LASTPHASE, PHASE_MASK, SCSISIGI ret;if ((p->features & AHC_CMD_CHAN) == 0) {set_stcnt_from_hcnt:	mov	STCNT[0], HCNT[0];	mov	STCNT[1], HCNT[1];	mov	STCNT[2], HCNT[2] ret;bcopy_7:	mov	DINDIR, SINDIR;	mov	DINDIR, SINDIR;bcopy_5:	mov	DINDIR, SINDIR;bcopy_4:	mov	DINDIR, SINDIR;bcopy_3:	mov	DINDIR, SINDIR;	mov	DINDIR, SINDIR;	mov	DINDIR, SINDIR ret;}/* * Setup addr assuming that A is an index into * an array of 32byte objects, SINDEX contains * the base address of that array, and DINDEX * contains the base address of the location * to store the indexed address. */set_32byte_addr:	shr	ARG_2, 3, A;	shl	A, 5;/* * Setup addr assuming that A + (ARG_1 * 256) is an * index into an array of 1byte objects, SINDEX contains * the base address of that array, and DINDEX contains * the base address of the location to store the computed * address. */set_1byte_addr:	add	DINDIR, A, SINDIR;	mov	A, ARG_2;	adc	DINDIR, A, SINDIR;	clr	A;	adc	DINDIR, A, SINDIR;	adc	DINDIR, A, SINDIR ret;/* * Either post or fetch and SCB from host memory based on the * DIRECTION bit in DMAPARAMS. The host SCB index is in SINDEX. */dma_scb:	mov	A, SINDEX;	if ((p->features & AHC_CMD_CHAN) != 0) {		mvi	DINDEX, CCHADDR;		mvi	HSCB_ADDR call set_32byte_addr;		mov	CCSCBPTR, SCBPTR;		mvi	CCHCNT, 32;		test	DMAPARAMS, DIRECTION jz dma_scb_tohost;		mvi	CCSCBCTL, CCARREN|CCSCBEN|CCSCBDIR|CCSCBRESET;		cmp	CCSCBCTL, CCSCBDONE|ARRDONE|CCARREN|CCSCBEN|CCSCBDIR jne .;		jmp	dma_scb_finish;dma_scb_tohost:		if ((p->features & AHC_ULTRA2) == 0) {			mvi	CCSCBCTL, CCSCBRESET;			bmov	CCSCBRAM, SCB_CONTROL, 32;			or	CCSCBCTL, CCSCBEN|CCSCBRESET;			test	CCSCBCTL, CCSCBDONE jz .;		}		if ((p->features & AHC_ULTRA2) != 0) {			if ((p->bugs & AHC_BUG_SCBCHAN_UPLOAD) != 0) {				mvi     CCSCBCTL, CCARREN|CCSCBRESET;				cmp     CCSCBCTL, ARRDONE|CCARREN jne .;                        	mvi     CCHCNT, 32;				mvi     CCSCBCTL, CCSCBEN|CCSCBRESET;				cmp     CCSCBCTL, CCSCBDONE|CCSCBEN jne .;			} else {				mvi	CCSCBCTL, CCARREN|CCSCBEN|CCSCBRESET;				cmp	CCSCBCTL, CCSCBDONE|ARRDONE|CCARREN|CCSCBEN jne .;			}		}dma_scb_finish:		clr	CCSCBCTL;		test	CCSCBCTL, CCARREN|CCSCBEN jnz .;		ret;	}	if ((p->features & AHC_CMD_CHAN) == 0) {		mvi	DINDEX, HADDR;		mvi	HSCB_ADDR call set_32byte_addr;		mvi	HCNT[0], 32;		clr	HCNT[1];		clr	HCNT[2];		mov	DFCNTRL, DMAPARAMS;		test	DMAPARAMS, DIRECTION	jnz dma_scb_fromhost;		/* Fill it with the SCB data */copy_scb_tofifo:		mvi	SINDEX, SCB_CONTROL;		add	A, 32, SINDEX;copy_scb_tofifo_loop:		mov	DFDAT,SINDIR;		mov	DFDAT,SINDIR;		mov	DFDAT,SINDIR;		mov	DFDAT,SINDIR;		mov	DFDAT,SINDIR;		mov	DFDAT,SINDIR;		mov	DFDAT,SINDIR;		mov	DFDAT,SINDIR;		cmp	SINDEX, A jne copy_scb_tofifo_loop;		or	DFCNTRL, HDMAEN|FIFOFLUSH;		jmp	dma_finish;dma_scb_fromhost:		mvi	DINDEX, SCB_CONTROL;		if ((p->bugs & AHC_BUG_PCI_2_1_RETRY) != 0) {			/*			 * Set the A to -24.  It it hits 0, then we let			 * our code fall through to dfdat_in_8 to complete			 * the last of the copy.			 *			 * Also, things happen 8 bytes at a time in this			 * case, so we may need to drain the fifo at most			 * 3 times to keep things flowing			 */			mvi	A, -24;dma_scb_hang_fifo:			/* Wait for the first bit of data to hit the fifo */			test	DFSTATUS, FIFOEMP jnz .;dma_scb_hang_wait:			/* OK, now they've started to transfer into the fifo,			 * so wait for them to stop trying to transfer any			 * more data.			 */			test	DFSTATUS, MREQPEND jnz .;			/*			 * OK, they started, then they stopped, now see if they			 * managed to complete the job before stopping.  Try			 * it multiple times to give the chip a few cycles to			 * set the flag if it did complete.			 */			test	DFSTATUS, HDONE jnz dma_scb_hang_dma_done;			test	DFSTATUS, HDONE jnz dma_scb_hang_dma_done;			test	DFSTATUS, HDONE jnz dma_scb_hang_dma_done;			/*			 * Too bad, the chip didn't complete the DMA, but there			 * aren't any more memory requests pending, so that			 * means it stopped part way through and hung.  That's			 * our bug, so now we drain what data there is in the			 * fifo in order to get things going again.			 */dma_scb_hang_empty_fifo:			call	dfdat_in_8;			add	A, 8;			add	SINDEX, A, HCNT;			/*			 * If there are another 8 bytes of data waiting in the			 * fifo, then the carry bit will be set as a result			 * of the above add command (unless A is non-negative,			 * in which case the carry bit won't be set).			 */			jc	dma_scb_hang_empty_fifo;			/*			 * We've emptied the fifo now, but we wouldn't have got			 * here if the memory transfer hadn't stopped part way			 * through, so go back up to the beginning of the			 * loop and start over.  When it succeeds in getting			 * all the data down, HDONE will be set and we'll			 * jump to the code just below here.			 */			jmp	dma_scb_hang_fifo;dma_scb_hang_dma_done:			and	DFCNTRL, ~HDMAEN;			test	DFCNTRL, HDMAEN jnz .;			call	dfdat_in_8;			add	A, 8;			cmp	A, 8 jne . - 2;			ret;		} else {			call	dma_finish;			call	dfdat_in_8;			call	dfdat_in_8;			call	dfdat_in_8;		}dfdat_in_8:		mov	DINDIR,DFDAT;dfdat_in_7:		mov	DINDIR,DFDAT;		mov	DINDIR,DFDAT;		mov	DINDIR,DFDAT;		mov	DINDIR,DFDAT;		mov	DINDIR,DFDAT;		mov	DINDIR,DFDAT;		mov	DINDIR,DFDAT ret;	}/* * Wait for DMA from host memory to data FIFO to complete, then disable * DMA and wait for it to acknowledge that it's off. */if ((p->features & AHC_CMD_CHAN) == 0) {dma_finish:	test	DFSTATUS,HDONE	jz dma_finish;	/* Turn off DMA */	and	DFCNTRL, ~HDMAEN;	test	DFCNTRL, HDMAEN jnz .;	ret;}add_scb_to_free_list:	if ((p->flags & AHC_PAGESCBS) != 0) {		mov	SCB_NEXT, FREE_SCBH;		mov	FREE_SCBH, SCBPTR;	}	mvi	SCB_TAG, SCB_LIST_NULL ret;if ((p->flags & AHC_PAGESCBS) != 0) {get_free_or_disc_scb:	cmp	FREE_SCBH, SCB_LIST_NULL jne dequeue_free_scb;	cmp	DISCONNECTED_SCBH, SCB_LIST_NULL jne dequeue_disc_scb;return_error:	mvi	SINDEX, SCB_LIST_NULL	ret;dequeue_disc_scb:	mov	SCBPTR, DISCONNECTED_SCBH;dma_up_scb:	mvi	DMAPARAMS, FIFORESET;	mov	SCB_TAG		call dma_scb;unlink_disc_scb:	mov	DISCONNECTED_SCBH, SCB_NEXT ret;dequeue_free_scb:	mov	SCBPTR, FREE_SCBH;	mov	FREE_SCBH, SCB_NEXT ret;}add_scb_to_disc_list:/* * Link this SCB into the DISCONNECTED list.  This list holds the * candidates for paging out an SCB if one is needed for a new command. * Modifying the disconnected list is a critical(pause dissabled) section. */	mov	SCB_NEXT, DISCONNECTED_SCBH;	mov	DISCONNECTED_SCBH, SCBPTR ret;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -