Index: README.dc395x =================================================================== RCS file: /home/cvsroot/dc395/README.dc395x,v retrieving revision 1.5 retrieving revision 1.6 diff -u -u -r1.5 -r1.6 --- README.dc395x 2000/02/13 16:52:55 1.5 +++ README.dc395x 2000/02/14 11:08:31 1.6 @@ -1,19 +1,20 @@ README file for the dc395x_trm SCSI driver ========================================== -Preliminary. 2000-02-10 Kurt Garloff -$Id: README.dc395x,v 1.5 2000/02/13 16:52:55 garloff Exp $ +Preliminary. 2000-02-14 Kurt Garloff +$Id: README.dc395x,v 1.6 2000/02/14 11:08:31 garloff Exp $ -This driver is similar to the dc390/AM53c974 driver (tmscsim), so you might +This driver is similar to the DC390/AM53c974 driver (tmscsim), so you might want to have a look into the README.tmscsim. The tmscsim has undergone a lot of development since the 1.10 version, most notably the configuration via parameters and /proc/scsi/tmscsim/?. -These features are now almost completely implemented for the dc395x_trm driver, -too. The kernel/module params are still missing, though. -Currently, you have to change the BIOS' settings, if you need to change the -driver's settings right from the start. (Later, you can do with the -/proc/scsi/dc395x_trm interface.) +These features are now almost completely implemented for the dc395x_trm +driver, too. +The kernel/module params have now also been added. The meaning is exactly +the same than the ones from the tmscsim driver, except, that the SpdIdx is +now interpreted as 20Mhz, 13.3MHz, 10MHz, 8MHz, 6.7MHz, 5.8Mhz, 5Mhz, 4Mhz +and that the bit5 (0x20) was added to the DevMode meaning Wide negotiation. Status ------ @@ -102,6 +103,7 @@ to change the settings again. You may choose to disable disconnections instead of lowering the speed of sync transfers.) + Usage ----- I would currently not suggest to use this driver, if you are dealing with @@ -127,6 +129,57 @@ If you can provide me with exact observations and logs, I would be very pleased! + + +Installation +------------ +As long as this driver is not yet integrated into the mainstream kernel, you +have to do some handwork to install the driver. +IF YOU NEVER COMPILED A KERNEL YOURSELF BEFORE, YOU SHOULD NOW BETTER GO AND +READ SOME DOCUMENTATION ABOUT IT. YOU ARE LIKELY TO SCREW YOURSELF, OTHERWISE. +Maybe you Linux distributor will be nice enough to include the driver in its +distribution, so you don't have to do it yourself. + +OK, if you want to do it: Get the driver distribution dc395-12?.tar.gz. +Unpack it: +> tar xvzf dc395-12?.tar.gz +Copy the driver files to the linux source tree: +> cp -p dc395/dc395x_trm.? /usr/src/linux/drivers/scsi/ +> cp -p dc395/README.dc395x /usr/src/linux/drivers/scsi/ +and apply the appropriate patch to your kernel source tree. Depending on +your kernel version, this is dc395-integ20.diff, dc395-integ22.diff or +dc395-integ23.diff. (Replace XX by 20, 22, or 23) +> cd /usr/src/ +> patch -p0 -d /usr/src cd /usr/src/linux +> make oldconfig (enable CONFIG_SCSI_DC395x_TRMS1040) +> make bzlilo +> make modules +> make modules_install +> depmod -ae + +I will provide a complete patch which makes kernel integration easier and +will ask to apply it to the main tree, as soon as I got enough reports about +the stability of the driver. + + +Copyright +--------- +The driver is free software. It is protected by the GNU General Public +License (GPL). Please read it, before using this driver. It should be +included in your kernel sources and with your distribution. It carries the +filename COPYING. If you don't have it, please ask me to send you one by +email. +Note: The GNU GPL says also something about warranty and liability. +Please be aware the following: While I do my best to provide a working and +reliable driver, there is a chance, that it will kill your valuable data. +I refuse to take any responsibility for that. The driver is provided as-is +and YOU USE IT AT YOUR OWN RESPONSIBILITY. Updates Index: dc395-integ.diff =================================================================== RCS file: dc395-integ.diff diff -N dc395-integ.diff --- /tmp/cvsFC9oVl Mon Feb 14 22:23:46 2000 +++ /dev/null Sun Oct 3 02:13:27 1999 @@ -1,99 +0,0 @@ ---- linux/drivers/scsi/Config.in.ORIG Wed Jun 16 23:32:33 1999 -+++ linux/drivers/scsi/Config.in Mon Jun 28 21:55:47 1999 -@@ -126,6 +126,9 @@ - fi - dep_tristate 'Seagate ST-02 and Future Domain TMC-8xx SCSI support' CONFIG_SCSI_SEAGATE $CONFIG_SCSI - if [ "$CONFIG_PCI" = "y" ]; then -+ if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then -+ dep_tristate 'Tekram DC395/U/UW and DC315/U SCSI support' CONFIG_SCSI_DC395x_TRMS1040 $CONFIG_SCSI -+ fi - dep_tristate 'Tekram DC390(T) and Am53/79C974 SCSI support' CONFIG_SCSI_DC390T $CONFIG_SCSI - if [ "$CONFIG_SCSI_DC390T" != "n" ]; then - bool ' _omit_ support for non-DC390 adapters' CONFIG_SCSI_DC390T_NOGENSUPP ---- linux/drivers/scsi/Makefile.ORIG Wed Jun 16 23:32:19 1999 -+++ linux/drivers/scsi/Makefile Mon Jun 28 21:53:11 1999 -@@ -346,6 +346,14 @@ - endif - endif - -+ifeq ($(CONFIG_SCSI_DC395x_TRMS1040),y) -+L_OBJS += dc395x_trm.o -+else -+ ifeq ($(CONFIG_SCSI_DC395x_TRMS1040),m) -+ M_OBJS += dc395x_trm.o -+ endif -+endif -+ - ifeq ($(CONFIG_SCSI_DC390T),y) - L_OBJS += tmscsim.o - else ---- linux/drivers/scsi/hosts.c.ORIG Wed Jun 16 23:46:03 1999 -+++ linux/drivers/scsi/hosts.c Mon Jun 28 21:58:44 1999 -@@ -231,6 +231,10 @@ - #include "sym53c416.h" - #endif - -+#ifdef CONFIG_SCSI_DC395x_TRMS1040 -+#include "dc395x_trm.h" -+#endif -+ - #ifdef CONFIG_SCSI_DC390T - #include "dc390.h" - #endif -@@ -529,6 +533,9 @@ - #endif - #ifdef CONFIG_SCSI_EATA - EATA, -+#endif -+#ifdef CONFIG_SCSI_DC395x_TRMS1040 -+ DC395x_TRMS1040, - #endif - #ifdef CONFIG_SCSI_DC390T - DC390_T, ---- linux/include/linux/proc_fs.h.ORIG Mon Jun 28 18:38:28 1999 -+++ linux/include/linux/proc_fs.h Mon Jun 28 22:03:51 1999 -@@ -183,6 +183,7 @@ - PROC_SCSI_IBMMCA, - PROC_SCSI_FD_MCS, - PROC_SCSI_EATA2X, -+ PROC_SCSI_DC395X_TRMS1040, - PROC_SCSI_DC390T, - PROC_SCSI_AM53C974, - PROC_SCSI_SSC, ---- linux/Documentation/Configure.help.ORIG Mon Jun 28 18:11:35 1999 -+++ linux/Documentation/Configure.help Mon Jun 28 22:10:44 1999 -@@ -4673,6 +4673,18 @@ - read Documentation/modules.txt. The module will be called - sym53c416.o. - -+Tekram DC395/U/UW and DC315/U SCSI support -+CONFIG_SCSI_DC395x_TRMS1040 -+ This driver supports the PCI SCSI host adapters baseds on Tekramīs -+ ASIC TRM-S1040 chip, i.e. Tekram DC315 and DC395 variants. -+ This driver does work, but please note that it is still alpha status, -+ so better have a bootable disk and a backup in case of emergency. -+ -+ If you want to compile this driver as a module ( = code which can be -+ inserted in and removed from the running kernel whenever you want), -+ say M here and read Documentation/modules.txt. The module will be -+ called dc395x_trm.o. -+ - Tekram DC390(T) and Am53/79C974 (PCscsi) SCSI support - CONFIG_SCSI_DC390T - This driver supports PCI SCSI host adapters based on the Am53C974A ---- linux/MAINTAINERS.ORIG Sun Jul 4 23:11:46 1999 -+++ linux/MAINTAINERS Mon Jul 12 17:00:23 1999 -@@ -212,10 +212,11 @@ - L: linux-hams@vger.rutgers.edu - S: Maintained - --DC390/AM53C974 SCSI driver -+DC390/AM53C974 and DC395/TRM-S1040 SCSI drivers - P: Kurt Garloff -+M: garloff@suse.de - M: kurt@garloff.de --W: http://www.garloff.de/kurt/linux/dc390/ -+W: http://www.garloff.de/kurt/linux/ - S: Maintained - - DECnet NETWORK LAYER Index: dc395-integ20.diff =================================================================== RCS file: /home/cvsroot/dc395/dc395-integ20.diff,v retrieving revision 1.3 retrieving revision 1.4 diff -u -u -r1.3 -r1.4 --- dc395-integ20.diff 2000/01/31 21:38:01 1.3 +++ dc395-integ20.diff 2000/02/14 11:08:32 1.4 @@ -107,3 +107,23 @@ S: Maintained EATA ISA/EISA/PCI SCSI DRIVER +--- linux/init/main.c.nodc395 Mon Dec 13 01:29:36 1999 ++++ linux/init/main.c Mon Feb 14 11:12:23 2000 +@@ -200,6 +200,7 @@ + extern void sym53c416_setup(char *str, int *ints); + extern void wd7000_setup(char *str, int *ints); + extern void dc390_setup(char* str, int *ints); ++extern void DC395x_trm_setup(char* str, int *ints); + extern void scsi_luns_setup(char *str, int *ints); + extern void scsi_logging_setup(char *str, int *ints); + extern void sound_setup(char *str, int *ints); +@@ -765,6 +766,9 @@ + #endif + #if defined(CONFIG_SCSI_DC390T) && ! defined(CONFIG_SCSI_DC390T_NOGENSUPP) + { "tmscsim=", dc390_setup }, ++#endif ++#if defined(CONFIG_SCSI_DC395x_TRMS1040) ++ { "dc395x_trm=", DC395x_trm_setup }, + #endif + #ifdef CONFIG_BLK_DEV_XD + { "xd=", xd_setup }, Index: dc395-integ22.diff =================================================================== RCS file: dc395-integ22.diff diff -N dc395-integ22.diff --- /dev/null Sun Oct 3 02:13:27 1999 +++ /tmp/cvsKntycG Mon Feb 14 22:23:46 2000 @@ -0,0 +1,119 @@ +--- linux/drivers/scsi/Config.in.ORIG Wed Jun 16 23:32:33 1999 ++++ linux/drivers/scsi/Config.in Mon Jun 28 21:55:47 1999 +@@ -126,6 +126,9 @@ + fi + dep_tristate 'Seagate ST-02 and Future Domain TMC-8xx SCSI support' CONFIG_SCSI_SEAGATE $CONFIG_SCSI + if [ "$CONFIG_PCI" = "y" ]; then ++ if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then ++ dep_tristate 'Tekram DC395/U/UW and DC315/U SCSI support' CONFIG_SCSI_DC395x_TRMS1040 $CONFIG_SCSI ++ fi + dep_tristate 'Tekram DC390(T) and Am53/79C974 SCSI support' CONFIG_SCSI_DC390T $CONFIG_SCSI + if [ "$CONFIG_SCSI_DC390T" != "n" ]; then + bool ' _omit_ support for non-DC390 adapters' CONFIG_SCSI_DC390T_NOGENSUPP +--- linux/drivers/scsi/Makefile.ORIG Wed Jun 16 23:32:19 1999 ++++ linux/drivers/scsi/Makefile Mon Jun 28 21:53:11 1999 +@@ -346,6 +346,14 @@ + endif + endif + ++ifeq ($(CONFIG_SCSI_DC395x_TRMS1040),y) ++L_OBJS += dc395x_trm.o ++else ++ ifeq ($(CONFIG_SCSI_DC395x_TRMS1040),m) ++ M_OBJS += dc395x_trm.o ++ endif ++endif ++ + ifeq ($(CONFIG_SCSI_DC390T),y) + L_OBJS += tmscsim.o + else +--- linux/drivers/scsi/hosts.c.ORIG Wed Jun 16 23:46:03 1999 ++++ linux/drivers/scsi/hosts.c Mon Jun 28 21:58:44 1999 +@@ -231,6 +231,10 @@ + #include "sym53c416.h" + #endif + ++#ifdef CONFIG_SCSI_DC395x_TRMS1040 ++#include "dc395x_trm.h" ++#endif ++ + #ifdef CONFIG_SCSI_DC390T + #include "dc390.h" + #endif +@@ -529,6 +533,9 @@ + #endif + #ifdef CONFIG_SCSI_EATA + EATA, ++#endif ++#ifdef CONFIG_SCSI_DC395x_TRMS1040 ++ DC395x_TRMS1040, + #endif + #ifdef CONFIG_SCSI_DC390T + DC390_T, +--- linux/include/linux/proc_fs.h.ORIG Mon Jun 28 18:38:28 1999 ++++ linux/include/linux/proc_fs.h Mon Jun 28 22:03:51 1999 +@@ -183,6 +183,7 @@ + PROC_SCSI_IBMMCA, + PROC_SCSI_FD_MCS, + PROC_SCSI_EATA2X, ++ PROC_SCSI_DC395X_TRMS1040, + PROC_SCSI_DC390T, + PROC_SCSI_AM53C974, + PROC_SCSI_SSC, +--- linux/Documentation/Configure.help.ORIG Mon Jun 28 18:11:35 1999 ++++ linux/Documentation/Configure.help Mon Jun 28 22:10:44 1999 +@@ -4673,6 +4673,18 @@ + read Documentation/modules.txt. The module will be called + sym53c416.o. + ++Tekram DC395/U/UW and DC315/U SCSI support ++CONFIG_SCSI_DC395x_TRMS1040 ++ This driver supports the PCI SCSI host adapters baseds on Tekramīs ++ ASIC TRM-S1040 chip, i.e. Tekram DC315 and DC395 variants. ++ This driver does work, but please note that it is still alpha status, ++ so better have a bootable disk and a backup in case of emergency. ++ ++ If you want to compile this driver as a module ( = code which can be ++ inserted in and removed from the running kernel whenever you want), ++ say M here and read Documentation/modules.txt. The module will be ++ called dc395x_trm.o. ++ + Tekram DC390(T) and Am53/79C974 (PCscsi) SCSI support + CONFIG_SCSI_DC390T + This driver supports PCI SCSI host adapters based on the Am53C974A +--- linux/MAINTAINERS.ORIG Sun Jul 4 23:11:46 1999 ++++ linux/MAINTAINERS Mon Jul 12 17:00:23 1999 +@@ -212,10 +212,11 @@ + L: linux-hams@vger.rutgers.edu + S: Maintained + +-DC390/AM53C974 SCSI driver ++DC390/AM53C974 and DC395/TRM-S1040 SCSI drivers + P: Kurt Garloff ++M: garloff@suse.de + M: kurt@garloff.de +-W: http://www.garloff.de/kurt/linux/dc390/ ++W: http://www.garloff.de/kurt/linux/ + S: Maintained + + DECnet NETWORK LAYER +--- linux/init/main.c.nodc395 Mon Dec 13 01:29:36 1999 ++++ linux/init/main.c Mon Feb 14 11:12:23 2000 +@@ -200,6 +200,7 @@ + extern void sym53c416_setup(char *str, int *ints); + extern void wd7000_setup(char *str, int *ints); + extern void dc390_setup(char* str, int *ints); ++extern void DC395x_trm_setup(char* str, int *ints); + extern void scsi_luns_setup(char *str, int *ints); + extern void scsi_logging_setup(char *str, int *ints); + extern void sound_setup(char *str, int *ints); +@@ -765,6 +766,9 @@ + #endif + #if defined(CONFIG_SCSI_DC390T) && ! defined(CONFIG_SCSI_DC390T_NOGENSUPP) + { "tmscsim=", dc390_setup }, ++#endif ++#if defined(CONFIG_SCSI_DC395x_TRMS1040) ++ { "dc395x_trm=", DC395x_trm_setup }, + #endif + #ifdef CONFIG_BLK_DEV_XD + { "xd=", xd_setup }, Index: dc395x_trm.c =================================================================== RCS file: /home/cvsroot/dc395/dc395x_trm.c,v retrieving revision 1.35 retrieving revision 1.36 diff -u -u -r1.35 -r1.36 --- dc395x_trm.c 2000/02/11 18:31:05 1.35 +++ dc395x_trm.c 2000/02/14 11:08:32 1.36 @@ -8,9 +8,11 @@ //* (SCSI chip set used Tekram ASIC TRM-S1040) //* (C)Copyright 1995-1999 Tekram Technology Co., Ltd. //*********************************************************************** -//* Patches and integration into 2.2+ kernel by +//* Lots of bugfixes and integration into 2.2+ kernels by //* Kurt Garloff -//* $Id: dc395x_trm.c,v 1.35 2000/02/11 18:31:05 garloff Exp $ +//* (C) 1999-2000 Kurt Garloff +//* License: GNU GPL +//* $Id: dc395x_trm.c,v 1.36 2000/02/14 11:08:32 garloff Exp $ //*********************************************************************** //* Tekram PCI SCSI adapter (DC395/U/UW/F or DC315/U) revision history //* @@ -56,6 +58,10 @@ //* solution //* 1.23 00/02/11 KG Automatically lower speed etc. in abort //* Remove CmdBlock copy. +//* 1.24 00/02/14 KG Try to really abort in case of bus lock +//* Fix bug wrt to lowering of sync speed +//* Boot params for BIOS-less adapters +//* Respect reset cfg but not on shutdown //*********************************************************************** /* ************************************************************************* @@ -139,7 +145,7 @@ # define TRACEPRINTF(x...) \ do { pSRB->debugpos += sprintf (pSRB->debugtrace+pSRB->debugpos, ## x) - 1; \ if (pSRB->debugpos >= DEBUGTRACEBUFSZ-16) \ - { pSRB->debugtrace[pSRB->debugpos] = 0; pSRB->debugpos = 128; pSRB->debugtrace[pSRB->debugpos++] = '-'; }; \ + { pSRB->debugtrace[pSRB->debugpos] = 0; pSRB->debugpos = DEBUGTRACEBUFSZ/5; pSRB->debugtrace[pSRB->debugpos++] = '-'; }; \ } while (0) # define TRACEOUT(x...) printk (## x) #else @@ -195,15 +201,6 @@ # define NEW_PCI 1 #endif -# if defined(MODULE) && LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,30) -//MODULE_PARM(dc395x_trm, "1-6i"); -//MODULE_PARM_DESC(dc395x_trm, "Host SCSI ID, Speed (0=10MHz), Device Flags, Adapter Flags, Max Tags (log2(tags)-1), DelayReset (s)"); -MODULE_AUTHOR("C.L. Huang / Erich Chen / Kurt Garloff"); -MODULE_DESCRIPTION("PCI SCSI host adapter driver for Tekram TRM-S1040 based adapters: DC395 and DC315 series."); -MODULE_SUPPORTED_DEVICE("sd,sr,sg,st"); -#endif - - #ifdef USE_SPINLOCKS # define DC395x_LOCK_IO spin_lock_irqsave (&io_request_lock, flags) # define DC395x_UNLOCK_IO spin_unlock_irqrestore (&io_request_lock, flags) @@ -435,7 +432,6 @@ */ struct _ACB { - DWORD PhysACB; PSH pScsiHost; struct _ACB *pNextACB; @@ -1202,6 +1198,7 @@ WORD Reserved[22]; /* 82,..125 */ WORD NvramCheckSum; /* 126,127 */ } NVRAMTYPE,*PNVRAMTYPE; +#if 0 /* Nvram Initiater bits definition */ #define MORE2_DRV BIT0 #define GREATER_1G BIT1 @@ -1209,7 +1206,7 @@ #define ACTIVE_NEGATION BIT3 #define NO_SEEK BIT4 #define LUN_CHECK BIT5 - +#endif /* Nvram Adapter Cfg bits definition */ #define NAC_SCANLUN 0x20 /* Include LUN as BIOS device */ #define NAC_POWERON_SCSI_RESET 0x04 /* Power on reset enable */ @@ -1252,6 +1249,7 @@ static void DC395x_Nop0( PACB pACB, PSRB pSRB, PWORD pscsi_status); static void DC395x_Nop1( PACB pACB, PSRB pSRB, PWORD pscsi_status); static void DC395x_basic_config (PACB pACB); +static void DC395x_cleanup_after_transfer (PACB pACB, PSRB pSRB); static void DC395x_ResetSCSIBus( PACB pACB ); int DC395x_initAdapter( PSH psh, DWORD io_port, BYTE Irq, WORD index ); void DC395x_DataIO_transfer( PACB pACB, PSRB pSRB, WORD ioDir); @@ -1343,6 +1341,102 @@ BYTE dc395x_clock_period[] = {12,18,25,31,37,43,50,62}; /* real period:48ns,72ns,100ns,124ns,148ns,172ns,200ns,248ns */ +/* Startup values, to be overriden on the commandline */ +int dc395x_trm[] = {7, 1 /* 13.3MHz */, + NTC_DO_PARITY_CHK | NTC_DO_DISCONNECT | NTC_DO_SYNC_NEGO + | NTC_DO_WIDE_NEGO | NTC_DO_TAG_QUEUEING | NTC_DO_SEND_START, + NAC_GT2DRIVES | NAC_GREATER_1G | NAC_POWERON_SCSI_RESET + /* | NAC_ACTIVE_NEG */ +# ifdef CONFIG_SCSI_MULTI_LUN + | NAC_SCANLUN +# endif + , 3 /* 16 Tags per LUN */, 1 /* s delay after Reset */ }; + +# if defined(MODULE) && LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,30) +MODULE_PARM(dc395x_trm, "1-6i"); +MODULE_PARM_DESC(dc395x_trm, "Host SCSI ID, Speed (0=20MHz), Device Flags, Adapter Flags, Max Tags (log2(tags)-1), DelayReset (s)"); +# endif + +#if defined(MODULE) && LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,30) +MODULE_AUTHOR("C.L. Huang / Erich Chen / Kurt Garloff"); +MODULE_DESCRIPTION("SCSI host adapter driver for Tekram TRM-S1040 based adapters: Tekram DC395 and DC315 series"); +MODULE_SUPPORTED_DEVICE("sd,sr,sg,st"); +#endif + +/* Delaying after a reset */ +static __initdata char DC395x_interpd [] = {1,3,5,10,16,30,60,120}; +static __init void DC395x_interpret_delay (PNVRAMTYPE pEEpromBuf) +{ + //printk ("DC395x: Debug: Delay: %i\n", pEEpromBuf->NvramDelayTime); + pEEpromBuf->NvramDelayTime = DC395x_interpd[pEEpromBuf->NvramDelayTime]; +}; +static __init int DC395x_uninterpret_delay (int delay) +{ + BYTE idx = 0; + while (idx < 7 && DC395x_interpd[idx] < delay) idx++; + return idx; +}; + + +static void __init DC395x_EEpromDefaults (PNVRAMTYPE pEEpromBuf) +{ + BYTE id; + + /* Adapter Settings */ + pEEpromBuf->NvramScsiId = (BYTE)dc395x_trm[0]; /* Adapter ID */ + pEEpromBuf->NvramChannelCfg = (BYTE)dc395x_trm[3]; + pEEpromBuf->NvramDelayTime = DC395x_uninterpret_delay (dc395x_trm[5]); /* Reset delay */ + pEEpromBuf->NvramMaxTag = (BYTE)dc395x_trm[4]; /* Tagged Cmds */ + + /* Device Settings */ + for (id = 0; id < DC395x_MAX_SCSI_ID; id++) + { + pEEpromBuf->NvramTarget[id].NvmTarCfg0 = (BYTE)dc395x_trm[2]; /* Cfg0 */ + pEEpromBuf->NvramTarget[id].NvmTarPeriod= (BYTE)dc395x_trm[1]; /* Speed */ + }; +} + +static void __init DC395x_checkparams (void) +{ + PARSEDEBUG(printk(KERN_INFO "DC395x: setup %08x %08x %08x %08x %08x %08x\n", dc395x_trm[0],\ + dc395x_trm[1], dc395x_trm[2], dc395x_trm[3], dc395x_trm[4], dc395x_trm[5]);) + if (dc395x_trm[0] < 0 || dc395x_trm[0] > 15) /* modules-2.0.0 passes -1 as string */ + { + dc395x_trm[0] = 7; dc395x_trm[1] = 4; + dc395x_trm[2] = 9; dc395x_trm[3] = 15; + dc395x_trm[4] = 2; dc395x_trm[5] = 10; + printk (KERN_INFO "DC395x: Using safe settings.\n"); + } + else + { + /* if (dc395x_trm[0] < 0 || dc395x_trm[0] > 7) dc395x_trm[0] = 7; */ + if (dc395x_trm[1] < 0 || dc395x_trm[1] > 7) dc395x_trm[1] = 4; + if (dc395x_trm[4] < 0 || dc395x_trm[4] > 5) dc395x_trm[4] = 4; + if (dc395x_trm[5] > 180) dc395x_trm[5] = 180; + }; +}; +/* Override defaults on cmdline: + * tmscsim: AdaptID, MaxSpeed (Index), DevMode (Bitmapped), AdaptMode (Bitmapped) + */ +void __init DC395x_trm_setup (char *str, int *ints) +{ + int i, im = ints[0]; + if (im > 6) + { + printk (KERN_NOTICE "DC395x: ignore extra params!\n"); + im = 6; + }; + for (i = 0; i < im; i++) + dc395x_trm[i] = ints[i+1]; + /* DC395x_checkparams (); */ +}; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,13) +#ifndef MODULE +__setup("dc395x_trm=", DC395x_trm_setup); +#endif +#endif + /* Queueing philosphy: * There are a couple of lists: * - Query: Contains the Scsi Commands not yet turned into SRBs (per ACB) @@ -2007,8 +2101,8 @@ struct pci_dev *pdev = pACB->pdev; pci_read_config_word (pdev, PCI_STATUS, &pstat); #else - UCHAR pbus = pACB->pbus; - UCHAR pdevfn = pACB->pdevfn; + BYTE pbus = pACB->pbus; + BYTE pdevfn = pACB->pdevfn; pcibios_read_config_word (pbus, pdevfn, PCISTATUS, &pstat); #endif if (!pDCB) pDCB = pACB->pActiveDCB; @@ -2056,6 +2150,41 @@ } + +static int DC395x_recover (PACB pACB, PDCB pDCB, PSRB pSRB) +{ + int ctr = 4097; + unsigned char lines = DC395x_read8 (TRM_S1040_SCSI_SIGNAL); + DC395x_EnableMsgOut_Abort (pACB, pSRB); + DC395x_cleanup_after_transfer (pACB, pSRB); + if (lines & 1) + { + /* read */ + DC395x_write8 (TRM_S1040_SCSI_CONTROL, DO_HWRESELECT | DO_DATALATCH); + while (--ctr && !(DC395x_read16 (TRM_S1040_SCSI_STATUS) & SCSIINTERRUPT)) + { + int ctr2 = 16; + DC395x_write32 (TRM_S1040_SCSI_COUNTER, ctr2); + DC395x_write8 (TRM_S1040_SCSI_COMMAND, SCMD_FIFO_IN); + while (ctr2--) DC395x_read8 (TRM_S1040_SCSI_FIFO); + } + return ctr; + } + else + { + /* write */ + while (--ctr && !(DC395x_read16 (TRM_S1040_SCSI_STATUS) & SCSIINTERRUPT)) + { + int ctr2 = 16; + DC395x_write32 (TRM_S1040_SCSI_COUNTER, ctr2); + while (ctr2--) DC395x_write8 (TRM_S1040_SCSI_FIFO, 0); + DC395x_write8 (TRM_S1040_SCSI_COMMAND, SCMD_FIFO_OUT); + } + return ctr; + } +} + + /* ********************************************************************** ** @@ -2190,13 +2319,12 @@ //pDCB->DevMode &= ~(NTC_DO_SYNC_NEGO); if (time_before (pDCB->last_derated, pACB->pScsiHost->last_reset)) { - if ((pDCB->DevMode & 7) < 7) + if ((pDCB->SyncPeriod & 7) < 7) { printk ("DC395x: abort: Lower SyncFreq to for dev %02i-%i!\n", pDCB->TargetID, pDCB->TargetLUN); pEEpromBuf->NvramTarget[pDCB->TargetID].NvmTarPeriod - = pEEpromBuf->NvramTarget[pDCB->TargetID].NvmTarPeriod - + pDCB->DevMode + 1; + = pDCB->SyncPeriod + 1; } else if (pDCB->DevMode & NTC_DO_SYNC_NEGO) { @@ -2219,7 +2347,7 @@ else printk ("DC395x: abort: All features already disabled for dev %02i-%i!\n", pDCB->TargetID, pDCB->TargetLUN); pDCB->last_derated = jiffies; - DC395x_updateDCB (pACB, pDCB); + //DC395x_updateDCB (pACB, pDCB); } //DC395x_write8 (TRM_S1040_DMA_STATUS, FORCEDMACOMP); @@ -2233,6 +2361,10 @@ cmd->pid, pSRB); DC395x_dumpinfo (pACB, pDCB, pSRB); //DC395x_EnableMsgOut_Abort (pACB, pSRB); + if (DC395x_recover (pACB, pDCB, pSRB)) { + printk ("DC395x: abort() seemed to be successful!\n"); + status = SCSI_ABORT_SNOOZE; + } goto ABO_X; } else @@ -2385,9 +2517,10 @@ DC395x_write8(TRM_S1040_DMA_CONTROL, DMARESETMODULE); DC395x_ResetSCSIBus( pACB ); - udelay(1000); + udelay(500); /* We may be in serious trouble. Wait some seconds */ - pACB->pScsiHost->last_reset = jiffies + HZ/2 + 5*HZ; + pACB->pScsiHost->last_reset = jiffies + 3*HZ/2 + + HZ * dc395x_trm_eepromBuf[pACB->AdapterIndex].NvramDelayTime; /* ** re-enable interrupt */ @@ -2903,11 +3036,13 @@ if( !(pSRB->SRBState & SRB_MSGOUT) ) { pSRB->SRBState |= SRB_MSGOUT; - printk ("DC395x: Debug: MsgOut Phase unexpected.\n"); /* So what ? */ + printk ("DC395x: Debug: pid %li: MsgOut Phase unexpected.\n", + pSRB->pcmd->pid); /* So what ? */ } if (!pSRB->MsgCnt) { - DEBUG0(printk ("DC395x: NOP Msg (no output message there).\n");) + DEBUG0(printk ("DC395x: Debug: pid %li: NOP Msg (no output message there).\n", + pSRB->pcmd->pid);) DC395x_write8( TRM_S1040_SCSI_FIFO, MSG_NOP); DC395x_write16 (TRM_S1040_SCSI_CONTROL, DO_DATALATCH);/* it's important for atn stop*/ DC395x_write8 (TRM_S1040_SCSI_COMMAND, SCMD_FIFO_OUT); @@ -3084,7 +3219,7 @@ * Should probably also be called from other places * Best might be to call it in DataXXPhase0, if new phase will differ */ -void static DC395x_cleanup_after_transfer (PACB pACB, PSRB pSRB) +static void DC395x_cleanup_after_transfer (PACB pACB, PSRB pSRB) { TRACEPRINTF (" Cln*"); //DC395x_write8 (TRM_S1040_DMA_STATUS, FORCEDMACOMP); @@ -3895,7 +4030,7 @@ pSRB->SGIndex = 0; if( pSRB->pcmd->use_sg ) { - pSRB->SGcount = (UCHAR) pSRB->pcmd->use_sg; + pSRB->SGcount = (BYTE) pSRB->pcmd->use_sg; pSRB->pSegmentList = (PSGL) pSRB->pcmd->request_buffer; psgl = pSRB->pSegmentList; while (pSRB->TotalXferredLen + (ULONG) psgl->length < pSRB->Saved_Ptr) @@ -3921,7 +4056,7 @@ { pSRB->SGcount = 1; pSRB->pSegmentList = (PSGL) &pSRB->Segmentx; - pSRB->Segmentx.address = (PUCHAR) pSRB->pcmd->request_buffer + pSRB->Saved_Ptr; + pSRB->Segmentx.address = (PBYTE) pSRB->pcmd->request_buffer + pSRB->Saved_Ptr; pSRB->Segmentx.length = pSRB->pcmd->request_bufflen - pSRB->Saved_Ptr; printk (KERN_INFO "DC395x: Pointer restored. Total %li, Bus %p\n", pSRB->Saved_Ptr, pSRB->Segmentx.address); @@ -4201,9 +4336,10 @@ if (!pDCB) { printk(KERN_ERR "DC395x: Disc: Exception Disconnect pDCB=NULL !!\n "); - udelay (1000); + udelay (500); // Suspend queue for a while - pACB->pScsiHost->last_reset = jiffies + 3 * HZ; + pACB->pScsiHost->last_reset = jiffies + HZ/2 + + HZ * dc395x_trm_eepromBuf[pACB->AdapterIndex].NvramDelayTime; DC395x_write16(TRM_S1040_SCSI_CONTROL, DO_CLRFIFO | DO_HWRESELECT); return; } @@ -4223,6 +4359,7 @@ { //PSCSICMD pcmd = pSRB->pcmd; pDCB->DCBFlag &= ~ABORT_DEV_; + pACB->pScsiHost->last_reset = jiffies + HZ/2 + 1; printk(KERN_ERR "DC395x: Disc: SRB_ABORT_SENT!\n"); DC395x_DoingSRB_Done (pACB, DID_ABORT); DC395x_Query_to_Waiting (pACB); @@ -4271,7 +4408,7 @@ TRACEPRINTF("+*"); if (bval & 0x40) { - printk ("DC395x: Degug: DISC: SCSI bus stat %02x: ACK set! SYNC trouble?\n", + printk ("DC395x: Debug: DISC: SCSI bus stat %02x: ACK set! SYNC trouble?\n", bval); // It could come from another initiator, therefore don't do much ! TRACEPRINTF("ACK(%02x)!*", bval); @@ -4923,9 +5060,10 @@ DC395x_write8(TRM_S1040_SCSI_CONTROL, DO_RSTMODULE); DC395x_write8(TRM_S1040_DMA_CONTROL, DMARESETMODULE); //DC395x_write8(TRM_S1040_DMA_CONTROL,STOPDMAXFER); - udelay (1000); + udelay (500); // Maybe we locked up the bus? Then lets wait even longer ... - pACB->pScsiHost->last_reset = jiffies + HZ/2 + 6*HZ; + pACB->pScsiHost->last_reset = jiffies + 5*HZ/2 + + HZ * dc395x_trm_eepromBuf[pACB->AdapterIndex].NvramDelayTime; DC395x_write16(TRM_S1040_SCSI_CONTROL, DO_CLRFIFO); DC395x_basic_config (pACB); @@ -5353,11 +5491,12 @@ pACB->Config |= HCC_WIDE_CARD; if (pEEpromBuf->NvramChannelCfg & NAC_POWERON_SCSI_RESET) pACB->Config |= HCC_SCSI_RESET; - if (1 /*pACB->Config & HCC_SCSI_RESET*/) + if (pACB->Config & HCC_SCSI_RESET) DC395x_write8 (TRM_S1040_SCSI_CONTROL, DO_RSTSCSI); //spin_unlock_irq (&io_request_lock); - udelay (1000); - pACB->pScsiHost->last_reset = jiffies + HZ/2 + 3*HZ; + udelay (500); + pACB->pScsiHost->last_reset = jiffies + HZ/2 + + HZ * dc395x_trm_eepromBuf[pACB->AdapterIndex].NvramDelayTime; //spin_lock_irq (&io_request_lock); DC395x_basic_config (pACB); @@ -5630,7 +5769,7 @@ { /* ** Checksum error, load default */ - printk ("DC395x: EEProm ChkSum error: Load defaults!\n"); + printk ("DC395x: EEProm ChkSum error: Use defaults/options!\n"); pEEpromBuf->NvramSubVendorID[0] = (BYTE) PCI_VendorID_TEKRAM; pEEpromBuf->NvramSubVendorID[1] = (BYTE) (PCI_VendorID_TEKRAM >> 8); pEEpromBuf->NvramSubSysID[0] = (BYTE) PCI_DeviceID_TRMS1040; @@ -5650,13 +5789,20 @@ for (dAddr = 0; dAddr < 12; dAddr++, dpEeprom++) *dpEeprom = 0x00; + /* Now load defaults (maybe set by boot/module params) */ + DC395x_checkparams (); + DC395x_EEpromDefaults (pEEpromBuf); + pEEpromBuf->NvramCheckSum = 0x00; for (wAddr = 0, wCheckSum = 0, wpEeprom = (WORD *) pEEpromBuf; wAddr < 63; wAddr++, wpEeprom++) wCheckSum += *wpEeprom; *wpEeprom = 0x1234 - wCheckSum; TRM_S1040_write_all(pEEpromBuf,scsiIOPort); + pEEpromBuf->NvramDelayTime = dc395x_trm[5]; } + else + DC395x_interpret_delay (pEEpromBuf); return; } @@ -6013,7 +6159,7 @@ #ifdef DC395x_DEBUGTRACE PSRB pSRB = pACB->pFreeSRB; #endif - printk (KERN_INFO "DC395x: INQUIRY (%02i-%i) returned %08x: %02x %02x %02x %02x...\n", + printk (KERN_INFO "DC395x: INQUIRY (%02i-%i) returned %08x: %02x %02x %02x %02x ...\n", cmd->target, cmd->lun, cmd->result, ((PBYTE)cmd->request_buffer)[0], ((PBYTE)cmd->request_buffer)[1], ((PBYTE)cmd->request_buffer)[2], ((PBYTE)cmd->request_buffer)[3]); @@ -6318,7 +6464,7 @@ SEARCH (pos, p0, pACB->ACBFlag, "ACBFLAG", 255); SEARCH (pos, p0, filtercfg, "FILTERCFG", 255); SEARCH3 (pos, p0, pACB->sel_timeout, "SELTIMEOUT", 400, 163, "MS"); - //SEARCH3 (pos, p0, dc395x_eepromBuf[pACB->AdapterIndex][EE_DELAY], "DELAYRESET", 180, 100, "S"); + SEARCH3 (pos, p0, dc395x_trm_eepromBuf[pACB->AdapterIndex].NvramDelayTime, "DELAYRESET", 180, 100, "S"); ok2: if (pACB->sel_timeout < 60) pACB->sel_timeout = 60; DC395x_write8 (TRM_S1040_SCSI_TIMEOUT, pACB->sel_timeout); @@ -6512,7 +6658,8 @@ SPRINTF("TagMaxNum %i, Status %i", pACB->TagMaxNum, pACB->status); //SPRINTF(", DMA_Status %i\n", DC395x_read8(TRM_S1040_DMA_STATUS)); - SPRINTF (", FilterCfg 0x%02x\n", DC395x_read8(TRM_S1040_SCSI_CONFIG1)); + SPRINTF (", FilterCfg 0x%02x", DC395x_read8(TRM_S1040_SCSI_CONFIG1)); + SPRINTF (", DelayReset %is\n", dc395x_trm_eepromBuf[pACB->AdapterIndex].NvramDelayTime); //SPRINTF("\n"); SPRINTF("Nr of attached devices: %i, Nr of DCBs: %i\n", pACB->DeviceCnt, pACB->DCBCnt); @@ -6631,7 +6778,7 @@ if (timer_pending (&pACB->Waiting_Timer)) del_timer (&pACB->Waiting_Timer); //if (timer_pending (&pACB->Data_Timer)) del_timer (&pACB->Data_Timer); - if (pACB->Config & HCC_SCSI_RESET) + if (1 || pACB->Config & HCC_SCSI_RESET) DC395x_ResetSCSIBus( pACB ); return( 0 ); Index: dc395x_trm.h =================================================================== RCS file: /home/cvsroot/dc395/dc395x_trm.h,v retrieving revision 1.19 retrieving revision 1.21 diff -u -u -r1.19 -r1.21 --- dc395x_trm.h 2000/02/11 18:31:05 1.19 +++ dc395x_trm.h 2000/02/14 19:58:10 1.21 @@ -8,7 +8,7 @@ ** ********************************************************************** */ -/* $Id: dc395x_trm.h,v 1.19 2000/02/11 18:31:05 garloff Exp $ */ +/* $Id: dc395x_trm.h,v 1.21 2000/02/14 19:58:10 garloff Exp $ */ /* ***************************************************** ** Tekram TRM_S1040 for DC395x driver, header file @@ -18,7 +18,7 @@ #define DC395x_trm_H #define DC395x_BANNER "Tekram DC395U/UW/F DC315/U" -#define DC395x_VERSION "1.23, 2000-02-11" +#define DC395x_VERSION "1.24, 2000-02-14" /* Kernel version autodetection */ #include @@ -50,6 +50,22 @@ #define DC395x_SEL_TIMEOUT 153 /* 250 ms selection timeout (@ 40 MHz) */ #define DC395x_MAX_RETRIES 3 +//#define SYNC_FIRST + +/* We don't have eh_abort_handler, eh_device_reset_handler, + * eh_bus_reset_handler, eh_host_reset_handler yet! + * So long: Use old exception handling :-( */ +#define OLD_EH + +#if (LINUX_VERSION_CODE < KERNEL_VERSION (2,1,70)) || defined(OLD_EH) +# define NEW_EH +# define NORM_REC_LVL 1 +#else +# define USE_NEW_EH +# define NORM_REC_LVL 0 +# define NEW_EH use_new_eh_code: 1, +#endif + #if defined(HOSTS_C) || defined(MODULE) # include @@ -71,22 +87,6 @@ #endif extern int DC395x_proc_info(char*, char**, off_t, int, int, int); //-------------- - -//#define SYNC_FIRST - -/* We don't have eh_abort_handler, eh_device_reset_handler, - * eh_bus_reset_handler, eh_host_reset_handler yet! - * So long: Use old exception handling :-( */ -#define OLD_EH - -#if (LINUX_VERSION_CODE < KERNEL_VERSION (2,1,70)) || defined(OLD_EH) -# define NEW_EH -# define NORM_REC_LVL 1 -#else -# define USE_NEW_EH -# define NORM_REC_LVL 0 -# define NEW_EH use_new_eh_code: 1, -#endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,30) # define DC395x_TRMS1040 { \