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

📄 aic7xxx.seq

📁 linux-2.6.15.6
💻 SEQ
📖 第 1 页 / 共 5 页
字号:
/* * Restore pointers message?  Data pointers are recopied from the * SCB anytime we enter a data phase for the first time, so all * we need to do is clear the DPHASE flag and let the data phase * code do the rest.  We also reset/reallocate the FIFO to make * sure we have a clean start for the next data or command phase. */mesgin_rdptrs:	and	SEQ_FLAGS, ~DPHASE;		/*						 * We'll reload them						 * the next time through						 * the dataphase.						 */	or	SXFRCTL0, CLRSTCNT|CLRCHN;	jmp	mesgin_done;/* * Index into our Busy Target table.  SINDEX and DINDEX are modified * upon return.  SCBPTR may be modified by this action. */set_busy_target:	shr	DINDEX, 4, SINDEX;	if ((ahc->flags & AHC_SCB_BTT) != 0) {		mov	SCBPTR, SAVED_LUN;		add	DINDEX, SCB_64_BTT;	} else {		add	DINDEX, BUSY_TARGETS;	}	mov	DINDIR, ARG_1 ret;/* * Identify message?  For a reconnecting target, this tells us the lun * that the reconnection is for - find the correct SCB and switch to it, * clearing the "disconnected" bit so we don't "find" it by accident later. */mesgin_identify:	/*	 * Determine whether a target is using tagged or non-tagged	 * transactions by first looking at the transaction stored in	 * the busy target array.  If there is no untagged transaction	 * for this target or the transaction is for a different lun, then	 * this must be a tagged transaction.	 */	shr	SINDEX, 4, SAVED_SCSIID;	and	SAVED_LUN, MSG_IDENTIFY_LUNMASK, A;	if ((ahc->flags & AHC_SCB_BTT) != 0) {		add	SINDEX, SCB_64_BTT;		mov	SCBPTR, SAVED_LUN;		if ((ahc->flags & AHC_SEQUENCER_DEBUG) != 0) {			add	NONE, -SCB_64_BTT, SINDEX;			jc	. + 2;			mvi	INTSTAT, OUT_OF_RANGE;			nop;			add	NONE, -(SCB_64_BTT + 16), SINDEX;			jnc	. + 2;			mvi	INTSTAT, OUT_OF_RANGE;			nop;		}	} else {		add	SINDEX, BUSY_TARGETS;		if ((ahc->flags & AHC_SEQUENCER_DEBUG) != 0) {			add	NONE, -BUSY_TARGETS, SINDEX;			jc	. + 2;			mvi	INTSTAT, OUT_OF_RANGE;			nop;			add	NONE, -(BUSY_TARGETS + 16), SINDEX;			jnc	. + 2;			mvi	INTSTAT, OUT_OF_RANGE;			nop;		}	}	mov	ARG_1, SINDIR;	cmp	ARG_1, SCB_LIST_NULL	je snoop_tag;	if ((ahc->flags & AHC_PAGESCBS) != 0) {		mov	ARG_1 call findSCB;	} else {		mov	SCBPTR, ARG_1;	}	if ((ahc->flags & AHC_SCB_BTT) != 0) {		jmp setup_SCB_id_lun_okay;	} else {		/*		 * We only allow one untagged command per-target		 * at a time.  So, if the lun doesn't match, look		 * for a tag message.		 */		and	A, LID, SCB_LUN;		cmp	SAVED_LUN, A	je setup_SCB_id_lun_okay;		if ((ahc->flags & AHC_PAGESCBS) != 0) {			/*			 * findSCB removes the SCB from the			 * disconnected list, so we must replace			 * it there should this SCB be for another			 * lun.			 */			call	cleanup_scb;		}	}/* * Here we "snoop" the bus looking for a SIMPLE QUEUE TAG message. * If we get one, we use the tag returned to find the proper * SCB.  With SCB paging, we must search for non-tagged * transactions since the SCB may exist in any slot.  If we're not * using SCB paging, we can use the tag as the direct index to the * SCB. */snoop_tag:	if ((ahc->flags & AHC_SEQUENCER_DEBUG) != 0) {		or	SEQ_FLAGS, 0x80;	}	mov	NONE,SCSIDATL;		/* ACK Identify MSG */	call	phase_lock;	if ((ahc->flags & AHC_SEQUENCER_DEBUG) != 0) {		or	SEQ_FLAGS, 0x1;	}	cmp	LASTPHASE, P_MESGIN	jne not_found;	if ((ahc->flags & AHC_SEQUENCER_DEBUG) != 0) {		or	SEQ_FLAGS, 0x2;	}	cmp	SCSIBUSL,MSG_SIMPLE_Q_TAG jne not_found;get_tag:	if ((ahc->flags & AHC_PAGESCBS) != 0) {		mvi	ARG_1	call inb_next;	/* tag value */		mov	ARG_1	call findSCB;	} else {		mvi	ARG_1	call inb_next;	/* tag value */		mov	SCBPTR, ARG_1;	}/* * Ensure that the SCB the tag points to is for * an SCB transaction to the reconnecting target. */setup_SCB:	if ((ahc->flags & AHC_SEQUENCER_DEBUG) != 0) {		or	SEQ_FLAGS, 0x4;	}	mov	A, SCB_SCSIID;	cmp	SAVED_SCSIID, A	jne not_found_cleanup_scb;	if ((ahc->flags & AHC_SEQUENCER_DEBUG) != 0) {		or	SEQ_FLAGS, 0x8;	}setup_SCB_id_okay:	and	A, LID, SCB_LUN;	cmp	SAVED_LUN, A	jne not_found_cleanup_scb;setup_SCB_id_lun_okay:	if ((ahc->flags & AHC_SEQUENCER_DEBUG) != 0) {		or	SEQ_FLAGS, 0x10;	}	test	SCB_CONTROL,DISCONNECTED jz not_found_cleanup_scb;	and	SCB_CONTROL,~DISCONNECTED;	test	SCB_CONTROL, TAG_ENB	jnz setup_SCB_tagged;	if ((ahc->flags & AHC_SCB_BTT) != 0) {		mov	A, SCBPTR;	}	mvi	ARG_1, SCB_LIST_NULL;	mov	SAVED_SCSIID	call	set_busy_target;	if ((ahc->flags & AHC_SCB_BTT) != 0) {		mov	SCBPTR, A;	}setup_SCB_tagged:	clr	SEQ_FLAGS;	/* make note of IDENTIFY */	call	set_transfer_settings;	/* See if the host wants to send a message upon reconnection */	test	SCB_CONTROL, MK_MESSAGE jz mesgin_done;	mvi	HOST_MSG	call mk_mesg;	jmp	mesgin_done;not_found_cleanup_scb:	if ((ahc->flags & AHC_PAGESCBS) != 0) {		call	cleanup_scb;	}not_found:	mvi	NO_MATCH call set_seqint;	jmp	mesgin_done;mk_mesg:	if ((ahc->features & AHC_DT) == 0) {		or	SCSISIGO, ATNO, LASTPHASE;	} else {		mvi	SCSISIGO, ATNO;	}	mov	MSG_OUT,SINDEX ret;/* * Functions to read data in Automatic PIO mode. * * According to Adaptec's documentation, an ACK is not sent on input from * the target until SCSIDATL is read from.  So we wait until SCSIDATL is * latched (the usual way), then read the data byte directly off the bus * using SCSIBUSL.  When we have pulled the ATN line, or we just want to * acknowledge the byte, then we do a dummy read from SCISDATL.  The SCSI * spec guarantees that the target will hold the data byte on the bus until * we send our ACK. * * The assumption here is that these are called in a particular sequence, * and that REQ is already set when inb_first is called.  inb_{first,next} * use the same calling convention as inb. */inb_next_wait_perr:	mvi	PERR_DETECTED call set_seqint;	jmp	inb_next_wait;inb_next:	mov	NONE,SCSIDATL;		/*dummy read from latch to ACK*/inb_next_wait:	/*	 * If there is a parity error, wait for the kernel to	 * see the interrupt and prepare our message response	 * before continuing.	 */	test	SSTAT1, REQINIT	jz inb_next_wait;	test	SSTAT1, SCSIPERR jnz inb_next_wait_perr;inb_next_check_phase:	and	LASTPHASE, PHASE_MASK, SCSISIGI;	cmp	LASTPHASE, P_MESGIN jne mesgin_phasemis;inb_first:	mov	DINDEX,SINDEX;	mov	DINDIR,SCSIBUSL	ret;		/*read byte directly from bus*/inb_last:	mov	NONE,SCSIDATL ret;		/*dummy read from latch to ACK*/}if ((ahc->flags & AHC_TARGETROLE) != 0) {/* * Change to a new phase.  If we are changing the state of the I/O signal, * from out to in, wait an additional data release delay before continuing. */change_phase:	/* Wait for preceeding I/O session to complete. */	test	SCSISIGI, ACKI jnz .;	/* Change the phase */	and	DINDEX, IOI, SCSISIGI;	mov	SCSISIGO, SINDEX;	and	A, IOI, SINDEX;	/*	 * If the data direction has changed, from	 * out (initiator driving) to in (target driving),	 * we must wait at least a data release delay plus	 * the normal bus settle delay. [SCSI III SPI 10.11.0]	 */	cmp 	DINDEX, A je change_phase_wait;	test	SINDEX, IOI jz change_phase_wait;	call	change_phase_wait;change_phase_wait:	nop;	nop;	nop;	nop ret;/* * Send a byte to an initiator in Automatic PIO mode. */target_outb:	or	SXFRCTL0, SPIOEN;	test	SSTAT0, SPIORDY	jz .;	mov	SCSIDATL, SINDEX;	test	SSTAT0, SPIORDY	jz .;	and	SXFRCTL0, ~SPIOEN ret;}	/* * Locate a disconnected SCB by SCBID.  Upon return, SCBPTR and SINDEX will * be set to the position of the SCB.  If the SCB cannot be found locally, * it will be paged in from host memory.  RETURN_2 stores the address of the * preceding SCB in the disconnected list which can be used to speed up * removal of the found SCB from the disconnected list. */if ((ahc->flags & AHC_PAGESCBS) != 0) {BEGIN_CRITICAL;findSCB:	mov	A, SINDEX;			/* Tag passed in SINDEX */	cmp	DISCONNECTED_SCBH, SCB_LIST_NULL je findSCB_notFound;	mov	SCBPTR, DISCONNECTED_SCBH;	/* Initialize SCBPTR */	mvi	ARG_2, SCB_LIST_NULL;		/* Head of list */	jmp	findSCB_loop;findSCB_next:	cmp	SCB_NEXT, SCB_LIST_NULL je findSCB_notFound;	mov	ARG_2, SCBPTR;	mov	SCBPTR,SCB_NEXT;findSCB_loop:	cmp	SCB_TAG, A	jne findSCB_next;rem_scb_from_disc_list:	cmp	ARG_2, SCB_LIST_NULL	je rHead;	mov	DINDEX, SCB_NEXT;	mov	SINDEX, SCBPTR;	mov	SCBPTR, ARG_2;	mov	SCB_NEXT, DINDEX;	mov	SCBPTR, SINDEX ret;rHead:	mov	DISCONNECTED_SCBH,SCB_NEXT ret;END_CRITICAL;findSCB_notFound:	/*	 * We didn't find it.  Page in the SCB.	 */	mov	ARG_1, A; /* Save tag */	mov	ALLZEROS call get_free_or_disc_scb;	mvi	DMAPARAMS, HDMAEN|DIRECTION|FIFORESET;	mov	ARG_1	jmp dma_scb;}/* * Prepare the hardware to post a byte to host memory given an * index of (A + (256 * SINDEX)) and a base address of SHARED_DATA_ADDR. */post_byte_setup:	mov	ARG_2, SINDEX;	if ((ahc->features & AHC_CMD_CHAN) != 0) {		mvi	DINDEX, CCHADDR;		mvi	SHARED_DATA_ADDR call	set_1byte_addr;		mvi	CCHCNT, 1;		mvi	CCSCBCTL, CCSCBRESET ret;	} else {		mvi	DINDEX, HADDR;		mvi	SHARED_DATA_ADDR call	set_1byte_addr;		mvi	1	call set_hcnt;		mvi	DFCNTRL, FIFORESET ret;	}post_byte:	if ((ahc->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;	}phase_lock_perr:	mvi	PERR_DETECTED call set_seqint;phase_lock:     	/*	 * If there is a parity error, wait for the kernel to	 * see the interrupt and prepare our message response	 * before continuing.	 */	test	SSTAT1, REQINIT jz phase_lock;	test	SSTAT1, SCSIPERR jnz phase_lock_perr;phase_lock_latch_phase:	if ((ahc->features & AHC_DT) == 0) {		and	SCSISIGO, PHASE_MASK, SCSISIGI;	}	and	LASTPHASE, PHASE_MASK, SCSISIGI ret;if ((ahc->features & AHC_CMD_CHAN) == 0) {set_hcnt:	mov	HCNT[0], SINDEX;clear_hcnt:	clr	HCNT[1];	clr	HCNT[2] ret;set_stcnt_from_hcnt:	mov	STCNT[0], HCNT[0];	mov	STCNT[1], HCNT[1];	mov	STCNT[2], HCNT[2] ret;bcopy_8:	mov	DINDIR, SINDIR;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;}if ((ahc->flags & AHC_TARGETROLE) != 0) {/* * 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;	jmp	set_1byte_addr;}/* * Setup addr assuming that A is an index into * an array of 64byte objects, SINDEX contains * the base address of that array, and DINDEX * contains the base address of the location * to store the indexed address. */set_64byte_addr:	shr	ARG_2, 2, A;	shl	A, 6;/* * Setup addr assuming that A + (ARG_2 * 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 an SCB from host memory based on the * DIRECTION bit in DMAPARAMS. The host SCB index is in SINDEX. */dma_scb:	mov	A, SINDEX;	if ((ahc->features & AHC_CMD_CHAN) != 0) {		mvi	DINDEX, CCHADDR;		mvi	HSCB_ADDR call set_64byte_addr;		mov	CCSCBPTR, SCBPTR;		test	DMAPARAMS, DIRECTION jz dma_scb_tohost;		if ((ahc->flags & AHC_SCB_BTT) != 0) {			mvi	CCHCNT, SCB_DOWNLOAD_SIZE_64;		} else {			mvi	CCHCNT, SCB_DOWNLOAD_SIZE;		}		mvi	CCSCBCTL, CCARREN|CCSCBEN|CCSCBDIR|CCSCBRESET;		cmp	CCSCBCTL, CCSCBDONE|ARRDONE|CCARREN|CCSCBEN|CCSCBDIR jne .;		jmp	dma_scb_finish;dma_scb_tohost:		mvi	CCHCNT, SCB_UPLOAD_SIZE;		if ((ahc->features & AHC_ULTRA2) == 0) {			mvi	CCSCBCTL, CCSCBRESET;			bmov	CCSCBRAM, SCB_BASE, SCB_UPLOAD_SIZE;			or	CCSCBCTL, CCSCBEN|CCSCBRESET;			test	CCS

⌨️ 快捷键说明

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