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

📄 aic79xx.seq

📁 linux-2.6.15.6
💻 SEQ
📖 第 1 页 / 共 5 页
字号:
	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.  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 complete_nomsg;	SET_SEQINTCODE(MKMSG_FAILED)complete_nomsg:	call	queue_scb_completion;	jmp	await_busfree;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;/* * 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;	test	SCB_FIFO_USE_COUNT, 0xFF jnz return;queue_scb_completion:	test	SCB_SCSI_STATUS,0xff	jnz bad_status;	/*	 * Check for residuals	 */	test	SCB_SGPTR, SG_LIST_NULL jnz complete;	/* No xfer */	test	SCB_SGPTR, SG_FULL_RESID jnz upload_scb;/* Never xfered */	test	SCB_RESIDUAL_SGPTR, SG_LIST_NULL jz upload_scb;complete:	bmov	SCB_NEXT_COMPLETE, COMPLETE_SCB_HEAD, 2;	bmov	COMPLETE_SCB_HEAD, SCBPTR, 2 ret;bad_status:	cmp	SCB_SCSI_STATUS, STATUS_PKT_SENSE je upload_scb;	call	freeze_queue;upload_scb:	/*	 * Restore SCB TAG since we reuse this field	 * in the sequencer.  We don't want to corrupt	 * it on the host.	 */	bmov	SCB_TAG, SCBPTR, 2;	bmov	SCB_NEXT_COMPLETE, COMPLETE_DMA_SCB_HEAD, 2;	bmov	COMPLETE_DMA_SCB_HEAD, SCBPTR, 2;	or	SCB_SGPTR, SG_STATUS_VALID ret;/* * 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;	test	SCB_CONTROL, TAG_ENB jnz await_busfree;queue_disc_scb:	bmov	REG0, SCBPTR, 2;	INDEX_DISC_LIST(SAVED_SCSIID, SAVED_LUN);	bmov	DINDEX, SINDEX, 2;	bmov	DINDIR, REG0, 2;	bmov	SCBPTR, REG0, 2;	/* FALLTHROUGH */await_busfree:	and	SIMODE1, ~ENBUSFREE;	if ((ahd->bugs & AHD_BUSFREEREV_BUG) == 0) {		/*		 * In the BUSFREEREV_BUG case, the		 * busfree status was cleared at the		 * beginning of the connection.		 */		mvi	CLRSINT1,CLRBUSFREE;	}	mov	NONE, SCSIDAT;		/* Ack the last byte */	test	MODE_PTR, ~(MK_MODE(M_DFF1, M_DFF1))		jnz await_busfree_not_m_dff;SET_SRC_MODE	M_DFF1;SET_DST_MODE	M_DFF1;await_busfree_clrchn:	mvi	DFFSXFRCTL, CLRCHN;await_busfree_not_m_dff:	call	clear_target_state;	test	SSTAT1,REQINIT|BUSFREE	jz .;	test	SSTAT1, BUSFREE jnz idle_loop;	SET_SEQINTCODE(MISSED_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. */SET_SRC_MODE	M_DFF1;SET_DST_MODE	M_DFF1;mesgin_sdptrs:	mov	NONE,SCSIDAT;		/*dummy read from latch to ACK*/	test	SEQ_FLAGS, DPHASE	jz ITloop;	call	save_pointers;	jmp	ITloop;save_pointers:	/*	 * 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 save_pointers_full;	or	SCB_SGPTR, SG_LIST_NULL ret;save_pointers_full:	/*	 * The SCB_DATAPTR becomes the current SHADDR.	 * All other information comes directly from our residual	 * state.	 */	bmov	SCB_DATAPTR, SHADDR, 8;	bmov	SCB_DATACNT, SCB_RESIDUAL_DATACNT, 8 ret;/* * 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;	test	MODE_PTR, ~(MK_MODE(M_DFF1, M_DFF1)) jnz msgin_rdptrs_get_fifo;	mvi	DFFSXFRCTL, RSTCHN|CLRSHCNT;	SET_MODE(M_SCSI, M_SCSI)msgin_rdptrs_get_fifo:	call	allocate_fifo;	jmp	mesgin_done;clear_target_state:	mvi	LASTPHASE, P_BUSFREE;	/* clear target specific flags */	mvi	SEQ_FLAGS, NOT_IDENTIFIED|NO_CDB_SENT ret;phase_lock:     	if ((ahd->bugs & AHD_EARLY_REQ_BUG) != 0) {		/*		 * Don't ignore persistent REQ assertions just because		 * they were asserted within the bus settle delay window.		 * This allows us to tolerate devices like the GEM318		 * that violate the SCSI spec.  We are careful not to		 * count REQ while we are waiting for it to fall during		 * an async phase due to our asserted ACK.  Each		 * sequencer instruction takes ~25ns, so the REQ must		 * last at least 100ns in order to be counted as a true		 * REQ.		 */		test	SCSIPHASE, 0xFF jnz phase_locked;		test	SCSISIGI, ACKI jnz phase_lock;		test	SCSISIGI, REQI jz phase_lock;		test	SCSIPHASE, 0xFF jnz phase_locked;		test	SCSISIGI, ACKI jnz phase_lock;		test	SCSISIGI, REQI jz phase_lock;phase_locked:	} else {		test	SCSIPHASE, 0xFF jz .;	}	test	SSTAT1, SCSIPERR jnz phase_lock;phase_lock_latch_phase:	and	LASTPHASE, PHASE_MASK, SCSISIGI ret;

⌨️ 快捷键说明

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