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

📄 aic79xx.seq

📁 这个linux源代码是很全面的~基本完整了~使用c编译的~由于时间问题我没有亲自测试~但就算用来做参考资料也是非常好的
💻 SEQ
📖 第 1 页 / 共 4 页
字号:
	 * messages (save data pointers/disconnect and command	 * complete) that usually follow a data phase.	 */	call	calc_residual;	/*	 * Go ahead and shut down the DMA engine now.	 */	test	DFCNTRL, DIRECTION jnz data_phase_finish;data_group_fifoflush:	if ((ahd->bugs & AHD_AUTOFLUSH_BUG) != 0) {		or	DFCNTRL, FIFOFLUSH;	}	/*	 * We have enabled the auto-ack feature.  This means	 * that the controller may have already transferred	 * some overrun bytes into the data FIFO and acked them	 * on the bus.  The only way to detect this situation is	 * to wait for LAST_SEG_DONE to come true on a completed	 * transfer and then test to see if the data FIFO is	 * non-empty.  We know there is more data yet to transfer	 * if SG_LIST_NULL is not yet set, thus there cannot be	 * an overrun.	 */	test	SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL jz data_phase_finish;	test	SG_CACHE_SHADOW, LAST_SEG_DONE jz .;	test	DFSTATUS, FIFOEMP jnz data_phase_finish;	/* Overrun */	jmp	p_data;data_phase_finish:	/*	 * If the target has left us in data phase, loop through	 * the dma code again.  We will only loop if there is a	 * data overrun.  	 */	if ((ahd->flags & AHD_TARGETROLE) != 0) {		test	SSTAT0, TARGET jnz data_phase_done;	}	if ((ahd->flags & AHD_INITIATORROLE) != 0) {		test	SSTAT1, REQINIT jz .;		test	SCSIPHASE, DATA_PHASE_MASK jnz p_data;	}data_phase_done:	/* Kill off any pending prefetch */	call	disable_ccsgen;	if ((ahd->flags & AHD_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	DATA_COUNT_ODD, 0x1 jz target_ITloop;		SET_MODE(M_SCSI, M_SCSI);		test	NEGCONOPTS, 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;	}/* * We assume that, even though data may still be * transferring to the host, that the SCSI side of * the DMA engine is now in a static state.  This * allows us to update our notion of where we are * in this transfer. * * If, by chance, we stopped before being able * to fetch additional segments for this transfer, * yet the last S/G was completely exhausted, * call our idle loop until it is able to load * another segment.  This will allow us to immediately * pickup on the next segment on the next data phase. * * If we happened to stop on the last segment, then * our residual information is still correct from * the idle loop and there is no need to perform * any fixups. */calc_residual:	test	SG_CACHE_SHADOW, LAST_SEG jz residual_before_last_seg;	/* Record if we've consumed all S/G entries */	test	MDFFSTAT, SHVALID	jz . + 2;	bmov	SCB_RESIDUAL_DATACNT, SHCNT, 3 ret;	or	SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL ret;residual_before_last_seg:	test    MDFFSTAT, SHVALID	jnz sgptr_fixup;	/*	 * Can never happen from an interrupt as the packetized	 * hardware will only interrupt us once SHVALID or	 * LAST_SEG_DONE.	 */	call	data_group_idle_loop;	jmp	calc_residual;sgptr_fixup:	/*	 * Fixup the residual next S/G pointer.  The S/G preload	 * feature of the chip allows us to load two elements	 * in addition to the currently active element.  We	 * store the bottom byte of the next S/G pointer in	 * the SG_CACHE_PTR register so we can restore the	 * correct value when the DMA completes.  If the next	 * sg ptr value has advanced to the point where higher	 * bytes in the address have been affected, fix them	 * too.	 */	test	SG_CACHE_SHADOW, 0x80 jz sgptr_fixup_done;	test	SCB_RESIDUAL_SGPTR[0], 0x80 jnz sgptr_fixup_done;	add	SCB_RESIDUAL_SGPTR[1], -1;	adc	SCB_RESIDUAL_SGPTR[2], -1; 	adc	SCB_RESIDUAL_SGPTR[3], -1;sgptr_fixup_done:	and	SCB_RESIDUAL_SGPTR[0], SG_ADDR_MASK, SG_CACHE_SHADOW;	clr	DATA_COUNT_ODD;	test	SG_CACHE_SHADOW, ODD_SEG jz . + 2;	or	DATA_COUNT_ODD, 0x1;	clr	SCB_RESIDUAL_DATACNT[3]; /* We are not the last seg */	bmov	SCB_RESIDUAL_DATACNT, SHCNT, 3 ret;export seq_isr:	nop;	/* Jumps in the first ISR instruction fail on Rev A. */	test	SEQINTSRC, SAVEPTRS	jnz saveptr_intr;	test	SEQINTSRC, CFG4DATA	jnz cfg4data_intr;	test	SEQINTSRC, CFG4ISTAT	jnz cfg4istat_intr;	test	SEQINTSRC, CFG4ICMD	jnz cfg4icmd_intr;	mvi	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. * * The second case is a save pointers on an active FIFO which occurs * if the target changes to a new L_Q or busfrees/QAS' 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:	test	DFCNTRL, HDMAENACK jz snapshot_saveptr;	and	SEQIMODE, ~ENSAVEPTRS;	or	SEQINTCTL, IRET ret;snapshot_saveptr:	mvi	DFFSXFRCTL, CLRCHN;	or	SEQINTCTL, IRET ret;cfg4data_intr:	test	SCB_SGPTR[0], SG_LIST_NULL jnz pkt_handle_overrun;	call	load_first_seg;	call	pkt_handle_xfer;	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.	 */	mvi	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.	 */	call	pkt_handle_status;	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 is 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:	bmov	LONGJMP_SCB, SCBPTR, 2;	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 last_pkt_done;	test	SCSIPHASE, ~DATA_PHASE_MASK jz . + 2;	test	SCSISIGO, ATNO jnz . + 2;	test	SSTAT2, NONPACKREQ jz return;	test	MDFFSTAT, SHVALID jnz pkt_saveptrs;	jmp	return;last_pkt_done:BEGIN_CRITICAL;	if ((ahd->bugs & AHD_AUTOFLUSH_BUG) != 0) {		or	DFCNTRL, FIFOFLUSH;	}	test	SCB_CONTROL, STATUS_RCVD jz wait_pkt_end;	check_overrun;	or	SCB_SGPTR, SG_LIST_NULL;	/*	 * I think it is safe to skip the FIFO check.	 * in this case as LAST_SEG_DONE implies	 * the other FIFO, if ever active for this transfer,	 * has completed.	 */last_pkt_queue_scb:	or	LONGJMP_ADDR[1], INVALID_ADDR;	bmov	ARG_1, SCBPTR, 2;	mvi	DFFSXFRCTL, CLRCHN;	jmp	queue_arg1_scb_completion;last_pkt_complete:	bmov	ARG_1, SCBPTR, 2;	mvi	DFFSXFRCTL, CLRCHN;check_other_fifo:	clc;	call	toggle_dff_mode;	call	check_fifo;	jnc	queue_arg1_scb_completion;return:	ret;wait_pkt_end:	call	setjmp;END_CRITICAL;wait_pkt_end_loop:	test	SEQINTSRC, CTXTDONE jnz pkt_end;	check_overrun;	test	SSTAT2, NONPACKREQ jz return;	test	SEQINTSRC, CTXTDONE jz unexpected_nonpkt_phase;pkt_end:BEGIN_CRITICAL;	check_overrun;	or	LONGJMP_ADDR[1], INVALID_ADDR;	or	SCB_SGPTR, SG_LIST_NULL;	test	SCB_CONTROL, STATUS_RCVD jnz last_pkt_complete;	mvi	DFFSXFRCTL, CLRCHN ret;END_CRITICAL;/* * 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 and handling the common code of these two cases. */pkt_saveptrs:BEGIN_CRITICAL;	if ((ahd->bugs & AHD_AUTOFLUSH_BUG) != 0) {		or	DFCNTRL, FIFOFLUSH;	}	mov	REG0, SEQINTSRC;	mvi	CLRSEQINTSRC, CLRSAVEPTRS;	call	calc_residual;	call	save_pointers;	call	disable_ccsgen;	or	SEQIMODE, ENSAVEPTRS;	or	LONGJMP_ADDR[1], INVALID_ADDR;pkt_saveptrs_check_status:	test	REG0, SAVEPTRS jz unexpected_nonpkt_phase;	test	SCB_CONTROL, STATUS_RCVD jz pkt_saveptrs_clrchn;	jmp	last_pkt_complete;pkt_saveptrs_clrchn:	mvi	DFFSXFRCTL, CLRCHN ret;END_CRITICAL;check_status_overrun:	test	SHCNT[2], 0xFF jz status_IU_done;	mvi	SEQINTCODE, STATUS_OVERRUN;	jmp	status_IU_done;pkt_handle_status:	call	setjmp_setscb;	test	MDFFSTAT, LASTSDONE jnz check_status_overrun;	test	SEQINTSRC, CTXTDONE jz return;status_IU_done:BEGIN_CRITICAL;	if ((ahd->bugs & AHD_AUTOFLUSH_BUG) != 0) {		or	DFCNTRL, FIFOFLUSH;	}	or	LONGJMP_ADDR[1], INVALID_ADDR;	mvi	SCB_SCSI_STATUS, STATUS_PKT_SENSE;	or	SCB_CONTROL, STATUS_RCVD;	jmp	last_pkt_complete;END_CRITICAL;SET_SRC_MODE	M_DFF0;SET_DST_MODE	M_DFF0;BEGIN_CRITICAL;check_fifo:	test	LONGJMP_ADDR[1], INVALID_ADDR jnz return;	mov	A, ARG_2;	cmp	LONGJMP_SCB[1], A	jne return;	mov	A, ARG_1;	cmp	LONGJMP_SCB[0], A	jne return;	stc	ret;END_CRITICAL;/* * 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 . + 3;SET_SRC_MODE	M_DFF0;SET_DST_MODE	M_DFF0;	or	LONGJMP_ADDR[1], INVALID_ADDR;	mvi	DFFSXFRCTL, CLRCHN;	mvi	CLRSINT2, CLRNONPACKREQ;	test	SCSIPHASE, ~(MSG_IN_PHASE|MSG_OUT_PHASE) jnz illegal_phase;	mvi	SEQINTCODE, ENTERING_NONPACK;	jmp	ITloop;illegal_phase:	mvi	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:	mvi	SEQINTCODE, CFG4OVERRUN;	call	freeze_queue;	if ((ahd->bugs & AHD_PKT_BITBUCKET_BUG) == 0) {		SET_MODE(M_SCSI, M_SCSI);		or	SXFRCTL1,BITBUCKET;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, PKT_PRELOAD_AVAIL jz overrun_load_done;		call	load_overrun_buf;		or	DFCNTRL, PRELOADEN;overrun_load_done:	}	test	SEQINTSRC, CTXTDONE jnz 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;	test	SCB_CONTROL, STATUS_RCVD jnz last_pkt_queue_scb;	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];}cfg4icmd_intr:

⌨️ 快捷键说明

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