Index: dc390/README.tmscsim =================================================================== RCS file: /usr/local/cvsroot/dc390/README.tmscsim,v retrieving revision 2.9 retrieving revision 2.11 diff -u -r2.9 -r2.11 --- README.tmscsim 1998/12/25 18:04:20 2.9 +++ README.tmscsim 1999/02/20 18:47:16 2.11 @@ -9,6 +9,7 @@ 6. Potential improvements 7. Bug reports, debugging and updates 8. Acknowledgements +9. Copyright 1. Purpose and history @@ -140,10 +141,10 @@ Here's an example: garloff@kg1:/home/garloff > cat /proc/scsi/tmscsim/0 -Tekram DC390/AM53C974 PCI SCSI Host Adapter, Driver Version 1.20s, 1998/08/20 +Tekram DC390/AM53C974 PCI SCSI Host Adapter, Driver Version 2.0d2, 1999/02/20 SCSI Host Nr 0, AM53C974 Adapter Nr 0 IOPortBase 0x6200, IRQLevel 0x09 -MaxID 7, MaxLUN 8, AdapterID 7, SelTimeout 250 ms +MaxID 7, MaxLUN 8, AdapterID 7, SelTimeout 250 ms, DelayReset 1 s TagMaxNum 16, Status 0, ACBFlag 0, GlitchEater 24 ns Statistics: Nr of Cmnds 39563, Cmnds not sent directly 0, Out of SRB conds 0 Nr of lost arbitrations 17 @@ -196,8 +197,8 @@ echo "MaxLUN=8 seltimeout 200" >/proc/scsi/tmscsim/0 Note that you can only change MaxID, MaxLUN, AdapterID, SelTimeOut, - TagMaxNum, ACBFlag and GlitchEater. Don't change ACBFlag unless you - want to see what happens, if the driver hangs. + TagMaxNum, ACBFlag, GlitchEater and DelayReset. Don't change ACBFlag + unless you want to see what happens, if the driver hangs. (2) Change device settings: You write a config line to the driver. The Nr must match the ID and LUN given. If you give "-" as parameter, it is @@ -207,8 +208,8 @@ an INQUIRY on the device if necessary to check if it is capable to operate with the given settings (Sync, TagQ). Examples: - echo "0 0 0 y y y - y - 10" >/proc/scsi/tmscsim/0 - echo "3 5 0 y n y" >/proc/scsi/tmscsim/0 + echo "0 0 0 y y y - y - - 10 " >/proc/scsi/tmscsim/0 + echo "3 5 0 y n y " >/proc/scsi/tmscsim/0 To give a short explanation of the first example: The first three numbers, "0 0 0" (Device index 0, SCSI ID 0, SCSI LUN 0), @@ -269,7 +270,7 @@ DC390 EEPROM, the settings are given in a DC390 BIOS' way. Here's the syntax: -tmscsim=AdaptID,SpdIdx,DevMode,AdaptMode,TaggedCmnds +tmscsim=AdaptID,SpdIdx,DevMode,AdaptMode,TaggedCmnds,DelayReset Each of the parameters is a number, containing the described information: @@ -315,6 +316,8 @@ *3 16 4 32 +* DelayReset is the time in seconds, the adapter waits, after a bus reset. + Example: modprobe tmscsim tmscsim=6,2,31 would set the adapter ID to 6, max. speed to 6.7 MHz, enable all device @@ -323,10 +326,10 @@ As you can see, you don't need to specify all of the five params. -The defaults (7,1,31,15,3) are aggressive to allow good performance. You can -use tmscsim=7,0,31,63,4 for maximum performance, if your SCSI chain is +The defaults (7,1,31,15,3,1) are aggressive to allow good performance. You can +use tmscsim=7,0,31,63,4,0 for maximum performance, if your SCSI chain is perfect. If you meet problems, you can use tmscsim=-1 which is a shortcut -for tmscsim=7,4,9,15,2. +for tmscsim=7,4,9,15,2,10. 6. Potential improvements @@ -409,10 +412,19 @@ Thanks to Doug Ledford, Gerard Roudier for support with SCSI coding. Thanks to a lot of people (espec. Chiaki Ishikawa, Andreas Haumer, Hubert Tonneau) for intensively testing the driver (and even risking data loss -doing this during early revisions). +doing this during early revisions). + +9. Copyright +------------ + This driver is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + If you want to use any later version of the GNU GPL, you will probably + be allowed to, but you have to ask me and Tekram + before. ------------------------------------------------------------------------- Written by Kurt Garloff 1998/06/11 -Last updated 1998/12/25, driver revision 2.0d -$Id: README.tmscsim,v 2.9 1998/12/25 18:04:20 garloff Exp $ +Last updated 1999/02/20, driver revision 2.0d2 +$Id: README.tmscsim,v 2.11 1999/02/20 18:47:16 garloff Exp $ Index: dc390/dc390.h =================================================================== RCS file: /usr/local/cvsroot/dc390/dc390.h,v retrieving revision 2.12 retrieving revision 2.14 diff -u -r2.12 -r2.14 --- dc390.h 1998/12/25 17:33:27 2.12 +++ dc390.h 1999/02/20 18:47:16 2.14 @@ -4,7 +4,7 @@ * Description: Device Driver for Tekram DC-390(T) PCI SCSI * * Bus Master Host Adapter * ***********************************************************************/ -/* $Id: dc390.h,v 2.12 1998/12/25 17:33:27 garloff Exp $ */ +/* $Id: dc390.h,v 2.14 1999/02/20 18:47:16 garloff Exp $ */ #include @@ -16,11 +16,9 @@ #define DC390_H #define DC390_BANNER "Tekram DC390/AM53C974" -#define DC390_VERSION "2.0d 1998/12/25" +#define DC390_VERSION "2.0d2 1999/02/20" #if defined(HOSTS_C) || defined(MODULE) - -#include extern int DC390_detect(Scsi_Host_Template *psht); extern int DC390_queue_command(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *)); Index: dc390/scsiiom.c =================================================================== RCS file: /usr/local/cvsroot/dc390/scsiiom.c,v retrieving revision 2.15 retrieving revision 2.21 diff -u -r2.15 -r2.21 --- scsiiom.c 1998/12/25 17:33:27 2.15 +++ scsiiom.c 1999/02/20 22:34:29 2.21 @@ -4,7 +4,7 @@ * Description: Device Driver for Tekram DC-390 (T) PCI SCSI * * Bus Master Host Adapter * ***********************************************************************/ -/* $Id: scsiiom.c,v 2.15 1998/12/25 17:33:27 garloff Exp $ */ +/* $Id: scsiiom.c,v 2.21 1999/02/20 22:34:29 garloff Exp $ */ UCHAR dc390_StartSCSI( PACB pACB, PDCB pDCB, PSRB pSRB ) @@ -739,6 +739,56 @@ }; +/* handle RESTORE_PTR */ +static void +dc390_restore_ptr (PACB pACB, PSRB pSRB) +{ + PSGL psgl; + pSRB->TotalXferredLen = 0; + pSRB->SGIndex = 0; + if( pSRB->pcmd->use_sg ) + { + pSRB->SGcount = (UCHAR) pSRB->pcmd->use_sg; + pSRB->pSegmentList = (PSGL) pSRB->pcmd->request_buffer; + psgl = pSRB->pSegmentList; + while (pSRB->TotalXferredLen + (ULONG) psgl->length < pSRB->Saved_Ptr) + { + pSRB->TotalXferredLen += (ULONG) psgl->length; + pSRB->SGIndex++; + if( pSRB->SGIndex < pSRB->SGcount ) + { + pSRB->pSegmentList++; + psgl = pSRB->pSegmentList; + + pSRB->SGBusAddr = virt_to_bus( psgl->address ); + pSRB->SGToBeXferLen = (ULONG) psgl->length; + } + else + pSRB->SGToBeXferLen = 0; + } + pSRB->SGToBeXferLen -= (pSRB->Saved_Ptr - pSRB->TotalXferredLen); + pSRB->SGBusAddr += (pSRB->Saved_Ptr - pSRB->TotalXferredLen); + printk (KERN_INFO "DC390: Pointer restored. Segment %i, Total %li, Bus %08lx\n", pSRB->SGIndex, pSRB->Saved_Ptr, pSRB->SGBusAddr); + } + else if( pSRB->pcmd->request_buffer ) + { + pSRB->SGcount = 1; + pSRB->pSegmentList = (PSGL) &pSRB->Segmentx; + pSRB->Segmentx.address = (PUCHAR) pSRB->pcmd->request_buffer + pSRB->Saved_Ptr; + pSRB->Segmentx.length = pSRB->pcmd->request_bufflen - pSRB->Saved_Ptr; + printk (KERN_INFO "DC390: Pointer restored. Total %li, Bus %p\n", + pSRB->Saved_Ptr, pSRB->Segmentx.address); + } + else + { + pSRB->SGcount = 0; + printk (KERN_INFO "DC390: RESTORE_PTR message for Transfer without Scatter-Gather ??\n"); + }; + + pSRB->TotalXferredLen = pSRB->Saved_Ptr; +}; + + /* According to the docs, the AM53C974 reads the message and * generates a Succesful Operation IRQ before asserting ACK for * the last byte (how does it know whether it's the last ?) */ @@ -812,13 +862,16 @@ // nothing has to be done case MSG_COMPLETE: break; - // SAVE POINTER my be ignored as we have the PSRB associated with the + // SAVE POINTER may be ignored as we have the PSRB associated with the // scsi command. Thanks, Gerard, for pointing it out. - case MSG_SAVE_PTR: break; + case MSG_SAVE_PTR: + pSRB->Saved_Ptr = pSRB->TotalXferredLen; + break; // The device might want to restart transfer with a RESTORE - case MSG_RESTORE_PTR: - printk ("DC390: RESTORE POINTER message received ... reject\n"); - // fall through + case MSG_RESTORE_PTR: + DEBUG0(printk ("DC390: RESTORE POINTER message received ... try to handle\n");) + dc390_restore_ptr (pACB, pSRB); + break; // reject unknown messages default: dc390_MsgIn_reject (pACB, pSRB); @@ -1648,9 +1701,10 @@ //DEBUG0(printk(KERN_INFO "RST_DETECT,");) DC390_write8 (DMA_Cmd, DMA_IDLE_CMD); + pACB->pScsiHost->last_reset = jiffies; /* Unlock before ? */ /* delay a second */ - { unsigned int msec = 1*1000; while (--msec) udelay(1000); } + { unsigned int msec = 500; while (--msec) udelay(1000); } DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD); if( pACB->ACBFlag & RESET_DEV ) Index: dc390/tmscsim.c =================================================================== RCS file: /usr/local/cvsroot/dc390/tmscsim.c,v retrieving revision 2.16 retrieving revision 2.20 diff -u -r2.16 -r2.20 --- tmscsim.c 1998/12/25 17:54:44 2.16 +++ tmscsim.c 1999/02/20 19:04:01 2.20 @@ -5,9 +5,9 @@ * Bus Master Host Adapter * * (C)Copyright 1995-1996 Tekram Technology Co., Ltd. * ***********************************************************************/ -/* (C) Copyright: put under GNU GPL in 10/96 * +/* (C) Copyright: put under GNU GPL in 10/96 (see README.tmscsim) * *************************************************************************/ -/* $Id: tmscsim.c,v 2.16 1998/12/25 17:54:44 garloff Exp $ */ +/* $Id: tmscsim.c,v 2.20 1999/02/20 19:04:01 garloff Exp $ */ /* Enhancements and bugfixes by * * Kurt Garloff * ***********************************************************************/ @@ -95,8 +95,11 @@ * 2.0c 98/11/19 KG Cleaned up detect/init for SMP boxes, * * Write Erase DMA (1.20t) caused problems * * 2.0d 98/12/25 KG Christmas release ;-) Message handling * - * competely reworked. Handle target ini- * + * completely reworked. Handle target ini- * * tiated SDTR correctly. * + * 2.0d1 99/01/25 KG Try to handle RESTORE_PTR * + * 2.0d2 99/02/08 KG Check for failure of kmalloc, correct * + * inclusion of scsicam.h, DelayReset * ***********************************************************************/ /* Uncomment SA_INTERRUPT, if the driver refuses to share its IRQ with other devices */ @@ -165,6 +168,7 @@ #include "constants.h" #include "sd.h" #include +#include #include "dc390.h" @@ -407,11 +411,11 @@ # ifdef CONFIG_SCSI_MULTI_LUN | LUN_CHECK # endif - , 3 /* 16 Tags per LUN */}; + , 3 /* 16 Tags per LUN */, 1 /* s delay after Reset */ }; # if defined(MODULE) && LINUX_VERSION_CODE >= LinuxVersionCode(2,1,30) -MODULE_PARM(tmscsim, "1-5i"); -MODULE_PARM_DESC(tmscsim, "Host SCSI ID, Speed (0=10MHz), Device Flags, Adapter Flags, Max Tags (log2(tags)-1)"); +MODULE_PARM(tmscsim, "1-6i"); +MODULE_PARM_DESC(tmscsim, "Host SCSI ID, Speed (0=10MHz), Device Flags, Adapter Flags, Max Tags (log2(tags)-1), DelayReset (s)"); # endif #endif /* CONFIG_SCSI_DC390T_NOGENSUPP */ @@ -518,29 +522,29 @@ ptr = (PUCHAR) dc390_eepromBuf[index]; /* Adapter Settings */ - ptr[EE_ADAPT_SCSI_ID] = (UCHAR)tmscsim[0]; /* Adapter ID */ + ptr[EE_ADAPT_SCSI_ID] = (UCHAR)tmscsim[0]; /* Adapter ID */ ptr[EE_MODE2] = (UCHAR)tmscsim[3]; - ptr[EE_DELAY] = 0; /* ?? */ - ptr[EE_TAG_CMD_NUM] = (UCHAR)tmscsim[4]; /* Tagged Comds */ + ptr[EE_DELAY] = tmscsim[5]; /* Reset delay */ + ptr[EE_TAG_CMD_NUM] = (UCHAR)tmscsim[4]; /* Tagged Cmds */ /* Device Settings */ for (id = 0; id < MAX_SCSI_ID; id++) { - ptr[id<<2] = (UCHAR)tmscsim[2]; /* EE_MODE1 */ - ptr[(id<<2) + 1] = (UCHAR)tmscsim[1]; /* EE_Speed */ + ptr[id<<2] = (UCHAR)tmscsim[2]; /* EE_MODE1 */ + ptr[(id<<2) + 1] = (UCHAR)tmscsim[1]; /* EE_Speed */ }; dc390_adapname = "AM53C974"; } static void __init dc390_checkparams (void) { - PARSEDEBUG(printk(KERN_INFO "DC390: setup %08x %08x %08x %08x %08x\n", tmscsim[0],\ - tmscsim[1], tmscsim[2], tmscsim[3], tmscsim[4]);) + PARSEDEBUG(printk(KERN_INFO "DC390: setup %08x %08x %08x %08x %08x %08x\n", tmscsim[0],\ + tmscsim[1], tmscsim[2], tmscsim[3], tmscsim[4], tmscsim[5]);) if (tmscsim[0] < 0 || tmscsim[0] > 7) /* modules-2.0.0 passes -1 as string */ { tmscsim[0] = 7; tmscsim[1] = 4; tmscsim[2] = 9; tmscsim[3] = 15; - tmscsim[4] = 2; + tmscsim[4] = 2; tmscsim[5] = 10; printk (KERN_INFO "DC390: Using safe settings.\n"); } else @@ -548,6 +552,7 @@ /* if (tmscsim[0] < 0 || tmscsim[0] > 7) tmscsim[0] = 7; */ if (tmscsim[1] < 0 || tmscsim[1] > 7) tmscsim[1] = 4; if (tmscsim[4] < 0 || tmscsim[4] > 5) tmscsim[4] = 4; + if (tmscsim[5] > 180) tmscsim[5] = 180; }; }; /* Override defaults on cmdline: @@ -555,11 +560,14 @@ */ void __init dc390_setup (char *str, int *ints) { - int i; - for (i = 0; i < ints[0]; i++) - tmscsim[i] = ints[i+1]; - if (ints[0] > 5) + int i, im = ints[0]; + if (im > 6) + { printk (KERN_NOTICE "DC390: ignore extra params!\n"); + im = 6; + }; + for (i = 0; i < im; i++) + tmscsim[i] = ints[i+1]; /* dc390_checkparams (); */ }; #endif /* CONFIG_SCSI_DC390T_NOGENSUPP */ @@ -651,6 +659,12 @@ } +static void __init dc390_interpret_delay (UCHAR index) +{ + char interpd [] = {1,2,5,10,15,30,60,120}; + dc390_eepromBuf[index][EE_DELAY] = interpd [dc390_eepromBuf[index][EE_DELAY]]; +}; + static UCHAR __init dc390_CheckEEpromCheckSum( PDEVDECL, UCHAR index ) { UCHAR i; @@ -661,6 +675,8 @@ memcpy (dc390_eepromBuf[index], EEbuf, EE_ADAPT_SCSI_ID); memcpy (&dc390_eepromBuf[index][EE_ADAPT_SCSI_ID], &EEbuf[REAL_EE_ADAPT_SCSI_ID], EE_LEN - EE_ADAPT_SCSI_ID); + dc390_interpret_delay (index); + wval = 0; for(i=0; i<0x40; i++, ptr++) wval += *ptr; @@ -1525,8 +1541,9 @@ DC390_write8 (CtrlReg1, bval); /* disable interrupt */ dc390_ResetSCSIBus( pACB ); + pACB->pScsiHost->last_reset = jiffies; /* Unlock ? */ - for( i=0; i<600; i++ ) + for( i=0; i<(500 + 1000*dc390_eepromBuf[pACB->AdapterIndex][EE_DELAY]); i++ ) udelay(1000); DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD); @@ -1831,8 +1848,9 @@ if (pACB->Gmode2 & RST_SCSI_BUS) { dc390_ResetSCSIBus( pACB ); + pACB->pScsiHost->last_reset = jiffies; /* Unlock before ? */ - for( i=0; i<600; i++ ) + for( i=0; i<(500 + 1000*dc390_eepromBuf[pACB->AdapterIndex][EE_DELAY]); i++ ) udelay(1000); }; pACB->ACBFlag = 0; @@ -1890,9 +1908,9 @@ dc390_checkparams (); period = dc390_clock_period1[tmscsim[1]]; printk (KERN_INFO "DC390: Used defaults: AdaptID=%i, SpeedIdx=%i (%i.%i MHz)," - " DevMode=0x%02x, AdaptMode=0x%02x, TaggedCmnds=%i (%i)\n", tmscsim[0], tmscsim[1], - 40 / period, ((40%period)*10 + period/2) / period, - (UCHAR)tmscsim[2], (UCHAR)tmscsim[3], tmscsim[4], 2 << (tmscsim[4])); + " DevMode=0x%02x, AdaptMode=0x%02x, TaggedCmnds=%i (%i), DelayReset=%is\n", + tmscsim[0], tmscsim[1], 40 / period, ((40%period)*10 + period/2) / period, + (UCHAR)tmscsim[2], (UCHAR)tmscsim[3], tmscsim[4], 2 << (tmscsim[4]), tmscsim[5]); dc390_EEpromDefaults (index); #endif }; @@ -2064,7 +2082,9 @@ char* buffer; Scsi_Cmnd* cmd; buffer = kmalloc (256, GFP_ATOMIC); + if (!buffer) { printk ("DC390: kmalloc (buffer) failed!\n"); return; }; cmd = kmalloc (sizeof (Scsi_Cmnd), GFP_ATOMIC); + if (!cmd) { printk ("DC390: kmalloc (cmd) failed!\n"); kfree (buffer); return; }; memset (buffer, 0, 256); memset (cmd, 0, sizeof(Scsi_Cmnd)); @@ -2314,6 +2334,7 @@ SEARCH (pos, p0, pACB->ACBFlag, "ACBFLAG", 255); SEARCH3 (pos, p0, dum, "GLITCHEATER", 40, 1000, "NS"); SEARCH3 (pos, p0, pACB->sel_timeout, "SELTIMEOUT", 400, 163, "MS"); + SEARCH3 (pos, p0, dc390_eepromBuf[pACB->AdapterIndex][EE_DELAY], "DELAYRESET", 180, 100, "S"); ok2: pACB->glitch_cfg = NS_TO_GLITCH (dum); if (pACB->sel_timeout < 60) pACB->sel_timeout = 60; @@ -2456,8 +2477,9 @@ SPRINTF("IRQLevel 0x%02x\n", pACB->IRQLevel); SPRINTF("MaxID %i, MaxLUN %i, ", shpnt->max_id, shpnt->max_lun); - SPRINTF("AdapterID %i, SelTimeout %i ms\n", - shpnt->this_id, (pACB->sel_timeout*164)/100); + SPRINTF("AdapterID %i, SelTimeout %i ms, DelayReset %i s\n", + shpnt->this_id, (pACB->sel_timeout*164)/100, + dc390_eepromBuf[pACB->AdapterIndex][EE_DELAY]); SPRINTF("TagMaxNum %i, Status %i, ACBFlag %i, GlitchEater %i ns\n", pACB->TagMaxNum, pACB->status, pACB->ACBFlag, GLITCH_TO_NS(pACB->glitch_cfg)*12); Index: dc390/tmscsim.h =================================================================== RCS file: /usr/local/cvsroot/dc390/tmscsim.h,v retrieving revision 2.4 retrieving revision 2.5 diff -u -r2.4 -r2.5 --- tmscsim.h 1998/12/25 17:33:27 2.4 +++ tmscsim.h 1999/01/25 11:57:30 2.5 @@ -3,7 +3,7 @@ ;* TEKRAM DC-390(T) PCI SCSI Bus Master Host Adapter * ;* Device Driver * ;***********************************************************************/ -/* $Id: tmscsim.h,v 2.4 1998/12/25 17:33:27 garloff Exp $ */ +/* $Id: tmscsim.h,v 2.5 1999/01/25 11:57:30 garloff Exp $ */ #ifndef _TMSCSIM_H #define _TMSCSIM_H @@ -112,8 +112,8 @@ UCHAR SGIndex; UCHAR SRBStatus; //UCHAR IORBFlag; /*;81h-Reset, 2-retry */ - /* 0x60: */ +ULONG Saved_Ptr; };