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

📄 aic7xxx.seq

📁 linux-2.6.15.6
💻 SEQ
📖 第 1 页 / 共 5 页
字号:
		or	SXFRCTL0, CLRSTCNT|CLRCHN;		/*		 * Put tag in connonical location since not		 * all connections have an SCB.		 */		mov	INITIATOR_TAG, SCB_TARGET_ITAG;		/*		 * We've just re-selected an initiator.		 * Assert BSY and setup the phase for		 * sending our identify messages.		 */		mvi	P_MESGIN|BSYO call change_phase;		mvi	CLRSINT0, CLRSELDO;		/*		 * Start out with a simple identify message.		 */		or	SAVED_LUN, MSG_IDENTIFYFLAG call target_outb;		/*		 * If we are the result of a tagged command, send		 * a simple Q tag and the tag id.		 */		test	SCB_CONTROL, TAG_ENB	jz . + 3;		mvi	MSG_SIMPLE_Q_TAG call target_outb;		mov	SCB_TARGET_ITAG call target_outb;target_synccmd:		/*		 * Now determine what phases the host wants us		 * to go through.		 */		mov	SEQ_FLAGS, SCB_TARGET_PHASES;				test	SCB_CONTROL, MK_MESSAGE	jz target_ITloop;		mvi	P_MESGIN|BSYO call change_phase;		jmp	host_target_message_loop;target_ITloop:		/*		 * Start honoring ATN signals now that		 * we properly identified ourselves.		 */		test	SCSISIGI, ATNI			jnz target_mesgout;		test	SEQ_FLAGS, CMDPHASE_PENDING	jnz target_cmdphase;		test	SEQ_FLAGS, DPHASE_PENDING	jnz target_dphase;		test	SEQ_FLAGS, SPHASE_PENDING	jnz target_sphase;		/*		 * No more work to do.  Either disconnect or not depending		 * on the state of NO_DISCONNECT.		 */		test	SEQ_FLAGS, NO_DISCONNECT jz target_disconnect; 		mvi	TARG_IMMEDIATE_SCB, SCB_LIST_NULL;		call	complete_target_cmd;		if ((ahc->flags & AHC_PAGESCBS) != 0) {			mov	ALLZEROS	call	get_free_or_disc_scb;		}		cmp	TARG_IMMEDIATE_SCB, SCB_LIST_NULL je .;		mvi	DMAPARAMS, HDMAEN|DIRECTION|FIFORESET;		mov	TARG_IMMEDIATE_SCB call dma_scb;		call	set_transfer_settings;		or	SXFRCTL0, CLRSTCNT|CLRCHN;		jmp	target_synccmd;target_mesgout:		mvi	SCSISIGO, P_MESGOUT|BSYO;target_mesgout_continue:		call	target_inb;target_mesgout_pending:		and	SEQ_FLAGS2, ~TARGET_MSG_PENDING;		/* Local Processing goes here... */		jmp	host_target_message_loop;		target_disconnect:		mvi	P_MESGIN|BSYO call change_phase;		test	SEQ_FLAGS, DPHASE	jz . + 2;		mvi	MSG_SAVEDATAPOINTER call target_outb;		mvi	MSG_DISCONNECT call target_outb;target_busfree_wait:		/* Wait for preceding I/O session to complete. */		test	SCSISIGI, ACKI jnz .;target_busfree:		and	SIMODE1, ~ENBUSFREE;		if ((ahc->features & AHC_ULTRA2) != 0) {			clr	SCSIBUSL;		}		clr	SCSISIGO;		mvi	LASTPHASE, P_BUSFREE;		call	complete_target_cmd;		jmp	poll_for_work;target_cmdphase:		/*		 * The target has dropped ATN (doesn't want to abort or BDR)		 * and we believe this selection to be valid.  If the ring		 * buffer for new commands is full, return busy or queue full.		 */		if ((ahc->features & AHC_HS_MAILBOX) != 0) {			and	A, HOST_TQINPOS, HS_MAILBOX;		} else {			mov	A, KERNEL_TQINPOS;		}		cmp	TQINPOS, A jne tqinfifo_has_space;		mvi	P_STATUS|BSYO call change_phase;		test	SEQ_FLAGS, TARGET_CMD_IS_TAGGED jz . + 3;		mvi	STATUS_QUEUE_FULL call target_outb;		jmp	target_busfree_wait;		mvi	STATUS_BUSY call target_outb;		jmp	target_busfree_wait;tqinfifo_has_space:			mvi	P_COMMAND|BSYO call change_phase;		call	target_inb;		mov	A, DINDEX;		/* Store for host */		if ((ahc->features & AHC_CMD_CHAN) != 0) {			mov	CCSCBRAM, A;		} else {			mov	DFDAT, A;		}		/*		 * Determine the number of bytes to read		 * based on the command group code via table lookup.		 * We reuse the first 8 bytes of the TARG_SCSIRATE		 * BIOS array for this table. Count is one less than		 * the total for the command since we've already fetched		 * the first byte.		 */		shr	A, CMD_GROUP_CODE_SHIFT;		add	SINDEX, CMDSIZE_TABLE, A;		mov	A, SINDIR;		test	A, 0xFF jz command_phase_done;		or	SXFRCTL0, SPIOEN;command_loop:		test	SSTAT0, SPIORDY jz .;		cmp	A, 1 jne . + 2;		and	SXFRCTL0, ~SPIOEN;	/* Last Byte */		if ((ahc->features & AHC_CMD_CHAN) != 0) {			mov	CCSCBRAM, SCSIDATL;		} else {			mov	DFDAT, SCSIDATL;		}		dec	A;		test	A, 0xFF jnz command_loop;command_phase_done:		and	SEQ_FLAGS, ~CMDPHASE_PENDING;		jmp	target_ITloop;target_dphase:		/*		 * Data phases on the bus are from the		 * perspective of the initiator.  The dma		 * code looks at LASTPHASE to determine the		 * data direction of the DMA.  Toggle it for		 * target transfers.		 */		xor	LASTPHASE, IOI, SCB_TARGET_DATA_DIR;		or	SCB_TARGET_DATA_DIR, BSYO call change_phase;		jmp	p_data;target_sphase:		mvi	P_STATUS|BSYO call change_phase;		mvi	LASTPHASE, P_STATUS;		mov	SCB_SCSI_STATUS call target_outb;		/* XXX Watch for ATN or parity errors??? */		mvi	SCSISIGO, P_MESGIN|BSYO;		/* MSG_CMDCMPLT is 0, but we can't do an immediate of 0 */		mov	ALLZEROS call target_outb;		jmp	target_busfree_wait;	complete_target_cmd:		test	SEQ_FLAGS, TARG_CMD_PENDING	jnz . + 2;		mov	SCB_TAG jmp complete_post;		if ((ahc->features & AHC_CMD_CHAN) != 0) {			/* Set the valid byte */			mvi	CCSCBADDR, 24;			mov	CCSCBRAM, ALLONES;			mvi	CCHCNT, 28;			or	CCSCBCTL, CCSCBEN|CCSCBRESET;			test	CCSCBCTL, CCSCBDONE jz .;			clr	CCSCBCTL;		} else {			/* Set the valid byte */			or	DFCNTRL, FIFORESET;			mvi	DFWADDR, 3; /* Third 64bit word or byte 24 */			mov	DFDAT, ALLONES;			mvi	28	call set_hcnt;			or	DFCNTRL, HDMAEN|FIFOFLUSH;			call	dma_finish;		}		inc	TQINPOS;		mvi	INTSTAT,CMDCMPLT ret;	}if ((ahc->flags & AHC_INITIATORROLE) != 0) {initiator_select:	or	SXFRCTL0, SPIOEN|CLRSTCNT|CLRCHN;	/*	 * As soon as we get a successful selection, the target	 * should go into the message out phase since we have ATN	 * asserted.	 */	mvi	MSG_OUT, MSG_IDENTIFYFLAG;	mvi	SEQ_FLAGS, NO_CDB_SENT;	mvi	CLRSINT0, CLRSELDO;	/*	 * Main loop for information transfer phases.  Wait for the	 * target to assert REQ before checking MSG, C/D and I/O for	 * the bus phase.	 */mesgin_phasemis:ITloop:	call	phase_lock;	mov	A, LASTPHASE;	test	A, ~P_DATAIN	jz p_data;	cmp	A,P_COMMAND	je p_command;	cmp	A,P_MESGOUT	je p_mesgout;	cmp	A,P_STATUS	je p_status;	cmp	A,P_MESGIN	je p_mesgin;	mvi	BAD_PHASE call set_seqint;	jmp	ITloop;			/* Try reading the bus again. */await_busfree:	and	SIMODE1, ~ENBUSFREE;	mov	NONE, SCSIDATL;		/* Ack the last byte */	if ((ahc->features & AHC_ULTRA2) != 0) {		clr	SCSIBUSL;	/* Prevent bit leakage durint SELTO */	}	and	SXFRCTL0, ~SPIOEN;	mvi	SEQ_FLAGS, NOT_IDENTIFIED|NO_CDB_SENT;	test	SSTAT1,REQINIT|BUSFREE	jz .;	test	SSTAT1, BUSFREE jnz poll_for_work;	mvi	MISSED_BUSFREE call set_seqint;}	clear_target_state:	/*	 * We assume that the kernel driver may reset us	 * at any time, even in the middle of a DMA, so	 * clear DFCNTRL too.	 */	clr	DFCNTRL;	or	SXFRCTL0, CLRSTCNT|CLRCHN;	/*	 * We don't know the target we will connect to,	 * so default to narrow transfers to avoid	 * parity problems.	 */	if ((ahc->features & AHC_ULTRA2) != 0) {		bmov	SCSIRATE, ALLZEROS, 2;	} else {		clr	SCSIRATE;		if ((ahc->features & AHC_ULTRA) != 0) {			and	SXFRCTL0, ~(FAST20);		}	}	mvi	LASTPHASE, P_BUSFREE;	/* clear target specific flags */	mvi	SEQ_FLAGS, NOT_IDENTIFIED|NO_CDB_SENT ret;sg_advance:	clr	A;			/* add sizeof(struct scatter) */	add	SCB_RESIDUAL_SGPTR[0],SG_SIZEOF;	adc	SCB_RESIDUAL_SGPTR[1],A;	adc	SCB_RESIDUAL_SGPTR[2],A;	adc	SCB_RESIDUAL_SGPTR[3],A ret;if ((ahc->features & AHC_CMD_CHAN) != 0) {disable_ccsgen:	test	CCSGCTL, CCSGEN jz return;	test	CCSGCTL, CCSGDONE jz .;disable_ccsgen_fetch_done:	clr	CCSGCTL;	test	CCSGCTL, CCSGEN jnz .;	ret;idle_loop:	/*	 * Do we need any more segments for this transfer?	 */	test	SCB_RESIDUAL_DATACNT[3], SG_LAST_SEG jnz return;	/* Did we just finish fetching segs? */	cmp	CCSGCTL, CCSGEN|CCSGDONE je idle_sgfetch_complete;	/* Are we actively fetching segments? */	test	CCSGCTL, CCSGEN jnz return;	/*	 * Do we have any prefetch left???	 */	cmp	CCSGADDR, SG_PREFETCH_CNT jne idle_sg_avail;	/*	 * Need to fetch segments, but we can only do that	 * if the command channel is completely idle.  Make	 * sure we don't have an SCB prefetch going on.	 */	test	CCSCBCTL, CCSCBEN jnz return;	/*	 * We fetch a "cacheline aligned" and sized amount of data	 * so we don't end up referencing a non-existant page.	 * Cacheline aligned is in quotes because the kernel will	 * set the prefetch amount to a reasonable level if the	 * cacheline size is unknown.	 */	mvi	CCHCNT, SG_PREFETCH_CNT;	and	CCHADDR[0], SG_PREFETCH_ALIGN_MASK, SCB_RESIDUAL_SGPTR;	bmov	CCHADDR[1], SCB_RESIDUAL_SGPTR[1], 3;	mvi	CCSGCTL, CCSGEN|CCSGRESET ret;idle_sgfetch_complete:	call	disable_ccsgen_fetch_done;	and	CCSGADDR, SG_PREFETCH_ADDR_MASK, SCB_RESIDUAL_SGPTR;idle_sg_avail:	if ((ahc->features & AHC_ULTRA2) != 0) {		/* Does the hardware have space for another SG entry? */		test	DFSTATUS, PRELOAD_AVAIL jz return;		bmov 	HADDR, CCSGRAM, 7;		bmov	SCB_RESIDUAL_DATACNT[3], CCSGRAM, 1;		if ((ahc->flags & AHC_39BIT_ADDRESSING) != 0) {			mov	SCB_RESIDUAL_DATACNT[3] call set_hhaddr;		}		call	sg_advance;		mov	SINDEX, SCB_RESIDUAL_SGPTR[0];		test	SCB_RESIDUAL_DATACNT[3], SG_LAST_SEG jz . + 2;		or	SINDEX, LAST_SEG;		mov	SG_CACHE_PRE, SINDEX;		/* Load the segment */		or	DFCNTRL, PRELOADEN;	}	ret;}if ((ahc->bugs & AHC_PCI_MWI_BUG) != 0 && ahc->pci_cachesize != 0) {/* * Calculate the trailing portion of this S/G segment that cannot * be transferred using memory write and invalidate PCI transactions.   * XXX Can we optimize this for PCI writes only??? */calc_mwi_residual:	/*	 * If the ending address is on a cacheline boundary,	 * there is no need for an extra segment.	 */	mov	A, HCNT[0];	add	A, A, HADDR[0];	and	A, CACHESIZE_MASK;	test	A, 0xFF jz return;	/*	 * If the transfer is less than a cachline,	 * there is no need for an extra segment.	 */	test	HCNT[1], 0xFF	jnz calc_mwi_residual_final;	test	HCNT[2], 0xFF	jnz calc_mwi_residual_final;	add	NONE, INVERTED_CACHESIZE_MASK, HCNT[0];	jnc	return;calc_mwi_residual_final:	mov	MWI_RESIDUAL, A;	not	A;	inc	A;	add	HCNT[0], A;	adc	HCNT[1], -1;	adc	HCNT[2], -1 ret;}p_data:	test	SEQ_FLAGS,NOT_IDENTIFIED|NO_CDB_SENT jz p_data_allowed;	mvi	PROTO_VIOLATION call set_seqint;p_data_allowed:	if ((ahc->features & AHC_ULTRA2) != 0) {		mvi	DMAPARAMS, PRELOADEN|SCSIEN|HDMAEN;	} else {		mvi	DMAPARAMS, WIDEODD|SCSIEN|SDMAEN|HDMAEN|FIFORESET;	}	test	LASTPHASE, IOI jnz . + 2;	or	DMAPARAMS, DIRECTION;	if ((ahc->features & AHC_CMD_CHAN) != 0) {		/* We don't have any valid S/G elements */		mvi	CCSGADDR, SG_PREFETCH_CNT;	}	test	SEQ_FLAGS, DPHASE	jz data_phase_initialize;	/*	 * If we re-enter the data phase after going through another	 * phase, our transfer location has almost certainly been	 * corrupted by the interveining, non-data, transfers.  Ask	 * the host driver to fix us up based on the transfer residual.	 */	mvi	PDATA_REINIT	call set_seqint;	jmp	data_phase_loop;data_phase_initialize:	/* We have seen a data phase for the first time */	or	SEQ_FLAGS, DPHASE;	/*	 * Initialize the DMA address and counter from the SCB.	 * Also set SCB_RESIDUAL_SGPTR, including the LAST_SEG	 * flag in the highest byte of the data count.  We cannot	 * modify the saved values in the SCB until we see a save	 * data pointers message.	 */	if ((ahc->flags & AHC_39BIT_ADDRESSING) != 0) {		/* The lowest address byte must be loaded last. */		mov	SCB_DATACNT[3] call set_hhaddr;	}	if ((ahc->features & AHC_CMD_CHAN) != 0) {		bmov	HADDR, SCB_DATAPTR, 7;		bmov	SCB_RESIDUAL_DATACNT[3], SCB_DATACNT[3], 5;	} else {		mvi	DINDEX, HADDR;		mvi	SCB_DATAPTR	call bcopy_7;		mvi	DINDEX, SCB_RESIDUAL_DATACNT + 3;		mvi	SCB_DATACNT + 3 call bcopy_5;	}	if ((ahc->bugs & AHC_PCI_MWI_BUG) != 0 && ahc->pci_cachesize != 0) {		call	calc_mwi_residual;	}	and	SCB_RESIDUAL_SGPTR[0], ~SG_FULL_RESID;	if ((ahc->features & AHC_ULTRA2) == 0) {		if ((ahc->features & AHC_CMD_CHAN) != 0) {			bmov	STCNT, HCNT, 3;		} else {			call	set_stcnt_from_hcnt;		}	}data_phase_loop:	/* Guard against overruns */	test	SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL jz data_phase_inbounds;

⌨️ 快捷键说明

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