📄 scsiio.c
字号:
pDCB->TagMask &= (~(1 << bval)); /* free tag mask */ pACB->pActiveDCB = NULL; /* no active device */ wlval = pACB->jmp_reselect; /* enable reselection */ outl(wlval,(ioport+DSP)); SRBdone( pACB, pDCB, pSRB); restore_flags(flags); return;}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; PSGE ptr1; PSGL ptr2; ULONG wlval,swlval; pcmd = pSRB->pcmd; status = pACB->status; 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][0]; pSRB->XferredLen = pSRB->Segment0[2][1]; if( (pSRB->XferredLen) && (pSRB->XferredLen >= pcmd->underflow) ) { pcmd->result |= (DID_OK << 16); } else pcmd->result = (DRIVER_SENSE << 24) | (DRIVER_OK << 16) | SCSI_STAT_CHECKCOND; goto ckc_e; } else { pSRB->RetryCnt--; pSRB->TargetStatus = 0; *((PULONG) &(pSRB->CmdBlock[0])) = pSRB->Segment0[0][0]; *((PULONG) &(pSRB->CmdBlock[4])) = pSRB->Segment0[0][1]; *((PULONG) &(pSRB->CmdBlock[8])) = pSRB->Segment0[1][0]; pSRB->__command[0] = pSRB->Segment0[1][1] & 0xff; pSRB->SGcount = (UCHAR) (pSRB->Segment0[1][1] >> 8); *((PULONG) &(pSRB->pSegmentList))= pSRB->Segment0[2][0]; 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); PrepareSG(pACB,pDCB,pSRB); pSRB->XferredLen = 0; DC390W_StartSCSI( pACB, pDCB, pSRB ); return; } } if( status ) { if( status == SCSI_STAT_CHECKCOND) { if( !(pSRB->ScratchABuf & SRB_OK) && (pSRB->SGcount) && (pSRB->RemainSegPtr) ) { wlval = pSRB->RemainSegPtr; swlval = pACB->jmp_table8; if(pDCB->DCBscntl3 & EN_WIDE_SCSI) swlval += jmp_table16; swlval -= wlval; swlval >>= 4; bval = (UCHAR) swlval; wlval = 0; ptr1 = (PSGE) &pSRB->Segment0[MAX_SG_LIST_BUF+1][0]; for( i=0; i< bval; i++) { wlval += ptr1->SGXLen; ptr1--; } bval = pSRB->SGcount; swlval = 0; ptr2 = pSRB->pSegmentList; for( i=0; i< bval; i++) { swlval += ptr2->length; ptr2++; } pSRB->XferredLen = swlval - wlval; pSRB->RemainSegPtr = 0;#ifdef DC390W_DEBUG0 printk("XferredLen=%8x,NotXferLen=%8x,",(UINT) pSRB->XferredLen,(UINT) wlval);#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 if(status == SCSI_STAT_UNEXP_BUS_F) { pSRB->AdaptStatus = H_UNEXP_BUS_FREE; pSRB->TargetStatus = 0; pcmd->result |= DID_NO_CONNECT << 16; } else if(status == SCSI_STAT_BUS_RST_DETECT ) { pSRB->AdaptStatus = H_ABORT; pSRB->TargetStatus = 0; pcmd->result = DID_RESET << 16; } else { pSRB->AdaptStatus = 0; pSRB->TargetStatus = status; if( pSRB->RetryCnt ) { pSRB->RetryCnt--; pSRB->TargetStatus = 0; PrepareSG(pACB,pDCB,pSRB); pSRB->XferredLen = 0; DC390W_StartSCSI( pACB, pDCB, pSRB ); return; } else { pcmd->result |= (DID_ERROR << 16) | (ULONG) (pACB->msgin123[0] << 8) | (ULONG) status; } } } else { status = pSRB->ScratchABuf; if(status & OVER_RUN_) { pSRB->AdaptStatus = H_OVER_UNDER_RUN; pSRB->TargetStatus = 0; pcmd->result |= (DID_OK << 16) | (pACB->msgin123[0] << 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( DC390W_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] != baddevname[i][j]) break; } if(j == 28) { disable_tag = 1; break; } } if( !disable_tag ) { pDCB->MaxCommand = pACB->TagMaxNum; pDCB->TagMask = 0; } } } } } } 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 voidDC390W_ResetSCSIBus( PACB pACB ){ USHORT ioport; UCHAR bval; ULONG flags; save_flags(flags); cli(); pACB->ACBFlag |= RESET_DEV; ioport = pACB->IOPortBase; bval = ABORT_OP; outb(bval,ioport+ISTAT); udelay(25); bval = 0; outb(bval,ioport+ISTAT); bval = ASSERT_RST; outb(bval,ioport+SCNTL1); udelay(25); /* 25 us */ bval = 0; outb(bval,ioport+SCNTL1); restore_flags(flags); return;}static voidDC390W_ResetSCSIBus2( PACB pACB ){ USHORT ioport; UCHAR bval; ULONG flags; save_flags(flags); cli(); ioport = pACB->IOPortBase; bval = ASSERT_RST; outb(bval,ioport+SCNTL1); udelay(25); /* 25 us */ bval = 0; outb(bval,ioport+SCNTL1); restore_flags(flags); return;}static voidDC390W_ScsiRstDetect( PACB pACB ){ ULONG wlval, flags; USHORT ioport; UCHAR bval; save_flags(flags); sti();#ifdef DC390W_DEBUG0 printk("Reset_Detect0,");#endif/* delay 1 sec */ wlval = jiffies + HZ; while( jiffies < wlval );/* USHORT i; for( i=0; i<1000; i++ ) udelay(1000); */ cli(); ioport = pACB->IOPortBase; bval = inb(ioport+STEST3); bval |= CLR_SCSI_FIFO; outb(bval,ioport+STEST3); bval = CLR_DMA_FIFO; outb(bval,ioport+CTEST3); if( pACB->ACBFlag & RESET_DEV ) pACB->ACBFlag |= RESET_DONE; else { pACB->ACBFlag |= RESET_DETECT; ResetDevParam( pACB );/* DoingSRB_Done( pACB ); ???? */ RecoverSRB( pACB ); pACB->pActiveDCB = NULL; wlval = pACB->jmp_reselect; outl(wlval,(ioport+DSP)); 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][0] = *((PULONG) &(pSRB->CmdBlock[0])); pSRB->Segment0[0][1] = *((PULONG) &(pSRB->CmdBlock[4])); pSRB->Segment0[1][0] = *((PULONG) &(pSRB->CmdBlock[8])); pSRB->Segment0[1][1] = pSRB->__command[0] | (pSRB->SGcount << 8); pSRB->Segment0[2][0] = *((PULONG) &(pSRB->pSegmentList)); pSRB->Segment0[2][1] = pSRB->XferredLen; 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; *((PULONG) &(pSRB->CmdBlock[0])) = 0x00000003; pSRB->CmdBlock[1] = pDCB->IdentifyMsg << 5; *((PUSHORT) &(pSRB->CmdBlock[4])) = sizeof(pcmd->sense_buffer); pSRB->__command[0] = 6; PrepareSG( pACB, pDCB, pSRB ); pSRB->XferredLen = 0; DC390W_StartSCSI( pACB, pDCB, pSRB ); return;}static voidDC390W_MessageOut( PACB pACB ){ DC390W_FatalError( pACB );}static voidDC390W_FatalError( PACB pACB ){ PSRB pSRB; PDCB pDCB; ULONG flags;#ifdef DC390W_DEBUG0 printk("DC390W: Fatal Error!!\n");#endif pDCB = pACB->pActiveDCB; pSRB = pDCB->pActiveSRB; if( pSRB->SRBState & SRB_UNEXPECT_RESEL ) { save_flags(flags); cli(); pSRB->SRBState &= ~SRB_UNEXPECT_RESEL; pSRB->pNextSRB = pACB->pFreeSRB; pACB->pFreeSRB = pSRB; pACB->pActiveDCB = NULL; pDCB->pActiveSRB = NULL; restore_flags(flags); DoWaitingSRB( pACB ); } else DC390W_ResetSCSIBus(pACB); return;}static voidDC390W_Debug( PACB pACB ){ ULONG wlval; USHORT ioport; ioport = pACB->IOPortBase; wlval = inl(ioport+DSP); outl(wlval,(ioport+DSP)); return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -