📄 scsiiom.c
字号:
else { /* minx: */ *pSRB->pMsgPtr = bval; pSRB->MsgCnt++; pSRB->pMsgPtr++; if( (pSRB->MsgInBuf[0] >= MSG_SIMPLE_QTAG) && (pSRB->MsgInBuf[0] <= MSG_ORDER_QTAG) ) { if( pSRB->MsgCnt == 2) { pSRB->SRBState = 0; bval = pSRB->MsgInBuf[1]; pSRB = pDCB->pGoingSRB; psrb = pDCB->pGoingLast; if( pSRB ) { for( ;; ) { if(pSRB->TagNumber != bval) { if( pSRB == psrb ) goto mingx0; pSRB = pSRB->pNextSRB; } else break; } if( pDCB->DCBFlag & ABORT_DEV_ ) { pSRB->SRBState = SRB_ABORT_SENT; EnableMsgOut( pACB, pSRB ); } if( !(pSRB->SRBState & SRB_DISCONNECT) ) goto mingx0; pDCB->pActiveSRB = pSRB; pSRB->SRBState = SRB_DATA_XFER; } else {mingx0: pSRB = pACB->pTmpSRB; pSRB->SRBState = SRB_UNEXPECT_RESEL; pDCB->pActiveSRB = pSRB; pSRB->MsgOutBuf[0] = MSG_ABORT_TAG; EnableMsgOut2( pACB, pSRB ); } } } else if( (pSRB->MsgInBuf[0] == MSG_EXTENDED) && (pSRB->MsgCnt == 5) ) { pSRB->SRBState &= ~(SRB_MSGIN_MULTI+DO_SYNC_NEGO); if( (pSRB->MsgInBuf[1] != 3) || (pSRB->MsgInBuf[2] != 1) ) { /* reject_msg: */ pSRB->MsgCnt = 1; pSRB->MsgInBuf[0] = MSG_REJECT_; bval = SET_ATN_CMD; outb(bval, ioport+ScsiCmd); } else if( !(pSRB->MsgInBuf[3]) || !(pSRB->MsgInBuf[4]) ) {set_async: pDCB = pSRB->pSRBDCB; pDCB->SyncMode &= ~(SYNC_ENABLE+SYNC_NEGO_DONE); pDCB->SyncPeriod = 0; pDCB->SyncOffset = 0; pDCB->CtrlR3 = FAST_CLK; /* ;non_fast */ pDCB->CtrlR4 &= 0x3f; pDCB->CtrlR4 |= EATER_25NS; /* ; 25ns glitch eater */ goto re_prog; } else { /* set_sync: */ pDCB = pSRB->pSRBDCB; pDCB->SyncMode |= SYNC_ENABLE+SYNC_NEGO_DONE; pDCB->SyncOffset &= 0x0f0; pDCB->SyncOffset |= pSRB->MsgInBuf[4]; pDCB->NegoPeriod = pSRB->MsgInBuf[3]; wval = (USHORT) pSRB->MsgInBuf[3]; wval = wval << 2; wval--; wval1 = wval / 25; if( (wval1 * 25) != wval) wval1++; bval = FAST_CLK+FAST_SCSI; pDCB->CtrlR4 &= 0x3f; if(wval1 >= 8) { wval1--; bval = FAST_CLK; /* ;fast clock/normal scsi */ pDCB->CtrlR4 |= EATER_25NS; /* ;25 ns glitch eater */ } pDCB->CtrlR3 = bval; pDCB->SyncPeriod = (UCHAR)wval1;re_prog: bval = pDCB->SyncPeriod; outb(bval, ioport+Sync_Period); bval = pDCB->SyncOffset; outb(bval, ioport+Sync_Offset); bval = pDCB->CtrlR3; outb(bval, ioport+CtrlReg3); bval = pDCB->CtrlR4; outb(bval, ioport+CtrlReg4); SetXferRate( pACB, pDCB); } } }min6: *psstatus = SCSI_NOP0; bval = MSG_ACCEPTED_CMD; outb(bval, ioport+ScsiCmd);}static voidDataIO_Comm( PACB pACB, PSRB pSRB, UCHAR ioDir){ PSGL psgl; UCHAR bval; USHORT ioport; ULONG lval; ioport = pACB->IOPortBase; if( pSRB->SGIndex < pSRB->SGcount ) { bval = DMA_IDLE_CMD | ioDir; /* ;+EN_DMA_INT */ outb( bval, ioport+DMA_Cmd); if( !pSRB->SGToBeXferLen ) { psgl = pSRB->pSegmentList;#ifndef VERSION_ELF_1_2_13 pSRB->SGPhysAddr = virt_to_phys( psgl->address );#else pSRB->SGPhysAddr = (ULONG) psgl->address;#endif pSRB->SGToBeXferLen = (ULONG) psgl->length; } lval = pSRB->SGToBeXferLen; bval = (UCHAR) lval; outb(bval,ioport+CtcReg_Low); lval = lval >> 8; bval = (UCHAR) lval; outb(bval,ioport+CtcReg_Mid); lval = lval >> 8; bval = (UCHAR) lval; outb(bval,ioport+CtcReg_High); lval = pSRB->SGToBeXferLen; outl(lval, ioport+DMA_XferCnt); lval = pSRB->SGPhysAddr; outl( lval, ioport+DMA_XferAddr); bval = DMA_COMMAND+INFO_XFER_CMD; outb(bval, ioport+ScsiCmd); pSRB->SRBState = SRB_DATA_XFER; bval = DMA_IDLE_CMD | ioDir; /* ;+EN_DMA_INT */ outb(bval, ioport+DMA_Cmd); bval = DMA_START_CMD | ioDir; /* ;+EN_DMA_INT */ outb(bval, ioport+DMA_Cmd); } else /* xfer pad */ { if( pSRB->SGcount ) { pSRB->AdaptStatus = H_OVER_UNDER_RUN; pSRB->SRBStatus |= OVER_RUN; } bval = 0; outb(bval,ioport+CtcReg_Low); outb(bval,ioport+CtcReg_Mid); outb(bval,ioport+CtcReg_High); pSRB->SRBState |= SRB_XFERPAD; bval = DMA_COMMAND+XFER_PAD_BYTE; outb(bval, ioport+ScsiCmd);/* bval = DMA_IDLE_CMD | ioDir; ;+EN_DMA_INT outb(bval, ioport+DMA_Cmd); bval = DMA_START_CMD | ioDir; ;+EN_DMA_INT outb(bval, ioport+DMA_Cmd);*/ }}static voidDC390_DataOutPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus){ UCHAR ioDir; ioDir = WRITE_DIRECTION; DataIO_Comm( pACB, pSRB, ioDir);}static voidDC390_DataInPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus){ UCHAR ioDir; ioDir = READ_DIRECTION; DataIO_Comm( pACB, pSRB, ioDir);}static voidDC390_CommandPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus){ PDCB pDCB; UCHAR bval; PUCHAR ptr; USHORT ioport, i, cnt; ioport = pACB->IOPortBase; bval = RESET_ATN_CMD; outb(bval, ioport+ScsiCmd); bval = CLEAR_FIFO_CMD; outb(bval, ioport+ScsiCmd); if( !(pSRB->SRBFlag & AUTO_REQSENSE) ) { cnt = (USHORT) pSRB->ScsiCmdLen; ptr = (PUCHAR) pSRB->CmdBlock; for(i=0; i < cnt; i++) { outb(*ptr, ioport+ScsiFifo); ptr++; } } else { bval = REQUEST_SENSE; outb(bval, ioport+ScsiFifo); pDCB = pACB->pActiveDCB; bval = pDCB->IdentifyMsg << 5; outb(bval, ioport+ScsiFifo); bval = 0; outb(bval, ioport+ScsiFifo); outb(bval, ioport+ScsiFifo); bval = sizeof(pSRB->pcmd->sense_buffer); outb(bval, ioport+ScsiFifo); bval = 0; outb(bval, ioport+ScsiFifo); } pSRB->SRBState = SRB_COMMAND; bval = INFO_XFER_CMD; outb(bval, ioport+ScsiCmd);}static voidDC390_StatusPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus){ UCHAR bval; USHORT ioport; ioport = pACB->IOPortBase; bval = CLEAR_FIFO_CMD; outb(bval, ioport+ScsiCmd); pSRB->SRBState = SRB_STATUS; bval = INITIATOR_CMD_CMPLTE; outb(bval, ioport+ScsiCmd);}static voidDC390_MsgOutPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus){ UCHAR bval; USHORT ioport, i, cnt; PUCHAR ptr; PDCB pDCB; ioport = pACB->IOPortBase; bval = CLEAR_FIFO_CMD; outb(bval, ioport+ScsiCmd); pDCB = pACB->pActiveDCB; if( !(pSRB->SRBState & SRB_MSGOUT) ) { cnt = pSRB->MsgCnt; if( cnt ) { ptr = (PUCHAR) pSRB->MsgOutBuf; for(i=0; i < cnt; i++) { outb(*ptr, ioport+ScsiFifo); ptr++; } pSRB->MsgCnt = 0; if( (pDCB->DCBFlag & ABORT_DEV_) && (pSRB->MsgOutBuf[0] == MSG_ABORT) ) pSRB->SRBState = SRB_ABORT_SENT; } else { bval = MSG_ABORT; /* ??? MSG_NOP */ if( (pSRB->CmdBlock[0] == INQUIRY ) || (pSRB->CmdBlock[0] == REQUEST_SENSE) || (pSRB->SRBFlag & AUTO_REQSENSE) ) { if( pDCB->SyncMode & SYNC_ENABLE ) goto mop1; } outb(bval, ioport+ScsiFifo); } bval = INFO_XFER_CMD; outb( bval, ioport+ScsiCmd); } else {mop1: bval = MSG_EXTENDED; outb(bval, ioport+ScsiFifo); bval = 3; /* ;length of extended msg */ outb(bval, ioport+ScsiFifo); bval = 1; /* ; sync nego */ outb(bval, ioport+ScsiFifo); bval = pDCB->NegoPeriod; outb(bval, ioport+ScsiFifo); bval = SYNC_NEGO_OFFSET; outb(bval, ioport+ScsiFifo); pSRB->SRBState |= DO_SYNC_NEGO; bval = INFO_XFER_CMD; outb(bval, ioport+ScsiCmd); }}static voidDC390_MsgInPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus){ UCHAR bval; USHORT ioport; ioport = pACB->IOPortBase; bval = CLEAR_FIFO_CMD; outb(bval, ioport+ScsiCmd); if( !(pSRB->SRBState & SRB_MSGIN) ) { pSRB->SRBState &= SRB_DISCONNECT; pSRB->SRBState |= SRB_MSGIN; } bval = INFO_XFER_CMD; outb(bval, ioport+ScsiCmd);}static voidDC390_Nop_0( PACB pACB, PSRB pSRB, PUCHAR psstatus){}static voidDC390_Nop_1( PACB pACB, PSRB pSRB, PUCHAR psstatus){}static voidSetXferRate( PACB pACB, PDCB pDCB ){ UCHAR bval; USHORT cnt, i; PDCB ptr; if( !(pDCB->IdentifyMsg & 0x07) ) { if( pACB->scan_devices ) { CurrSyncOffset = pDCB->SyncOffset; } else { ptr = pACB->pLinkDCB; cnt = pACB->DeviceCnt; bval = pDCB->UnitSCSIID; for(i=0; i<cnt; i++) { if( ptr->UnitSCSIID == bval ) { ptr->SyncPeriod = pDCB->SyncPeriod; ptr->SyncOffset = pDCB->SyncOffset; ptr->CtrlR3 = pDCB->CtrlR3; ptr->CtrlR4 = pDCB->CtrlR4; ptr->SyncMode = pDCB->SyncMode; } ptr = ptr->pNextDCB; } } } return;}static voidDC390_Disconnect( PACB pACB ){ PDCB pDCB; PSRB pSRB, psrb; ULONG flags; USHORT ioport, i, cnt; UCHAR bval;#ifdef DC390_DEBUG0 printk("DISC,");#endif save_flags(flags); cli(); ioport = pACB->IOPortBase; pDCB = pACB->pActiveDCB; if (!pDCB) {#ifdef DC390_DEBUG0 printk("ACB:%08lx->ActiveDCB:%08lx !,",(ULONG)pACB,(ULONG)pDCB);#endif restore_flags(flags); return; } pSRB = pDCB->pActiveSRB; pACB->pActiveDCB = 0; pSRB->ScsiPhase = SCSI_NOP0; bval = EN_SEL_RESEL; outb(bval, ioport+ScsiCmd); if( pSRB->SRBState & SRB_UNEXPECT_RESEL ) { pSRB->SRBState = 0; DoWaitingSRB( pACB ); } else if( pSRB->SRBState & SRB_ABORT_SENT ) { pDCB->TagMask = 0; pDCB->DCBFlag = 0; cnt = pDCB->GoingSRBCnt; pDCB->GoingSRBCnt = 0; pSRB = pDCB->pGoingSRB; for( i=0; i < cnt; i++) { psrb = pSRB->pNextSRB; pSRB->pNextSRB = pACB->pFreeSRB; pACB->pFreeSRB = pSRB; pSRB = psrb; } pDCB->pGoingSRB = 0; DoWaitingSRB( pACB ); } else { if( (pSRB->SRBState & (SRB_START_+SRB_MSGOUT)) || !(pSRB->SRBState & (SRB_DISCONNECT+SRB_COMPLETED)) ) { /* Selection time out */ if( !(pACB->scan_devices) ) { pSRB->SRBState = SRB_READY; RewaitSRB( pDCB, pSRB); } else { pSRB->TargetStatus = SCSI_STAT_SEL_TIMEOUT; goto disc1; } } else if( pSRB->SRBState & SRB_DISCONNECT ) { DoWaitingSRB( pACB ); } else if( pSRB->SRBState & SRB_COMPLETED ) {disc1: if(pDCB->MaxCommand > 1) { bval = pSRB->TagNumber; pDCB->TagMask &= (~(1 << bval)); /* free tag mask */ } pDCB->pActiveSRB = 0; pSRB->SRBState = SRB_FREE; SRBdone( pACB, pDCB, pSRB); } } restore_flags(flags); return;}static voidDC390_Reselect( PACB pACB ){ PDCB pDCB, pdcb; PSRB pSRB; USHORT ioport, wval; UCHAR bval, bval1;#ifdef DC390_DEBUG0 printk("RSEL,");#endif ioport = pACB->IOPortBase; pDCB = pACB->pActiveDCB; if( pDCB ) { /* Arbitration lost but Reselection win */ pSRB = pDCB->pActiveSRB; if( !( pACB->scan_devices ) ) { pSRB->SRBState = SRB_READY; RewaitSRB( pDCB, pSRB); } } bval = inb(ioport+ScsiFifo); /* get ID */ bval = bval ^ pACB->HostID_Bit; wval = 0; bval1 = 1; for(;;) { if( !(bval & bval1) ) { bval1 = bval1 << 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -