📄 scsiiom.c
字号:
wval++; } else break; } wval |= ( (USHORT) inb(ioport+ScsiFifo) & 7) << 8; /* get LUN */ pDCB = pACB->pLinkDCB; pdcb = pDCB; while( wval != *((PUSHORT) &pDCB->UnitSCSIID) ) { pDCB = pDCB->pNextDCB; if( pDCB == pdcb ) return; } pACB->pActiveDCB = pDCB; if( pDCB->SyncMode & EN_TAG_QUEUING ) { pSRB = pACB->pTmpSRB; pDCB->pActiveSRB = pSRB; } else { pSRB = pDCB->pActiveSRB; if( !pSRB || !(pSRB->SRBState & SRB_DISCONNECT) ) { pSRB= pACB->pTmpSRB; pSRB->SRBState = SRB_UNEXPECT_RESEL; pDCB->pActiveSRB = pSRB; EnableMsgOut( pACB, pSRB ); } else { if( pDCB->DCBFlag & ABORT_DEV_ ) { pSRB->SRBState = SRB_ABORT_SENT; EnableMsgOut( pACB, pSRB ); } else pSRB->SRBState = SRB_DATA_XFER; } } pSRB->ScsiPhase = SCSI_NOP0; bval = pDCB->UnitSCSIID; outb( bval, ioport+Scsi_Dest_ID); bval = pDCB->SyncPeriod; outb(bval, ioport+Sync_Period); bval = pDCB->SyncOffset; outb( bval, ioport+Sync_Offset); bval = pDCB->CtrlR1; outb(bval, ioport+CtrlReg1); bval = pDCB->CtrlR3; outb(bval, ioport+CtrlReg3); bval = pDCB->CtrlR4; /* ; Glitch eater */ outb(bval, ioport+CtrlReg4); bval = MSG_ACCEPTED_CMD; /* ;to rls the /ACK signal */ outb(bval, ioport+ScsiCmd);}static voidSRBdone( PACB pACB, PDCB pDCB, PSRB pSRB ){ PSRB psrb; UCHAR bval, bval1, i, j, status; PSCSICMD pcmd; PSCSI_INQDATA ptr; USHORT disable_tag; ULONG flags; PSGL ptr2; ULONG swlval; pcmd = pSRB->pcmd; status = pSRB->TargetStatus; if(pSRB->SRBFlag & AUTO_REQSENSE) { pSRB->SRBFlag &= ~AUTO_REQSENSE; pSRB->AdaptStatus = 0; pSRB->TargetStatus = SCSI_STAT_CHECKCOND; if(status == SCSI_STAT_CHECKCOND) { pcmd->result = DID_BAD_TARGET << 16; goto ckc_e; } if(pSRB->RetryCnt == 0) { *((PULONG) &(pSRB->CmdBlock[0])) = pSRB->Segment0[0]; pSRB->TotalXferredLen = pSRB->Segment1[1]; if( (pSRB->TotalXferredLen) && (pSRB->TotalXferredLen >= pcmd->underflow) ) pcmd->result |= (DID_OK << 16); else pcmd->result = (DRIVER_SENSE << 24) | (DRIVER_OK << 16) | SCSI_STAT_CHECKCOND;#ifdef DC390_DEBUG0 printk("Cmd=%2x,Result=%8x,XferL=%8x,",pSRB->CmdBlock[0], (UINT) pcmd->result, (UINT) pSRB->TotalXferredLen);#endif goto ckc_e; } else { pSRB->RetryCnt--; pSRB->AdaptStatus = 0; pSRB->TargetStatus = 0; *((PULONG) &(pSRB->CmdBlock[0])) = pSRB->Segment0[0]; *((PULONG) &(pSRB->CmdBlock[4])) = pSRB->Segment0[1]; if( pSRB->CmdBlock[0] == TEST_UNIT_READY ) { pcmd->result = (DRIVER_SENSE << 24) | (DRIVER_OK << 16) | SCSI_STAT_CHECKCOND; goto ckc_e; } pcmd->result |= (DRIVER_SENSE << 24); pSRB->SGcount = (UCHAR) pSRB->Segment1[0]; pSRB->ScsiCmdLen = (UCHAR) (pSRB->Segment1[0] >> 8); pSRB->SGIndex = 0; pSRB->TotalXferredLen = 0; pSRB->SGToBeXferLen = 0; if( pcmd->use_sg ) pSRB->pSegmentList = (PSGL) pcmd->request_buffer; else if( pcmd->request_buffer ) { pSRB->pSegmentList = (PSGL) &pSRB->Segmentx; pSRB->Segmentx.address = (PUCHAR) pcmd->request_buffer; pSRB->Segmentx.length = pcmd->request_bufflen; } if( DC390_StartSCSI( pACB, pDCB, pSRB ) ) RewaitSRB( pDCB, pSRB ); return; } } if( status ) { if( status == SCSI_STAT_CHECKCOND) { if( (pSRB->SGIndex < pSRB->SGcount) && (pSRB->SGcount) && (pSRB->SGToBeXferLen) ) { bval = pSRB->SGcount; swlval = 0; ptr2 = pSRB->pSegmentList; for( i=pSRB->SGIndex; i < bval; i++) { swlval += ptr2->length; ptr2++; }#ifdef DC390_DEBUG0 printk("XferredLen=%8x,NotXferLen=%8x,", (UINT) pSRB->TotalXferredLen, (UINT) swlval);#endif } RequestSense( pACB, pDCB, pSRB ); return; } else if( status == SCSI_STAT_QUEUEFULL ) { bval = (UCHAR) pDCB->GoingSRBCnt; bval--; pDCB->MaxCommand = bval; RewaitSRB( pDCB, pSRB ); pSRB->AdaptStatus = 0; pSRB->TargetStatus = 0; return; } else if(status == SCSI_STAT_SEL_TIMEOUT) { pSRB->AdaptStatus = H_SEL_TIMEOUT; pSRB->TargetStatus = 0; pcmd->result = DID_BAD_TARGET << 16; } else { pSRB->AdaptStatus = 0; if( pSRB->RetryCnt ) { pSRB->RetryCnt--; pSRB->TargetStatus = 0; pSRB->SGIndex = 0; pSRB->TotalXferredLen = 0; pSRB->SGToBeXferLen = 0; if( pcmd->use_sg ) pSRB->pSegmentList = (PSGL) pcmd->request_buffer; else if( pcmd->request_buffer ) { pSRB->pSegmentList = (PSGL) &pSRB->Segmentx; pSRB->Segmentx.address = (PUCHAR) pcmd->request_buffer; pSRB->Segmentx.length = pcmd->request_bufflen; } if( DC390_StartSCSI( pACB, pDCB, pSRB ) ) RewaitSRB( pDCB, pSRB ); return; } else { pcmd->result |= (DID_ERROR << 16) | (ULONG) (pSRB->EndMessage << 8) | (ULONG) status; } } } else { status = pSRB->AdaptStatus; if(status & H_OVER_UNDER_RUN) { pSRB->TargetStatus = 0; pcmd->result |= (DID_OK << 16) | (pSRB->EndMessage << 8); } else if( pSRB->SRBStatus & PARITY_ERROR) { pcmd->result |= (DID_PARITY << 16) | (pSRB->EndMessage << 8); } else /* No error */ { pSRB->AdaptStatus = 0; pSRB->TargetStatus = 0; pcmd->result |= (DID_OK << 16); } }ckc_e: if( pACB->scan_devices ) { if( pSRB->CmdBlock[0] == TEST_UNIT_READY ) { if(pcmd->result != (DID_OK << 16)) { if( pcmd->result & SCSI_STAT_CHECKCOND ) { goto RTN_OK; } else { pACB->DCBmap[pcmd->target] &= ~(1 << pcmd->lun); pPrevDCB->pNextDCB = pACB->pLinkDCB; if( (pcmd->target == pACB->max_id) && ((pcmd->lun == 0) || (pcmd->lun == pACB->max_lun)) ) { pACB->scan_devices = 0; } } } else {RTN_OK: pPrevDCB->pNextDCB = pDCB; pDCB->pNextDCB = pACB->pLinkDCB; if( (pcmd->target == pACB->max_id) && (pcmd->lun == pACB->max_lun) ) pACB->scan_devices = END_SCAN; } } else if( pSRB->CmdBlock[0] == INQUIRY ) { if( (pcmd->target == pACB->max_id) && (pcmd->lun == pACB->max_lun) ) { pACB->scan_devices = 0; } ptr = (PSCSI_INQDATA) (pcmd->request_buffer); if( pcmd->use_sg ) ptr = (PSCSI_INQDATA) (((PSGL) ptr)->address); bval1 = ptr->DevType & SCSI_DEVTYPE; if(bval1 == SCSI_NODEV) { pACB->DCBmap[pcmd->target] &= ~(1 << pcmd->lun); pPrevDCB->pNextDCB = pACB->pLinkDCB; } else { pACB->DeviceCnt++; pPrevDCB = pDCB; pACB->pDCB_free = (PDCB) ((ULONG) (pACB->pDCB_free) + sizeof( DC390_DCB )); pDCB->DevType = bval1; if(bval1 == TYPE_DISK || bval1 == TYPE_MOD) { if( (((ptr->Vers & 0x07) >= 2) || ((ptr->RDF & 0x0F) == 2)) && (ptr->Flags & SCSI_INQ_CMDQUEUE) && (pDCB->DevMode & TAG_QUEUING_) && (pDCB->DevMode & EN_DISCONNECT_) ) { disable_tag = 0; for(i=0; i<BADDEVCNT; i++) { for(j=0; j<28; j++) { if( ((PUCHAR)ptr)[8+j] != baddevname1[i][j]) break; } if(j == 28) { disable_tag = 1; break; } } if( !disable_tag ) { pDCB->MaxCommand = pACB->TagMaxNum; pDCB->SyncMode |= EN_TAG_QUEUING; pDCB->TagMask = 0; } else { pDCB->SyncMode |= EN_ATN_STOP; } } } } } } save_flags( flags ); cli();/* ReleaseSRB( pDCB, pSRB ); */ if(pSRB == pDCB->pGoingSRB ) { pDCB->pGoingSRB = pSRB->pNextSRB; } else { psrb = pDCB->pGoingSRB; while( psrb->pNextSRB != pSRB ) psrb = psrb->pNextSRB; psrb->pNextSRB = pSRB->pNextSRB; if( pSRB == pDCB->pGoingLast ) pDCB->pGoingLast = psrb; } pSRB->pNextSRB = pACB->pFreeSRB; pACB->pFreeSRB = pSRB; pDCB->GoingSRBCnt--; DoWaitingSRB( pACB ); restore_flags(flags);/* Notify cmd done */ pcmd->scsi_done( pcmd ); if( pDCB->QIORBCnt ) DoNextCmd( pACB, pDCB ); return;}static voidDoingSRB_Done( PACB pACB ){ PDCB pDCB, pdcb; PSRB psrb, psrb2; USHORT cnt, i; PSCSICMD pcmd; pDCB = pACB->pLinkDCB; pdcb = pDCB; do { cnt = pdcb->GoingSRBCnt; psrb = pdcb->pGoingSRB; for( i=0; i<cnt; i++) { psrb2 = psrb->pNextSRB; pcmd = psrb->pcmd; pcmd->result = DID_RESET << 16;/* ReleaseSRB( pDCB, pSRB ); */ psrb->pNextSRB = pACB->pFreeSRB; pACB->pFreeSRB = psrb; pcmd->scsi_done( pcmd ); psrb = psrb2; } pdcb->GoingSRBCnt = 0;; pdcb->pGoingSRB = NULL; pdcb->TagMask = 0; pdcb = pdcb->pNextDCB; } while( pdcb != pDCB );}static voidDC390_ResetSCSIBus( PACB pACB ){ USHORT ioport; UCHAR bval; ULONG flags; save_flags(flags); cli(); pACB->ACBFlag |= RESET_DEV; ioport = pACB->IOPortBase; bval = DMA_IDLE_CMD; outb(bval,ioport+DMA_Cmd); bval = RST_SCSI_BUS_CMD; outb(bval,ioport+ScsiCmd); restore_flags(flags); return;}static voidDC390_ScsiRstDetect( PACB pACB ){ ULONG wlval, flags; USHORT ioport; UCHAR bval;#ifdef DC390_DEBUG0 printk("RST_DETEC");#endif save_flags(flags); sti(); wlval = jiffies + HZ; while( jiffies < wlval ); /* delay 1 sec */ cli(); ioport = pACB->IOPortBase; bval = DMA_IDLE_CMD; outb(bval,ioport+DMA_Cmd); bval = CLEAR_FIFO_CMD; outb(bval,ioport+ScsiCmd); if( pACB->ACBFlag & RESET_DEV ) pACB->ACBFlag |= RESET_DONE; else { pACB->ACBFlag |= RESET_DETECT; ResetDevParam( pACB );/* DoingSRB_Done( pACB ); ???? */ RecoverSRB( pACB ); pACB->pActiveDCB = NULL; pACB->ACBFlag = 0; DoWaitingSRB( pACB ); } restore_flags(flags); return;}static voidRequestSense( PACB pACB, PDCB pDCB, PSRB pSRB ){ PSCSICMD pcmd; pSRB->SRBFlag |= AUTO_REQSENSE; pSRB->Segment0[0] = *((PULONG) &(pSRB->CmdBlock[0])); pSRB->Segment0[1] = *((PULONG) &(pSRB->CmdBlock[4])); pSRB->Segment1[0] = (ULONG) ((pSRB->ScsiCmdLen << 8) + pSRB->SGcount); pSRB->Segment1[1] = pSRB->TotalXferredLen; pSRB->AdaptStatus = 0; pSRB->TargetStatus = 0; pcmd = pSRB->pcmd; pSRB->Segmentx.address = (PUCHAR) &(pcmd->sense_buffer); pSRB->Segmentx.length = sizeof(pcmd->sense_buffer); pSRB->pSegmentList = &pSRB->Segmentx; pSRB->SGcount = 1; pSRB->SGIndex = 0; *((PULONG) &(pSRB->CmdBlock[0])) = 0x00000003; pSRB->CmdBlock[1] = pDCB->IdentifyMsg << 5; *((PUSHORT) &(pSRB->CmdBlock[4])) = sizeof(pcmd->sense_buffer); pSRB->ScsiCmdLen = 6; pSRB->TotalXferredLen = 0; pSRB->SGToBeXferLen = 0; if( DC390_StartSCSI( pACB, pDCB, pSRB ) ) RewaitSRB( pDCB, pSRB );}static voidEnableMsgOut2( PACB pACB, PSRB pSRB ){ USHORT ioport; UCHAR bval; ioport = pACB->IOPortBase; pSRB->MsgCnt = 1; bval = SET_ATN_CMD; outb(bval, ioport+ScsiCmd);}static voidEnableMsgOut( PACB pACB, PSRB pSRB ){ pSRB->MsgOutBuf[0] = MSG_ABORT; EnableMsgOut2( pACB, pSRB );}static voidDC390_InvalidCmd( PACB pACB ){ UCHAR bval; USHORT ioport; PSRB pSRB; pSRB = pACB->pActiveDCB->pActiveSRB; if( pSRB->SRBState & (SRB_START_+SRB_MSGOUT) ) { ioport = pACB->IOPortBase; bval = CLEAR_FIFO_CMD; outb(bval,(ioport+ScsiCmd)); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -