Index: dc395x_trm.c =================================================================== RCS file: /usr/local/cvsroot/dc395/dc395x_trm.c,v retrieving revision 1.12 retrieving revision 1.13 diff -u -r1.12 -r1.13 --- dc395x_trm.c 1999/07/14 23:42:04 1.12 +++ dc395x_trm.c 1999/07/18 23:50:03 1.13 @@ -11,7 +11,7 @@ //* Patches and integration into 2.2+ kernel by //* Kurt Garloff //*********************************************************************** -//* Tekram PCI SCSI adapter (DC395/U/UW/F or DC315/U) revision history +//* Tekram PCI SCSI adapter (DC395/U/UW/F or DC315/U) revision history //* //* REV# DATE NAME DESCRIPTION //* 1.00 99/02/28 Erich Chen First release @@ -22,6 +22,8 @@ //* 1.07 99/07/12 Kurt Garloff Merge of 1.01 and 1.06 //* 1.08 99/07/15 Kurt Garloff Fix Oopses, Message Handling, //* Copy SyncMode to LUNs +//* 1.09 99/07/18 Kurt Garloff Fix Oops. Fix recognition of devs. +//* Fixed TagQ: MaxCommand limit! //*********************************************************************** /* ************************************************************************* @@ -1305,9 +1307,9 @@ //DWORD drv_flags=0; //DC395x_TRM_DRV_LOCK(drv_flags); - #ifdef DC395x_trm_DEBUG0 +#ifdef DC395x_trm_DEBUG0 printk(KERN_INFO "DC395x_RewaitSRB..............\n "); - #endif +#endif pACB = pDCB->pDCBACB; @@ -1481,9 +1483,9 @@ //DWORD drv_flags=0; //DC395x_TRM_DRV_LOCK(drv_flags); - #ifdef DC395x_trm_DEBUG0 +#ifdef DC395x_trm_DEBUG0 printk(KERN_INFO "DC395x_SendSRB..............\n "); - #endif +#endif pDCB = pSRB->pSRBDCB; if( !(pDCB->MaxCommand > pDCB->GoingSRBCnt) || (pACB->pActiveDCB) || (pACB->ACBFlag & (RESET_DETECT+RESET_DONE+RESET_DEV)) ) @@ -1569,10 +1571,8 @@ pACB = (PACB) cmd->host->hostdata; -#ifdef DC395x_trm_DEBUG0 - printk(KERN_INFO "DC395x_queue_command..............\n "); - printk(KERN_INFO "pACB = %8x,Cmd=%2x,ID=%d,LUN=%d\n",(UINT)pACB,cmd->cmnd[0],cmd->target,cmd->lun); -#endif + printk(KERN_INFO "DC395x_queue_command 0x%02x (pid=%li, target=%i-%i)\n", + cmd->cmnd[0], cmd->pid, cmd->target, cmd->lun); //DC395x_TRM_ACB_LOCK(pACB,acb_flags); @@ -1825,9 +1825,8 @@ //DWORD acb_flags=0; pACB = (PACB) cmd->host->hostdata; -#ifdef DC395x_trm_DEBUG0 - printk(KERN_INFO "DC395x_abort..............\n "); -#endif + printk(KERN_INFO "DC395x_abort: pid=%li, target=%i-%i\n", + cmd->pid, cmd->target, cmd->lun); pACB = (PACB) cmd->host->hostdata; //DC395x_TRM_ACB_LOCK(pACB,acb_flags); @@ -1933,7 +1932,7 @@ //DC395x_TRM_ACB_UNLOCK(pACB,acb_flags); cmd->result = DID_ABORT << 16; - cmd->scsi_done(cmd); + if (status == SCSI_ABORT_SUCCESS) cmd->scsi_done(cmd); return( status ); } @@ -2046,9 +2045,7 @@ //DWORD acb_flags=0; pACB = (PACB ) cmd->host->hostdata; -#ifdef DC395x_trm_DEBUG0 - printk(KERN_INFO "DC395x_reset..............\n "); -#endif + printk(KERN_INFO "DC395x: reset requested!\n"); pACB = (PACB) cmd->host->hostdata; //DC395x_TRM_ACB_LOCK(pACB,acb_flags); @@ -2061,7 +2058,7 @@ outb(0x00,ioport+TRM_S1040_SCSI_INTEN); DC395x_trm_ResetSCSIBus( pACB ); - for( i=0; i<2600; i++ ) + for( i=0; i<600; i++ ) udelay(1000); /* ** re-enable interrupt @@ -2099,7 +2096,7 @@ WORD DC395x_trm_StartSCSI( PACB pACB, PDCB pDCB, PSRB pSRB ) { WORD ioport, return_code; - BYTE tag_number, scsicommand, i,command,identify_message; + BYTE tag_number, scsicommand, i, command, identify_message; PBYTE ptr; DWORD tag_mask; @@ -2159,12 +2156,19 @@ tag_mask = tag_mask << 1; tag_number++; } + if (tag_number >= pDCB->MaxCommand) + { + printk (KERN_WARNING "DC395x: Start_SCSI: Out of tags for pid %li (%i-%i)\n", + pSRB->pcmd->pid, pSRB->pcmd->target, pSRB->pcmd->lun); + pSRB->SRBState = SRB_READY; + return 1; + }; /* ** Send Tag id */ outb(MSG_SIMPLE_QTAG,ioport+TRM_S1040_SCSI_FIFO); outb(tag_number,ioport+TRM_S1040_SCSI_FIFO); - + printk (KERN_INFO "DC395x: Start_SCSI (pid %li): Tag %i\n", pSRB->pcmd->pid, tag_number); pDCB->TagMask |= tag_mask; pSRB->TagNumber = tag_number; @@ -2209,9 +2213,8 @@ else { /* - ** If DC395x_trm_StartSCSI return 0 : - ** current interrupt status is interrupt enable - ** It's said that SCSI processor is unoccupied + ** If DC395x_trm_StartSCSI returns 0: + ** we know that the SCSI processor is free */ pSRB->ScsiPhase = PH_BUS_FREE;/* initial phase */ pACB->pActiveDCB = pDCB; @@ -2316,7 +2319,7 @@ } scsi_intstatus = inb( ioport+TRM_S1040_SCSI_INTSTATUS ); #ifdef DC395x_trm_DEBUG0 - printk(KERN_INFO "scsi_intstatus=%02x ioport=%4x \n",scsi_intstatus,ioport); + printk(KERN_INFO "scsi_intstatus=%02x \n", scsi_intstatus); #endif //DC395x_TRM_ACB_LOCK(pACB,acb_flags); @@ -2669,11 +2672,13 @@ } if((dLeftCounter == 0) || (scsi_status & SCSIXFERCNT_2_ZERO) ) { + int ctr = 6000000; do { TempDMAstatus = inb(ioport+TRM_S1040_DMA_STATUS); } - while( !(TempDMAstatus & DMAXFERCOMP) ); + while( !(TempDMAstatus & DMAXFERCOMP) && --ctr); + if (!ctr) printk (KERN_ERR "DC395x: Deadlock in DataOutPhase0 !!\n"); pSRB->SRBTotalXferLength = 0; } else /* Update SG list */ @@ -2771,19 +2776,20 @@ { if( scsi_status & PARITYERROR ) { -#ifdef DC395x_trm_DEBUG0 - printk(KERN_INFO "PARITYERROR.......\n "); -#endif + printk(KERN_INFO "DC395x: Parity Error (pid %li, target %i-%i)\n", + pSRB->pcmd->pid, pSRB->pcmd->target, pSRB->pcmd->lun); pSRB->SRBStatus |= PARITY_ERROR; } dLeftCounter += inl(ioport+TRM_S1040_SCSI_COUNTER); if((dLeftCounter == 0) || (scsi_status & SCSIXFERCNT_2_ZERO) ) { + int ctr = 6000000; do { TempDMAstatus = inb(ioport+TRM_S1040_DMA_STATUS); } - while( !(TempDMAstatus & DMAXFERCOMP) ); + while( !(TempDMAstatus & DMAXFERCOMP) && --ctr); + if (!ctr) printk (KERN_ERR "DC395x: Deadlock in DataInPhase0 !!\n"); pSRB->SRBTotalXferLength = 0; } else /* phase changed */ @@ -3415,16 +3421,13 @@ WORD ioport,i,j,count; #ifdef DC395x_trm_DEBUG0 - printk(KERN_INFO "DC395x_Disconnected..............\n "); + printk(KERN_INFO "DC395x_Disconnect................\n "); #endif ioport = pACB->IOPortBase; pDCB = pACB->pActiveDCB; if (!pDCB) { -#ifdef DC395x_trm_DEBUG0 printk(KERN_INFO " Exception Disconnect pDCB=NULL........\n "); -#endif - j = 400; while (--j) udelay(1000); outw((DO_CLRFIFO | DO_HWRESELECT),ioport+TRM_S1040_SCSI_CONTROL); @@ -3475,7 +3478,7 @@ ** !SRB_DISCONNECT ** !SRB_COMPLETED */ - if( !(pACB->scan_devices) ) + if( !(1/*pACB->scan_devices*/) ) { pSRB->SRBState = SRB_READY; DC395x_trm_RewaitSRB( pDCB, pSRB); @@ -3483,6 +3486,8 @@ else { pSRB->TargetStatus = SCSI_STAT_SEL_TIMEOUT; + printk ("DC395x: Selection Timeout (pid %li, target %i-%i)\n", + pSRB->pcmd->pid, pSRB->pcmd->target, pSRB->pcmd->lun); goto disc1; } } @@ -3534,9 +3539,7 @@ pSRB = pDCB->pActiveSRB; if( !( pACB->scan_devices ) ) { -#ifdef DC395x_trm_DEBUG0 printk(KERN_INFO "Arbitration lost but Reselection win..............\n "); -#endif pSRB->SRBState = SRB_READY; DC395x_trm_RewaitSRB( pDCB, pSRB); } @@ -3618,10 +3621,9 @@ PSCSI_INQDATA ptr; //DWORD drv_flags=0; -#ifdef DC395x_trm_DEBUG0 - printk(KERN_INFO "DC395x_SRBdone..............\n "); -#endif pcmd = pSRB->pcmd; + printk(KERN_INFO "DC395x_SRBdone (pid %li, target %i-%i): ", + pSRB->pcmd->pid, pSRB->pcmd->target, pSRB->pcmd->lun); status = pSRB->TargetStatus; if(pSRB->SRBFlag & AUTO_REQSENSE) { @@ -3680,7 +3682,7 @@ { pSRB->AdaptStatus = H_SEL_TIMEOUT; pSRB->TargetStatus = 0; - pcmd->result = DID_BAD_TARGET << 16; + pcmd->result = DID_NO_CONNECT << 16; } else { @@ -3715,21 +3717,17 @@ { if( pSRB->CmdBlock[0] == TEST_UNIT_READY ) { - if(pcmd->result != (DID_OK << 16)) /*status word :NO error*/ + 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 ) { - if( pcmd->result & SCSI_STAT_CHECKCOND ) - goto RTN_OK; - else - { - pACB->DCBmap[pcmd->target] &= ~(1 << pcmd->lun); - DC395x_TRM_pPrevDCB->pNextDCB = pACB->pLinkDCB; - if( (pcmd->target == pACB->max_id) && ((pcmd->lun == 0) || (pcmd->lun == pACB->max_lun)) ) - pACB->scan_devices = 0; - } + pACB->DCBmap[pcmd->target] &= ~(1 << pcmd->lun); + DC395x_TRM_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: DC395x_TRM_pPrevDCB->pNextDCB = pDCB; pDCB->pNextDCB = pACB->pLinkDCB; if( (pcmd->target == pACB->max_id) && (pcmd->lun == pACB->max_lun) ) @@ -3762,7 +3760,7 @@ (pDCB->DevMode & NTC_DO_TAG_QUEUEING) && (pDCB->DevMode & NTC_DO_DISCONNECT) ) { - pDCB->MaxCommand = 32 ; /* there had some thing wrong with pACB->TagMaxNum;*/ + pDCB->MaxCommand = 16; /* Fixed, KG 99/07/18 */ pDCB->SyncMode |= EN_TAG_QUEUEING; pDCB->TagMask = 0; } @@ -3804,6 +3802,7 @@ pDCB->GoingSRBCnt--; //DC395x_TRM_DRV_UNLOCK(drv_flags); + printk ("0x%08x\n", pcmd->result); DC395x_trm_DoWaitingSRB( pACB ); @@ -3832,9 +3831,7 @@ WORD cnt, i; PSCSICMD pcmd; -#ifdef DC395x_trm_DEBUG0 - printk(KERN_INFO "DC395x_DoingSRB_Done..............\n "); -#endif + printk(KERN_INFO "DC395x_DoingSRB_Done: pids "); pDCB = pACB->pLinkDCB; pDCBTemp = pDCB; do @@ -3849,6 +3846,7 @@ /* ReleaseSRB( pDCB, pSRB ); */ pSRBTemp->pNextSRB = pACB->pFreeSRB; pACB->pFreeSRB = pSRBTemp; + printk ("%li(%i-%i) ", pcmd->pid, pcmd->target, pcmd->lun); //DC395x_TRM_SCSI_DONE_ACB_UNLOCK; pcmd->scsi_done( pcmd ); @@ -3862,6 +3860,7 @@ pDCBTemp = pDCBTemp->pNextDCB; } while( pDCBTemp != pDCB ); + printk ("\n"); } /* @@ -3903,9 +3902,7 @@ DWORD msec; WORD ioport; -#ifdef DC395x_trm_DEBUG0 - printk(KERN_INFO "DC395x_ScsiRstDetect..............\n "); -#endif + printk (KERN_INFO "DC395x_ScsiRstDetect\n"); /* delay half a second */ { msec = 600; while (--msec) udelay(1000); } @@ -3923,7 +3920,7 @@ { pACB->ACBFlag |= RESET_DETECT; DC395x_trm_ResetDevParam( pACB ); - /* DC395x_trm_DoingSRB_Done( pACB ); ???? */ + DC395x_trm_DoingSRB_Done( pACB ); DC395x_trm_RecoverSRB( pACB ); pACB->pActiveDCB = NULL; pACB->ACBFlag = 0; @@ -3944,9 +3941,9 @@ { PSCSICMD pcmd; -#ifdef DC395x_trm_DEBUG0 - printk(KERN_INFO "DC395x_RequestSense..............\n "); -#endif + pcmd = pSRB->pcmd; + printk(KERN_INFO "DC395x_RequestSense for pid %li, target %i-%i\n", + pcmd->pid, pcmd->target, pcmd->lun); pSRB->SRBFlag |= AUTO_REQSENSE; pSRB->Segment0[0] = *((PDWORD) &(pSRB->CmdBlock[0])); pSRB->Segment0[1] = *((PDWORD) &(pSRB->CmdBlock[4])); @@ -3955,7 +3952,6 @@ pSRB->AdaptStatus = 0; pSRB->TargetStatus = 0; - pcmd = pSRB->pcmd; /* pSRB->SegmentX : a one entry of S/G list table */ pSRB->SRBTotalXferLength = sizeof(pcmd->sense_buffer); pSRB->SgSenseTemp.address = pSRB->SegmentX[0].address; @@ -3974,10 +3970,9 @@ if( DC395x_trm_StartSCSI( pACB, pDCB, pSRB ) ) { /* - ** If DC395x_trm_StartSCSI return 1 : - ** current interrupt status is interrupt disreenable - ** It's said that SCSI processor has more one SRB need to do - */ + ** If DC395x_trm_StartSCSI returns 1: + ** SCSI chip is busy; let's requeue the SRB + */ DC395x_trm_RewaitSRB( pDCB, pSRB ); } } @@ -4267,6 +4262,7 @@ BYTE bval; PACB pACB, pTempACB; WORD used_irq = 0; + DWORD i; pEEpromBuf = &dc395x_trm_eepromBuf[index]; pTempACB = DC395x_TRM_pACB_start; @@ -4333,8 +4329,11 @@ bval = PHASELATCH | INITIATOR | BLOCKRST | PARITYCHECK; else bval = PHASELATCH | INITIATOR | BLOCKRST ; + + outb(bval,ioport+TRM_S1040_SCSI_CONFIG0); + for( i=0; i<3600; i++ ) + udelay(1000); - outb(bval,ioport+TRM_S1040_SCSI_CONFIG0); /* program configuration 1 */ outb(0x13,ioport+TRM_S1040_SCSI_CONFIG1); /* program Host ID */ @@ -4342,7 +4341,7 @@ outb(bval,ioport+TRM_S1040_SCSI_HOSTID); /* set ansynchronous transfer */ outb(0x00,ioport+TRM_S1040_SCSI_OFFSET); - /* Trun LED control off*/ + /* Turn LED control off*/ wval = inw(ioport+TRM_S1040_GEN_CONTROL) & 0x7F; outw(wval,ioport+TRM_S1040_GEN_CONTROL); /* DMA config */ @@ -5000,7 +4999,8 @@ DC395x_LOCK_IO; SPRINTF("SCSI Host Nr %i, ", shpnt->host_no); - SPRINTF("DC395U/UW/F DC315/U Adapter Nr %i\n", acbpnt->AdapterIndex); + SPRINTF("DC395U/UW/F DC315/U %s Adapter Nr %i\n", + (acbpnt->Config & HCC_WIDE_CARD)? "Wide": "", acbpnt->AdapterIndex); SPRINTF("IOPortBase 0x%04x, ", acbpnt->IOPortBase); SPRINTF("IRQLevel 0x%02x\n", acbpnt->IRQLevel); Index: dc395x_trm.h =================================================================== RCS file: /usr/local/cvsroot/dc395/dc395x_trm.h,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- dc395x_trm.h 1999/07/14 20:58:06 1.6 +++ dc395x_trm.h 1999/07/18 23:50:03 1.7 @@ -18,7 +18,7 @@ #define DC395x_trm_H #define DC395x_BANNER "Tekram DC395U/UW/F DC315/U" -#define DC395x_VERSION "1.08, 1999/07/15" +#define DC395x_VERSION "1.09, 1999/07/18" /* Kernel version autodetection */ #include @@ -35,15 +35,15 @@ #define VERSION_2_0_0 #endif +#define DC395x_trm_MAX_CMD_QUEUE 20 #define DC395x_trm_MAX_QTAGS 32 +#define DC395x_trm_MAX_ADAPTER_NUM 4 +#define DC395x_trm_MAX_TARGETS_NUM 16 +#define DC395x_trm_MAX_SCSI_ID 16 #define DC395x_trm_MAX_CAN_QUEUE 7 * DC395x_trm_MAX_QTAGS #define DC395x_trm_MAX_CMD_PER_LUN DC395x_trm_MAX_QTAGS #define DC395x_trm_MAX_SG_TABLESIZE 64 -#define DC395x_trm_MAX_ADAPTER_NUM 4 -#define DC395x_trm_MAX_TARGETS_NUM 16 #define DC395x_trm_MAX_SG_LISTENTRY 64 -#define DC395x_trm_MAX_CMD_QUEUE 20 -#define DC395x_trm_MAX_SCSI_ID 16 #define DC395x_trm_MAX_SRB_CNT DC395x_trm_MAX_CMD_QUEUE+4 #define DC395x_trm_END_SCAN 2 #define DC395x_trm_SEL_TIMEOUT 153 /* 250 ms selection timeout (@ 40 MHz) */