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

📄 aic79xx.seq

📁 linux-2.6.15.6
💻 SEQ
📖 第 1 页 / 共 5 页
字号:
		 * Rev A.  Snapshot LQISTAT2 so the status is not missed		 * and deffer the test by one instruction.		 */		mov	REG_ISR, LQISTAT2;		test	REG_ISR, LQIWORKONLQ jz main_isr;		test	SEQINTSRC, SAVEPTRS  jz main_isr;		test	LONGJMP_ADDR[1], INVALID_ADDR jz saveptr_active_fifo;		/*		 * Switch to the active FIFO after clearing the snapshot		 * savepointer in the current FIFO.  We do this so that		 * a pending CTXTDONE or SAVEPTR is visible in the active		 * FIFO.  This status is the only way we can detect if we		 * have lost the race (e.g. host paused us) and our attepts		 * to disable the channel occurred after all REQs were		 * already seen and acked (REQINIT never comes true).		 */		mvi	DFFSXFRCTL, CLRCHN;		xor	MODE_PTR, MK_MODE(M_DFF1, M_DFF1);		test	DFCNTRL, DIRECTION jz interrupt_return;		and	DFCNTRL, ~SCSIEN;snapshot_wait_data_valid:		test	SEQINTSRC, (CTXTDONE|SAVEPTRS) jnz snapshot_data_valid;		test	SSTAT1, REQINIT	jz snapshot_wait_data_valid;snapshot_data_valid:		or	DFCNTRL, SCSIEN;		or	SEQINTCTL, IRET ret;snapshot_saveptr:		mvi	DFFSXFRCTL, CLRCHN;		or	SEQINTCTL, IRET ret;main_isr:	}	test	SEQINTSRC, CFG4DATA	jnz cfg4data_intr;	test	SEQINTSRC, CFG4ISTAT	jnz cfg4istat_intr;	test	SEQINTSRC, SAVEPTRS	jnz saveptr_intr;	test	SEQINTSRC, CFG4ICMD	jnz cfg4icmd_intr;	SET_SEQINTCODE(INVALID_SEQINT)/* * There are two types of save pointers interrupts: * The first is a snapshot save pointers where the current FIFO is not * active and contains a snapshot of the current poniter information. * This happens between packets in a stream for a single L_Q.  Since we * are not performing a pointer save, we can safely clear the channel * so it can be used for other transactions.  On RTI capable controllers, * where snapshots can, and are, disabled, the code to handle this type * of snapshot is not active. * * The second case is a save pointers on an active FIFO which occurs * if the target changes to a new L_Q or busfrees/QASes and the transfer * has a residual.  This should occur coincident with a ctxtdone.  We * disable the interrupt and allow our active routine to handle the * save. */saveptr_intr:	if ((ahd->features & AHD_RTI) == 0) {		test	LONGJMP_ADDR[1], INVALID_ADDR jnz snapshot_saveptr;	}saveptr_active_fifo:	and	SEQIMODE, ~ENSAVEPTRS;	or	SEQINTCTL, IRET ret;cfg4data_intr:	test	SCB_SGPTR[0], SG_LIST_NULL jnz pkt_handle_overrun_inc_use_count;	call	load_first_seg;	call	pkt_handle_xfer;	inc	SCB_FIFO_USE_COUNT;interrupt_return:	or	SEQINTCTL, IRET ret;cfg4istat_intr:	call	freeze_queue;	add	NONE, -13, SCB_CDB_LEN;	jnc	cfg4istat_have_sense_addr;	test	SCB_CDB_LEN, SCB_CDB_LEN_PTR jnz cfg4istat_have_sense_addr;	/*	 * Host sets up address/count and enables transfer.	 */	SET_SEQINTCODE(CFG4ISTAT_INTR)	jmp	cfg4istat_setup_handler;cfg4istat_have_sense_addr:	bmov	HADDR, SCB_SENSE_BUSADDR, 4;	mvi	HCNT[1], (AHD_SENSE_BUFSIZE >> 8);	mvi	SG_CACHE_PRE, LAST_SEG;	mvi	DFCNTRL, PRELOADEN|SCSIEN|HDMAEN;cfg4istat_setup_handler:	/*	 * Status pkt is transferring to host.	 * Wait in idle loop for transfer to complete.	 * If a command completed before an attempted	 * task management function completed, notify the host.	 */	test	SCB_TASK_MANAGEMENT, 0xFF jz cfg4istat_no_taskmgmt_func;	SET_SEQINTCODE(TASKMGMT_CMD_CMPLT_OKAY)cfg4istat_no_taskmgmt_func:	call	pkt_handle_status;	or	SEQINTCTL, IRET ret;cfg4icmd_intr:	/*	 * In the case of DMAing a CDB from the host, the normal	 * CDB buffer is formatted with an 8 byte address followed	 * by a 1 byte count.	 */	bmov	HADDR[0], SCB_HOST_CDB_PTR, 9;	mvi	SG_CACHE_PRE, LAST_SEG;	mvi	DFCNTRL, (PRELOADEN|SCSIEN|HDMAEN);	call	pkt_handle_cdb;	or	SEQINTCTL, IRET ret;/* * See if the target has gone on in this context creating an * overrun condition.  For the write case, the hardware cannot * ack bytes until data are provided.  So, if the target begins * another  packet without changing contexts, implying we are * not sitting on a packet boundary, we are in an overrun * situation.  For the read case, the hardware will continue to * ack bytes into the FIFO, and may even ack the last overrun packet * into the FIFO.   If the FIFO should become non-empty, we are in * a read overrun case. */#define check_overrun							\	/* Not on a packet boundary. */					\	test 	MDFFSTAT, DLZERO jz pkt_handle_overrun;			\	test	DFSTATUS, FIFOEMP jz pkt_handle_overrunpkt_handle_xfer:	test	SG_STATE, LOADING_NEEDED jz pkt_last_seg;	call	setjmp;	test	SEQINTSRC, SAVEPTRS jnz pkt_saveptrs;	test	SCSIPHASE, ~DATA_PHASE_MASK jz . + 2;	test	SCSISIGO, ATNO jnz . + 2;	test	SSTAT2, NONPACKREQ jz pkt_service_fifo;	/*	 * Defer handling of this NONPACKREQ until we	 * can be sure it pertains to this FIFO.  SAVEPTRS	 * will not be asserted if the NONPACKREQ is for us,	 * so we must simulate it if shaddow is valid.  If	 * shaddow is not valid, keep running this FIFO until we	 * have satisfied the transfer by loading segments and	 * waiting for either shaddow valid or last_seg_done.	 */	test	MDFFSTAT, SHVALID jnz pkt_saveptrs;pkt_service_fifo:	test	SG_STATE, LOADING_NEEDED jnz service_fifo;pkt_last_seg:	call	setjmp;	test	SEQINTSRC, SAVEPTRS jnz pkt_saveptrs;	test	SG_CACHE_SHADOW, LAST_SEG_DONE jnz pkt_last_seg_done;	test	SCSIPHASE, ~DATA_PHASE_MASK jz . + 2;	test	SCSISIGO, ATNO jnz . + 2;	test	SSTAT2, NONPACKREQ jz return;	test	MDFFSTAT, SHVALID jz return;	/* FALLTHROUGH *//* * Either a SAVEPTRS interrupt condition is pending for this FIFO * or we have a pending NONPACKREQ for this FIFO.  We differentiate * between the two by capturing the state of the SAVEPTRS interrupt * prior to clearing this status and executing the common code for * these two cases. */pkt_saveptrs:BEGIN_CRITICAL;	if ((ahd->bugs & AHD_AUTOFLUSH_BUG) != 0) {		or	DFCNTRL, FIFOFLUSH;	}	mov	REG0, SEQINTSRC;	call	calc_residual;	call	save_pointers;	mvi	CLRSEQINTSRC, CLRSAVEPTRS;	call	disable_ccsgen;	or	SEQIMODE, ENSAVEPTRS;	test	DFCNTRL, DIRECTION jnz pkt_saveptrs_check_status;	test	DFSTATUS, FIFOEMP jnz pkt_saveptrs_check_status;	/*	 * Keep a handler around for this FIFO until it drains	 * to the host to guarantee that we don't complete the	 * command to the host before the data arrives.	 */pkt_saveptrs_wait_fifoemp:	call	setjmp;	test	DFSTATUS, FIFOEMP jz return;pkt_saveptrs_check_status:	or	LONGJMP_ADDR[1], INVALID_ADDR;	test	REG0, SAVEPTRS jz unexpected_nonpkt_phase;	dec	SCB_FIFO_USE_COUNT;	test	SCB_CONTROL, STATUS_RCVD jnz pkt_complete_scb_if_fifos_idle;	mvi	DFFSXFRCTL, CLRCHN ret;END_CRITICAL;/* * LAST_SEG_DONE status has been seen in the current FIFO. * This indicates that all of the allowed data for this * command has transferred across the SCSI and host buses. * Check for overrun and see if we can complete this command. */pkt_last_seg_done:BEGIN_CRITICAL;	/*	 * Mark transfer as completed.	 */	or	SCB_SGPTR, SG_LIST_NULL;	/*	 * Wait for the current context to finish to verify that	 * no overrun condition has occurred.	 */	test	SEQINTSRC, CTXTDONE jnz pkt_ctxt_done;	call	setjmp;pkt_wait_ctxt_done_loop:	test	SEQINTSRC, CTXTDONE jnz pkt_ctxt_done;	/*	 * A sufficiently large overrun or a NONPACKREQ may	 * prevent CTXTDONE from ever asserting, so we must	 * poll for these statuses too.	 */	check_overrun;	test	SSTAT2, NONPACKREQ jz return;	test	SEQINTSRC, CTXTDONE jz unexpected_nonpkt_phase;	/* FALLTHROUGH */pkt_ctxt_done:	check_overrun;	or	LONGJMP_ADDR[1], INVALID_ADDR;	/*	 * If status has been received, it is safe to skip	 * the check to see if another FIFO is active because	 * LAST_SEG_DONE has been observed.  However, we check	 * the FIFO anyway since it costs us only one extra	 * instruction to leverage common code to perform the	 * SCB completion.	 */	dec	SCB_FIFO_USE_COUNT;	test	SCB_CONTROL, STATUS_RCVD jnz pkt_complete_scb_if_fifos_idle;	mvi	DFFSXFRCTL, CLRCHN ret;END_CRITICAL;/* * Must wait until CDB xfer is over before issuing the * clear channel. */pkt_handle_cdb:	call	setjmp;	test	SG_CACHE_SHADOW, LAST_SEG_DONE jz return;	or	LONGJMP_ADDR[1], INVALID_ADDR;	mvi	DFFSXFRCTL, CLRCHN ret;/* * Watch over the status transfer.  Our host sense buffer is * large enough to take the maximum allowed status packet. * None-the-less, we must still catch and report overruns to * the host.  Additionally, properly catch unexpected non-packet * phases that are typically caused by CRC errors in status packet * transmission. */pkt_handle_status:	call	setjmp;	test	SG_CACHE_SHADOW, LAST_SEG_DONE jnz pkt_status_check_overrun;	test	SEQINTSRC, CTXTDONE jz pkt_status_check_nonpackreq;	test	SG_CACHE_SHADOW, LAST_SEG_DONE jnz pkt_status_check_overrun;pkt_status_IU_done:	if ((ahd->bugs & AHD_AUTOFLUSH_BUG) != 0) {		or	DFCNTRL, FIFOFLUSH;	}	test	DFSTATUS, FIFOEMP jz return;BEGIN_CRITICAL;	or	LONGJMP_ADDR[1], INVALID_ADDR;	mvi	SCB_SCSI_STATUS, STATUS_PKT_SENSE;	or	SCB_CONTROL, STATUS_RCVD;	jmp	pkt_complete_scb_if_fifos_idle;END_CRITICAL;pkt_status_check_overrun:	/*	 * Status PKT overruns are uncerimoniously recovered with a	 * bus reset.  If we've overrun, let the host know so that	 * recovery can be performed.	 *	 * LAST_SEG_DONE has been observed.  If either CTXTDONE or	 * a NONPACKREQ phase change have occurred and the FIFO is	 * empty, there is no overrun.	 */	test	DFSTATUS, FIFOEMP jz pkt_status_report_overrun;	test	SEQINTSRC, CTXTDONE jz . + 2;	test	DFSTATUS, FIFOEMP jnz pkt_status_IU_done;	test	SCSIPHASE, ~DATA_PHASE_MASK jz return;	test	DFSTATUS, FIFOEMP jnz pkt_status_check_nonpackreq;pkt_status_report_overrun:	SET_SEQINTCODE(STATUS_OVERRUN)	/* SEQUENCER RESTARTED */pkt_status_check_nonpackreq:	/*	 * CTXTDONE may be held off if a NONPACKREQ is associated with	 * the current context.  If a NONPACKREQ is observed, decide	 * if it is for the current context.  If it is for the current	 * context, we must defer NONPACKREQ processing until all data	 * has transferred to the host.	 */	test	SCSIPHASE, ~DATA_PHASE_MASK jz return;	test	SCSISIGO, ATNO jnz . + 2;	test	SSTAT2, NONPACKREQ jz return;	test	SEQINTSRC, CTXTDONE jnz pkt_status_IU_done;	test	DFSTATUS, FIFOEMP jz return;	/*	 * The unexpected nonpkt phase handler assumes that any	 * data channel use will have a FIFO reference count.  It	 * turns out that the status handler doesn't need a refernce	 * count since the status received flag, and thus completion	 * processing, cannot be set until the handler is finished.	 * We increment the count here to make the nonpkt handler	 * happy.	 */	inc	SCB_FIFO_USE_COUNT;	/* FALLTHROUGH *//* * Nonpackreq is a polled status.  It can come true in three situations: * we have received an L_Q, we have sent one or more L_Qs, or there is no * L_Q context associated with this REQ (REQ occurs immediately after a * (re)selection).  Routines that know that the context responsible for this * nonpackreq call directly into unexpected_nonpkt_phase.  In the case of the * top level idle loop, we exhaust all active contexts prior to determining that * we simply do not have the full I_T_L_Q for this phase. */unexpected_nonpkt_phase_find_ctxt:	/*	 * This nonpackreq is most likely associated with one of the tags	 * in a FIFO or an outgoing LQ.  Only treat it as an I_T only	 * nonpackreq if we've cleared out the FIFOs and handled any	 * pending SELDO.	 */SET_SRC_MODE	M_SCSI;SET_DST_MODE	M_SCSI;	and	A, FIFO1FREE|FIFO0FREE, DFFSTAT;	cmp	A, FIFO1FREE|FIFO0FREE jne return;	test	SSTAT0, SELDO jnz return;	mvi	SCBPTR[1], SCB_LIST_NULL;unexpected_nonpkt_phase:	test	MODE_PTR, ~(MK_MODE(M_DFF1, M_DFF1))		jnz unexpected_nonpkt_mode_cleared;SET_SRC_MODE	M_DFF0;SET_DST_MODE	M_DFF0;	or	LONGJMP_ADDR[1], INVALID_ADDR;	dec	SCB_FIFO_USE_COUNT;	mvi	DFFSXFRCTL, CLRCHN;unexpected_nonpkt_mode_cleared:	mvi	CLRSINT2, CLRNONPACKREQ;	test	SCSIPHASE, ~(MSG_IN_PHASE|MSG_OUT_PHASE) jnz illegal_phase;	SET_SEQINTCODE(ENTERING_NONPACK)	jmp	ITloop;illegal_phase:	SET_SEQINTCODE(ILLEGAL_PHASE)	jmp	ITloop;/* * We have entered an overrun situation.  If we have working * BITBUCKET, flip that on and let the hardware eat any overrun * data.  Otherwise use an overrun buffer in the host to simulate * BITBUCKET. */pkt_handle_overrun_inc_use_count:	inc	SCB_FIFO_USE_COUNT;pkt_handle_overrun:	SET_SEQINTCODE(CFG4OVERRUN)	call	freeze_queue;	if ((ahd->bugs & AHD_PKT_BITBUCKET_BUG) == 0) {		or	DFFSXFRCTL, DFFBITBUCKET;SET_SRC_MODE	M_DFF1;SET_DST_MODE	M_DFF1;	} else {		call	load_overrun_buf;		mvi	DFCNTRL, (HDMAEN|SCSIEN|PRELOADEN);	}	call	setjmp;	if ((ahd->bugs & AHD_PKT_BITBUCKET_BUG) != 0) {		test	DFSTATUS, PRELOAD_AVAIL jz overrun_load_done;		call	load_overrun_buf;		or	DFCNTRL, PRELOADEN;overrun_load_done:		test	SEQINTSRC, CTXTDONE jnz pkt_overrun_end;	} else {		test	DFFSXFRCTL, DFFBITBUCKET jz pkt_overrun_end;	}	test	SSTAT2, NONPACKREQ jz return;pkt_overrun_end:	or	SCB_RESIDUAL_SGPTR, SG_OVERRUN_RESID;	test	SEQINTSRC, CTXTDONE jz unexpected_nonpkt_phase;	dec	SCB_FIFO_USE_COUNT;	or	LONGJMP_ADDR[1], INVALID_ADDR;	test	SCB_CONTROL, STATUS_RCVD jnz pkt_complete_scb_if_fifos_idle;	mvi	DFFSXFRCTL, CLRCHN ret;if ((ahd->bugs & AHD_PKT_BITBUCKET_BUG) != 0) {load_overrun_buf:	/*	 * Load a dummy segment if preload space is available.	 */	mov 	HADDR[0], SHARED_DATA_ADDR;	add	HADDR[1], PKT_OVERRUN_BUFOFFSET, SHARED_DATA_ADDR[1];	mov	ACCUM_SAVE, A;	clr	A;	adc	HADDR[2], A, SHARED_DATA_ADDR[2];	adc	HADDR[3], A, SHARED_DATA_ADDR[3];	mov	A, ACCUM_SAVE;	bmov	HADDR[4], ALLZEROS, 4;	/* PKT_OVERRUN_BUFSIZE is a multiple of 256 */	clr	HCNT[0];	mvi	HCNT[1], ((PKT_OVERRUN_BUFSIZE >> 8) & 0xFF);	clr	HCNT[2] ret;}

⌨️ 快捷键说明

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