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

📄 aic79xx.seq

📁 这个linux源代码是很全面的~基本完整了~使用c编译的~由于时间问题我没有亲自测试~但就算用来做参考资料也是非常好的
💻 SEQ
📖 第 1 页 / 共 4 页
字号:
/* * Adaptec 274x/284x/294x device driver firmware for Linux and FreeBSD. * * Copyright (c) 1994-2001 Justin T. Gibbs. * Copyright (c) 2000-2001 Adaptec Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions, and the following disclaimer, *    without modification. * 2. Redistributions in binary form must reproduce at minimum a disclaimer *    substantially similar to the "NO WARRANTY" disclaimer below *    ("Disclaimer") and any redistribution must be conditioned upon *    including a substantially similar Disclaimer requirement for further *    binary redistribution. * 3. Neither the names of the above-listed copyright holders nor the names *    of any contributors may be used to endorse or promote products derived *    from this software without specific prior written permission. * * Alternatively, this software may be distributed under the terms of the * GNU General Public License ("GPL") version 2 as published by the Free * Software Foundation. * * NO WARRANTY * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * $FreeBSD$ */VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#42 $"PATCH_ARG_LIST = "struct ahd_softc *ahd"#include "aic79xx.reg"#include "scsi_message.h"idle_loop:	SET_MODE(M_SCSI, M_SCSI);	test	SCSISEQ0, ENSELO|ENARBO jnz idle_loop_checkbus;	test	SEQ_FLAGS2, SELECTOUT_QFROZEN jnz idle_loop_checkbus;	cmp	WAITING_TID_HEAD[1], SCB_LIST_NULL je idle_loop_checkbus;	/*	 * ENSELO is cleared by a SELDO, so we must test for SELDO	 * one last time.	 */BEGIN_CRITICAL;	test	SSTAT0, SELDO jnz select_out;END_CRITICAL;	call	start_selection;idle_loop_checkbus:BEGIN_CRITICAL;	test	SSTAT0, SELDO jnz select_out;END_CRITICAL;	test	SSTAT0, SELDI jnz select_in;	test	SCSIPHASE, ~DATA_PHASE_MASK jz idle_loop_check_nonpackreq;	test	SCSISIGO, ATNO jz idle_loop_check_nonpackreq;	call	unexpected_nonpkt_phase_find_ctxt;idle_loop_check_nonpackreq:	test	SSTAT2, NONPACKREQ jz idle_loop_scsi;	call	unexpected_nonpkt_phase_find_ctxt;idle_loop_scsi:BEGIN_CRITICAL;	test	LQISTAT2, LQIGSAVAIL jz idle_loop_service_fifos;	/*	 * We have received good status for this transaction.  There may	 * still be data in our FIFOs draining to the host.  Setup	 * monitoring of the draining process or complete the SCB.	 */good_status_IU_done:	bmov	SCBPTR, GSFIFO, 2;	clr	SCB_SCSI_STATUS;	or	SCB_CONTROL, STATUS_RCVD;	/*	 * Since this status did not consume a FIFO, we have to	 * be a bit more dilligent in how we check for FIFOs pertaining	 * to this transaction.  There are three states that a FIFO still	 * transferring data may be in.	 *	 * 1) Configured and draining to the host, with a pending CLRCHN.	 * 2) Configured and draining to the host, no pending CLRCHN.	 * 3) Pending cfg4data, fifo not empty.	 *	 * For case 1, we assume that our DMA post of the completed command	 * will occur after the FIFO finishes draining due to the higher	 * priority of data FIFO transfers relative to command channel	 * transfers.	 *	 * Case 2 can be detected by noticing that a longjmp is active for the	 * FIFO and LONGJMP_SCB matches our SCB.  In this case, we allow	 * the routine servicing the FIFO to complete the SCB.	 * 	 * Case 3 implies either a pending or yet to occur save data	 * pointers for this same context in the other FIFO.  So, if	 * we detect case 2, we will properly defer the post of the SCB	 * and achieve the desired result.  The pending cfg4data will	 * notice that status has been received and complete the SCB.	 */	test	SCB_SGPTR, SG_LIST_NULL jz good_status_check_fifos;	/*	 * All segments have been loaded (or no data transfer), so	 * it is safe to complete the command.  Since this was a	 * cheap command to check for completion, loop to see if	 * more entries can be removed from the GSFIFO.	 */	call	complete;END_CRITICAL;	jmp	idle_loop_scsi;BEGIN_CRITICAL;good_status_check_fifos:	clc;	bmov	ARG_1, SCBPTR, 2;	SET_MODE(M_DFF0, M_DFF0);	call	check_fifo;	jc	idle_loop_service_fifos;	SET_MODE(M_DFF1, M_DFF1);	call	check_fifo;	jc	idle_loop_service_fifos;	SET_MODE(M_SCSI, M_SCSI);	call	queue_scb_completion;END_CRITICAL;idle_loop_service_fifos:	SET_MODE(M_DFF0, M_DFF0);	test	LONGJMP_ADDR[1], INVALID_ADDR jnz idle_loop_next_fifo;	call	longjmp;idle_loop_next_fifo:	SET_MODE(M_DFF1, M_DFF1);	test	LONGJMP_ADDR[1], INVALID_ADDR jnz idle_loop_last_fifo_done;	call	longjmp;idle_loop_last_fifo_done:	call	idle_loop_cchan;	jmp	idle_loop;idle_loop_cchan:	SET_MODE(M_CCHAN, M_CCHAN);	test	CCSCBCTL, CCARREN|CCSCBEN jz scbdma_idle;	test	CCSCBCTL, CCSCBDIR jnz fetch_new_scb_inprog;	test	CCSCBCTL, CCSCBDONE jz return;	/* FALLTHROUGH */scbdma_tohost_done:	test	CCSCBCTL, CCARREN jz fill_qoutfifo_dmadone;	/*	 * A complete SCB upload requires no intervention.	 * The SCB is already on the COMPLETE_SCB list	 * and its completion notification will now be	 * handled just like any other SCB.	 */	and	CCSCBCTL, ~(CCARREN|CCSCBEN) ret;fill_qoutfifo_dmadone:	and	CCSCBCTL, ~(CCARREN|CCSCBEN);	mvi	INTSTAT, CMDCMPLT;	mvi	COMPLETE_SCB_DMAINPROG_HEAD[1], SCB_LIST_NULL;	bmov	QOUTFIFO_NEXT_ADDR, SCBHADDR, 4;	test	QOFF_CTLSTA, SDSCB_ROLLOVR jz return;	bmov	QOUTFIFO_NEXT_ADDR, SHARED_DATA_ADDR, 4 ret;fetch_new_scb_inprog:	test	CCSCBCTL, ARRDONE jz return;fetch_new_scb_done:	and	CCSCBCTL, ~(CCARREN|CCSCBEN);	bmov	REG0, SCBPTR, 2;	/* Update the next SCB address to download. */	bmov	NEXT_QUEUED_SCB_ADDR, SCB_NEXT_SCB_BUSADDR, 4;	mvi	SCB_NEXT[1], SCB_LIST_NULL;	mvi	SCB_NEXT2[1], SCB_LIST_NULL;	/*	 * SCBs that want to send messages are always	 * queued independently.  This ensures that they	 * are at the head of the SCB list to select out	 * to a target and we will see the MK_MESSAGE flag.	 */	test	SCB_CONTROL, MK_MESSAGE jnz first_new_target_scb;	shr	SINDEX, 3, SCB_SCSIID;	and	SINDEX, ~0x1;	mvi	SINDEX[1], (WAITING_SCB_TAILS >> 8);	bmov	DINDEX, SINDEX, 2;	bmov	SCBPTR, SINDIR, 2;	bmov	DINDIR, REG0, 2;	cmp	SCBPTR[1], SCB_LIST_NULL je first_new_target_scb;	bmov	SCB_NEXT, REG0, 2;fetch_new_scb_fini:	/* Increment our position in the QINFIFO. */	mov	NONE, SNSCB_QOFF ret;first_new_target_scb:	cmp	WAITING_TID_HEAD[1], SCB_LIST_NULL je first_new_scb;	bmov	SCBPTR, WAITING_TID_TAIL, 2;	bmov	SCB_NEXT2, REG0, 2;	bmov	WAITING_TID_TAIL, REG0, 2;	/* Increment our position in the QINFIFO. */	mov	NONE, SNSCB_QOFF ret;first_new_scb:	bmov	WAITING_TID_HEAD, REG0, 2;	bmov	WAITING_TID_TAIL, REG0, 2;	/* Increment our position in the QINFIFO. */	mov	NONE, SNSCB_QOFF ret;scbdma_idle:	/*	 * Give precedence to downloading new SCBs to execute	 * unless select-outs are currently frozen.	 * XXX Use a timer to prevent completion starvation.	 */	test	SEQ_FLAGS2, SELECTOUT_QFROZEN jnz . + 2;BEGIN_CRITICAL;	test	QOFF_CTLSTA, NEW_SCB_AVAIL jnz fetch_new_scb;	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;	bmov	CCSCBRAM, COMPLETE_SCB_HEAD, 2;	bmov	SCBPTR, COMPLETE_SCB_HEAD, 2;	jmp	fill_qoutfifo_first_entry;fill_qoutfifo_loop:	bmov	CCSCBRAM, SCB_NEXT_COMPLETE, 2;	bmov	SCBPTR, SCB_NEXT_COMPLETE, 2;fill_qoutfifo_first_entry:	mov	NONE, SDSCB_QOFF;	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 jz 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 call dma_scb;	/*	 * Now that we've started the DMA, push us onto	 * the normal completion queue to have our SCBID	 * posted to the kernel.	 */	bmov	COMPLETE_DMA_SCB_HEAD, SCB_NEXT_COMPLETE, 2;	bmov	SCB_NEXT_COMPLETE, COMPLETE_SCB_HEAD, 2;	bmov	COMPLETE_SCB_HEAD, SCBPTR, 2 ret;END_CRITICAL;/* * 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;	or	SEQ_FLAGS2, SCB_DMA ret;BEGIN_CRITICAL;setjmp_setscb:	bmov	LONGJMP_SCB, SCBPTR, 2;setjmp:	bmov	LONGJMP_ADDR, STACK, 2 ret;setjmp_inline:	bmov	LONGJMP_ADDR, STACK, 2;longjmp:	bmov	STACK, LONGJMP_ADDR, 2 ret;END_CRITICAL;/************************ Packetized LongJmp Routines *************************//* * 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. */set_mode_work_around:	mvi	SEQINTCTL, INTVEC1DSL;	mov	MODE_PTR, SINDEX;	clr	SEQINTCTL ret;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 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. * For some reason unkown to me, both FIFOs must be free before we * can allocate a FIFO for a non-packetized transaction.  This * may be fixed in Rev B. */allocate_fifo_loop:	/*	 * Do whatever work is required to free a FIFO.	 */	SET_MODE(M_DFF0, M_DFF0);	test	LONGJMP_ADDR[1], INVALID_ADDR jnz . + 2;	call	longjmp;	SET_MODE(M_DFF1, M_DFF1);	test	LONGJMP_ADDR[1], INVALID_ADDR jnz . + 2;	call	longjmp;	SET_MODE(M_SCSI, M_SCSI);allocate_fifo:	and	A, FIFO0FREE|FIFO1FREE, DFFSTAT;	cmp	A, FIFO0FREE|FIFO1FREE jne allocate_fifo_loop;take_fifo:	bmov	ARG_1, SCBPTR, 2;	or	DFFSTAT, CURRFIFO;	SET_MODE(M_DFF1, M_DFF1);	bmov	SCBPTR, ARG_1, 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:	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;	/* 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 acuate.		 */		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.		 */

⌨️ 快捷键说明

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