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

📄 aic79xx.seq

📁 linux2.6.16版本
💻 SEQ
📖 第 1 页 / 共 5 页
字号:
		or	SIMODE1, ENBUSFREE;	}	mov	SAVED_SCSIID, SCB_SCSIID;	mov	SAVED_LUN, SCB_LUN;	mvi	SEQ_FLAGS, NO_CDB_SENT;END_CRITICAL;	or	SXFRCTL0, SPIOEN;	/*	 * As soon as we get a successful selection, the target	 * should go into the message out phase since we have ATN	 * asserted.	 */	mvi	MSG_OUT, MSG_IDENTIFYFLAG;	/*	 * Main loop for information transfer phases.  Wait for the	 * target to assert REQ before checking MSG, C/D and I/O for	 * the bus phase.	 */mesgin_phasemis:ITloop:	call	phase_lock;	mov	A, LASTPHASE;	test	A, ~P_DATAIN_DT	jz p_data;	cmp	A,P_COMMAND	je p_command;	cmp	A,P_MESGOUT	je p_mesgout;	cmp	A,P_STATUS	je p_status;	cmp	A,P_MESGIN	je p_mesgin;	SET_SEQINTCODE(BAD_PHASE)	jmp	ITloop;			/* Try reading the bus again. *//* * Command phase.  Set up the DMA registers and let 'er rip. */p_command:	test	SEQ_FLAGS, NOT_IDENTIFIED jz p_command_okay;	SET_SEQINTCODE(PROTO_VIOLATION)p_command_okay:	test	MODE_PTR, ~(MK_MODE(M_DFF1, M_DFF1))		jnz p_command_allocate_fifo;	/*	 * Command retry.  Free our current FIFO and	 * re-allocate a FIFO so transfer state is	 * reset.	 */SET_SRC_MODE	M_DFF1;SET_DST_MODE	M_DFF1;	mvi	DFFSXFRCTL, RSTCHN|CLRSHCNT;	SET_MODE(M_SCSI, M_SCSI)p_command_allocate_fifo:	bmov	ALLOCFIFO_SCBPTR, SCBPTR, 2;	call	allocate_fifo;SET_SRC_MODE	M_DFF1;SET_DST_MODE	M_DFF1;	add	NONE, -17, SCB_CDB_LEN;	jnc	p_command_embedded;p_command_from_host:	bmov	HADDR[0], SCB_HOST_CDB_PTR, 9;	mvi	SG_CACHE_PRE, LAST_SEG;	mvi	DFCNTRL, (PRELOADEN|SCSIEN|HDMAEN);	jmp	p_command_xfer;p_command_embedded:	bmov	SHCNT[0], SCB_CDB_LEN,  1;	bmov	DFDAT, SCB_CDB_STORE, 16; 	mvi	DFCNTRL, SCSIEN;p_command_xfer:	and	SEQ_FLAGS, ~NO_CDB_SENT;	if ((ahd->features & AHD_FAST_CDB_DELIVERY) != 0) {		/*		 * To speed up CDB delivery in Rev B, all CDB acks		 * are "released" to the output sync as soon as the		 * command phase starts.  There is only one problem		 * with this approach.  If the target changes phase		 * before all data are sent, we have left over acks		 * that can go out on the bus in a data phase.  Due		 * to other chip contraints, this only happens if		 * the target goes to data-in, but if the acks go		 * out before we can test SDONE, we'll think that		 * the transfer has completed successfully.  Work		 * around this by taking advantage of the 400ns or		 * 800ns dead time between command phase and the REQ		 * of the new phase.  If the transfer has completed		 * successfully, SCSIEN should fall *long* before we		 * see a phase change.  We thus treat any phasemiss		 * that occurs before SCSIEN falls as an incomplete		 * transfer.		 */		test	SSTAT1, PHASEMIS jnz p_command_xfer_failed;		test	DFCNTRL, SCSIEN jnz . - 1;	} else {		test	DFCNTRL, SCSIEN jnz .;	}	/*	 * DMA Channel automatically disabled.	 * Don't allow a data phase if the command	 * was not fully transferred.	 */	test	SSTAT2, SDONE jnz ITloop;p_command_xfer_failed:	or	SEQ_FLAGS, NO_CDB_SENT;	jmp	ITloop;/* * Status phase.  Wait for the data byte to appear, then read it * and store it into the SCB. */SET_SRC_MODE	M_SCSI;SET_DST_MODE	M_SCSI;p_status:	test	SEQ_FLAGS,NOT_IDENTIFIED jnz mesgin_proto_violation;p_status_okay:	mov	SCB_SCSI_STATUS, SCSIDAT;	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 */	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, SCB_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_NONPACKET_TAG as the tag value. */p_mesgout_tag:	test	SCB_CONTROL,TAG_ENB jz  p_mesgout_onebyte;	mov	SCSIDAT, SINDEX;	/* Send the identify message */	call	phase_lock;	cmp	LASTPHASE, P_MESGOUT	jne p_mesgout_done;	and	SCSIDAT,TAG_ENB|SCB_TAG_TYPE,SCB_CONTROL;	call	phase_lock;	cmp	LASTPHASE, P_MESGOUT	jne p_mesgout_done;	mov	SCBPTR 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	SCSIDAT, 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:	/* read the 1st message byte */	mvi	ACCUM		call inb_first;	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:	call	phase_lock;	/* Benign the first time through. */	SET_SEQINTCODE(HOST_MSG_LOOP)	cmp	RETURN_1, EXIT_MSG_LOOP	je ITloop;	cmp	RETURN_1, CONT_MSG_LOOP_WRITE	jne . + 3;	mov	SCSIDAT, RETURN_2;	jmp	host_message_loop;	/* Must be CONT_MSG_LOOP_READ */	mov	NONE, SCSIDAT;	/* ACK Byte */	jmp	host_message_loop;mesgin_ign_wide_residue:	mov	SAVED_MODE, MODE_PTR;	SET_MODE(M_SCSI, M_SCSI)	shr	NEGOADDR, 4, SAVED_SCSIID;	mov	A, NEGCONOPTS;	RESTORE_MODE(SAVED_MODE)	test	A, WIDEXFER jz mesgin_reject;	/* Pull the residue byte */	mvi	REG0	call inb_next;	cmp	REG0, 0x01 jne mesgin_reject;	test	SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL jz . + 2;	test	SCB_TASK_ATTRIBUTE, SCB_XFERLEN_ODD jnz mesgin_done;	SET_SEQINTCODE(IGN_WIDE_RES)	jmp	mesgin_done;mesgin_proto_violation:	SET_SEQINTCODE(PROTO_VIOLATION)	jmp	mesgin_done;mesgin_reject:	mvi	MSG_MESSAGE_REJECT	call mk_mesg;mesgin_done:	mov	NONE,SCSIDAT;		/*dummy read from latch to ACK*/	jmp	ITloop;#define INDEX_DISC_LIST(scsiid, lun)					\	and	A, 0xC0, scsiid;					\	or	SCBPTR, A, lun;						\	clr	SCBPTR[1];						\	and	SINDEX, 0x30, scsiid;					\	shr	SINDEX, 3;	/* Multiply by 2 */			\	add	SINDEX, (SCB_DISCONNECTED_LISTS & 0xFF);		\	mvi	SINDEX[1], ((SCB_DISCONNECTED_LISTS >> 8) & 0xFF)mesgin_identify:	/*	 * Determine whether a target is using tagged or non-tagged	 * transactions by first looking at the transaction stored in	 * the per-device, disconnected array.  If there is no untagged	 * transaction for this target, this must be a tagged transaction.	 */	and	SAVED_LUN, MSG_IDENTIFY_LUNMASK, A;	INDEX_DISC_LIST(SAVED_SCSIID, SAVED_LUN);	bmov	DINDEX, SINDEX, 2;	bmov	REG0, SINDIR, 2;	cmp	REG0[1], SCB_LIST_NULL je snoop_tag;	/* Untagged.  Clear the busy table entry and setup the SCB. */	bmov	DINDIR, ALLONES, 2;	bmov	SCBPTR, REG0, 2;	jmp	setup_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.  After receiving the tag, look for the SCB at SCB locations tag and * tag + 256. */snoop_tag:	if ((ahd->flags & AHD_SEQUENCER_DEBUG) != 0) {		or	SEQ_FLAGS, 0x80;	}	mov	NONE, SCSIDAT;		/* ACK Identify MSG */	call	phase_lock;	if ((ahd->flags & AHD_SEQUENCER_DEBUG) != 0) {		or	SEQ_FLAGS, 0x1;	}	cmp	LASTPHASE, P_MESGIN	jne not_found_ITloop;	if ((ahd->flags & AHD_SEQUENCER_DEBUG) != 0) {		or	SEQ_FLAGS, 0x2;	}	cmp	SCSIBUS, MSG_SIMPLE_Q_TAG jne not_found;get_tag:	clr	SCBPTR[1];	mvi	SCBPTR	call inb_next;	/* tag value */verify_scb:	test	SCB_CONTROL,DISCONNECTED jz verify_other_scb;	mov	A, SAVED_SCSIID;	cmp	SCB_SCSIID, A jne verify_other_scb;	mov	A, SAVED_LUN;	cmp	SCB_LUN, A je setup_SCB_disconnected;verify_other_scb:	xor	SCBPTR[1], 1;	test	SCBPTR[1], 0xFF jnz verify_scb;	jmp	not_found;/* * Ensure that the SCB the tag points to is for * an SCB transaction to the reconnecting target. */setup_SCB:	if ((ahd->flags & AHD_SEQUENCER_DEBUG) != 0) {		or	SEQ_FLAGS, 0x10;	}	test	SCB_CONTROL,DISCONNECTED jz not_found;setup_SCB_disconnected:	and	SCB_CONTROL,~DISCONNECTED;	clr	SEQ_FLAGS;	/* make note of IDENTIFY */	test	SCB_SGPTR, SG_LIST_NULL jnz . + 3;	bmov	ALLOCFIFO_SCBPTR, SCBPTR, 2;	call	allocate_fifo;	/* 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:	SET_SEQINTCODE(NO_MATCH)	jmp	mesgin_done;not_found_ITloop:	SET_SEQINTCODE(NO_MATCH)	jmp	ITloop;/* * We received a "command complete" message.  Put the SCB on the complete * queue and trigger a completion interrupt via the idle loop.  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. */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 complete_nomsg;	SET_SEQINTCODE(MKMSG_FAILED)complete_nomsg:	call	queue_scb_completion;	jmp	await_busfree;BEGIN_CRITICAL;freeze_queue:	/* Cancel any pending select-out. */	test	SSTAT0, SELDO|SELINGO jnz . + 2;	and	SCSISEQ0, ~ENSELO;	mov	ACCUM_SAVE, A;	clr	A;	add	QFREEZE_COUNT, 1;	adc	QFREEZE_COUNT[1], A;	or	SEQ_FLAGS2, SELECTOUT_QFROZEN;	mov	A, ACCUM_SAVE ret;END_CRITICAL;/* * Complete the current FIFO's SCB if data for this same * SCB is not transferring in the other FIFO. */SET_SRC_MODE	M_DFF1;SET_DST_MODE	M_DFF1;pkt_complete_scb_if_fifos_idle:	bmov	ARG_1, SCBPTR, 2;	mvi	DFFSXFRCTL, CLRCHN;	SET_MODE(M_SCSI, M_SCSI)	bmov	SCBPTR, ARG_1, 2;

⌨️ 快捷键说明

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