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

📄 aic79xx.seq

📁 linux-2.6.15.6
💻 SEQ
📖 第 1 页 / 共 5 页
字号:
/* * Adaptec U320 device driver firmware for Linux and FreeBSD. * * Copyright (c) 1994-2001 Justin T. Gibbs. * Copyright (c) 2000-2002 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#99 $"PATCH_ARG_LIST = "struct ahd_softc *ahd"PREFIX = "ahd_"#include "aic79xx.reg"#include "scsi_message.h"restart:if ((ahd->bugs & AHD_INTCOLLISION_BUG) != 0) {	test	SEQINTCODE, 0xFF jz idle_loop;	SET_SEQINTCODE(NO_SEQINT)}idle_loop:	if ((ahd->bugs & AHD_INTCOLLISION_BUG) != 0) {		/*		 * Convert ERROR status into a sequencer		 * interrupt to handle the case of an		 * interrupt collision on the hardware		 * setting of HWERR.		 */		test	ERROR, 0xFF jz no_error_set;		SET_SEQINTCODE(SAW_HWERR)no_error_set:	}	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 . + 2;	call	unexpected_nonpkt_phase_find_ctxt;	if ((ahd->bugs & AHD_FAINT_LED_BUG) != 0) {		and	A, FIFO0FREE|FIFO1FREE, DFFSTAT;		cmp	A, FIFO0FREE|FIFO1FREE jne . + 3;		and	SBLKCTL, ~DIAGLEDEN|DIAGLEDON;		jmp	. + 2;		or	SBLKCTL, DIAGLEDEN|DIAGLEDON;	}	call	idle_loop_gsfifo_in_scsi_mode;	call	idle_loop_service_fifos;	call	idle_loop_cchan;	jmp	idle_loop;BEGIN_CRITICAL;idle_loop_gsfifo:	SET_MODE(M_SCSI, M_SCSI)idle_loop_gsfifo_in_scsi_mode:	test	LQISTAT2, LQIGSAVAIL jz return;	/*	 * We have received good status for this transaction.  There may	 * still be data in our FIFOs draining to the host.  Complete	 * the SCB only if all data has transferred to the host.	 */good_status_IU_done:	bmov	SCBPTR, GSFIFO, 2;	clr	SCB_SCSI_STATUS;	/*	 * If a command completed before an attempted task management	 * function completed, notify the host after disabling any	 * pending select-outs.	 */	test	SCB_TASK_MANAGEMENT, 0xFF jz gsfifo_complete_normally;	test	SSTAT0, SELDO|SELINGO jnz . + 2;	and	SCSISEQ0, ~ENSELO;	SET_SEQINTCODE(TASKMGMT_CMD_CMPLT_OKAY)gsfifo_complete_normally:	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 two states that a FIFO still	 * transferring data may be in.	 *	 * 1) Configured and draining to the host, with a FIFO handler.	 * 2) Pending cfg4data, fifo not empty.	 *	 * Case 1 can be detected by noticing a non-zero FIFO active	 * count in the SCB.  In this case, we allow the routine servicing	 * the FIFO to complete the SCB.	 * 	 * Case 2 implies either a pending or yet to occur save data	 * pointers for this same context in the other FIFO.  So, if	 * we detect case 1, 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_FIFO_USE_COUNT, 0xFF jnz idle_loop_gsfifo_in_scsi_mode;	call	complete;END_CRITICAL;	jmp	idle_loop_gsfifo_in_scsi_mode;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 jz longjmp;return:	ret;idle_loop_cchan:	SET_MODE(M_CCHAN, M_CCHAN)	test	QOFF_CTLSTA, HS_MAILBOX_ACT jz	hs_mailbox_empty;	or	QOFF_CTLSTA, HS_MAILBOX_ACT;	mov	LOCAL_HS_MAILBOX, HS_MAILBOX;hs_mailbox_empty:BEGIN_CRITICAL;	test	CCSCBCTL, CCARREN|CCSCBEN jz scbdma_idle;	test	CCSCBCTL, CCSCBDIR jnz fetch_new_scb_inprog;	test	CCSCBCTL, CCSCBDONE jz return;END_CRITICAL;	/* FALLTHROUGH */scbdma_tohost_done:	test	CCSCBCTL, CCARREN jz fill_qoutfifo_dmadone;	/*	 * An SCB has been succesfully uploaded to the host.	 * If the SCB was uploaded for some reason other than	 * bad SCSI status (currently only for underruns), we	 * queue the SCB for normal completion.  Otherwise, we	 * wait until any select-out activity has halted, and	 * then notify the host so that the transaction can be	 * dealt with.	 */	test	SCB_SCSI_STATUS, 0xff jnz scbdma_notify_host;	and	CCSCBCTL, ~(CCARREN|CCSCBEN);	bmov	COMPLETE_DMA_SCB_HEAD, SCB_NEXT_COMPLETE, 2;	bmov	SCB_NEXT_COMPLETE, COMPLETE_SCB_HEAD, 2;	bmov	COMPLETE_SCB_HEAD, SCBPTR, 2 ret;scbdma_notify_host:	SET_MODE(M_SCSI, M_SCSI)	test	SCSISEQ0, ENSELO jnz return;	test	SSTAT0, (SELDO|SELINGO) jnz return;	SET_MODE(M_CCHAN, M_CCHAN)	/*	 * Remove SCB and notify host.	 */	and	CCSCBCTL, ~(CCARREN|CCSCBEN);	bmov	COMPLETE_DMA_SCB_HEAD, SCB_NEXT_COMPLETE, 2;	SET_SEQINTCODE(BAD_SCB_STATUS)	ret;fill_qoutfifo_dmadone:	and	CCSCBCTL, ~(CCARREN|CCSCBEN);	call	qoutfifo_updated;	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;	xor	QOUTFIFO_ENTRY_VALID_TAG, QOUTFIFO_ENTRY_VALID_TOGGLE ret;qoutfifo_updated:	/*	 * If there are more commands waiting to be dma'ed	 * to the host, always coalesce.  Otherwise honor the	 * host's wishes.	 */	cmp	COMPLETE_DMA_SCB_HEAD[1], SCB_LIST_NULL jne coalesce_by_count;	cmp	COMPLETE_SCB_HEAD[1], SCB_LIST_NULL jne coalesce_by_count;	test	LOCAL_HS_MAILBOX, ENINT_COALESCE jz issue_cmdcmplt;	/*	 * If we have relatively few commands outstanding, don't	 * bother waiting for another command to complete.	 */	test	CMDS_PENDING[1], 0xFF jnz coalesce_by_count;	/* Add -1 so that jnc means <= not just < */	add	A, -1, INT_COALESCING_MINCMDS;	add	NONE, A, CMDS_PENDING;	jnc	issue_cmdcmplt;		/*	 * If coalescing, only coalesce up to the limit	 * provided by the host driver.	 */coalesce_by_count:	mov	A, INT_COALESCING_MAXCMDS;	add	NONE, A, INT_COALESCING_CMDCOUNT;	jc	issue_cmdcmplt;	/*	 * If the timer is not currently active,	 * fire it up.	 */	test	INTCTL, SWTMINTMASK jz return;	bmov	SWTIMER, INT_COALESCING_TIMER, 2;	mvi	CLRSEQINTSTAT, CLRSEQ_SWTMRTO;	or	INTCTL, SWTMINTEN|SWTIMER_START;	and	INTCTL, ~SWTMINTMASK ret;issue_cmdcmplt:	mvi	INTSTAT, CMDCMPLT;	clr	INT_COALESCING_CMDCOUNT;	or	INTCTL, SWTMINTMASK ret;BEGIN_CRITICAL;fetch_new_scb_inprog:	test	CCSCBCTL, ARRDONE jz return;fetch_new_scb_done:	and	CCSCBCTL, ~(CCARREN|CCSCBEN);	bmov	REG0, SCBPTR, 2;	clr	A;	add	CMDS_PENDING, 1;	adc	CMDS_PENDING[1], A;	if ((ahd->bugs & AHD_PKT_LUN_BUG) != 0) {		/*		 * "Short Luns" are not placed into outgoing LQ		 * packets in the correct byte order.  Use a full		 * sized lun field instead and fill it with the		 * one byte of lun information we support.		 */		mov	SCB_PKT_LUN[6], SCB_LUN;	}	/*	 * The FIFO use count field is shared with the	 * tag set by the host so that our SCB dma engine	 * knows the correct location to store the SCB.	 * Set it to zero before processing the SCB.	 */	clr	SCB_FIFO_USE_COUNT;	/* 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;	/* Increment our position in the QINFIFO. */	mov	NONE, SNSCB_QOFF;	/*	 * 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 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 ret;first_new_scb:	bmov	WAITING_TID_HEAD, REG0, 2;	bmov	WAITING_TID_TAIL, REG0, 2 ret;END_CRITICAL;scbdma_idle:	/*	 * Give precedence to downloading new SCBs to execute	 * unless select-outs are currently frozen.	 */	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.	 */	mov	A, QOUTFIFO_ENTRY_VALID_TAG;	bmov	COMPLETE_SCB_DMAINPROG_HEAD, COMPLETE_SCB_HEAD, 2;	mvi	CCSCBCTL, CCSCBRESET;	bmov	SCBHADDR, QOUTFIFO_NEXT_ADDR, 4;	bmov	SCBPTR, COMPLETE_SCB_HEAD, 2;fill_qoutfifo_loop:	mov	CCSCBRAM, SCBPTR;	or	CCSCBRAM, A, SCBPTR[1];	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;	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;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 ret;BEGIN_CRITICAL;setjmp:	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;toggle_dff_mode_work_around:	mvi	SEQINTCTL, INTVEC1DSL;	xor	MODE_PTR, MK_MODE(M_DFF1, M_DFF1);	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:

⌨️ 快捷键说明

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