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

📄 aic7xxx.seq

📁 linux-2.6.15.6
💻 SEQ
📖 第 1 页 / 共 5 页
字号:
	 * are now initialized.  Clear the full residual flag.	 */	and	SCB_SGPTR[0], ~SG_FULL_RESID;	if ((ahc->features & AHC_ULTRA2) != 0) {		/* Clear the channel in case we return to data phase later */		or	SXFRCTL0, CLRSTCNT|CLRCHN;		or	SXFRCTL0, CLRSTCNT|CLRCHN;	}	if ((ahc->flags & AHC_TARGETROLE) != 0) {		test	SEQ_FLAGS, DPHASE_PENDING jz ITloop;		and	SEQ_FLAGS, ~DPHASE_PENDING;		/*		 * For data-in phases, wait for any pending acks from the		 * initiator before changing phase.  We only need to		 * send Ignore Wide Residue messages for data-in phases.		 */		test	DFCNTRL, DIRECTION jz target_ITloop;		test	SSTAT1, REQINIT	jnz .;		test	SCB_LUN, SCB_XFERLEN_ODD jz target_ITloop;		test	SCSIRATE, WIDEXFER jz target_ITloop;		/*		 * Issue an Ignore Wide Residue Message.		 */		mvi	P_MESGIN|BSYO call change_phase;		mvi	MSG_IGN_WIDE_RESIDUE call target_outb;		mvi	1 call target_outb;		jmp	target_ITloop;	} else {		jmp	ITloop;	}if ((ahc->flags & AHC_INITIATORROLE) != 0) {/* * Command phase.  Set up the DMA registers and let 'er rip. */p_command:	test	SEQ_FLAGS, NOT_IDENTIFIED jz p_command_okay;	mvi	PROTO_VIOLATION call set_seqint;p_command_okay:	if ((ahc->features & AHC_ULTRA2) != 0) {		bmov	HCNT[0], SCB_CDB_LEN,  1;		bmov	HCNT[1], ALLZEROS, 2;		mvi	SG_CACHE_PRE, LAST_SEG;	} else if ((ahc->features & AHC_CMD_CHAN) != 0) {		bmov	STCNT[0], SCB_CDB_LEN, 1;		bmov	STCNT[1], ALLZEROS, 2;	} else {		mov	STCNT[0], SCB_CDB_LEN;		clr	STCNT[1];		clr	STCNT[2];	}	add	NONE, -13, SCB_CDB_LEN;	mvi	SCB_CDB_STORE jnc p_command_embedded;p_command_from_host:	if ((ahc->features & AHC_ULTRA2) != 0) {		bmov	HADDR[0], SCB_CDB_PTR, 4;		mvi	DFCNTRL, (PRELOADEN|SCSIEN|HDMAEN|DIRECTION);	} else {		if ((ahc->features & AHC_CMD_CHAN) != 0) {			bmov	HADDR[0], SCB_CDB_PTR, 4;			bmov	HCNT, STCNT, 3;		} else {			mvi	DINDEX, HADDR;			mvi	SCB_CDB_PTR call bcopy_4;			mov	SCB_CDB_LEN call set_hcnt;		}		mvi	DFCNTRL, (SCSIEN|SDMAEN|HDMAEN|DIRECTION|FIFORESET);	}	jmp	p_command_xfer;p_command_embedded:	/*	 * The data fifo seems to require 4 byte aligned	 * transfers from the sequencer.  Force this to	 * be the case by clearing HADDR[0] even though	 * we aren't going to touch host memory.	 */	clr	HADDR[0];	if ((ahc->features & AHC_ULTRA2) != 0) {		mvi	DFCNTRL, (PRELOADEN|SCSIEN|DIRECTION);		bmov	DFDAT, SCB_CDB_STORE, 12; 	} else if ((ahc->features & AHC_CMD_CHAN) != 0) {		if ((ahc->flags & AHC_SCB_BTT) != 0) {			/*			 * On the 7895 the data FIFO will			 * get corrupted if you try to dump			 * data from external SCB memory into			 * the FIFO while it is enabled.  So,			 * fill the fifo and then enable SCSI			 * transfers.			 */			mvi	DFCNTRL, (DIRECTION|FIFORESET);		} else {			mvi	DFCNTRL, (SCSIEN|SDMAEN|DIRECTION|FIFORESET);		}		bmov	DFDAT, SCB_CDB_STORE, 12; 		if ((ahc->flags & AHC_SCB_BTT) != 0) {			mvi	DFCNTRL, (SCSIEN|SDMAEN|DIRECTION|FIFOFLUSH);		} else {			or	DFCNTRL, FIFOFLUSH;		}	} else {		mvi	DFCNTRL, (SCSIEN|SDMAEN|DIRECTION|FIFORESET);		call	copy_to_fifo_6;		call	copy_to_fifo_6;		or	DFCNTRL, FIFOFLUSH;	}p_command_xfer:	and	SEQ_FLAGS, ~NO_CDB_SENT;	if ((ahc->features & AHC_DT) == 0) {		test	SSTAT0, SDONE jnz . + 2;		test    SSTAT1, PHASEMIS jz . - 1;		/*		 * Wait for our ACK to go-away on it's own		 * instead of being killed by SCSIEN getting cleared.		 */		test	SCSISIGI, ACKI jnz .;	} else {		test	DFCNTRL, SCSIEN jnz .;	}	test	SSTAT0, SDONE jnz p_command_successful;	/*	 * Don't allow a data phase if the command	 * was not fully transferred.	 */	or	SEQ_FLAGS, NO_CDB_SENT;p_command_successful:	and	DFCNTRL, ~(SCSIEN|SDMAEN|HDMAEN);	test	DFCNTRL, (SCSIEN|SDMAEN|HDMAEN) jnz .;	jmp	ITloop;/* * Status phase.  Wait for the data byte to appear, then read it * and store it into the SCB. */p_status:	test	SEQ_FLAGS, NOT_IDENTIFIED jnz mesgin_proto_violation;p_status_okay:	mov	SCB_SCSI_STATUS, SCSIDATL;	or	SCB_CONTROL, STATUS_RCVD;	jmp	ITloop;/* * Message out phase.  If MSG_OUT is MSG_IDENTIFYFLAG, build a full * indentify message sequence and send it to the target.  The host may * override this behavior by setting the MK_MESSAGE bit in the SCB * control byte.  This will cause us to interrupt the host and allow * it to handle the message phase completely on its own.  If the bit * associated with this target is set, we will also interrupt the host, * thereby allowing it to send a message on the next selection regardless * of the transaction being sent. *  * If MSG_OUT is == HOST_MSG, also interrupt the host and take a message. * This is done to allow the host to send messages outside of an identify * sequence while protecting the seqencer from testing the MK_MESSAGE bit * on an SCB that might not be for the current nexus. (For example, a * BDR message in responce to a bad reselection would leave us pointed to * an SCB that doesn't have anything to do with the current target). * * Otherwise, treat MSG_OUT as a 1 byte message to send (abort, abort tag, * bus device reset). * * When there are no messages to send, MSG_OUT should be set to MSG_NOOP, * in case the target decides to put us in this phase for some strange * reason. */p_mesgout_retry:	/* Turn on ATN for the retry */	if ((ahc->features & AHC_DT) == 0) {		or	SCSISIGO, ATNO, LASTPHASE;	} else {		mvi	SCSISIGO, ATNO;	}p_mesgout:	mov	SINDEX, MSG_OUT;	cmp	SINDEX, MSG_IDENTIFYFLAG jne p_mesgout_from_host;	test	SCB_CONTROL,MK_MESSAGE	jnz host_message_loop;p_mesgout_identify:	or	SINDEX, MSG_IDENTIFYFLAG|DISCENB, SAVED_LUN;	test	SCB_CONTROL, DISCENB jnz . + 2;	and	SINDEX, ~DISCENB;/* * Send a tag message if TAG_ENB is set in the SCB control block. * Use SCB_TAG (the position in the kernel's SCB array) as the tag value. */p_mesgout_tag:	test	SCB_CONTROL,TAG_ENB jz  p_mesgout_onebyte;	mov	SCSIDATL, SINDEX;	/* Send the identify message */	call	phase_lock;	cmp	LASTPHASE, P_MESGOUT	jne p_mesgout_done;	and	SCSIDATL,TAG_ENB|SCB_TAG_TYPE,SCB_CONTROL;	call	phase_lock;	cmp	LASTPHASE, P_MESGOUT	jne p_mesgout_done;	mov	SCB_TAG	jmp p_mesgout_onebyte;/* * Interrupt the driver, and allow it to handle this message * phase and any required retries. */p_mesgout_from_host:	cmp	SINDEX, HOST_MSG	jne p_mesgout_onebyte;	jmp	host_message_loop;p_mesgout_onebyte:	mvi	CLRSINT1, CLRATNO;	mov	SCSIDATL, SINDEX;/* * If the next bus phase after ATN drops is message out, it means * that the target is requesting that the last message(s) be resent. */	call	phase_lock;	cmp	LASTPHASE, P_MESGOUT	je p_mesgout_retry;p_mesgout_done:	mvi	CLRSINT1,CLRATNO;	/* Be sure to turn ATNO off */	mov	LAST_MSG, MSG_OUT;	mvi	MSG_OUT, MSG_NOOP;	/* No message left */	jmp	ITloop;/* * Message in phase.  Bytes are read using Automatic PIO mode. */p_mesgin:	mvi	ACCUM		call inb_first;	/* read the 1st message byte */	test	A,MSG_IDENTIFYFLAG	jnz mesgin_identify;	cmp	A,MSG_DISCONNECT	je mesgin_disconnect;	cmp	A,MSG_SAVEDATAPOINTER	je mesgin_sdptrs;	cmp	ALLZEROS,A		je mesgin_complete;	cmp	A,MSG_RESTOREPOINTERS	je mesgin_rdptrs;	cmp	A,MSG_IGN_WIDE_RESIDUE	je mesgin_ign_wide_residue;	cmp	A,MSG_NOOP		je mesgin_done;/* * Pushed message loop to allow the kernel to * run it's own message state engine.  To avoid an * extra nop instruction after signaling the kernel, * we perform the phase_lock before checking to see * if we should exit the loop and skip the phase_lock * in the ITloop.  Performing back to back phase_locks * shouldn't hurt, but why do it twice... */host_message_loop:	mvi	HOST_MSG_LOOP call set_seqint;	call	phase_lock;	cmp	RETURN_1, EXIT_MSG_LOOP	je ITloop + 1;	jmp	host_message_loop;mesgin_ign_wide_residue:if ((ahc->features & AHC_WIDE) != 0) {	test	SCSIRATE, WIDEXFER jz mesgin_reject;	/* Pull the residue byte */	mvi	ARG_1	call inb_next;	cmp	ARG_1, 0x01 jne mesgin_reject;	test	SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL jz . + 2;	test	SCB_LUN, SCB_XFERLEN_ODD jnz mesgin_done;	mvi	IGN_WIDE_RES call set_seqint;	jmp	mesgin_done;}mesgin_proto_violation:	mvi	PROTO_VIOLATION call set_seqint;	jmp	mesgin_done;mesgin_reject:	mvi	MSG_MESSAGE_REJECT	call mk_mesg;mesgin_done:	mov	NONE,SCSIDATL;		/*dummy read from latch to ACK*/	jmp	ITloop;/* * We received a "command complete" message.  Put the SCB_TAG into the QOUTFIFO, * and trigger a completion interrupt.  Before doing so, check to see if there * is a residual or the status byte is something other than STATUS_GOOD (0). * In either of these conditions, we upload the SCB back to the host so it can * process this information.  In the case of a non zero status byte, we  * additionally interrupt the kernel driver synchronously, allowing it to * decide if sense should be retrieved.  If the kernel driver wishes to request * sense, it will fill the kernel SCB with a request sense command, requeue * it to the QINFIFO and tell us not to post to the QOUTFIFO by setting  * RETURN_1 to SEND_SENSE. */mesgin_complete:	/*	 * If ATN is raised, we still want to give the target a message.	 * Perhaps there was a parity error on this last message byte.	 * Either way, the target should take us to message out phase	 * and then attempt to complete the command again.  We should use a	 * critical section here to guard against a timeout triggering	 * for this command and setting ATN while we are still processing	 * the completion.	test	SCSISIGI, ATNI jnz mesgin_done;	 */	/*	 * If we are identified and have successfully sent the CDB,	 * any status will do.  Optimize this fast path.	 */	test	SCB_CONTROL, STATUS_RCVD jz mesgin_proto_violation;	test	SEQ_FLAGS, NOT_IDENTIFIED|NO_CDB_SENT jz complete_accepted; 	/*	 * If the target never sent an identify message but instead went	 * to mesgin to give an invalid message, let the host abort us.	 */	test	SEQ_FLAGS, NOT_IDENTIFIED jnz mesgin_proto_violation;	/*	 * If we recevied good status but never successfully sent the	 * cdb, abort the command.	 */	test	SCB_SCSI_STATUS,0xff	jnz complete_accepted;	test	SEQ_FLAGS, NO_CDB_SENT jnz mesgin_proto_violation;complete_accepted:	/*	 * See if we attempted to deliver a message but the target ingnored us.	 */	test	SCB_CONTROL, MK_MESSAGE jz . + 2;	mvi	MKMSG_FAILED call set_seqint;	/*	 * Check for residuals	 */	test	SCB_SGPTR, SG_LIST_NULL jnz check_status;/* No xfer */	test	SCB_SGPTR, SG_FULL_RESID jnz upload_scb;/* Never xfered */	test	SCB_RESIDUAL_SGPTR, SG_LIST_NULL jz upload_scb;check_status:	test	SCB_SCSI_STATUS,0xff	jz complete;	/* Good Status? */upload_scb:	or	SCB_SGPTR, SG_RESID_VALID;	mvi	DMAPARAMS, FIFORESET;	mov	SCB_TAG		call dma_scb;	test	SCB_SCSI_STATUS, 0xff	jz complete;	/* Just a residual? */	mvi	BAD_STATUS call set_seqint;		/* let driver know */	cmp	RETURN_1, SEND_SENSE	jne complete;	call	add_scb_to_free_list;	jmp	await_busfree;complete:	mov	SCB_TAG call complete_post;	jmp	await_busfree;}complete_post:	/* Post the SCBID in SINDEX and issue an interrupt */	call	add_scb_to_free_list;	mov	ARG_1, SINDEX;	if ((ahc->features & AHC_QUEUE_REGS) != 0) {		mov	A, SDSCB_QOFF;	} else {		mov	A, QOUTPOS;	}	mvi	QOUTFIFO_OFFSET call post_byte_setup;	mov	ARG_1 call post_byte;	if ((ahc->features & AHC_QUEUE_REGS) == 0) {		inc 	QOUTPOS;	}	mvi	INTSTAT,CMDCMPLT ret;if ((ahc->flags & AHC_INITIATORROLE) != 0) {/* * Is it a disconnect message?  Set a flag in the SCB to remind us * and await the bus going free.  If this is an untagged transaction * store the SCB id for it in our untagged target table for lookup on * a reselction. */mesgin_disconnect:	/*	 * If ATN is raised, we still want to give the target a message.	 * Perhaps there was a parity error on this last message byte	 * or we want to abort this command.  Either way, the target	 * should take us to message out phase and then attempt to	 * disconnect again.	 * XXX - Wait for more testing.	test	SCSISIGI, ATNI jnz mesgin_done;	 */	test	SEQ_FLAGS, NOT_IDENTIFIED|NO_CDB_SENT		jnz mesgin_proto_violation;	or	SCB_CONTROL,DISCONNECTED;	if ((ahc->flags & AHC_PAGESCBS) != 0) {		call	add_scb_to_disc_list;	}	test	SCB_CONTROL, TAG_ENB jnz await_busfree;	mov	ARG_1, SCB_TAG;	and	SAVED_LUN, LID, SCB_LUN;	mov	SCB_SCSIID	call set_busy_target;	jmp	await_busfree;/* * Save data pointers message: * Copying RAM values back to SCB, for Save Data Pointers message, but * only if we've actually been into a data phase to change them.  This * protects against bogus data in scratch ram and the residual counts * since they are only initialized when we go into data_in or data_out. * Ack the message as soon as possible.  For chips without S/G pipelining, * we can only ack the message after SHADDR has been saved.  On these * chips, SHADDR increments with every bus transaction, even PIO. */mesgin_sdptrs:	if ((ahc->features & AHC_ULTRA2) != 0) {		mov	NONE,SCSIDATL;		/*dummy read from latch to ACK*/		test	SEQ_FLAGS, DPHASE	jz ITloop;	} else {		test	SEQ_FLAGS, DPHASE	jz mesgin_done;	}	/*	 * If we are asked to save our position at the end of the	 * transfer, just mark us at the end rather than perform a	 * full save.	 */	test	SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL jz mesgin_sdptrs_full;	or	SCB_SGPTR, SG_LIST_NULL;	if ((ahc->features & AHC_ULTRA2) != 0) {		jmp	ITloop;	} else {		jmp	mesgin_done;	}mesgin_sdptrs_full:	/*	 * The SCB_SGPTR becomes the next one we'll download,	 * and the SCB_DATAPTR becomes the current SHADDR.	 * Use the residual number since STCNT is corrupted by	 * any message transfer.	 */	if ((ahc->features & AHC_CMD_CHAN) != 0) {		bmov	SCB_DATAPTR, SHADDR, 4;		if ((ahc->features & AHC_ULTRA2) == 0) {			mov	NONE,SCSIDATL;	/*dummy read from latch to ACK*/		}		bmov	SCB_DATACNT, SCB_RESIDUAL_DATACNT, 8;	} else {		mvi	DINDEX, SCB_DATAPTR;		mvi	SHADDR call bcopy_4;		mov	NONE,SCSIDATL;	/*dummy read from latch to ACK*/		mvi	SCB_RESIDUAL_DATACNT call bcopy_8;	}	jmp	ITloop;

⌨️ 快捷键说明

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