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

📄 aic79xx.seq

📁 linux 内核源代码
💻 SEQ
📖 第 1 页 / 共 5 页
字号:
scbdma_idle:	/*	 * Don't bother downloading new SCBs to execute	 * if select-outs are currently frozen or we have	 * a MK_MESSAGE SCB waiting to enter the queue.	 */	test	SEQ_FLAGS2, SELECTOUT_QFROZEN|PENDING_MK_MESSAGE		jnz scbdma_no_new_scbs;BEGIN_CRITICAL;	test	QOFF_CTLSTA, NEW_SCB_AVAIL jnz fetch_new_scb;scbdma_no_new_scbs:	cmp	COMPLETE_DMA_SCB_HEAD[1], SCB_LIST_NULL jne dma_complete_scb;	cmp	COMPLETE_SCB_HEAD[1], SCB_LIST_NULL je return;	/* FALLTHROUGH */fill_qoutfifo:	/*	 * Keep track of the SCBs we are dmaing just	 * in case the DMA fails or is aborted.	 */	bmov	COMPLETE_SCB_DMAINPROG_HEAD, COMPLETE_SCB_HEAD, 2;	mvi	CCSCBCTL, CCSCBRESET;	bmov	SCBHADDR, QOUTFIFO_NEXT_ADDR, 4;	mov	A, QOUTFIFO_NEXT_ADDR;	bmov	SCBPTR, COMPLETE_SCB_HEAD, 2;fill_qoutfifo_loop:	bmov	CCSCBRAM, SCBPTR, 2;	mov	CCSCBRAM, SCB_SGPTR[0];	mov	CCSCBRAM, QOUTFIFO_ENTRY_VALID_TAG;	mov	NONE, SDSCB_QOFF;	inc	INT_COALESCING_CMDCOUNT;	add	CMDS_PENDING, -1;	adc	CMDS_PENDING[1], -1;	cmp	SCB_NEXT_COMPLETE[1], SCB_LIST_NULL je fill_qoutfifo_done;	cmp	CCSCBADDR, CCSCBADDR_MAX je fill_qoutfifo_done;	test	QOFF_CTLSTA, SDSCB_ROLLOVR jnz fill_qoutfifo_done;	/*	 * Don't cross an ADB or Cachline boundary when DMA'ing	 * completion entries.  In PCI mode, at least in 32/33	 * configurations, the SCB DMA engine may lose its place	 * in the data-stream should the target force a retry on	 * something other than an 8byte aligned boundary. In	 * PCI-X mode, we do this to avoid split transactions since	 * many chipsets seem to be unable to format proper split	 * completions to continue the data transfer.	 */	add	SINDEX, A, CCSCBADDR;	test	SINDEX, CACHELINE_MASK jz fill_qoutfifo_done;	bmov	SCBPTR, SCB_NEXT_COMPLETE, 2;	jmp	fill_qoutfifo_loop;fill_qoutfifo_done:	mov	SCBHCNT, CCSCBADDR;	mvi	CCSCBCTL, CCSCBEN|CCSCBRESET;	bmov	COMPLETE_SCB_HEAD, SCB_NEXT_COMPLETE, 2;	mvi	SCB_NEXT_COMPLETE[1], SCB_LIST_NULL ret;fetch_new_scb:	bmov	SCBHADDR, NEXT_QUEUED_SCB_ADDR, 4;	mvi	CCARREN|CCSCBEN|CCSCBDIR|CCSCBRESET jmp dma_scb;dma_complete_scb:	bmov	SCBPTR, COMPLETE_DMA_SCB_HEAD, 2;	bmov	SCBHADDR, SCB_BUSADDR, 4;	mvi	CCARREN|CCSCBEN|CCSCBRESET jmp dma_scb;/* * Either post or fetch an SCB from host memory.  The caller * is responsible for polling for transfer completion. * * Prerequisits: Mode == M_CCHAN *		 SINDEX contains CCSCBCTL flags *		 SCBHADDR set to Host SCB address *		 SCBPTR set to SCB src location on "push" operations */SET_SRC_MODE	M_CCHAN;SET_DST_MODE	M_CCHAN;dma_scb:	mvi	SCBHCNT, SCB_TRANSFER_SIZE;	mov	CCSCBCTL, SINDEX ret;setjmp:	/*	 * At least on the A, a return in the same	 * instruction as the bmov results in a return	 * to the caller, not to the new address at the	 * top of the stack.  Since we want the latter	 * (we use setjmp to register a handler from an	 * interrupt context but not invoke that handler	 * until we return to our idle loop), use a	 * separate ret instruction.	 */	bmov	LONGJMP_ADDR, STACK, 2;	ret;setjmp_inline:	bmov	LONGJMP_ADDR, STACK, 2;longjmp:	bmov	STACK, LONGJMP_ADDR, 2 ret;END_CRITICAL;/*************************** Chip Bug Work Arounds ****************************//* * Must disable interrupts when setting the mode pointer * register as an interrupt occurring mid update will * fail to store the new mode value for restoration on * an iret. */if ((ahd->bugs & AHD_SET_MODE_BUG) != 0) {set_mode_work_around:	mvi	SEQINTCTL, INTVEC1DSL;	mov	MODE_PTR, SINDEX;	clr	SEQINTCTL ret;}if ((ahd->bugs & AHD_INTCOLLISION_BUG) != 0) {set_seqint_work_around:	mov	SEQINTCODE, SINDEX;	mvi	SEQINTCODE, NO_SEQINT ret;}/************************ Packetized LongJmp Routines *************************/SET_SRC_MODE	M_SCSI;SET_DST_MODE	M_SCSI;start_selection:BEGIN_CRITICAL;	if ((ahd->bugs & AHD_SENT_SCB_UPDATE_BUG) != 0) {		/*		 * Razor #494		 * Rev A hardware fails to update LAST/CURR/NEXTSCB		 * correctly after a packetized selection in several		 * situations:		 *		 * 1) If only one command existed in the queue, the		 *    LAST/CURR/NEXTSCB are unchanged.		 *		 * 2) In a non QAS, protocol allowed phase change,		 *    the queue is shifted 1 too far.  LASTSCB is		 *    the last SCB that was correctly processed.		 * 		 * 3) In the QAS case, if the full list of commands		 *    was successfully sent, NEXTSCB is NULL and neither		 *    CURRSCB nor LASTSCB can be trusted.  We must		 *    manually walk the list counting MAXCMDCNT elements		 *    to find the last SCB that was sent correctly.		 *		 * To simplify the workaround for this bug in SELDO		 * handling, we initialize LASTSCB prior to enabling		 * selection so we can rely on it even for case #1 above.		 */		bmov	LASTSCB, WAITING_TID_HEAD, 2;	}	bmov	CURRSCB, WAITING_TID_HEAD, 2;	bmov	SCBPTR, WAITING_TID_HEAD, 2;	shr	SELOID, 4, SCB_SCSIID;	/*	 * If we want to send a message to the device, ensure	 * we are selecting with atn irregardless of our packetized	 * agreement.  Since SPI4 only allows target reset or PPR	 * messages if this is a packetized connection, the change	 * to our negotiation table entry for this selection will	 * be cleared when the message is acted on.	 */	test	SCB_CONTROL, MK_MESSAGE jz . + 3;	mov	NEGOADDR, SELOID;	or	NEGCONOPTS, ENAUTOATNO;	or	SCSISEQ0, ENSELO ret;END_CRITICAL;/* * Allocate a FIFO for a non-packetized transaction. * In RevA hardware, both FIFOs must be free before we * can allocate a FIFO for a non-packetized transaction. */allocate_fifo_loop:	/*	 * Do whatever work is required to free a FIFO.	 */	call	idle_loop_service_fifos;	SET_MODE(M_SCSI, M_SCSI)allocate_fifo:	if ((ahd->bugs & AHD_NONPACKFIFO_BUG) != 0) {		and	A, FIFO0FREE|FIFO1FREE, DFFSTAT;		cmp	A, FIFO0FREE|FIFO1FREE jne allocate_fifo_loop;	} else {		test	DFFSTAT, FIFO1FREE jnz allocate_fifo1;		test	DFFSTAT, FIFO0FREE jz allocate_fifo_loop;		mvi	DFFSTAT, B_CURRFIFO_0;		SET_MODE(M_DFF0, M_DFF0)		bmov	SCBPTR, ALLOCFIFO_SCBPTR, 2 ret;	}SET_SRC_MODE	M_SCSI;SET_DST_MODE	M_SCSI;allocate_fifo1:	mvi	DFFSTAT, CURRFIFO_1;	SET_MODE(M_DFF1, M_DFF1)	bmov	SCBPTR, ALLOCFIFO_SCBPTR, 2 ret;/* * We have been reselected as an initiator * or selected as a target. */SET_SRC_MODE	M_SCSI;SET_DST_MODE	M_SCSI;select_in:	if ((ahd->bugs & AHD_FAINT_LED_BUG) != 0) {		/*		 * On Rev A. hardware, the busy LED is only		 * turned on automaically during selections		 * and re-selections.  Make the LED status		 * more useful by forcing it to be on from		 * the point of selection until our idle		 * loop determines that neither of our FIFOs		 * are busy.  This handles the non-packetized		 * case nicely as we will not return to the		 * idle loop until the busfree at the end of		 * each transaction.		 */		or	SBLKCTL, DIAGLEDEN|DIAGLEDON;	}	if ((ahd->bugs & AHD_BUSFREEREV_BUG) != 0) {		/*		 * Test to ensure that the bus has not		 * already gone free prior to clearing		 * any stale busfree status.  This avoids		 * a window whereby a busfree just after		 * a selection could be missed.		 */		test	SCSISIGI, BSYI jz . + 2;		mvi	CLRSINT1,CLRBUSFREE;		or	SIMODE1, ENBUSFREE;	}	or	SXFRCTL0, SPIOEN;	and	SAVED_SCSIID, SELID_MASK, SELID;	and	A, OID, IOWNID;	or	SAVED_SCSIID, A;	mvi	CLRSINT0, CLRSELDI;	jmp	ITloop;/* * We have successfully selected out. * * Clear SELDO. * Dequeue all SCBs sent from the waiting queue * Requeue all SCBs *not* sent to the tail of the waiting queue * Take Razor #494 into account for above. * * In Packetized Mode: *	Return to the idle loop.  Our interrupt handler will take *	care of any incoming L_Qs. * * In Non-Packetize Mode: *	Continue to our normal state machine. */SET_SRC_MODE	M_SCSI;SET_DST_MODE	M_SCSI;select_out:BEGIN_CRITICAL;	if ((ahd->bugs & AHD_FAINT_LED_BUG) != 0) {		/*		 * On Rev A. hardware, the busy LED is only		 * turned on automaically during selections		 * and re-selections.  Make the LED status		 * more useful by forcing it to be on from		 * the point of re-selection until our idle		 * loop determines that neither of our FIFOs		 * are busy.  This handles the non-packetized		 * case nicely as we will not return to the		 * idle loop until the busfree at the end of		 * each transaction.		 */		or	SBLKCTL, DIAGLEDEN|DIAGLEDON;	}	/* Clear out all SCBs that have been successfully sent. */	if ((ahd->bugs & AHD_SENT_SCB_UPDATE_BUG) != 0) {		/*		 * For packetized, the LQO manager clears ENSELO on		 * the assertion of SELDO.  If we are non-packetized,		 * LASTSCB and CURRSCB are accurate.		 */		test	SCSISEQ0, ENSELO jnz use_lastscb;		/*		 * The update is correct for LQOSTAT1 errors.  All		 * but LQOBUSFREE are handled by kernel interrupts.		 * If we see LQOBUSFREE, return to the idle loop.		 * Once we are out of the select_out critical section,		 * the kernel will cleanup the LQOBUSFREE and we will		 * eventually restart the selection if appropriate.		 */		test	LQOSTAT1, LQOBUSFREE jnz idle_loop;		/*		 * On a phase change oustside of packet boundaries,		 * LASTSCB points to the currently active SCB context		 * on the bus.		 */		test	LQOSTAT2, LQOPHACHGOUTPKT jnz use_lastscb;		/*		 * If the hardware has traversed the whole list, NEXTSCB		 * will be NULL, CURRSCB and LASTSCB cannot be trusted,		 * but MAXCMDCNT is accurate.  If we stop part way through		 * the list or only had one command to issue, NEXTSCB[1] is		 * not NULL and LASTSCB is the last command to go out.		 */		cmp	NEXTSCB[1], SCB_LIST_NULL jne use_lastscb;		/*		 * Brute force walk.		 */		bmov	SCBPTR, WAITING_TID_HEAD, 2;		mvi	SEQINTCTL, INTVEC1DSL;		mvi	MODE_PTR, MK_MODE(M_CFG, M_CFG);		mov	A, MAXCMDCNT;		mvi	MODE_PTR, MK_MODE(M_SCSI, M_SCSI);		clr	SEQINTCTL;find_lastscb_loop:		dec	A;		test	A, 0xFF jz found_last_sent_scb;		bmov	SCBPTR, SCB_NEXT, 2;		jmp	find_lastscb_loop;use_lastscb:		bmov	SCBPTR, LASTSCB, 2;found_last_sent_scb:		bmov	CURRSCB, SCBPTR, 2;curscb_ww_done:	} else {		bmov	SCBPTR, CURRSCB, 2;	}	/*	 * The whole list made it.  Clear our tail pointer to indicate	 * that the per-target selection queue is now empty.	 */	cmp	SCB_NEXT[1], SCB_LIST_NULL je select_out_clear_tail;	/*	 * Requeue any SCBs not sent, to the tail of the waiting Q.	 * We know that neither the per-TID list nor the list of	 * TIDs is empty.  Use this knowledge to our advantage and	 * queue the remainder to the tail of the global execution	 * queue.	 */	bmov	REG0, SCB_NEXT, 2;select_out_queue_remainder:	bmov	SCBPTR, WAITING_TID_TAIL, 2;	bmov	SCB_NEXT2, REG0, 2;	bmov	WAITING_TID_TAIL, REG0, 2;	jmp	select_out_inc_tid_q;select_out_clear_tail:	/*	 * Queue any pending MK_MESSAGE SCB for this target now	 * that the queue is empty.	 */	test	SEQ_FLAGS2, PENDING_MK_MESSAGE jz select_out_no_mk_message_scb;	mov	A, MK_MESSAGE_SCSIID;	cmp	SCB_SCSIID, A jne select_out_no_mk_message_scb;	and	SEQ_FLAGS2, ~PENDING_MK_MESSAGE;	bmov	REG0, MK_MESSAGE_SCB, 2;	jmp select_out_queue_remainder;select_out_no_mk_message_scb:	/*	 * Clear this target's execution tail and increment the queue.	 */	shr	DINDEX, 3, SCB_SCSIID;	or	DINDEX, 1;	/* Want only the second byte */	mvi	DINDEX[1], ((WAITING_SCB_TAILS) >> 8);	mvi	DINDIR, SCB_LIST_NULL;select_out_inc_tid_q:	bmov	SCBPTR, WAITING_TID_HEAD, 2;	bmov	WAITING_TID_HEAD, SCB_NEXT2, 2;	cmp	WAITING_TID_HEAD[1], SCB_LIST_NULL jne . + 2;	mvi	WAITING_TID_TAIL[1], SCB_LIST_NULL;	bmov	SCBPTR, CURRSCB, 2;	mvi	CLRSINT0, CLRSELDO;	test	LQOSTAT2, LQOPHACHGOUTPKT jnz unexpected_nonpkt_mode_cleared;	test	LQOSTAT1, LQOPHACHGINPKT jnz unexpected_nonpkt_mode_cleared;	/*	 * If this is a packetized connection, return to our	 * idle_loop and let our interrupt handler deal with	 * any connection setup/teardown issues.  The only	 * exceptions are the case of MK_MESSAGE and task management	 * SCBs.	 */	if ((ahd->bugs & AHD_LQO_ATNO_BUG) != 0) {		/*		 * In the A, the LQO manager transitions to LQOSTOP0 even if		 * we have selected out with ATN asserted and the target		 * REQs in a non-packet phase.		 */		test 	SCB_CONTROL, MK_MESSAGE jz select_out_no_message;		test	SCSISIGO, ATNO jnz select_out_non_packetized;select_out_no_message:	}	test	LQOSTAT2, LQOSTOP0 jz select_out_non_packetized;	test	SCB_TASK_MANAGEMENT, 0xFF jz idle_loop;	SET_SEQINTCODE(TASKMGMT_FUNC_COMPLETE)	jmp	idle_loop;select_out_non_packetized:	/* Non packetized request. */	and     SCSISEQ0, ~ENSELO;	if ((ahd->bugs & AHD_BUSFREEREV_BUG) != 0) {		/*		 * Test to ensure that the bus has not		 * already gone free prior to clearing		 * any stale busfree status.  This avoids		 * a window whereby a busfree just after		 * a selection could be missed.		 */		test	SCSISIGI, BSYI jz . + 2;		mvi	CLRSINT1,CLRBUSFREE;

⌨️ 快捷键说明

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