Index: dc390/README.tmscsim =================================================================== RCS file: /usr/local/cvsroot/dc390/README.tmscsim,v retrieving revision 2.19 retrieving revision 2.21 diff -u -r2.19 -r2.21 --- dc390/README.tmscsim 1999/06/06 20:17:11 2.19 +++ dc390/README.tmscsim 1999/06/21 07:02:08 2.21 @@ -26,7 +26,7 @@ Tekram DC390(T) adapter. This is where the name comes from: tm = Tekram scsi = SCSI driver, m = AMD (?) as opposed to w for the DC390W/U/F (NCR53c8X5, X=2/7) driver. Yes, there was also a driver for the latter, -tmscsimw, which supported DC390W/U/F adapters. It's not maintained any more, +tmscsiw, which supported DC390W/U/F adapters. It's not maintained any more, as the ncr53c8xx is perfectly supporting these adpaters since some time. The driver first appeared in April 1996, exclusively supported the DC390 @@ -92,6 +92,8 @@ tune2fs -e remount-ro /dev/sd?? * have copies of your SCSI disk's partition tables on some safe location: dd if=/dev/sda of=/mnt/floppy/sda bs=512 count=1 + or just print it with: + fdisk -l | lpr * make sure you are able to boot Linux (e.g. from floppy disk using InitRD) if your SCSI disk gets corrupted. You can use ftp://student.physik.uni-dortmund.de/pub/linux/kernel/bootdisk.gz @@ -103,7 +105,7 @@ than the 33.33 MHz being in the PCI spec. If you want to share the IRQ with another device and the driver refuses to -do, you might succeed with changing the DC390_IRQ type in tmscsim.c to +do so, you might succeed with changing the DC390_IRQ type in tmscsim.c to SA_SHIRQ | SA_INTERRUPT. @@ -125,8 +127,9 @@ specific locks (Linux 2.3) * Uniform source code for Linux-2.x.y * Support for dyn. addition/removal of devices via add/remove-single-device - (Try: echo "scsi add-single-device H C I L" >/proc/scsi/scsi - H = Host, C = Channel, I = SCSI ID, L = SCSI LUN.) Use with care! + (Try: echo "scsi add-single-device C B T U" >/proc/scsi/scsi + C = Controller, B = Bus, T = Target SCSI ID, U = Unit SCSI LUN.) Use + with care! * Try to use the partition table for the determination of the mapping @@ -141,7 +144,7 @@ Here's an example: garloff@kg1:/home/garloff > cat /proc/scsi/tmscsim/0 -Tekram DC390/AM53C974 PCI SCSI Host Adapter, Driver Version 2.0d9 1999/06/06 +Tekram DC390/AM53C974 PCI SCSI Host Adapter, Driver Version 2.0d10 1999/06/20 SCSI Host Nr 1, AM53C974 Adapter Nr 0 IOPortBase 0xe800, IRQ 17 MaxID 7, MaxLUN 8, AdapterID 7, SelTimeout 250 ms, DelayReset 1 s @@ -150,11 +153,11 @@ Lost arbitrations 0, Connected: No Nr of attached devices: 4, Nr of DCBs: 4 Map of attached LUNs: 01 01 00 01 00 01 00 00 -Idx ID LUN Prty Sync DsCn SndS TagQ NegoPeriod SyncSpeed SyncOffs -00 00 00 Yes Yes Yes Yes Yes 100 ns 10.0 M 15 -01 01 00 Yes Yes Yes Yes Yes 100 ns 10.0 M 15 -02 03 00 Yes Yes Yes Yes No 100 ns 10.0 M 15 -03 05 00 Yes No Yes Yes No (200 ns) +Idx ID LUN Prty Sync DsCn SndS TagQ NegoPeriod SyncSpeed SyncOffs MaxCmd +00 00 00 Yes Yes Yes Yes Yes 100 ns 10.0 M 15 32 +01 01 00 Yes Yes Yes Yes Yes 100 ns 10.0 M 15 16 +02 03 00 Yes Yes Yes Yes No 100 ns 10.0 M 15 1 +03 05 00 Yes No Yes Yes No (200 ns) 1 Note that the settings MaxID and MaxLUN are not zero- but one-based, which means that a setting MaxLUN=4, will result in the support of LUNs 0..3. This @@ -180,6 +183,8 @@ The last values are only shown, if Sync is enabled. (NegoPeriod is still displayed in brackets to show the values which will be used after enabling Sync.) +MaxCmd ist the number of commands (=tags) which can be processed at the same +time by the device. If you want to change a setting, you can do that by writing to /proc/scsi/tmscsim/?. Basically you have to imitate the output of driver. @@ -342,9 +347,9 @@ * Cleanly separate per-Target and per-LUN properties (DCB) * More intelligent abort() routine * Implement new_eh code (Linux-2.1+) -* Have the mid-level code (and not the driver) handle more of the various - conditions. -* Rework command queueing in the driver +* Have the mid-level (ML) code (and not the driver) handle more of the + various conditions. +* Command queueing in the driver: Eliminate Query list and use ML instead. * More user friendly boot/module param syntax Further investigation on these problems: @@ -353,17 +358,21 @@ Known problems: +* Changing the parameters of multi-lun by the tmscsim/? interface will + cause problems, cause these settings are mostly per Target and not per LUN + and should be updated accordingly. * There was a report that with a certain Scanner, the last SCSI command - won't be finished correctly. This might be a command queueing bug or a bug - in SCSI implementation of the scanner. Issueing another command to the - scanner seems to help. (Try echo "INQUIRY x" >/proc/scsi/tmscsim/?, where + won't be finished correctly. This might be a bug in the SCSI + implementation of the scanner. Issueing another command to the scanner + seems to help. (Try echo "INQUIRY x" >/proc/scsi/tmscsim/?, where x is the index (not the SCSI ID!) of the scanner. See 4.(3).) * If there is a valid partition table, the driver will use it for determing the mapping. Other operating systems may not like this mapping, though it's consistent with the BIOS' behaviour. Old DC390 drivers ignored the partition table and used a H/S = 64/32 or 255/63 translation. So if you want to be compatible to those, use this old mapping when creating - partition tables. + partition tables. Even worse, on bootup the DC390 might complain if other + mappings are found, so auto rebooting will fail. * In some situations, the driver will get stuck in an abort loop. Please disable DsCn, if you meet this problem. Please contact me for further debugging. @@ -400,9 +409,6 @@ The latest version of the driver can be found at: http://www.garloff.de/kurt/linux/dc390/ -and - ftp://student.physik.uni-dortmund.de/pub/linux/kernel/dc390/ -(The latter might shut down some day.) 8. Acknowledgements @@ -431,5 +437,5 @@ ------------------------------------------------------------------------- Written by Kurt Garloff 1998/06/11 -Last updated 1999/06/02, driver revision 2.0d6 -$Id: README.tmscsim,v 2.19 1999/06/06 20:17:11 garloff Exp $ +Last updated 1999/06/20, driver revision 2.0d10 +$Id: README.tmscsim,v 2.21 1999/06/21 07:02:08 garloff Exp $ Index: dc390/dc390.h =================================================================== RCS file: /usr/local/cvsroot/dc390/dc390.h,v retrieving revision 2.25 retrieving revision 2.26 diff -u -r2.25 -r2.26 --- dc390/dc390.h 1999/06/06 20:17:11 2.25 +++ dc390/dc390.h 1999/06/21 07:02:08 2.26 @@ -4,7 +4,7 @@ * Description: Device Driver for Tekram DC-390(T) PCI SCSI * * Bus Master Host Adapter * ***********************************************************************/ -/* $Id: dc390.h,v 2.25 1999/06/06 20:17:11 garloff Exp $ */ +/* $Id: dc390.h,v 2.26 1999/06/21 07:02:08 garloff Exp $ */ #include @@ -16,7 +16,7 @@ #define DC390_H #define DC390_BANNER "Tekram DC390/AM53C974" -#define DC390_VERSION "2.0d9 1999/06/06" +#define DC390_VERSION "2.0d10 1999/06/20" #if defined(HOSTS_C) || defined(MODULE) Index: dc390/scsiiom.c =================================================================== RCS file: /usr/local/cvsroot/dc390/scsiiom.c,v retrieving revision 2.32 retrieving revision 2.36 diff -u -r2.32 -r2.36 --- dc390/scsiiom.c 1999/06/06 20:17:11 2.32 +++ dc390/scsiiom.c 1999/06/21 07:33:04 2.36 @@ -4,15 +4,24 @@ * Description: Device Driver for Tekram DC-390 (T) PCI SCSI * * Bus Master Host Adapter * ***********************************************************************/ -/* $Id: scsiiom.c,v 2.32 1999/06/06 20:17:11 garloff Exp $ */ +/* $Id: scsiiom.c,v 2.36 1999/06/21 07:33:04 garloff Exp $ */ +static void __inline__ +dc390_freetag (PDCB pDCB, PSRB pSRB) +{ + if (pSRB->TagNumber < 255) { + pDCB->TagMask &= ~(1 << pSRB->TagNumber); /* free tag mask */ + pSRB->TagNumber = 255; + } +}; + + UCHAR dc390_StartSCSI( PACB pACB, PDCB pDCB, PSRB pSRB ) { UCHAR cmd; UCHAR disc_allowed, try_sync_nego; pSRB->ScsiPhase = SCSI_NOP0; - pSRB->TagNumber = 31; if (pACB->Connected) { @@ -33,19 +42,18 @@ DEBUG1(printk (KERN_INFO "DC390: Start SCSI command: %02x (Sync:%02x)\n",\ pSRB->pcmd->cmnd[0], pDCB->SyncMode);) disc_allowed = pDCB->DevMode & EN_DISCONNECT_; try_sync_nego = 0; - /* Don't disconnect on AUTO_REQ_SENSE, cause it might be an + /* Don't disconnect on AUTO_REQSENSE, cause it might be an * Contingent Allegiance Condition (6.6), where no tags should be used. * All other have to be allowed to disconnect to prevent Incorrect * Initiator Connection (6.8.2/6.5.2) */ /* Changed KG, 99/06/06 */ if( /*(((pSRB->pcmd->cmnd[0] == INQUIRY) || (pSRB->pcmd->cmnd[0] == REQUEST_SENSE) || - (pSRB->pcmd->cmnd[0] == TEST_UNIT_READY)) && pACB->scan_devices) + * (pSRB->pcmd->cmnd[0] == TEST_UNIT_READY)) && pACB->scan_devices) ||*/ (pSRB->SRBFlag & AUTO_REQSENSE) ) disc_allowed = 0; - if ( (pDCB->SyncMode & SYNC_ENABLE) && !(pDCB->SyncMode & SYNC_NEGO_DONE) - && (pDCB->UnitSCSILUN == 0) && - ( (pSRB->pcmd->cmnd[0] == INQUIRY) || (pSRB->pcmd->cmnd[0] == REQUEST_SENSE) || - (pSRB->SRBFlag & AUTO_REQSENSE) ) ) + if ( (pDCB->SyncMode & SYNC_ENABLE) && (pDCB->UnitSCSILUN == 0) && + ( ( ( (pSRB->pcmd->cmnd[0] == REQUEST_SENSE) || (pSRB->SRBFlag & AUTO_REQSENSE) ) + && !(pDCB->SyncMode & SYNC_NEGO_DONE) ) || (pSRB->pcmd->cmnd[0] == INQUIRY) ) ) try_sync_nego = 1; pSRB->MsgCnt = 0; cmd = SEL_W_ATN; @@ -55,10 +63,12 @@ { UCHAR tag_no = 0; while ((1 << tag_no) & pDCB->TagMask) tag_no++; - if (tag_no >= sizeof (pDCB->TagMask)*8 || tag_no >= pDCB->MaxCommand) - { printk (KERN_WARNING "DC390: Out of tags for Dev. %02x %02x\n", pDCB->UnitSCSIID, pDCB->UnitSCSILUN); goto no_tag; } + if (tag_no >= sizeof (pDCB->TagMask)*8 || tag_no >= pDCB->MaxCommand) { + printk (KERN_WARNING "DC390: Out of tags for Dev. %02x %02x\n", pDCB->UnitSCSIID, pDCB->UnitSCSILUN); + goto no_tag; + }; DC390_write8 (ScsiFifo, SIMPLE_QUEUE_TAG); - pDCB->TagMask |= 1 << tag_no; pSRB->TagNumber = tag_no; + pDCB->TagMask |= (1 << tag_no); pSRB->TagNumber = tag_no; DC390_write8 (ScsiFifo, tag_no); DEBUG1(printk (KERN_DEBUG "DC390: Select w/DisCn for Cmd %li (SRB %p), Using Tag %02x\n", pSRB->pcmd->pid, pSRB, tag_no);) cmd = SEL_W_ATN3; @@ -99,7 +109,6 @@ DC390_write8 (ScsiFifo, sizeof(pSRB->pcmd->sense_buffer)); DC390_write8 (ScsiFifo, 0); DEBUG1(printk (KERN_DEBUG "DC390: AutoReqSense !\n");) - //cmd = SEL_W_ATN_STOP; } else /* write cmnd to bus */ { @@ -109,15 +118,15 @@ DC390_write8 (ScsiFifo, *(ptr++)); }; } - pSRB->ScsiPhase = SCSI_NOP1; DEBUG0(if (pACB->pActiveDCB) \ printk (KERN_WARNING "DC390: ActiveDCB != 0\n");) DEBUG0(if (pDCB->pActiveSRB) \ printk (KERN_WARNING "DC390: ActiveSRB != 0\n");) - pACB->pActiveDCB = pDCB; pDCB->pActiveSRB = pSRB; //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD); DC390_write8 (ScsiCmd, cmd); + pACB->pActiveDCB = pDCB; pDCB->pActiveSRB = pSRB; pACB->Connected = 1; + pSRB->ScsiPhase = SCSI_NOP1; return 0; } @@ -151,7 +160,7 @@ }; if (dstate & DMA_XFER_DONE) { - ULONG residual, xferCnt; int ctr = 5000000; + ULONG residual, xferCnt; int ctr = 50000000; if (! (DC390_read8 (DMA_Cmd) & READ_DIRECTION)) { do @@ -208,6 +217,8 @@ printk(KERN_WARNING "DC390: Interrupt on uninitialized adapter!\n"); return; } + + DC390_ASSUMELOCK (dc390_drvlock, 0, "scsiiom.c:Interrupt 221, drv"); DC390_LOCK_DRV; for( i=0; i < dc390_adapterCnt; i++ ) @@ -250,6 +261,8 @@ //DC390_write32 (DMA_ScsiBusCtrl, EN_INT_ON_PCI_ABORT); #endif + //DC390_ASSUMELOCK (io_request_lock, 0, "scsiiom.c:Interrupt 264, io"); + //DC390_ASSUMELOCK (pACB->lock, 0, "scsiiom.c:Interrupt 265, acb"); DC390_LOCK_IO; DC390_LOCK_ACB; DC390_UNLOCK_DRV_NI; /* Allow _other_ CPUs to process IRQ (useful for shared IRQs) */ @@ -273,13 +286,13 @@ goto unlock; } - if(istatus & RESELECTED) + else if(istatus & RESELECTED) { dc390_Reselect( pACB ); goto unlock; } - if( istatus & (SUCCESSFUL_OP|SERVICE_REQUEST) ) + else if( istatus & (SUCCESSFUL_OP|SERVICE_REQUEST) ) { pDCB = pACB->pActiveDCB; if (!pDCB) @@ -304,19 +317,19 @@ goto unlock; } - if(istatus & INVALID_CMD) + else if(istatus & INVALID_CMD) { dc390_InvalidCmd( pACB ); goto unlock; } - if(istatus & SCSI_RESET) + else if(istatus & SCSI_RESET) { dc390_ScsiRstDetect( pACB ); goto unlock; } - if(istatus & (SELECTED | SEL_ATTENTION)) + else if(istatus & (SELECTED | SEL_ATTENTION)) { printk (KERN_ERR "DC390: Target mode not supported!\n"); goto unlock; @@ -355,7 +368,7 @@ if( sstatus & COUNT_2_ZERO ) { - int ctr = 5000000; /* only try for about a tenth of a second */ + int ctr = 50000000; /* only try for about a second */ while( --ctr && !((dstate = DC390_read8 (DMA_Status)) & DMA_XFER_DONE) && pSRB->SGToBeXferLen ); if (!ctr) printk (KERN_CRIT "DC390: Deadlock in DataOut_0: DMA aborted unfinished: %06x bytes remain!!\n", DC390_read32 (DMA_Wk_ByteCntr)); dc390_laststatus &= ~0xff000000; dc390_laststatus |= dstate << 24; @@ -405,7 +418,7 @@ if( sstatus & COUNT_2_ZERO ) { - int ctr = 5000000; /* only try for about a tenth of a second */ + int ctr = 50000000; /* only try for about a second */ int dstate = 0; while( --ctr && !((dstate = DC390_read8 (DMA_Status)) & DMA_XFER_DONE) && pSRB->SGToBeXferLen ); if (!ctr) printk (KERN_CRIT "DC390: Deadlock in DataIn_0: DMA aborted unfinished: %06x bytes remain!!\n", DC390_read32 (DMA_Wk_ByteCntr)); @@ -947,6 +960,7 @@ DC390_write8 (ScsiFifo, bval); DC390_write8 (ScsiFifo, sizeof(pSRB->pcmd->sense_buffer)); DC390_write8 (ScsiFifo, bval); + DEBUG0(printk(KERN_DEBUG "DC390: AutoReqSense (CmndPhase)!\n");) } pSRB->SRBState = SRB_COMMAND; DC390_write8 (ScsiCmd, INFO_XFER_CMD); @@ -1046,12 +1060,8 @@ if( !(pDCB->UnitSCSILUN) ) { - if( pACB->scan_devices ) + if( !pACB->scan_devices ) { - dc390_CurrSyncOffset = pDCB->SyncOffset; - } - else - { ptr = pACB->pLinkDCB; cnt = pACB->DCBCnt; bval = pDCB->UnitSCSIID; @@ -1102,7 +1112,7 @@ if( pSRB->SRBState & SRB_UNEXPECT_RESEL ) { pSRB->SRBState = 0; - dc390_DoWaitingSRB( pACB ); + dc390_Waiting_process ( pACB ); } else if( pSRB->SRBState & SRB_ABORT_SENT ) { @@ -1114,12 +1124,12 @@ for( i=0; i < cnt; i++) { psrb = pSRB->pNextSRB; - pSRB->pNextSRB = pACB->pFreeSRB; - pACB->pFreeSRB = pSRB; + dc390_Free_insert (pACB, pSRB); pSRB = psrb; } pDCB->pGoingSRB = 0; - dc390_DoWaitingSRB( pACB ); + dc390_Query_to_Waiting (pACB); + dc390_Waiting_process (pACB); } else { @@ -1129,7 +1139,8 @@ if( !(1/*pACB->scan_devices*/) ) { pSRB->SRBState = SRB_READY; - dc390_RewaitSRB( pDCB, pSRB); + dc390_freetag (pDCB, pSRB); + dc390_Going_to_Waiting (pDCB, pSRB); } else { @@ -1139,15 +1150,12 @@ } else if( pSRB->SRBState & SRB_DISCONNECT ) { - dc390_DoWaitingSRB( pACB ); + dc390_Waiting_process ( pACB ); } else if( pSRB->SRBState & SRB_COMPLETED ) { disc1: - if(pDCB->MaxCommand > 1) - { - pDCB->TagMask &= (~(1 << pSRB->TagNumber)); /* free tag mask */ - } + dc390_freetag (pDCB, pSRB); pDCB->pActiveSRB = 0; pSRB->SRBState = SRB_FREE; dc390_SRBdone( pACB, pDCB, pSRB); @@ -1175,7 +1183,8 @@ if( !( pACB->scan_devices ) ) { pSRB->SRBState = SRB_READY; - dc390_RewaitSRB( pDCB, pSRB); + dc390_freetag (pDCB, pSRB); + dc390_Going_to_Waiting ( pDCB, pSRB); } } bval = DC390_read8 (ScsiFifo); /* get ID */ @@ -1275,7 +1284,10 @@ DCBDEBUG(printk (KERN_INFO "DC390: Driver about to free DCB (ID %i, LUN %i): %p\n",\ pDCB->UnitSCSIID, pDCB->UnitSCSILUN, pDCB);) - kfree (pDCB); if (pDCB == pACB->pActiveDCB) pACB->pActiveDCB = 0; + kfree (pDCB); + if (pDCB == pACB->pActiveDCB) pACB->pActiveDCB = 0; + if (pDCB == pACB->pLinkDCB) pACB->pLinkDCB = pDCB->pNextDCB; + if (pDCB == pACB->pDCBRunRobin) pACB->pDCBRunRobin = pDCB->pNextDCB; pACB->DCBCnt--; /* pACB->DeviceCnt--; */ }; @@ -1304,21 +1316,12 @@ || (pDCB->DevType == TYPE_MOD)) &&*/ !dc390_tagq_blacklist (((char*)ptr)+8) ) { - pDCB->MaxCommand = pDCB->pDCBACB->TagMaxNum; + if (pDCB->MaxCommand ==1) pDCB->MaxCommand = pDCB->pDCBACB->TagMaxNum; pDCB->SyncMode |= EN_TAG_QUEUEING /* | EN_ATN_STOP */; - pDCB->TagMask = 0; + //pDCB->TagMask = 0; } else - { - /* Do we really need to check for DevType here ? */ - if ( 0 /*(pDCB->DevMode & EN_DISCONNECT_)*/ - /* && ((pDCB->DevType == TYPE_DISK) - || (pDCB->DevType == TYPE_MOD))*/ ) - pDCB->SyncMode |= EN_ATN_STOP; - else - //pDCB->SyncMode &= ~EN_ATN_STOP; - pDCB->SyncMode &= ~0; - } + pDCB->MaxCommand = 1; } }; @@ -1421,7 +1424,7 @@ pSRB->Segmentx.length = pcmd->request_bufflen; } if( dc390_StartSCSI( pACB, pDCB, pSRB ) ) - dc390_RewaitSRB( pDCB, pSRB ); + dc390_Going_to_Waiting ( pDCB, pSRB ); return; } } @@ -1452,7 +1455,8 @@ bval = (UCHAR) pDCB->GoingSRBCnt; bval--; pDCB->MaxCommand = bval; - dc390_RewaitSRB( pDCB, pSRB ); + dc390_freetag (pDCB, pSRB); + dc390_Going_to_Waiting ( pDCB, pSRB ); pSRB->AdaptStatus = 0; pSRB->TargetStatus = 0; return; @@ -1491,7 +1495,7 @@ pSRB->Segmentx.length = pcmd->request_bufflen; } if( dc390_StartSCSI( pACB, pDCB, pSRB ) ) - dc390_RewaitSRB( pDCB, pSRB ); + dc390_Going_to_Waiting ( pDCB, pSRB ); return; } else @@ -1591,23 +1595,22 @@ if( pSRB == pDCB->pGoingLast ) pDCB->pGoingLast = psrb; } - pSRB->pNextSRB = pACB->pFreeSRB; - pACB->pFreeSRB = pSRB; + /* Add to free list */ + dc390_Free_insert (pACB, pSRB); pDCB->GoingSRBCnt--; - dc390_DoWaitingSRB( pACB ); - + DEBUG0(printk (KERN_DEBUG "DC390: SRBdone: done pid %li\n", pcmd->pid);) DC390_UNLOCK_ACB_NI; pcmd->scsi_done( pcmd ); DC390_LOCK_ACB_NI; - if( pDCB->QIORBCnt ) - dc390_DoNextCmd( pACB, pDCB ); + dc390_Query_to_Waiting ( pACB ); + dc390_Waiting_process ( pACB ); return; } -/* Remove all SRBs and tell midlevel code DID_RESET */ +/* Remove all SRBs from Going list and inform midlevel */ void dc390_DoingSRB_Done( PACB pACB ) { @@ -1630,9 +1633,9 @@ /* ReleaseSRB( pDCB, pSRB ); */ - psrb->pNextSRB = pACB->pFreeSRB; - pACB->pFreeSRB = psrb; + dc390_Free_insert (pACB, 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; @@ -1643,15 +1646,16 @@ pdcb->TagMask = 0; pdcb = pdcb->pNextDCB; } while( pdcb != pDCB ); + dc390_Query_to_Waiting (pACB); } static void dc390_ResetSCSIBus( PACB pACB ) { - DC390_write8 (ScsiCmd, RST_DEVICE_CMD); - udelay (250); - DC390_write8 (ScsiCmd, NOP_CMD); + //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); @@ -1678,7 +1682,7 @@ if( pACB->ACBFlag & RESET_DEV ) pACB->ACBFlag |= RESET_DONE; else - { + { /* Reset was issued by sb else */ pACB->ACBFlag |= RESET_DETECT; dc390_ResetDevParam( pACB ); @@ -1686,7 +1690,7 @@ dc390_RecoverSRB( pACB ); pACB->pActiveDCB = NULL; pACB->ACBFlag = 0; - dc390_DoWaitingSRB( pACB ); + dc390_Waiting_process( pACB ); } return; } @@ -1727,7 +1731,7 @@ pSRB->TotalXferredLen = 0; pSRB->SGToBeXferLen = 0; if( dc390_StartSCSI( pACB, pDCB, pSRB ) ) - dc390_RewaitSRB( pDCB, pSRB ); + dc390_Going_to_Waiting ( pDCB, pSRB ); } Index: dc390/tmscsim.c =================================================================== RCS file: /usr/local/cvsroot/dc390/tmscsim.c,v retrieving revision 2.39 retrieving revision 2.41 diff -u -r2.39 -r2.41 --- dc390/tmscsim.c 1999/06/06 20:17:11 2.39 +++ dc390/tmscsim.c 1999/06/21 07:02:08 2.41 @@ -7,7 +7,7 @@ ***********************************************************************/ /* (C) Copyright: put under GNU GPL in 10/96 (see README.tmscsim) * *************************************************************************/ -/* $Id: tmscsim.c,v 2.39 1999/06/06 20:17:11 garloff Exp $ */ +/* $Id: tmscsim.c,v 2.41 1999/06/21 07:02:08 garloff Exp $ */ /* Enhancements and bugfixes by * * Kurt Garloff * ***********************************************************************/ @@ -117,6 +117,9 @@ * Fixed Oops in _release(). * * 2.0d9 99/06/06 KG Also tag queue INQUIRY, T_U_R, ... * * Allow arb. no. of Tagged Cmnds. Max 32 * + * 2.0d1099/06/20 KG TagMaxNo changes now honoured! Queueing * + * clearified (renamed ..) TagMask handling* + * cleaned. * ***********************************************************************/ /* Uncomment SA_INTERRUPT, if the driver refuses to share its IRQ with other devices */ @@ -128,6 +131,7 @@ //#define DC390_DCBDEBUG //#define DC390_PARSEDEBUG //#define DC390_REMOVABLEDEBUG +//#define DC390_LOCKDEBUG /* Debug definitions */ #ifdef DC390_DEBUG0 @@ -157,6 +161,14 @@ #endif #define DCBDEBUG1(x) +#ifdef DC390_LOCKDEBUG +# define DC390_ASSUMELOCK(x,y,z) if (x.lock != y) { \ + printk (KERN_CRIT "DC390: (%s): Lock %p in unexpected state %i (exp: %i)!!\n", z, &x, x.lock, y); \ +} +#else +# define DC390_ASSUMELOCK(x,y,z) +#endif + /* Includes */ #ifdef MODULE # include @@ -414,7 +426,6 @@ static PACB dc390_pACB_start= NULL; static PACB dc390_pACB_current = NULL; static UCHAR dc390_adapterCnt = 0; -static UCHAR dc390_CurrSyncOffset = 0; static ULONG dc390_lastabortedpid = 0; static ULONG dc390_laststatus = 0; @@ -724,47 +735,59 @@ return pDCB; }; -static void dc390_QLinkcmd( PSCSICMD cmd, PDCB pDCB ) -{ - PSCSICMD pcmd; +/* Queueing philosphy: + * There are a couple of lists: + * - Query: Contains the Scsi Commands not yet turned into SRBs (per ACB) + * - Waiting: Contains a list of SRBs not yet sent (per DCB) + * - Free: List of free SRB slots + * + * If there are no waiting commands for the DCB, the new one is sent to the bus + * otherwise the oldest one is taken from the Waiting list and the new one is + * queued to the Waiting List + * + * Lists are managed using two pointers and eventually a counter + */ - if( !pDCB->QIORBCnt ) - { - pDCB->pQIORBhead = cmd; - pDCB->pQIORBtail = cmd; - pDCB->QIORBCnt++; - cmd->next = NULL; - } + +/* Append to Query List */ +static void dc390_Query_append( PSCSICMD cmd, PACB pACB ) +{ + DEBUG0(printk ("DC390: Append cmd %li to Query\n", cmd->pid);) + if( !pACB->QueryCnt ) + pACB->pQueryHead = cmd; else - { - pcmd = pDCB->pQIORBtail; - pcmd->next = cmd; - pDCB->pQIORBtail = cmd; - pDCB->QIORBCnt++; - cmd->next = NULL; - } + pACB->pQueryTail->next = cmd; + pACB->pQueryTail = cmd; + pACB->QueryCnt++; + pACB->CmdOutOfSRB++; + cmd->next = NULL; } -static __inline__ PSCSICMD dc390_Getcmd( PDCB pDCB ) +/* Return next cmd from Query list */ +static PSCSICMD dc390_Query_get ( PACB pACB ) { PSCSICMD pcmd; - pcmd = pDCB->pQIORBhead; - pDCB->pQIORBhead = pcmd->next; + pcmd = pACB->pQueryHead; + if (!pcmd) return pcmd; + DEBUG0(printk ("DC390: Get cmd %li from Query\n", pcmd->pid);) + pACB->pQueryHead = pcmd->next; pcmd->next = NULL; - pDCB->QIORBCnt--; - + if (!pACB->pQueryHead) pACB->pQueryTail = NULL; + pACB->QueryCnt--; return( pcmd ); } -static __inline__ PSRB dc390_GetSRB( PACB pACB ) +/* Return next free SRB */ +static __inline__ PSRB dc390_Free_get ( PACB pACB ) { PSRB pSRB; pSRB = pACB->pFreeSRB; + DEBUG0(printk ("DC390: Get Free SRB %p\n", pSRB);) if( pSRB ) { pACB->pFreeSRB = pSRB->pNextSRB; @@ -773,32 +796,64 @@ return( pSRB ); } - -static __inline__ void dc390_RewaitSRB0( PDCB pDCB, PSRB pSRB ) +/* Insert SRB oin top of free list */ +static __inline__ void dc390_Free_insert (PACB pACB, PSRB pSRB) { - PSRB psrb1; + DEBUG0(printk ("DC390: Free SRB %p\n", pSRB);) + pSRB->pNextSRB = pACB->pFreeSRB; + pACB->pFreeSRB = pSRB; +} - if( (psrb1 = pDCB->pWaitingSRB) ) - { - pSRB->pNextSRB = psrb1; - } - else - { - pSRB->pNextSRB = NULL; + +/* Inserts a SRB to the top of the Waiting list */ +static __inline__ void dc390_Waiting_insert ( PDCB pDCB, PSRB pSRB ) +{ + DEBUG0(printk ("DC390: Insert pSRB %p cmd %li to Waiting\n", pSRB, pSRB->pcmd->pid);) + pSRB->pNextSRB = pDCB->pWaitingSRB; + if (!pDCB->pWaitingSRB) pDCB->pWaitLast = pSRB; - } pDCB->pWaitingSRB = pSRB; } + +/* Queue SRB to waiting list */ +static __inline__ void dc390_Waiting_append ( PDCB pDCB, PSRB pSRB) +{ + DEBUG0(printk ("DC390: Append pSRB %p cmd %li to Waiting\n", pSRB, pSRB->pcmd->pid);) + if( pDCB->pWaitingSRB ) + pDCB->pWaitLast->pNextSRB = pSRB; + else + pDCB->pWaitingSRB = pSRB; + + pDCB->pWaitLast = pSRB; + pSRB->pNextSRB = NULL; + pDCB->pDCBACB->CmdInQ++; +} + +static __inline__ void dc390_Going_append (PDCB pDCB, PSRB pSRB) +{ + pDCB->GoingSRBCnt++; + DEBUG0(printk("DC390: Append SRB %p to Going\n", pSRB);) + /* Append to the list of Going commands */ + if( pDCB->pGoingSRB ) + pDCB->pGoingLast->pNextSRB = pSRB; + else + pDCB->pGoingSRB = pSRB; + + pDCB->pGoingLast = pSRB; + /* No next one in sent list */ + pSRB->pNextSRB = NULL; +}; -static void dc390_RewaitSRB( PDCB pDCB, PSRB pSRB ) +/* Moves SRB from Going list to the top of Waiting list */ +static void dc390_Going_to_Waiting ( PDCB pDCB, PSRB pSRB ) { PSRB psrb1; - UCHAR bval; pDCB->GoingSRBCnt--; //pDCB->pDCBACB->SelLost++; - DEBUG0(printk(KERN_INFO "DC390: RewaitSRB (%p, %p) pid = %li\n", pDCB, pSRB, pSRB->pcmd->pid);) + DEBUG0(printk(KERN_INFO "DC390: Going_to_Waiting (SRB %p) pid = %li\n", pSRB, pSRB->pcmd->pid);) + /* Find SRB in Going */ psrb1 = pDCB->pGoingSRB; if( pSRB == psrb1 ) { @@ -806,98 +861,63 @@ } else { + /* Scan list */ while( pSRB != psrb1->pNextSRB ) psrb1 = psrb1->pNextSRB; psrb1->pNextSRB = pSRB->pNextSRB; if( pSRB == pDCB->pGoingLast ) pDCB->pGoingLast = psrb1; - } - if( (psrb1 = pDCB->pWaitingSRB) ) - { - pSRB->pNextSRB = psrb1; - pDCB->pWaitingSRB = pSRB; } - else - { - pSRB->pNextSRB = NULL; - pDCB->pWaitingSRB = pSRB; - pDCB->pWaitLast = pSRB; - } - - bval = pSRB->TagNumber; - pDCB->TagMask &= (~(1 << bval)); /* Free TAG number */ + + /* Insert on top of Waiting */ + dc390_Waiting_insert (pDCB, pSRB); + + /* Tag Mask must be freed elsewhere ! (KG, 99/06/18)*/ } +/* Moves first SRB from Waiting list to Going list */ +static __inline__ void dc390_Waiting_to_Going ( PDCB pDCB, PSRB pSRB ) +{ + /* Remove from waiting list */ + DEBUG0(printk("DC390: Remove SRB %p from head of Waiting\n", pSRB);) + pDCB->pWaitingSRB = pSRB->pNextSRB; + if( !pDCB->pWaitingSRB ) pDCB->pWaitLast = NULL; + dc390_Going_append (pDCB, pSRB); +} -static void dc390_DoWaitingSRB( PACB pACB ) +/* Send the next command from the waiting list to the bus */ +static void dc390_Waiting_process ( PACB pACB ) { PDCB ptr, ptr1; PSRB pSRB; - if( !(pACB->pActiveDCB) && !(pACB->ACBFlag & (RESET_DETECT+RESET_DONE+RESET_DEV) ) ) - { - ptr = pACB->pDCBRunRobin; - if( !ptr ) - { - ptr = pACB->pLinkDCB; - pACB->pDCBRunRobin = ptr; - } - ptr1 = ptr; - for( ;ptr1; ) - { - pACB->pDCBRunRobin = ptr1->pNextDCB; - if( !( ptr1->MaxCommand > ptr1->GoingSRBCnt ) || - !( pSRB = ptr1->pWaitingSRB ) ) - { - if(pACB->pDCBRunRobin == ptr) - break; - ptr1 = ptr1->pNextDCB; - } - else - { - if( !dc390_StartSCSI(pACB, ptr1, pSRB) ) - { - ptr1->GoingSRBCnt++; - if( ptr1->pWaitLast == pSRB ) - { - ptr1->pWaitingSRB = NULL; - ptr1->pWaitLast = NULL; - } - else - { - ptr1->pWaitingSRB = pSRB->pNextSRB; - } - pSRB->pNextSRB = NULL; - - if( ptr1->pGoingSRB ) - ptr1->pGoingLast->pNextSRB = pSRB; - else - ptr1->pGoingSRB = pSRB; - ptr1->pGoingLast = pSRB; - } - break; - } - } - } + if( (pACB->pActiveDCB) || (pACB->ACBFlag & (RESET_DETECT+RESET_DONE+RESET_DEV) ) ) + return; + ptr = pACB->pDCBRunRobin; + if( !ptr ) + { + ptr = pACB->pLinkDCB; + pACB->pDCBRunRobin = ptr; + } + ptr1 = ptr; + if (!ptr1) return; + do + { + pACB->pDCBRunRobin = ptr1->pNextDCB; + if( !( pSRB = ptr1->pWaitingSRB ) || + ( ptr1->MaxCommand <= ptr1->GoingSRBCnt )) + ptr1 = ptr1->pNextDCB; + else + { + /* Try to send to the bus */ + if( !dc390_StartSCSI(pACB, ptr1, pSRB) ) + dc390_Waiting_to_Going (ptr1, pSRB); + break; + } + } while (ptr1 != ptr); return; } - -static __inline__ void dc390_SRBwaiting( PDCB pDCB, PSRB pSRB) -{ - if( pDCB->pWaitingSRB ) - { - pDCB->pWaitLast->pNextSRB = pSRB; - pSRB->pNextSRB = NULL; - } - else - { - pDCB->pWaitingSRB = pSRB; - } - pDCB->pWaitLast = pSRB; -} - - /*********************************************************************** * Function: static void dc390_SendSRB (PACB pACB, PSRB pSRB) * @@ -910,41 +930,32 @@ PDCB pDCB; pDCB = pSRB->pSRBDCB; - if( !(pDCB->MaxCommand > pDCB->GoingSRBCnt) || (pACB->pActiveDCB) || + if( (pDCB->MaxCommand <= pDCB->GoingSRBCnt) || (pACB->pActiveDCB) || (pACB->ACBFlag & (RESET_DETECT+RESET_DONE+RESET_DEV)) ) { - dc390_SRBwaiting(pDCB, pSRB); - goto SND_EXIT; + dc390_Waiting_append (pDCB, pSRB); + dc390_Waiting_process (pACB); + return; } +#if 0 if( pDCB->pWaitingSRB ) { - dc390_SRBwaiting(pDCB, pSRB); + dc390_Waiting_append (pDCB, pSRB); /* pSRB = GetWaitingSRB(pDCB); */ /* non-existent */ pSRB = pDCB->pWaitingSRB; + /* Remove from waiting list */ pDCB->pWaitingSRB = pSRB->pNextSRB; pSRB->pNextSRB = NULL; + if (!pDCB->pWaitingSRB) pDCB->pWaitLast = NULL; } - - if( !dc390_StartSCSI(pACB, pDCB, pSRB) ) - { - pDCB->GoingSRBCnt++; - if( pDCB->pGoingSRB ) - { - pDCB->pGoingLast->pNextSRB = pSRB; - pDCB->pGoingLast = pSRB; - } - else - { - pDCB->pGoingSRB = pSRB; - pDCB->pGoingLast = pSRB; - } - } +#endif + + if (!dc390_StartSCSI(pACB, pDCB, pSRB)) + dc390_Going_append (pDCB, pSRB); else - dc390_RewaitSRB0( pDCB, pSRB ); + dc390_Waiting_insert (pDCB, pSRB); -SND_EXIT: - return; } /*********************************************************************** @@ -993,8 +1004,39 @@ pSRB->SGToBeXferLen = 0; pSRB->ScsiPhase = 0; pSRB->EndMessage = 0; + pSRB->TagNumber = 255; }; +/* Put cmnd from Query to Waiting list and send next Waiting cmnd */ +static void dc390_Query_to_Waiting (PACB pACB) +{ + Scsi_Cmnd *pcmd; + PSRB pSRB; + PDCB pDCB; + + if( pACB->ACBFlag & (RESET_DETECT+RESET_DONE+RESET_DEV) ) + return; + + while (pACB->QueryCnt) + { + pSRB = dc390_Free_get ( pACB ); + if (!pSRB) return; + pcmd = dc390_Query_get ( pACB ); + if (!pcmd) { dc390_Free_insert (pACB, pSRB); return; }; /* should not happen */ + pDCB = dc390_findDCB (pACB, pcmd->target, pcmd->lun); + if (!pDCB) + { + dc390_Free_insert (pACB, pSRB); + printk (KERN_ERR "DC390: Command in queue to non-existing device!\n"); + pcmd->result = MK_RES(DRIVER_ERROR,DID_ERROR,0,0); + DC390_UNLOCK_ACB_NI; + pcmd->done (pcmd); + DC390_LOCK_ACB_NI; + }; + dc390_BuildSRB (pcmd, pDCB, pSRB); + dc390_Waiting_append ( pDCB, pSRB ); + } +} /*********************************************************************** * Function : static int DC390_queue_command (Scsi_Cmnd *cmd, @@ -1017,7 +1059,6 @@ int DC390_queue_command (Scsi_Cmnd *cmd, void (* done)(Scsi_Cmnd *)) { - Scsi_Cmnd *pcmd; PDCB pDCB; PSRB pSRB; DC390_AFLAGS @@ -1028,6 +1069,8 @@ printk(KERN_INFO "DC390: Queue Cmd=%02x,ID=%d,LUN=%d (pid=%li)\n",\ cmd->cmnd[0],cmd->target,cmd->lun,cmd->pid);) + DC390_ASSUMELOCK (io_request_lock, 1, "tmscsim.c:queue 1072, io"); + //DC390_ASSUMELOCK (pACB->lock, 0, "tmscsim.c:queue 1073, acb"); DC390_LOCK_ACB; /* Assume BAD_TARGET; will be cleared later */ @@ -1062,8 +1105,8 @@ { printk (KERN_ERR "DC390: kmalloc for DCB failed, ID=%2x\n", cmd->target); DC390_UNLOCK_ACB; - done(cmd); - return(0); + //done(cmd); + return(1); }; } @@ -1081,62 +1124,56 @@ if (!pDCB) { /* should never happen */ DC390_UNLOCK_ACB; - done(cmd); - return(0); + //done(cmd); + return(1); }; } pACB->Cmds++; cmd->scsi_done = done; cmd->result = 0; + + dc390_Query_to_Waiting (pACB); - if( pDCB->QIORBCnt ) /* Unsent commands ? */ + if( pACB->QueryCnt ) /* Unsent commands ? */ { - dc390_QLinkcmd( cmd, pDCB ); - pcmd = dc390_Getcmd( pDCB ); /* Get first command */ - pACB->CmdInQ++; + DEBUG0(printk ("DC390: QueryCnt != 0\n");) + dc390_Query_append ( cmd, pACB ); + dc390_Waiting_process (pACB); } - else - pcmd = cmd; - - pSRB = dc390_GetSRB( pACB ); - - if( !pSRB ) + else if (pDCB->pWaitingSRB) { - dc390_QLinkcmd( pcmd, pDCB ); /* Queue command at the end */ - pACB->CmdOutOfSRB++; - DC390_UNLOCK_ACB; - return(0); + pSRB = dc390_Free_get ( pACB ); + DEBUG0(if (!pSRB) printk ("DC390: No free SRB but Waiting\n"); else printk ("DC390: Free SRB w/ Waiting\n");) + if (!pSRB) dc390_Query_append (cmd, pACB); + else + { + dc390_BuildSRB (cmd, pDCB, pSRB); + dc390_Waiting_append (pDCB, pSRB); + } + dc390_Waiting_process (pACB); } - - dc390_BuildSRB (pcmd, pDCB, pSRB); - dc390_SendSRB( pACB, pSRB ); + else + { + pSRB = dc390_Free_get ( pACB ); + DEBUG0(if (!pSRB) printk ("DC390: No free SRB w/o Waiting\n"); else printk ("DC390: Free SRB w/o Waiting\n");) + if (!pSRB) + { + dc390_Query_append (cmd, pACB); + dc390_Waiting_process (pACB); + } + else + { + dc390_BuildSRB (cmd, pDCB, pSRB); + dc390_SendSRB (pACB, pSRB); + }; + }; DC390_UNLOCK_ACB; DEBUG1(printk (KERN_DEBUG " ... command (%02x) queued successfully.\n", pcmd->cmnd[0]);) return(0); } - -static void dc390_DoNextCmd( PACB pACB, PDCB pDCB ) -{ - Scsi_Cmnd *pcmd; - PSRB pSRB; - - if( pACB->ACBFlag & (RESET_DETECT+RESET_DONE+RESET_DEV) ) - return; - - pcmd = dc390_Getcmd( pDCB ); - pSRB = dc390_GetSRB( pACB ); - if( !pSRB ) - dc390_QLinkcmd( pcmd, pDCB ); - else - { - dc390_BuildSRB (pcmd, pDCB, pSRB); - dc390_SendSRB( pACB, pSRB ); - }; -} - /* We ignore mapping problems, as we expect everybody to respect * valid partition tables. Waiting for complaints ;-) */ @@ -1327,43 +1364,41 @@ PDCB pDCB; PSRB pSRB, psrb; ULONG count, i; - PSCSICMD pcmd, pcmd1; + PSCSICMD pcmd; int status; - ULONG sbac; + //ULONG sbac; DC390_AFLAGS PACB pACB = (PACB) cmd->host->hostdata; + DC390_ASSUMELOCK (io_request_lock, 1, "tmscsim.c:abort 1373, io"); + //DC390_ASSUMELOCK (pACB->lock, 0, "tmscsim.c:abort 1374, acb"); DC390_LOCK_ACB; - - pDCB = dc390_findDCB (pACB, cmd->target, cmd->lun); - /* abort() is too buggy at the moment. If it's called we are in trouble anyway. - * so let's dump some info into the syslog at least. (KG, 98/08/20) */ - if (pDCB) pSRB = pDCB->pActiveSRB; else pSRB = 0; - printk ("DC390: Abort command (pid %li, DCB %p, SRB %p)\n", - cmd->pid, pDCB, pSRB); - dc390_dumpinfo (pACB, pDCB, pSRB); - if( !pDCB ) goto NOT_RUN; + printk ("DC390: Abort command (pid %li, Device %02i-%02i)\n", + cmd->pid, cmd->target, cmd->lun); - if( pDCB->QIORBCnt ) + /* First scan Query list */ + if( pACB->QueryCnt ) { - pcmd = pDCB->pQIORBhead; + pcmd = pACB->pQueryHead; if( pcmd == cmd ) { - pDCB->pQIORBhead = pcmd->next; + /* Found: Dequeue */ + pACB->pQueryHead = pcmd->next; pcmd->next = NULL; - pDCB->QIORBCnt--; + if (cmd == pACB->pQueryTail) pACB->pQueryTail = NULL; + pACB->QueryCnt--; status = SCSI_ABORT_SUCCESS; goto ABO_X; } - for( count = pDCB->QIORBCnt, i=0; iQueryCnt, i=0; inext == cmd ) { - pcmd1 = pcmd->next; - pcmd->next = pcmd1->next; - pcmd1->next = NULL; - pDCB->QIORBCnt--; + pcmd->next = cmd->next; + cmd->next = NULL; + if (cmd == pACB->pQueryTail) pACB->pQueryTail = NULL; + pACB->QueryCnt--; status = SCSI_ABORT_SUCCESS; goto ABO_X; } @@ -1374,14 +1409,20 @@ } } + pDCB = dc390_findDCB (pACB, cmd->target, cmd->lun); + if( !pDCB ) goto NOT_RUN; + if (pDCB) pSRB = pDCB->pActiveSRB; else pSRB = 0; + /* Added 98/07/02 KG */ pSRB = pDCB->pActiveSRB; if (pSRB && pSRB->pcmd == cmd ) goto ON_GOING; - + pSRB = pDCB->pWaitingSRB; if( !pSRB ) goto ON_GOING; + + /* Now scan Waiting queue */ if( pSRB->pcmd == cmd ) { pDCB->pWaitingSRB = pSRB->pNextSRB; @@ -1401,16 +1442,20 @@ pSRB = psrb->pNextSRB; psrb->pNextSRB = pSRB->pNextSRB; if( pSRB == pDCB->pWaitLast ) - pDCB->pWaitLast = psrb; /* No check for psrb == NULL ? */ + pDCB->pWaitLast = psrb; IN_WAIT: - pSRB->pNextSRB = pACB->pFreeSRB; - pACB->pFreeSRB = pSRB; + dc390_Free_insert (pACB, pSRB); cmd->next = NULL; status = SCSI_ABORT_SUCCESS; goto ABO_X; } + /* SRB has already been sent ! */ ON_GOING: + /* abort() is too stupid for already sent commands at the moment. + * If it's called we are in trouble anyway, so let's dump some info + * into the syslog at least. (KG, 98/08/20,99/06/20) */ + dc390_dumpinfo (pACB, pDCB, pSRB); pSRB = pDCB->pGoingSRB; pDCB->DCBFlag |= ABORT_DEV_; /* Now for the hard part: The command is currently processed */ @@ -1441,6 +1486,7 @@ ABO_X: cmd->result = DID_ABORT << 16; printk(KERN_INFO "DC390: Aborted pid %li with status %i\n", cmd->pid, status); +#if 0 if (cmd->pid == dc390_lastabortedpid) /* repeated failure ? */ { /* Let's do something to help the bus getting clean again */ @@ -1471,6 +1517,7 @@ sbac = DC390_read32 (DMA_ScsiBusCtrl); printk ("%08lx\n", sbac); }; +#endif dc390_lastabortedpid = cmd->pid; DC390_UNLOCK_ACB; //do_DC390_Interrupt (pACB->IRQLevel, 0, 0); @@ -1491,6 +1538,7 @@ pDCB->SyncMode &= ~SYNC_NEGO_DONE; pDCB->SyncPeriod = 0; pDCB->SyncOffset = 0; + pDCB->TagMask = 0; pDCB->CtrlR3 = FAST_CLK; pDCB->CtrlR4 &= NEGATE_REQACKDATA | CTRL4_RESERVED | NEGATE_REQACK; pDCB->CtrlR4 |= pACB->glitch_cfg; @@ -1559,14 +1607,18 @@ printk(KERN_INFO "DC390: RESET ... "); + DC390_ASSUMELOCK (io_request_lock, 1, "tmscsim.c:reset 1610, io"); + //DC390_ASSUMELOCK (pACB->lock, 0, "tmscsim.c:reset 1611, acb"); DC390_LOCK_ACB; bval = DC390_read8 (CtrlReg1); bval |= DIS_INT_ON_SCSI_RST; - DC390_write8 (CtrlReg1, bval); /* disable interrupt */ + DC390_write8 (CtrlReg1, bval); /* disable IRQ on bus reset */ pACB->ACBFlag |= RESET_DEV; dc390_ResetSCSIBus( pACB ); pACB->pScsiHost->last_reset = jiffies; + + dc390_ResetDevParam( pACB ); /* Unlock ? */ for( i=0; i<(500 + 1000*dc390_eepromBuf[pACB->AdapterIndex][EE_DELAY]); i++ ) udelay(1000); @@ -1574,7 +1626,6 @@ DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD); DC390_read8 (INT_Status); /* Reset Pending INT */ - dc390_ResetDevParam( pACB ); dc390_DoingSRB_Done( pACB ); /* dc390_RecoverSRB (pACB); */ pACB->pActiveDCB = NULL; @@ -1584,10 +1635,10 @@ bval &= ~DIS_INT_ON_SCSI_RST; DC390_write8 (CtrlReg1, bval); /* re-enable interrupt */ - dc390_DoWaitingSRB( pACB ); + dc390_Waiting_process( pACB ); - DC390_UNLOCK_ACB; printk("done\n"); + DC390_UNLOCK_ACB; return( SCSI_RESET_SUCCESS ); } @@ -1630,7 +1681,6 @@ pACB->pLastDCB = pDCB; pDCB->pDCBACB = pACB; - pDCB->QIORBCnt = 0; pDCB->UnitSCSIID = id; pDCB->UnitSCSILUN = lun; pDCB->pWaitingSRB = NULL; @@ -1686,22 +1736,26 @@ void dc390_updateDCB (PACB pACB, PDCB pDCB) { - if (pDCB->DevMode & TAG_QUEUEING_) pDCB->SyncMode &= EN_TAG_QUEUEING | SYNC_NEGO_DONE | EN_ATN_STOP; - else pDCB->SyncMode &= SYNC_NEGO_DONE | EN_ATN_STOP; - - if( pDCB->DevMode & SYNC_NEGO_ && (!(pDCB->UnitSCSILUN) || dc390_CurrSyncOffset) ) - pDCB->SyncMode |= SYNC_ENABLE; - else - { + pDCB->SyncMode &= EN_TAG_QUEUEING | SYNC_NEGO_DONE /*| EN_ATN_STOP*/; + if (pDCB->DevMode & TAG_QUEUEING_) { + //if (pDCB->SyncMode & EN_TAG_QUEUEING) pDCB->MaxCommand = pACB->TagMaxNum; + } else { + pDCB->SyncMode &= ~EN_TAG_QUEUEING; + pDCB->MaxCommand = 1; + }; + + if( pDCB->DevMode & SYNC_NEGO_ ) + pDCB->SyncMode |= SYNC_ENABLE; + else { pDCB->SyncMode &= ~(SYNC_NEGO_DONE | SYNC_ENABLE); pDCB->SyncOffset &= ~0x0f; - }; - - if (! (pDCB->DevMode & EN_DISCONNECT_)) pDCB->SyncMode &= ~EN_ATN_STOP; - + }; + + //if (! (pDCB->DevMode & EN_DISCONNECT_)) pDCB->SyncMode &= ~EN_ATN_STOP; + pDCB->CtrlR1 = pACB->pScsiHost->this_id; if( pDCB->DevMode & PARITY_CHK_ ) - pDCB->CtrlR1 |= PARITY_ERR_REPO; + pDCB->CtrlR1 |= PARITY_ERR_REPO; }; @@ -1742,9 +1796,9 @@ ULONG count, i; count = pACB->SRBCount; - for( i=0; i< count; i++) + for( i=0; iSRB_array[i].pNextSRB = &pACB->SRB_array[i+1]; else pACB->SRB_array[i].pNextSRB = NULL; @@ -1799,6 +1853,8 @@ pACB->pActiveDCB = NULL; pACB->pFreeSRB = pACB->SRB_array; pACB->SRBCount = MAX_SRB_CNT; + pACB->QueryCnt = 0; + pACB->pQueryHead = NULL; pACB->AdapterIndex = index; pACB->status = 0; psh->this_id = dc390_eepromBuf[index][EE_ADAPT_SCSI_ID]; @@ -2062,6 +2118,9 @@ UINT io_port; DC390_IFLAGS DC390_DFLAGS + DC390_ASSUMELOCK (io_request_lock, 0, "tmscsim.c:detect 2121, io"); + DC390_ASSUMELOCK (dc390_drvlock, 0, "tmscsim.c:detect 2122, drv"); + DC390_LOCK_DRV; //dc390_pSHT_start = psht; dc390_pACB_start = NULL; @@ -2255,6 +2314,8 @@ DC390_AFLAGS pos[length] = 0; + DC390_ASSUMELOCK (io_request_lock, 0, "tmscsim.c:set_info 2317, io"); + //DC390_ASSUMELOCK (pACB->lock, 0, "tmscsim.c:set_info 2318, acb"); DC390_LOCK_IO; DC390_LOCK_ACB; /* UPPERCASE */ @@ -2329,7 +2390,7 @@ else pos = strtok (0, " \t\n:=,;."); if (!pos) goto ok; - /* Speed: NegoPeriod */ + /* Sync Speed in MHz */ if (*pos != '-') { SCANF (pos, p0, dum, 1, 13); @@ -2344,11 +2405,11 @@ for (; p0-pos > 1; p0--) dum /= 10; pDCB->NegoPeriod = (100000/(100*dumold + dum)) >> 2; if (pDCB->NegoPeriod < 19) pDCB->NegoPeriod = 19; - if (pDCB->NegoPeriod != olddevmode) needs_inquiry++; pos = strtok (0, " \t\n:=,;"); if (!pos) goto ok; }; if (*pos == 'M') pos = strtok (0, " \t\n:=,;"); + if (pDCB->NegoPeriod != olddevmode) needs_inquiry++; } else pos = strtok (0, " \t\n:=,;"); /* dc390_updateDCB (pACB, pDCB); */ @@ -2363,7 +2424,20 @@ if (pDCB->SyncOffset > olddevmode) needs_inquiry++; } else pos = strtok (0, " \t\n:=,;"); + if (!pos) goto ok; dc390_updateDCB (pACB, pDCB); + + //olddevmode = pDCB->MaxCommand; + /* MaxCommand (Tags) */ + if (*pos != '-') + { + SCANF (pos, p0, dum, 1, 32 /*pACB->TagMaxNum*/); + if (pDCB->SyncMode & EN_TAG_QUEUEING) + pDCB->MaxCommand = dum; + else printk (KERN_INFO "DC390: Can't set MaxCmd larger than one without Tag Queueing!\n"); + } + else pos = strtok (0, " \t\n:=,;"); + } else { @@ -2373,7 +2447,7 @@ /* Adapter setting */ SEARCH (pos, p0, pACB->pScsiHost->max_id, "MAXID", 8); SEARCH (pos, p0, pACB->pScsiHost->max_lun, "MAXLUN", 8); - SEARCH (pos, p0, pACB->pScsiHost->this_id, "ADAPTERID", 7); + SEARCH (pos, p0, pACB->pScsiHost->this_id, "ADAPTERID", 7); SEARCH (pos, p0, pACB->TagMaxNum, "TAGMAXNUM", 32); SEARCH (pos, p0, pACB->ACBFlag, "ACBFLAG", 255); SEARCH3 (pos, p0, dum, "GLITCHEATER", 40, 1000, "NS"); @@ -2384,8 +2458,8 @@ if (pACB->sel_timeout < 60) pACB->sel_timeout = 60; //dum = 0; while (1 << dum <= pACB->TagMaxNum) dum ++; //pACB->TagMaxNum &= (1 << --dum); - if (pos == p1) goto einv; dc390_updateDCBs (pACB); + if (pos == p1) goto einv; } if (pos) goto next; @@ -2528,6 +2602,8 @@ SPRINTF("Tekram DC390/AM53C974 PCI SCSI Host Adapter, "); SPRINTF("Driver Version %s\n", DC390_VERSION); + DC390_ASSUMELOCK (io_request_lock, 0, "tmscsim.c:proc_info 2605, io"); + //DC390_ASSUMELOCK (pACB->lock, 0, "tmscsim.c:proc_info 2606, acb"); DC390_LOCK_ACB; SPRINTF("SCSI Host Nr %i, ", shpnt->host_no); @@ -2553,7 +2629,7 @@ pACB->DCBmap[0], pACB->DCBmap[1], pACB->DCBmap[2], pACB->DCBmap[3], pACB->DCBmap[4], pACB->DCBmap[5], pACB->DCBmap[6], pACB->DCBmap[7]); - SPRINTF("Idx ID LUN Prty Sync DsCn SndS TagQ NegoPeriod SyncSpeed SyncOffs\n"); + SPRINTF("Idx ID LUN Prty Sync DsCn SndS TagQ NegoPeriod SyncSpeed SyncOffs MaxCmd\n"); pDCB = pACB->pLinkDCB; for (dev = 0; dev < pACB->DCBCnt; dev++) @@ -2570,10 +2646,11 @@ SPRINTF(" %03i ns ", (pDCB->NegoPeriod) << 2); spd = 40/(sp); spd1 = 40%(sp); spd1 = (spd1 * 10 + sp/2) / (sp); - SPRINTF(" %2i.%1i M %02i\n", spd, spd1, (pDCB->SyncOffset & 0x0f)); + SPRINTF(" %2i.%1i M %02i", spd, spd1, (pDCB->SyncOffset & 0x0f)); } - else SPRINTF(" (%03i ns)\n", (pDCB->NegoPeriod) << 2); + else SPRINTF(" (%03i ns) ", (pDCB->NegoPeriod) << 2); /* Add more info ...*/ + SPRINTF (" %02i\n", pDCB->MaxCommand); pDCB = pDCB->pNextDCB; } @@ -2648,6 +2725,8 @@ PACB pACB = (PACB)(host->hostdata); #endif + DC390_ASSUMELOCK (io_request_lock, 0, "tmscsim.c:release 2728, io"); + //DC390_ASSUMELOCK (pACB->lock, 0, "tmscsim.c:release 2729, acb"); DC390_LOCK_IO; DC390_LOCK_ACB; Index: dc390/tmscsim.h =================================================================== RCS file: /usr/local/cvsroot/dc390/tmscsim.h,v retrieving revision 2.11 retrieving revision 2.12 diff -u -r2.11 -r2.12 --- dc390/tmscsim.h 1999/06/06 20:17:11 2.11 +++ dc390/tmscsim.h 1999/06/21 07:02:08 2.12 @@ -3,7 +3,7 @@ ;* TEKRAM DC-390(T) PCI SCSI Bus Master Host Adapter * ;* Device Driver * ;***********************************************************************/ -/* $Id: tmscsim.h,v 2.11 1999/06/06 20:17:11 garloff Exp $ */ +/* $Id: tmscsim.h,v 2.12 1999/06/21 07:02:08 garloff Exp $ */ #ifndef _TMSCSIM_H #define _TMSCSIM_H @@ -131,25 +131,25 @@ struct _DCB *pNextDCB; struct _ACB *pDCBACB; -PSCSICMD pQIORBhead; -PSCSICMD pQIORBtail; -PSCSICMD AboIORBhead; -PSCSICMD AboIORBtail; -ULONG QIORBCnt; -ULONG AboIORBcnt; +/* Aborted Commands */ +//PSCSICMD AboIORBhead; +//PSCSICMD AboIORBtail; +//ULONG AboIORBcnt; -/* 0x20: */ +/* 0x08: */ +/* Queued SRBs */ PSRB pWaitingSRB; PSRB pWaitLast; PSRB pGoingSRB; PSRB pGoingLast; PSRB pActiveSRB; +UCHAR WaitSRBCnt; /* Not used */ UCHAR GoingSRBCnt; -UCHAR WaitSRBCnt; /* ??? */ + UCHAR DevType; UCHAR MaxCommand; -/* 0x38: */ +/* 0x20: */ ULONG TagMask; UCHAR UnitSCSIID; /*; SCSI Target ID (SCSI Only) */ @@ -162,16 +162,16 @@ UCHAR CtrlR4; UCHAR pad; -/* 0x44: */ +/* 0x2c: */ UCHAR SyncMode; /*; 0:async mode */ UCHAR NegoPeriod; /*;for nego. */ UCHAR SyncPeriod; /*;for reg. */ UCHAR SyncOffset; /*;for reg. and nego.(low nibble) */ -/* 0x48:*/ +/* 0x30:*/ //UCHAR InqDataBuf[8]; //UCHAR CapacityBuf[8]; -/* 0x58: */ +/* 0x40: */ }; typedef struct _DCB DC390_DCB, *PDCB; @@ -208,13 +208,17 @@ PSRB pTmpSRB; /* 0x2c: */ +ULONG QueryCnt; +PSCSICMD pQueryHead; +PSCSICMD pQueryTail; +/* 0x38: */ UCHAR msgin123[4]; UCHAR DCBmap[MAX_SCSI_ID]; UCHAR Connected; UCHAR pad; -/* 0x30: */ +/* 0x3c: */ #if defined(USE_SPINLOCKS) && USE_SPINLOCKS > 1 && (defined(__SMP__) || DEBUG_SPINLOCKS > 0) spinlock_t lock; #endif @@ -225,18 +229,18 @@ UCHAR Ignore_IRQ; /* Not used */ PDEVDECL1; /* Pointer to PCI cfg. space */ -/* 0x40/0x3c: */ +/* 0x4c/0x48: */ ULONG Cmds; ULONG CmdInQ; ULONG CmdOutOfSRB; ULONG SelLost; -/* 0x50/0x4c: */ +/* 0x5c/0x58: */ DC390_SRB TmpSRB; -/* 0xb4/0xb0: */ -DC390_SRB SRB_array[MAX_SRB_CNT]; /* 18 SRBs */ -/* 0x7bc/0x7b8: */ +/* 0xc0/0xbc: */ +DC390_SRB SRB_array[MAX_SRB_CNT]; /* 50 SRBs */ +/* 0xf98/0xf94: */ }; typedef struct _ACB DC390_ACB, *PACB;