📄 scsiiom.c
字号:
};static void dc390_add_dev (PACB pACB, PDCB pDCB, PSCSI_INQDATA ptr){ UCHAR bval1 = ptr->DevType & SCSI_DEVTYPE; pDCB->DevType = bval1; /* if (bval1 == TYPE_DISK || bval1 == TYPE_MOD) */ dc390_disc_tagq_set (pDCB, ptr);};voiddc390_SRBdone( PACB pACB, PDCB pDCB, PSRB pSRB ){ UCHAR bval, status, i, DCB_removed; PSCSICMD pcmd; PSCSI_INQDATA ptr; PSGL ptr2; ULONG swlval; pcmd = pSRB->pcmd; DCB_removed = 0; status = pSRB->TargetStatus; ptr = (PSCSI_INQDATA) (pcmd->request_buffer); if( pcmd->use_sg ) ptr = (PSCSI_INQDATA) (((PSGL) ptr)->address); DEBUG0(printk (" SRBdone (%02x,%08x), SRB %p, pid %li\n", status, pcmd->result,\ pSRB, pcmd->pid);) if(pSRB->SRBFlag & AUTO_REQSENSE) { /* Last command was a Request Sense */ pSRB->SRBFlag &= ~AUTO_REQSENSE; pSRB->AdaptStatus = 0; pSRB->TargetStatus = CHECK_CONDITION << 1;#ifdef DC390_REMOVABLEDEBUG switch (pcmd->sense_buffer[2] & 0x0f) { case NOT_READY: printk (KERN_INFO "DC390: ReqSense: NOT_READY (Cmnd = 0x%02x, Dev = %i-%i, Stat = %i, Scan = %i)\n", pcmd->cmnd[0], pDCB->TargetID, pDCB->TargetLUN, status, pACB->scan_devices); break; case UNIT_ATTENTION: printk (KERN_INFO "DC390: ReqSense: UNIT_ATTENTION (Cmnd = 0x%02x, Dev = %i-%i, Stat = %i, Scan = %i)\n", pcmd->cmnd[0], pDCB->TargetID, pDCB->TargetLUN, status, pACB->scan_devices); break; case ILLEGAL_REQUEST: printk (KERN_INFO "DC390: ReqSense: ILLEGAL_REQUEST (Cmnd = 0x%02x, Dev = %i-%i, Stat = %i, Scan = %i)\n", pcmd->cmnd[0], pDCB->TargetID, pDCB->TargetLUN, status, pACB->scan_devices); break; case MEDIUM_ERROR: printk (KERN_INFO "DC390: ReqSense: MEDIUM_ERROR (Cmnd = 0x%02x, Dev = %i-%i, Stat = %i, Scan = %i)\n", pcmd->cmnd[0], pDCB->TargetID, pDCB->TargetLUN, status, pACB->scan_devices); break; case HARDWARE_ERROR: printk (KERN_INFO "DC390: ReqSense: HARDWARE_ERROR (Cmnd = 0x%02x, Dev = %i-%i, Stat = %i, Scan = %i)\n", pcmd->cmnd[0], pDCB->TargetID, pDCB->TargetLUN, status, pACB->scan_devices); break; }#endif //pcmd->result = MK_RES(DRIVER_SENSE,DID_OK,0,status); if (status == (CHECK_CONDITION << 1)) { pcmd->result = MK_RES_LNX(0,DID_BAD_TARGET,0,/*CHECK_CONDITION*/0); goto ckc_e; } if(pSRB->RetryCnt == 0) { //(UINT)(pSRB->pcmd->cmnd[0]) = pSRB->Segment0[0]; pSRB->TotalXferredLen = pSRB->SavedTotXLen; if( (pSRB->TotalXferredLen) && (pSRB->TotalXferredLen >= pcmd->underflow) ) SET_RES_DID(pcmd->result,DID_OK) else pcmd->result = MK_RES_LNX(DRIVER_SENSE,DID_OK,0,CHECK_CONDITION); REMOVABLEDEBUG(printk(KERN_INFO "Cmd=%02x,Result=%08x,XferL=%08x\n",pSRB->pcmd->cmnd[0],\ (UINT) pcmd->result, (UINT) pSRB->TotalXferredLen);) goto ckc_e; } else /* Retry */ { pSRB->RetryCnt--; pSRB->AdaptStatus = 0; pSRB->TargetStatus = 0; //*((PUINT) &(pSRB->CmdBlock[0])) = pSRB->Segment0[0]; //*((PUINT) &(pSRB->CmdBlock[4])) = pSRB->Segment0[1]; /* Don't retry on TEST_UNIT_READY */ if( pSRB->pcmd->cmnd[0] == TEST_UNIT_READY /* || pSRB->pcmd->cmnd[0] == START_STOP */) { pcmd->result = MK_RES_LNX(DRIVER_SENSE,DID_OK,0,CHECK_CONDITION); REMOVABLEDEBUG(printk(KERN_INFO "Cmd=%02x, Result=%08x, XferL=%08x\n",pSRB->pcmd->cmnd[0],\ (UINT) pcmd->result, (UINT) pSRB->TotalXferredLen);) goto ckc_e; } SET_RES_DRV(pcmd->result,DRIVER_SENSE); pSRB->SGcount = (UCHAR) pSRB->SavedSGCount; //pSRB->ScsiCmdLen = (UCHAR) (pSRB->Segment1[0] >> 8); DEBUG0 (printk ("DC390: RETRY pid %li (%02x), target %02i-%02i\n", pcmd->pid, pcmd->cmnd[0], pcmd->target, pcmd->lun);) 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 ) ) { dc390_Going_to_Waiting ( pDCB, pSRB ); dc390_waiting_timer (pACB, HZ/5); } return; } } if( status ) { if( status_byte(status) == CHECK_CONDITION ) { REMOVABLEDEBUG(printk (KERN_INFO "DC390: Check_Condition (Cmd %02x, Id %02x, LUN %02x)\n",\ pcmd->cmnd[0], pDCB->TargetID, pDCB->TargetLUN);) 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++; } REMOVABLEDEBUG(printk(KERN_INFO "XferredLen=%08x,NotXferLen=%08x\n",\ (UINT) pSRB->TotalXferredLen, (UINT) swlval);) } dc390_RequestSense( pACB, pDCB, pSRB ); return; } else if( status_byte(status) == QUEUE_FULL ) { bval = (UCHAR) pDCB->GoingSRBCnt; bval--; pDCB->MaxCommand = bval; dc390_freetag (pDCB, pSRB); dc390_Going_to_Waiting ( pDCB, pSRB ); dc390_waiting_timer (pACB, HZ/5); pSRB->AdaptStatus = 0; pSRB->TargetStatus = 0; return; } else if(status == SCSI_STAT_SEL_TIMEOUT) { pSRB->AdaptStatus = H_SEL_TIMEOUT; pSRB->TargetStatus = 0; pcmd->result = MK_RES(0,DID_NO_CONNECT,0,0); /* Devices are removed below ... */ } else if (status_byte(status) == BUSY && (pcmd->cmnd[0] == TEST_UNIT_READY || pcmd->cmnd[0] == INQUIRY) && pACB->scan_devices) { pSRB->AdaptStatus = 0; pSRB->TargetStatus = status; pcmd->result = MK_RES(0,0,pSRB->EndMessage,/*status*/0); } else { /* Another error */ pSRB->AdaptStatus = 0; if( pSRB->RetryCnt ) { /* Retry */ //printk ("DC390: retry\n"); 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 ) ) { dc390_Going_to_Waiting ( pDCB, pSRB ); dc390_waiting_timer (pACB, HZ/5); } return; } else { /* Report error */ //pcmd->result = MK_RES(0, DID_ERROR, pSRB->EndMessage, status); SET_RES_DID(pcmd->result,DID_ERROR); SET_RES_MSG(pcmd->result,pSRB->EndMessage); SET_RES_TARGET(pcmd->result,status); } } } else { /* Target status == 0 */ status = pSRB->AdaptStatus; if(status & H_OVER_UNDER_RUN) { pSRB->TargetStatus = 0; SET_RES_DID(pcmd->result,DID_OK); SET_RES_MSG(pcmd->result,pSRB->EndMessage); } else if( pSRB->SRBStatus & PARITY_ERROR) { //pcmd->result = MK_RES(0,DID_PARITY,pSRB->EndMessage,0); SET_RES_DID(pcmd->result,DID_PARITY); SET_RES_MSG(pcmd->result,pSRB->EndMessage); } else /* No error */ { pSRB->AdaptStatus = 0; pSRB->TargetStatus = 0; SET_RES_DID(pcmd->result,DID_OK); } } if ((pcmd->result & RES_DID) == 0 && pcmd->cmnd[0] == INQUIRY && pcmd->cmnd[2] == 0 && pcmd->request_bufflen >= 8 && ptr && (ptr->Vers & 0x07) >= 2) pDCB->Inquiry7 = ptr->Flags;ckc_e: if( pACB->scan_devices ) { if( pcmd->cmnd[0] == TEST_UNIT_READY || pcmd->cmnd[0] == INQUIRY) {#ifdef DC390_DEBUG0 printk (KERN_INFO "DC390: %s: result: %08x", (pcmd->cmnd[0] == INQUIRY? "INQUIRY": "TEST_UNIT_READY"), pcmd->result); if (pcmd->result & (DRIVER_SENSE << 24)) printk (" (sense: %02x %02x %02x %02x)\n", pcmd->sense_buffer[0], pcmd->sense_buffer[1], pcmd->sense_buffer[2], pcmd->sense_buffer[3]); else printk ("\n");#endif if( (host_byte(pcmd->result) != DID_OK && !(status_byte(pcmd->result) & CHECK_CONDITION) && !(status_byte(pcmd->result) & BUSY)) || ((driver_byte(pcmd->result) & DRIVER_SENSE) && (pcmd->sense_buffer[0] & 0x70) == 0x70 && (pcmd->sense_buffer[2] & 0xf) == ILLEGAL_REQUEST) || host_byte(pcmd->result) & DID_ERROR ) { /* device not present: remove */ //dc390_Going_remove (pDCB, pSRB); dc390_remove_dev (pACB, pDCB); DCB_removed = 1; if( (pcmd->target == pACB->pScsiHost->max_id - 1) && ((pcmd->lun == 0) || (pcmd->lun == pACB->pScsiHost->max_lun - 1)) ) pACB->scan_devices = 0; } else { /* device present: add */ if( (pcmd->target == pACB->pScsiHost->max_id - 1) && (pcmd->lun == pACB->pScsiHost->max_lun - 1) ) pACB->scan_devices = END_SCAN ; /* pACB->DeviceCnt++; */ /* Dev is added on INQUIRY */ } } } //if( pSRB->pcmd->cmnd[0] == INQUIRY && // (host_byte(pcmd->result) == DID_OK || status_byte(pcmd->result) & CHECK_CONDITION) ) if( pcmd->cmnd[0] == INQUIRY && (pcmd->result == (DID_OK << 16) || status_byte(pcmd->result) & CHECK_CONDITION) ) { if ((ptr->DevType & SCSI_DEVTYPE) == TYPE_NODEV && !DCB_removed) { //printk ("DC390: Type = nodev! (%02i-%i)\n", pcmd->target, pcmd->lun); /* device not present: remove */ //dc390_Going_remove (pDCB, pSRB); dc390_remove_dev (pACB, pDCB); DCB_removed = 1; } else { /* device found: add */ dc390_add_dev (pACB, pDCB, ptr); if (pACB->scan_devices) pACB->DeviceCnt++; } if( (pcmd->target == pACB->pScsiHost->max_id - 1) && (pcmd->lun == pACB->pScsiHost->max_lun - 1) ) pACB->scan_devices = 0; };#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,30) pcmd->resid = pcmd->request_bufflen - pSRB->TotalXferredLen;#endif if (!DCB_removed) dc390_Going_remove (pDCB, pSRB); /* Add to free list */ dc390_Free_insert (pACB, pSRB); DEBUG0(printk (KERN_DEBUG "DC390: SRBdone: done pid %li\n", pcmd->pid);) DC390_UNLOCK_ACB_NI; pcmd->scsi_done (pcmd); DC390_LOCK_ACB_NI; dc390_Query_to_Waiting (pACB); dc390_Waiting_process (pACB); return;}/* Remove all SRBs from Going list and inform midlevel */voiddc390_DoingSRB_Done( PACB pACB, PSCSICMD cmd ){ PDCB pDCB, pdcb; PSRB psrb, psrb2; UCHAR i; PSCSICMD pcmd; pDCB = pACB->pLinkDCB; pdcb = pDCB; if (! pdcb) return; do { psrb = pdcb->pGoingSRB; for( i=0; i<pdcb->GoingSRBCnt; i++) { psrb2 = psrb->pNextSRB; pcmd = psrb->pcmd; dc390_Free_insert (pACB, psrb);#ifndef USE_NEW_EH /* New EH will crash on being given timed out cmnds */ if (pcmd == cmd) pcmd->result = MK_RES(0,DID_ABORT,0,0); else pcmd->result = MK_RES(0,DID_RESET,0,0);/* ReleaseSRB( pDCB, pSRB ); */ DEBUG0(printk (KERN_DEBUG "DC390: DoingSRB_Done: done pid %li\n", pcmd->pid);) DC390_UNLOCK_ACB_NI; pcmd->scsi_done( pcmd ); DC390_LOCK_ACB_NI;#endif psrb = psrb2; } pdcb->GoingSRBCnt = 0;; pdcb->pGoingSRB = NULL; pdcb->TagMask = 0; pdcb = pdcb->pNextDCB; } while( pdcb != pDCB ); dc390_Query_to_Waiting (pACB);}static voiddc390_ResetSCSIBus( PACB pACB ){ //DC390_write8 (ScsiCmd, RST_DEVICE_CMD); //udelay (250); //DC390_write8 (ScsiCmd, NOP_CMD); DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD); DC390_write8 (DMA_Cmd, DMA_IDLE_CMD); DC390_write8 (ScsiCmd, RST_SCSI_BUS_CMD); pACB->Connected = 0; return;}static voiddc390_ScsiRstDetect( PACB pACB ){ printk ("DC390: Rst_Detect: laststat = %08x\n", dc390_laststatus); //DEBUG0(printk(KERN_INFO "RST_DETECT,");) if (timer_pending (&pACB->Waiting_Timer)) del_timer (&pACB->Waiting_Timer); DC390_write8 (DMA_Cmd, DMA_IDLE_CMD); /* Unlock before ? */ /* delay half a second */ udelay (1000); DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD); pACB->pScsiHost->last_reset = jiffies + 5*HZ/2 + HZ * dc390_eepromBuf[pACB->AdapterIndex][EE_DELAY]; pACB->Connected = 0; if( pACB->ACBFlag & RESET_DEV ) pACB->ACBFlag |= RESET_DONE; else { /* Reset was issued by sb else */ pACB->ACBFlag |= RESET_DETECT; dc390_ResetDevParam( pACB ); dc390_DoingSRB_Done( pACB, 0 ); //dc390_RecoverSRB( pACB ); pACB->pActiveDCB = NULL; pACB->ACBFlag = 0; dc390_Waiting_process( pACB ); } return;}static void __inline__dc390_RequestSense( PACB pACB, PDCB pDCB, PSRB pSRB ){ PSCSICMD pcmd; REMOVABLEDEBUG(printk (KERN_INFO "DC390: RequestSense (Cmd %02x, Id %02x, LUN %02x)\n",\ pSRB->pcmd->cmnd[0], pDCB->TargetID, pDCB->TargetLUN);) pSRB->SRBFlag |= AUTO_REQSENSE; //pSRB->Segment0[0] = (UINT) pSRB->CmdBlock[0]; //pSRB->Segment0[1] = (UINT) pSRB->CmdBlock[4]; //pSRB->Segment1[0] = ((UINT)(pSRB->pcmd->cmd_len) << 8) + pSRB->SGcount; //pSRB->Segment1[1] = pSRB->TotalXferredLen; pSRB->SavedSGCount = pSRB->SGcount; pSRB->SavedTotXLen = pSRB->TotalXferredLen; pSRB->AdaptStatus = 0; pSRB->TargetStatus = 0; /* CHECK_CONDITION<<1; */ 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; //pSRB->CmdBlock[0] = REQUEST_SENSE; //pSRB->CmdBlock[1] = pDCB->TargetLUN << 5; //(USHORT) pSRB->CmdBlock[2] = 0; //(USHORT) pSRB->CmdBlock[4] = sizeof(pcmd->sense_buffer); //pSRB->ScsiCmdLen = 6; pSRB->TotalXferredLen = 0; pSRB->SGToBeXferLen = 0; if( dc390_StartSCSI( pACB, pDCB, pSRB ) ) { dc390_Going_to_Waiting ( pDCB, pSRB ); dc390_waiting_timer (pACB, HZ/5); }}static void __inline__dc390_InvalidCmd( PACB pACB ){ if( pACB->pActiveDCB->pActiveSRB->SRBState & (SRB_START_+SRB_MSGOUT) ) DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -