📄 scsiio.c
字号:
static voidDC390W_MsgReject( PACB pACB ){ PDCB pDCB; PSRB pSRB; ULONG wlval; USHORT ioport; UCHAR bval;#ifdef DC390W_DEBUG0 printk("Msgrjt,");#endif pDCB = pACB->pActiveDCB; pSRB = pDCB->pActiveSRB; wlval = pACB->jmp_clear_ack; if(pSRB->SRBState & DO_WIDE_NEGO) { pSRB->SRBState &= ~DO_WIDE_NEGO; pDCB->DCBscntl3 &= ~EN_WIDE_SCSI; AdjustTemp( pACB, pDCB, pSRB ); SetXferRate( pACB, pDCB ); if( pDCB->DevMode & SYNC_NEGO_ ) { *((PULONG) &(pSRB->MsgOutBuf[0])) = 0x00010301; pSRB->MsgOutBuf[3] = pDCB->NegoPeriod; pSRB->MsgOutBuf[4] = SYNC_NEGO_OFFSET; pSRB->__msgout0[0] = 5; pSRB->SRBState |= DO_SYNC_NEGO; wlval = pACB->jmp_set_atn; } } else { if(pSRB->SRBState & DO_SYNC_NEGO) { pSRB->SRBState &= ~DO_SYNC_NEGO; pDCB->DCBsxfer = 0; /* reject sync msg, set aync */ if( pACB->AdaptType == DC390W ) bval = SYNC_CLK_F2+ASYNC_CLK_F2; else bval = SYNC_CLK_F4+ASYNC_CLK_F4; pDCB->DCBscntl3 = bval; SetXferRate(pACB,pDCB); wlval = pACB->jmp_clear_ack; } } ioport = pACB->IOPortBase; bval = pDCB->DCBscntl3; outb(bval,ioport+SCNTL3); bval = pDCB->DCBsxfer; outb(bval,ioport+SXFER); outl(wlval,(ioport+DSP)); return;}static voidAdjustTemp( PACB pACB, PDCB pDCB, PSRB pSRB ){ USHORT ioport; ULONG wlval; wlval = pSRB->ReturnAddr; if(wlval <= pACB->jmp_table8) { if(pDCB->DCBscntl3 & EN_WIDE_SCSI) wlval += jmp_table16; } else { if((pDCB->DCBscntl3 & EN_WIDE_SCSI) == 0) wlval -= jmp_table16; } pSRB->ReturnAddr = wlval; ioport = pACB->IOPortBase; outl(wlval,(ioport+TEMP)); return;}static voidSetXferRate( PACB pACB, PDCB pDCB ){ UCHAR bval; USHORT cnt, i; PDCB ptr; if( !(pDCB->IdentifyMsg & 0x07) ) { if( pACB->scan_devices ) { CurrDCBscntl3 = pDCB->DCBscntl3; } else { ptr = pACB->pLinkDCB; cnt = pACB->DeviceCnt; bval = pDCB->UnitSCSIID; for(i=0; i<cnt; i++) { if( ptr->UnitSCSIID == bval ) { ptr->DCBsxfer = pDCB->DCBsxfer; ptr->DCBscntl3 = pDCB->DCBscntl3; } ptr = ptr->pNextDCB; } } } return;}static voidDC390W_UnknownMsg( PACB pACB ){ PSRB pSRB; ULONG wlval; USHORT ioport; pSRB = pACB->pActiveDCB->pActiveSRB; pSRB->__msgout0[0] = 1; pSRB->MsgOutBuf[0] = MSG_REJECT_; wlval = pACB->jmp_set_atn; ioport = pACB->IOPortBase; outl(wlval,(ioport+DSP)); return;}static voidDC390W_MessageExtnd( PACB pACB ){ DC390W_UnknownMsg( pACB );}static voidDC390W_Disconnected( PACB pACB ){ PDCB pDCB; PSRB pSRB; ULONG wlval, flags; USHORT ioport; UCHAR bval;#ifdef DC390W_DEBUG0 printk("Discnet,");#endif save_flags(flags); cli(); pDCB = pACB->pActiveDCB; if (! pDCB) {#ifdef DC390W_DEBUG0 printk("ACB:%08lx->ActiveDCB:%08lx !,", (ULONG)pACB, (ULONG)pDCB);#endif restore_flags(flags); return; } pSRB = pDCB->pActiveSRB; ioport = pACB->IOPortBase; bval = inb(ioport+SCRATCHA); pSRB->ScratchABuf = bval; pSRB->SRBState |= SRB_DISCONNECT; /* 1.02 */ wlval = pACB->jmp_reselect; outl(wlval,(ioport+DSP)); pACB->pActiveDCB = 0; DoWaitingSRB( pACB ); restore_flags(flags); return;}static voidDC390W_Reselected( PACB pACB ){#ifdef DC390W_DEBUG0 printk("Rsel,");#endif pACB->msgin123[0] = 0x80; /* set identify byte 80h */ DC390W_Reselected1(pACB); return;}static voidDC390W_Reselected1( PACB pACB ){ PDCB pDCB; PSRB pSRB; USHORT ioport, wval; ULONG wlval, flags; UCHAR bval;#ifdef DC390W_DEBUG0 printk("Rsel1,");#endif ioport = pACB->IOPortBase; pDCB = pACB->pActiveDCB; if(pDCB) { pSRB = pDCB->pActiveSRB; RewaitSRB( pDCB, pSRB ); } wval = (USHORT) (pACB->msgin123[0]); wval = (wval & 7) << 8; /* get LUN */ wval |= (USHORT) (inb(ioport+SSID) & 0x0f); /* get ID */ pDCB = pACB->pLinkDCB; while( *((PUSHORT) &pDCB->UnitSCSIID) != wval ) pDCB = pDCB->pNextDCB; pACB->pActiveDCB = pDCB; bval = pDCB->DCBscntl3; outb(bval,ioport+SCNTL3); bval = pDCB->DCBsxfer; outb(bval,ioport+SXFER); bval = pDCB->DCBscntl0; outb(bval,ioport+SCNTL0); if(pDCB->MaxCommand > 1) { wlval = pACB->jmp_reselecttag; outl(wlval,(ioport+DSP)); } else { pSRB = pDCB->pActiveSRB; if( !pSRB || !(pSRB->SRBState & SRB_DISCONNECT) ) { save_flags(flags); cli(); pSRB = pACB->pFreeSRB; pACB->pFreeSRB = pSRB->pNextSRB; restore_flags(flags); pSRB->SRBState = SRB_UNEXPECT_RESEL; pDCB->pActiveSRB = pSRB; pSRB->MsgOutBuf[0] = MSG_ABORT; pSRB->__msgout0[0] = 1; } pSRB->SRBState &= ~SRB_DISCONNECT; wlval = pSRB->PhysSRB; outl(wlval,(ioport+DSA)); wlval = pSRB->ReturnAddr; outl(wlval,(ioport+TEMP)); bval = pSRB->ScratchABuf; outb(bval,ioport+SCRATCHA); if( pSRB->SRBState & SRB_UNEXPECT_RESEL ) wlval = pACB->jmp_set_atn; else wlval = pACB->jmp_clear_ack; outl(wlval,(ioport+DSP)); } return;}static voidDC390W_ReselectedT( PACB pACB ){ PDCB pDCB; PSRB pSRB, psrb1; USHORT ioport; ULONG wlval, flags; UCHAR bval;#ifdef DC390W_DEBUG0 printk("RselT,");#endif ioport = pACB->IOPortBase; bval = pACB->msgin123[1]; pDCB = pACB->pActiveDCB; pSRB = pDCB->pGoingSRB; psrb1 = pDCB->pGoingLast; if( !pSRB ) goto UXP_RSL; for(;;) { if(pSRB->TagNumber != bval) { if( pSRB != psrb1 ) pSRB = pSRB->pNextSRB; else goto UXP_RSL; } else break; } if( !(pSRB->SRBState & SRB_DISCONNECT) ) {UXP_RSL: save_flags(flags); cli(); pSRB = pACB->pFreeSRB; pACB->pFreeSRB = pSRB->pNextSRB; restore_flags(flags); pSRB->SRBState = SRB_UNEXPECT_RESEL; pDCB->pActiveSRB = pSRB; pSRB->MsgOutBuf[0] = MSG_ABORT_TAG; pSRB->__msgout0[0] = 1; } else { pSRB->SRBState &= ~SRB_DISCONNECT; pDCB->pActiveSRB = pSRB; } wlval = pSRB->PhysSRB; outl(wlval,(ioport+DSA)); wlval = pSRB->ReturnAddr; outl(wlval,(ioport+TEMP)); bval = pSRB->ScratchABuf; outb(bval,ioport+SCRATCHA); if( pSRB->SRBState & SRB_UNEXPECT_RESEL ) wlval = pACB->jmp_set_atn; else wlval = pACB->jmp_clear_ack; outl(wlval,(ioport+DSP)); return;}static voidDC390W_RestorePtr( PACB pACB ){ PSRB pSRB; USHORT ioport; ULONG wlval; pSRB = pACB->pActiveDCB->pActiveSRB; wlval = pSRB->ReturnAddr; ioport = pACB->IOPortBase; outl(wlval,(ioport+TEMP)); wlval = inl(ioport+DSP); outl(wlval,(ioport+DSP)); return;}static voidPhaseMismatch( PACB pACB ){ USHORT ioport; ULONG wlval,swlval; USHORT wval; UCHAR bval,phase; PDCB pDCB;#ifdef DC390W_DEBUG0 printk("Mismatch,");#endif ioport = pACB->IOPortBase; bval = inb(ioport+SCRATCHA); if(bval & OVER_RUN_) /* xfer PAD */ { bval = inb(ioport+STEST3); bval |= CLR_SCSI_FIFO; outb(bval,ioport+STEST3); bval = CLR_DMA_FIFO; outb(bval,ioport+CTEST3); wlval = pACB->jmp_next; /* check phase */ outl(wlval,(ioport+DSP)); return; } pDCB = pACB->pActiveDCB; wlval = inl(ioport+DBC); phase = (UCHAR)((wlval & 0x07000000) >> 24); wlval &= 0xffffff; /* bytes not xferred */ if( phase == SCSI_DATA_IN ) { swlval = pACB->jmp_din8; if( pDCB->DCBscntl3 & EN_WIDE_SCSI ) swlval += jmp_din16; DataIOcommon(pACB,swlval,wlval); } else if( phase == SCSI_DATA_OUT ) { wval = (USHORT)inb(ioport+CTEST5); wval <<= 8; bval = inb(ioport+DFIFO); wval |= (USHORT) bval; wval -= ((USHORT)(wlval & 0xffff)); wval &= 0x3ff; wlval += (ULONG)wval; /* # of bytes remains in FIFO */ bval = inb(ioport+SSTAT0); if(bval & SODR_LSB_FULL) wlval++; /* data left in Scsi Output Data Buffer */ if(bval & SODL_LSB_FULL) wlval++; /* data left in Scsi Output Data Latch */ swlval = pACB->jmp_dout8; if(pDCB->DCBscntl3 & EN_WIDE_SCSI) { swlval += jmp_dout16; bval = inb(ioport+SSTAT2); if(bval & SODR_MSB_FULL) wlval++; if(bval & SODL_MSB_FULL) wlval++; } bval = inb(ioport+STEST3); bval |= CLR_SCSI_FIFO; outb(bval,ioport+STEST3); bval = CLR_DMA_FIFO; outb(bval,ioport+CTEST3); DataIOcommon(pACB,swlval,wlval); } else { bval = inb(ioport+STEST3); bval |= CLR_SCSI_FIFO; outb(bval,ioport+STEST3); bval = CLR_DMA_FIFO; outb(bval,ioport+CTEST3); if(phase == SCSI_MSG_OUT) wlval = pACB->jmp_clear_atn; else wlval = pACB->jmp_next; /* check phase */ outl(wlval,(ioport+DSP)); } return;}static voidDataIOcommon( PACB pACB, ULONG Swlval, ULONG Cwlval ){ /* Swlval - script address */ /* Cwlval - bytes not xferred */ PDCB pDCB; PSRB pSRB; PSGE Segptr; USHORT ioport; ULONG wlval,swlval,dataXferCnt; UCHAR bval,bvald; ioport = pACB->IOPortBase; wlval = inl((ioport+DSP)); pDCB = pACB->pActiveDCB; pSRB = pDCB->pActiveSRB; wlval -= Swlval; bval = inb(ioport+SBCL); bval &= 0x07; if(bval == SCSI_MSG_IN) { bval = pDCB->DCBscntl3; bval &= ~EN_WIDE_SCSI; outb(bval,ioport+SCNTL3); bval = inb(ioport+SBDL); bvald = pDCB->DCBscntl3; /* enable WIDE SCSI */ outb(bvald,ioport+SCNTL3); if(bval == MSG_DISCONNECT || bval == MSG_SAVE_PTR) { Segptr = (PSGE)((ULONG) &(pSRB->Segment0[0][0]) + wlval); dataXferCnt = Segptr->SGXLen - Cwlval; Segptr->SGXLen = Cwlval; /* modified count */ Segptr->SGXPtr += dataXferCnt; /* modified address */ swlval = pACB->jmp_table8; if(pDCB->DCBscntl3 & EN_WIDE_SCSI) swlval += jmp_table16; wlval <<= 1; swlval += wlval; swlval = swlval - ((MAX_SG_LIST_BUF+1) * 16); pSRB->ReturnAddr = swlval; } } else if( Cwlval ) /* Remaining not xferred -- UNDER_RUN */ { Segptr = (PSGE)((ULONG) &(pSRB->Segment0[0][0]) + wlval); dataXferCnt = Segptr->SGXLen - Cwlval; Segptr->SGXLen = Cwlval; /* modified count */ Segptr->SGXPtr += dataXferCnt; /* modified address */ swlval = pACB->jmp_table8; if(pDCB->DCBscntl3 & EN_WIDE_SCSI) swlval += jmp_table16; wlval <<= 1; swlval += wlval; swlval = swlval - ((MAX_SG_LIST_BUF+1) * 16); pSRB->RemainSegPtr = swlval; }/* pm__1: */ wlval = pSRB->ReturnAddr; outl(wlval,(ioport+TEMP)); wlval = pACB->jmp_next; outl(wlval,(ioport+DSP)); return;}static voidDC390W_CmdCompleted( PACB pACB ){ PDCB pDCB; PSRB pSRB; USHORT ioport; ULONG wlval, flags; UCHAR bval;#ifdef DC390W_DEBUG0 printk("Cmplete,");#endif save_flags(flags); cli(); pDCB = pACB->pActiveDCB; pSRB = pDCB->pActiveSRB; pDCB->pActiveSRB = NULL; ioport = pACB->IOPortBase; bval = inb(ioport+SCRATCHA); pSRB->ScratchABuf = bval; /* save status */ bval = pSRB->TagNumber; if(pDCB->MaxCommand > 1)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -