From 27cfca1ec98e91261b1a5355d10a8996464b63af Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 17 Mar 1998 22:05:47 +0000 Subject: Look Ma' what I found on my harddisk ... o New faster syscalls for 2.1.x, too o Upgrade to 2.1.89. Don't try to run this. It's flaky as hell. But feel free to debug ... --- drivers/scsi/.cvsignore | 1 + drivers/scsi/53c7,8xx.c | 2 +- drivers/scsi/53c7,8xx.h | 68 +- drivers/scsi/53c7xx.c | 3 - drivers/scsi/AM53C974.c | 86 +- drivers/scsi/AM53C974.h | 41 +- drivers/scsi/BusLogic.c | 2659 ++--- drivers/scsi/BusLogic.h | 483 +- drivers/scsi/ChangeLog.ncr53c8xx | 27 + drivers/scsi/Config.in | 26 +- drivers/scsi/FlashPoint.c | 513 +- drivers/scsi/Makefile | 47 +- drivers/scsi/NCR5380.c | 3 +- drivers/scsi/NCR53c406a.c | 2 +- drivers/scsi/NCR53c406a.h | 36 +- drivers/scsi/README.BusLogic | 512 +- drivers/scsi/README.Mylex | 6 + drivers/scsi/README.ncr53c8xx | 112 +- drivers/scsi/a2091.h | 33 +- drivers/scsi/a3000.h | 34 +- drivers/scsi/advansys.c | 20588 +++++++++++++++++++++++-------------- drivers/scsi/advansys.h | 38 +- drivers/scsi/aha152x.h | 38 +- drivers/scsi/aha1542.c | 270 +- drivers/scsi/aha1542.h | 47 +- drivers/scsi/aha1740.h | 34 +- drivers/scsi/aic7xxx.c | 2 +- drivers/scsi/aic7xxx.h | 35 +- drivers/scsi/amiga7xx.h | 32 +- drivers/scsi/atari_scsi.h | 32 +- drivers/scsi/constants.c | 5 - drivers/scsi/dc390.h | 126 +- drivers/scsi/dtc.h | 19 +- drivers/scsi/eata.h | 33 +- drivers/scsi/eata_dma.h | 31 +- drivers/scsi/eata_dma_proc.c | 12 +- drivers/scsi/eata_pio.h | 31 +- drivers/scsi/eata_pio_proc.c | 10 +- drivers/scsi/esp.c | 2 +- drivers/scsi/fdomain.h | 34 +- drivers/scsi/g_NCR5380.c | 4 +- drivers/scsi/g_NCR5380.h | 25 +- drivers/scsi/gdth.h | 59 +- drivers/scsi/gdth_proc.c | 10 +- drivers/scsi/gvp11.h | 33 +- drivers/scsi/hosts.c | 55 +- drivers/scsi/hosts.h | 92 +- drivers/scsi/ibmmca.c | 335 +- drivers/scsi/ibmmca.h | 48 +- drivers/scsi/ide-scsi.c | 67 +- drivers/scsi/ide-scsi.h | 36 +- drivers/scsi/in2000.h | 37 +- drivers/scsi/jazz_esp.h | 38 +- drivers/scsi/mac53c94.h | 33 +- drivers/scsi/mesh.h | 33 +- drivers/scsi/ncr53c8xx.c | 176 +- drivers/scsi/ncr53c8xx.h | 90 +- drivers/scsi/pas16.c | 4 +- drivers/scsi/pas16.h | 19 +- drivers/scsi/pci2000.c | 2 +- drivers/scsi/pci2000.h | 33 +- drivers/scsi/pci2220i.h | 33 +- drivers/scsi/pluto.c | 313 + drivers/scsi/pluto.h | 59 + drivers/scsi/ppa.h | 36 +- drivers/scsi/psi240i.h | 33 +- drivers/scsi/qlogicfas.h | 33 +- drivers/scsi/qlogicisp.h | 35 +- drivers/scsi/qlogicpti.h | 34 +- drivers/scsi/scsi.c | 2900 +++--- drivers/scsi/scsi.h | 598 +- drivers/scsi/scsi_debug.c | 268 +- drivers/scsi/scsi_debug.h | 35 +- drivers/scsi/scsi_error.c | 1897 ++++ drivers/scsi/scsi_ioctl.c | 53 +- drivers/scsi/scsi_obsolete.c | 1132 ++ drivers/scsi/scsi_obsolete.h | 106 + drivers/scsi/scsi_proc.c | 8 +- drivers/scsi/scsi_queue.c | 321 + drivers/scsi/scsi_syms.c | 20 +- drivers/scsi/scsicam.c | 5 - drivers/scsi/scsiiom.c | 21 - drivers/scsi/sd.c | 287 +- drivers/scsi/sd_ioctl.c | 16 + drivers/scsi/seagate.h | 19 +- drivers/scsi/sg.c | 56 +- drivers/scsi/sgiwd93.c | 12 +- drivers/scsi/sgiwd93.h | 37 +- drivers/scsi/sparc_esp.h | 41 +- drivers/scsi/sr.c | 89 +- drivers/scsi/sr_ioctl.c | 35 +- drivers/scsi/sr_vendor.c | 67 +- drivers/scsi/st.c | 161 +- drivers/scsi/t128.c | 16 +- drivers/scsi/t128.h | 19 +- drivers/scsi/tmscsim.c | 19 +- drivers/scsi/tmscsim.h | 6 +- drivers/scsi/u14-34f.h | 33 +- drivers/scsi/ultrastor.h | 33 +- drivers/scsi/wd7000.c | 2 +- drivers/scsi/wd7000.h | 28 +- 101 files changed, 23257 insertions(+), 13001 deletions(-) create mode 100644 drivers/scsi/README.Mylex create mode 100644 drivers/scsi/pluto.c create mode 100644 drivers/scsi/pluto.h create mode 100644 drivers/scsi/scsi_error.c create mode 100644 drivers/scsi/scsi_obsolete.c create mode 100644 drivers/scsi/scsi_obsolete.h create mode 100644 drivers/scsi/scsi_queue.c (limited to 'drivers/scsi') diff --git a/drivers/scsi/.cvsignore b/drivers/scsi/.cvsignore index 38d1d3090..6d007a06f 100644 --- a/drivers/scsi/.cvsignore +++ b/drivers/scsi/.cvsignore @@ -1,3 +1,4 @@ .depend +.*.flags aic7xxx_asm aic7xxx_seq.h diff --git a/drivers/scsi/53c7,8xx.c b/drivers/scsi/53c7,8xx.c index 5f1a4d8da..092b8500a 100644 --- a/drivers/scsi/53c7,8xx.c +++ b/drivers/scsi/53c7,8xx.c @@ -5958,7 +5958,7 @@ print_queues (struct Scsi_Host *host) { host->host_no, cmd->pid); /* print_dsa does sanity check on address, no need to check */ else - print_dsa (host, le32_to_cpu(((struct NCR53c7x0_cmd *) cmd->host_scribble)-> dsa), ""); + print_dsa (host, bus_to_virt(le32_to_cpu(((struct NCR53c7x0_cmd *) cmd->host_scribble)-> dsa)), ""); } else printk ("scsi%d : scsi pid %ld for target %d lun %d has no NCR53c7x0_cmd\n", host->host_no, cmd->pid, cmd->target, cmd->lun); diff --git a/drivers/scsi/53c7,8xx.h b/drivers/scsi/53c7,8xx.h index cb0071e9d..994577ab0 100644 --- a/drivers/scsi/53c7,8xx.h +++ b/drivers/scsi/53c7,8xx.h @@ -66,66 +66,22 @@ extern int NCR53c7xx_release(struct Scsi_Host *); #define NCR53c7xx_release NULL #endif -#ifdef LINUX_1_2 -#define NCR53c7xx {NULL, NULL, "NCR53c{7,8}xx (rel 17)", NCR53c7xx_detect,\ - NULL, /* info */ NULL, /* command, deprecated */ NULL, \ - NCR53c7xx_queue_command, NCR53c7xx_abort, NCR53c7xx_reset, \ - NULL /* slave attach */, scsicam_bios_param, /* can queue */ 24, \ - /* id */ 7, 127 /* old SG_ALL */, /* cmd per lun */ 3, \ - /* present */ 0, /* unchecked isa dma */ 0, DISABLE_CLUSTERING} -#else -#define NCR53c7xx {NULL, NULL, NULL, NULL, \ - "NCR53c{7,8}xx (rel 17)", NCR53c7xx_detect,\ - NULL, /* info */ NULL, /* command, deprecated */ NULL, \ - NCR53c7xx_queue_command, NCR53c7xx_abort, NCR53c7xx_reset, \ - NULL /* slave attach */, scsicam_bios_param, /* can queue */ 24, \ - /* id */ 7, 127 /* old SG_ALL */, /* cmd per lun */ 3, \ - /* present */ 0, /* unchecked isa dma */ 0, DISABLE_CLUSTERING} -#endif +#define NCR53c7xx { \ + name: "NCR53c{7,8}xx (rel 17)", \ + detect: NCR53c7xx_detect, \ + queuecommand: NCR53c7xx_queue_command, \ + abort: NCR53c7xx_abort, \ + reset: NCR53c7xx_reset, \ + bios_param: scsicam_bios_param, \ + can_queue: 24, \ + this_id: 7, \ + sg_tablesize: 127, \ + cmd_per_lun: 3, \ + use_clustering: DISABLE_CLUSTERING} #endif /* defined(HOSTS_C) || defined(MODULE) */ #ifndef HOSTS_C -#ifdef LINUX_1_2 -/* - * Change virtual addresses to physical addresses and vv. - * These are trivial on the 1:1 Linux/i386 mapping (but if we ever - * make the kernel segment mapped at 0, we need to do translation - * on the i386 as well) - */ -extern inline unsigned long virt_to_phys(volatile void * address) -{ - return (unsigned long) address; -} - -extern inline void * phys_to_virt(unsigned long address) -{ - return (void *) address; -} - -/* - * IO bus memory addresses are also 1:1 with the physical address - */ -#define virt_to_bus virt_to_phys -#define bus_to_virt phys_to_virt - -/* - * readX/writeX() are used to access memory mapped devices. On some - * architectures the memory mapped IO stuff needs to be accessed - * differently. On the x86 architecture, we just read/write the - * memory location directly. - */ -#define readb(addr) (*(volatile unsigned char *) (addr)) -#define readw(addr) (*(volatile unsigned short *) (addr)) -#define readl(addr) (*(volatile unsigned int *) (addr)) - -#define writeb(b,addr) ((*(volatile unsigned char *) (addr)) = (b)) -#define writew(b,addr) ((*(volatile unsigned short *) (addr)) = (b)) -#define writel(b,addr) ((*(volatile unsigned int *) (addr)) = (b)) - -#define mb() - -#endif /* def LINUX_1_2 */ /* Register addresses, ordered numerically */ diff --git a/drivers/scsi/53c7xx.c b/drivers/scsi/53c7xx.c index a8cd93828..95400fe68 100644 --- a/drivers/scsi/53c7xx.c +++ b/drivers/scsi/53c7xx.c @@ -100,8 +100,6 @@ * the fourth byte from 50 to 25. */ -#include - /* * Sponsored by * iX Multiuser Multitasking Magazine @@ -233,7 +231,6 @@ #endif #include - #include #include #include diff --git a/drivers/scsi/AM53C974.c b/drivers/scsi/AM53C974.c index 0ea714166..f19065027 100644 --- a/drivers/scsi/AM53C974.c +++ b/drivers/scsi/AM53C974.c @@ -2543,52 +2543,54 @@ return(SCSI_ABORT_NOT_RUNNING); * Inputs : cmd -- which command within the command block was responsible for the reset * * Returns : status (SCSI_ABORT_SUCCESS) +* +* FIXME(eric) the reset_flags are ignored. **************************************************************************/ -int AM53C974_reset(Scsi_Cmnd *cmd) +int AM53C974_reset(Scsi_Cmnd *cmd, unsigned int reset_flags) { -AM53C974_local_declare(); -int i; -struct Scsi_Host *instance = cmd->host; -struct AM53C974_hostdata *hostdata = (struct AM53C974_hostdata *)instance->hostdata; -AM53C974_setio(instance); - -cli(); -DEB(printk("AM53C974_reset called; ")); - -printk("AM53C974_reset called\n"); -AM53C974_print(instance); -AM53C974_keywait(); - + AM53C974_local_declare(); + int i; + struct Scsi_Host *instance = cmd->host; + struct AM53C974_hostdata *hostdata = (struct AM53C974_hostdata *)instance->hostdata; + AM53C974_setio(instance); + + cli(); + DEB(printk("AM53C974_reset called; ")); + + printk("AM53C974_reset called\n"); + AM53C974_print(instance); + AM53C974_keywait(); + /* do hard reset */ -AM53C974_write_8(CMDREG, CMDREG_RDEV); -AM53C974_write_8(CMDREG, CMDREG_NOP); -hostdata->msgout[0] = NOP; -for (i = 0; i < 8; i++) { - hostdata->busy[i] = 0; - hostdata->sync_per[i] = DEF_STP; - hostdata->sync_off[i] = 0; - hostdata->sync_neg[i] = 0; } -hostdata->last_message[0] = NOP; -hostdata->sel_cmd = NULL; -hostdata->connected = NULL; -hostdata->issue_queue = NULL; -hostdata->disconnected_queue = NULL; -hostdata->in_reset = 0; -hostdata->aborted = 0; -hostdata->selecting = 0; -hostdata->disconnecting = 0; -hostdata->dma_busy = 0; - + AM53C974_write_8(CMDREG, CMDREG_RDEV); + AM53C974_write_8(CMDREG, CMDREG_NOP); + hostdata->msgout[0] = NOP; + for (i = 0; i < 8; i++) { + hostdata->busy[i] = 0; + hostdata->sync_per[i] = DEF_STP; + hostdata->sync_off[i] = 0; + hostdata->sync_neg[i] = 0; } + hostdata->last_message[0] = NOP; + hostdata->sel_cmd = NULL; + hostdata->connected = NULL; + hostdata->issue_queue = NULL; + hostdata->disconnected_queue = NULL; + hostdata->in_reset = 0; + hostdata->aborted = 0; + hostdata->selecting = 0; + hostdata->disconnecting = 0; + hostdata->dma_busy = 0; + /* reset bus */ -AM53C974_write_8(CNTLREG1, CNTLREG1_DISR | instance->this_id); /* disable interrupt upon SCSI RESET */ -AM53C974_write_8(CMDREG, CMDREG_RBUS); /* reset SCSI bus */ -udelay(40); -AM53C974_config_after_reset(instance); - -sti(); -cmd->result = DID_RESET << 16; -cmd->scsi_done(cmd); -return SCSI_ABORT_SUCCESS; + AM53C974_write_8(CNTLREG1, CNTLREG1_DISR | instance->this_id); /* disable interrupt upon SCSI RESET */ + AM53C974_write_8(CMDREG, CMDREG_RBUS); /* reset SCSI bus */ + udelay(40); + AM53C974_config_after_reset(instance); + + sti(); + cmd->result = DID_RESET << 16; + cmd->scsi_done(cmd); + return SCSI_ABORT_SUCCESS; } diff --git a/drivers/scsi/AM53C974.h b/drivers/scsi/AM53C974.h index 4e187d993..f4542c778 100644 --- a/drivers/scsi/AM53C974.h +++ b/drivers/scsi/AM53C974.h @@ -52,29 +52,22 @@ struct AM53C974_hostdata { extern struct proc_dir_entry proc_scsi_am53c974; -#define AM53C974 { \ - NULL, /* pointer to next in list */ \ - NULL, /* struct module *module */ \ - &proc_scsi_am53c974, /* struct proc_dir_entry *proc_dir */ \ - NULL, /* int (*proc_info)(char *, char **, off_t, int, int, int); */ \ - "AM53C974", /* name */ \ - AM53C974_detect, /* int (* detect)(struct SHT *) */ \ - AM53C974_release, /* int (*release)(struct Scsi_Host *) */ \ - AM53C974_info, /* const char *(* info)(struct Scsi_Host *) */ \ - AM53C974_command, /* int (* command)(Scsi_Cmnd *) */ \ - AM53C974_queue_command, /* int (* queuecommand)(Scsi_Cmnd *, \ - void (*done)(Scsi_Cmnd *)) */ \ - AM53C974_abort, /* int (* abort)(Scsi_Cmnd *) */ \ - AM53C974_reset, /* int (* reset)(Scsi_Cmnd *) */ \ - NULL, /* int (* slave_attach)(int, int) */ \ - scsicam_bios_param, /* int (* bios_param)(Disk *, int, int[]) */ \ - 12, /* can_queue */ \ - -1, /* this_id */ \ - SG_ALL, /* sg_tablesize */ \ - 1, /* cmd_per_lun */ \ - 0, /* present, i.e. how many adapters of this kind */ \ - 0, /* unchecked_isa_dma */ \ - DISABLE_CLUSTERING /* use_clustering */ \ +#define AM53C974 { \ + proc_dir: &proc_scsi_am53c974, \ + name: "AM53C974", \ + detect: AM53C974_detect, \ + release: AM53C974_release, \ + info: AM53C974_info, \ + command: AM53C974_command, \ + queuecommand: AM53C974_queue_command, \ + abort: AM53C974_abort, \ + reset: AM53C974_reset, \ + bios_param: scsicam_bios_param, \ + can_queue: 12, \ + this_id: -1, \ + sg_tablesize: SG_ALL, \ + cmd_per_lun: 1, \ + use_clustering: DISABLE_CLUSTERING \ } void AM53C974_setup(char *str, int *ints); @@ -85,7 +78,7 @@ const char *AM53C974_info(struct Scsi_Host *); int AM53C974_command(Scsi_Cmnd *SCpnt); int AM53C974_queue_command(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *)); int AM53C974_abort(Scsi_Cmnd *cmd); -int AM53C974_reset (Scsi_Cmnd *cmd); +int AM53C974_reset (Scsi_Cmnd *cmd, unsigned int); #endif /* AM53C974_H */ diff --git a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c index 9119be7f3..b81756cc8 100644 --- a/drivers/scsi/BusLogic.c +++ b/drivers/scsi/BusLogic.c @@ -6,8 +6,7 @@ This program is free software; you may redistribute and/or modify it under the terms of the GNU General Public License Version 2 as published by the - Free Software Foundation, provided that none of the source code or runtime - copyright notices are removed or modified. + Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY @@ -27,17 +26,17 @@ */ -#define BusLogic_DriverVersion "2.0.10" -#define BusLogic_DriverDate "11 August 1997" +#define BusLogic_DriverVersion "2.0.11" +#define BusLogic_DriverDate "31 January 1998" +#include #include #include #include #include #include #include -#include #include #include #include @@ -45,30 +44,43 @@ #include #include #include +#include #include #include "scsi.h" #include "hosts.h" #include "sd.h" #include "BusLogic.h" +#include "FlashPoint.c" /* - BusLogic_CommandLineEntryCount is a count of the number of "BusLogic=" - entries provided on the Linux Kernel Command Line. + BusLogic_DriverOptionsCount is a count of the number of BusLogic Driver + Options specifications provided via the Linux Kernel Command Line or via + the Loadable Kernel Module Installation Facility. */ static int - BusLogic_CommandLineEntryCount = 0; + BusLogic_DriverOptionsCount = 0; /* - BusLogic_CommandLineEntries is an array of Command Line Entry structures - representing the "BusLogic=" entries provided on the Linux Kernel Command - Line. + BusLogic_DriverOptions is an array of Driver Options structures representing + BusLogic Driver Options specifications provided via the Linux Kernel Command + Line or via the Loadable Kernel Module Installation Facility. */ -static BusLogic_CommandLineEntry_T - BusLogic_CommandLineEntries[BusLogic_MaxHostAdapters]; +static BusLogic_DriverOptions_T + BusLogic_DriverOptions[BusLogic_MaxHostAdapters]; + + +/* + BusLogic_Options can be assigned a string by the Loadable Kernel Module + Installation Facility to be parsed for BusLogic Driver Options + specifications. +*/ + +static char + *BusLogic_Options = NULL; /* @@ -77,7 +89,7 @@ static BusLogic_CommandLineEntry_T */ static BusLogic_ProbeOptions_T - BusLogic_ProbeOptions = { 0 }; + BusLogic_ProbeOptions = { 0 }; /* @@ -86,7 +98,17 @@ static BusLogic_ProbeOptions_T */ static BusLogic_GlobalOptions_T - BusLogic_GlobalOptions = { 0 }; + BusLogic_GlobalOptions = { 0 }; + + +/* + BusLogic_FirstRegisteredHostAdapter and BusLogic_LastRegisteredHostAdapter + are pointers to the first and last registered BusLogic Host Adapters. +*/ + +static BusLogic_HostAdapter_T + *BusLogic_FirstRegisteredHostAdapter = NULL, + *BusLogic_LastRegisteredHostAdapter = NULL; /* @@ -99,11 +121,11 @@ static BusLogic_HostAdapter_T /* - BusLogic_ProbeInfoCount is the numbers of entries in BusLogic_ProbeInfoList. + BusLogic_ProbeInfoCount is the number of entries in BusLogic_ProbeInfoList. */ static int - BusLogic_ProbeInfoCount = 0; + BusLogic_ProbeInfoCount = 0; /* @@ -114,7 +136,7 @@ static int */ static BusLogic_ProbeInfo_T - BusLogic_ProbeInfoList[BusLogic_MaxHostAdapters] = { { 0 } }; + *BusLogic_ProbeInfoList = NULL; /* @@ -133,8 +155,8 @@ static char */ static BusLogic_CCB_T - *BusLogic_FirstCompletedCCB = NULL, - *BusLogic_LastCompletedCCB = NULL; + *BusLogic_FirstCompletedCCB = NULL, + *BusLogic_LastCompletedCCB = NULL; /* @@ -181,6 +203,17 @@ const char *BusLogic_DriverInfo(SCSI_Host_T *Host) static void BusLogic_RegisterHostAdapter(BusLogic_HostAdapter_T *HostAdapter) { + HostAdapter->NextAll = NULL; + if (BusLogic_FirstRegisteredHostAdapter == NULL) + { + BusLogic_FirstRegisteredHostAdapter = HostAdapter; + BusLogic_LastRegisteredHostAdapter = HostAdapter; + } + else + { + BusLogic_LastRegisteredHostAdapter->NextAll = HostAdapter; + BusLogic_LastRegisteredHostAdapter = HostAdapter; + } HostAdapter->Next = NULL; if (BusLogic_RegisteredHostAdapters[HostAdapter->IRQ_Channel] != NULL) { @@ -202,14 +235,33 @@ static void BusLogic_RegisterHostAdapter(BusLogic_HostAdapter_T *HostAdapter) static void BusLogic_UnregisterHostAdapter(BusLogic_HostAdapter_T *HostAdapter) { + if (HostAdapter == BusLogic_FirstRegisteredHostAdapter) + { + BusLogic_FirstRegisteredHostAdapter = + BusLogic_FirstRegisteredHostAdapter->NextAll; + if (HostAdapter == BusLogic_LastRegisteredHostAdapter) + BusLogic_LastRegisteredHostAdapter = NULL; + } + else + { + BusLogic_HostAdapter_T *PreviousHostAdapter = + BusLogic_FirstRegisteredHostAdapter; + while (PreviousHostAdapter != NULL && + PreviousHostAdapter->NextAll != HostAdapter) + PreviousHostAdapter = PreviousHostAdapter->NextAll; + if (PreviousHostAdapter != NULL) + PreviousHostAdapter->NextAll = HostAdapter->NextAll; + } + HostAdapter->NextAll = NULL; if (BusLogic_RegisteredHostAdapters[HostAdapter->IRQ_Channel] != HostAdapter) { - BusLogic_HostAdapter_T *LastHostAdapter = + BusLogic_HostAdapter_T *PreviousHostAdapter = BusLogic_RegisteredHostAdapters[HostAdapter->IRQ_Channel]; - while (LastHostAdapter != NULL && LastHostAdapter->Next != HostAdapter) - LastHostAdapter = LastHostAdapter->Next; - if (LastHostAdapter != NULL) - LastHostAdapter->Next = HostAdapter->Next; + while (PreviousHostAdapter != NULL && + PreviousHostAdapter->Next != HostAdapter) + PreviousHostAdapter = PreviousHostAdapter->Next; + if (PreviousHostAdapter != NULL) + PreviousHostAdapter->Next = HostAdapter->Next; } else BusLogic_RegisteredHostAdapters[HostAdapter->IRQ_Channel] = HostAdapter->Next; @@ -218,85 +270,33 @@ static void BusLogic_UnregisterHostAdapter(BusLogic_HostAdapter_T *HostAdapter) /* - BusLogic_CreateMailboxes allocates the Outgoing and Incoming Mailboxes for - Host Adapter. -*/ - -static boolean BusLogic_CreateMailboxes(BusLogic_HostAdapter_T *HostAdapter) -{ - /* - FlashPoint Host Adapters do not use Outgoing and Incoming Mailboxes. - */ - if (BusLogic_FlashPointHostAdapterP(HostAdapter)) return true; - /* - Allocate space for the Outgoing and Incoming Mailboxes. - */ - HostAdapter->FirstOutgoingMailbox = - (BusLogic_OutgoingMailbox_T *) - scsi_init_malloc(HostAdapter->MailboxCount - * (sizeof(BusLogic_OutgoingMailbox_T) - + sizeof(BusLogic_IncomingMailbox_T)), - (HostAdapter->BounceBuffersRequired - ? GFP_ATOMIC | GFP_DMA - : GFP_ATOMIC)); - if (HostAdapter->FirstOutgoingMailbox == NULL) - { - BusLogic_Error("UNABLE TO ALLOCATE MAILBOXES - DETACHING\n", - HostAdapter, HostAdapter->HostNumber); - return false; - } - HostAdapter->LastOutgoingMailbox = - HostAdapter->FirstOutgoingMailbox + HostAdapter->MailboxCount - 1; - HostAdapter->FirstIncomingMailbox = - (BusLogic_IncomingMailbox_T *) (HostAdapter->LastOutgoingMailbox + 1); - HostAdapter->LastIncomingMailbox = - HostAdapter->FirstIncomingMailbox + HostAdapter->MailboxCount - 1; - return true; -} - - -/* - BusLogic_DestroyMailboxes deallocates the Outgoing and Incoming Mailboxes - for Host Adapter. + BusLogic_InitializeCCBs initializes a group of Command Control Blocks (CCBs) + for Host Adapter from the BlockSize bytes located at BlockPointer. The newly + created CCBs are added to Host Adapter's free list. */ -static void BusLogic_DestroyMailboxes(BusLogic_HostAdapter_T *HostAdapter) +static void BusLogic_InitializeCCBs(BusLogic_HostAdapter_T *HostAdapter, + void *BlockPointer, int BlockSize) { - if (HostAdapter->FirstOutgoingMailbox == NULL) return; - scsi_init_free((char *) HostAdapter->FirstOutgoingMailbox, - HostAdapter->MailboxCount - * (sizeof(BusLogic_OutgoingMailbox_T) - + sizeof(BusLogic_IncomingMailbox_T))); -} - - -/* - BusLogic_CreateCCB allocates and initializes a single Command Control - Block (CCB) for Host Adapter, and adds it to Host Adapter's free list. -*/ - -static boolean BusLogic_CreateCCB(BusLogic_HostAdapter_T *HostAdapter) -{ - BusLogic_CCB_T *CCB = (BusLogic_CCB_T *) - scsi_init_malloc(sizeof(BusLogic_CCB_T), - (HostAdapter->BounceBuffersRequired - ? GFP_ATOMIC | GFP_DMA - : GFP_ATOMIC)); - if (CCB == NULL) return false; - memset(CCB, 0, sizeof(BusLogic_CCB_T)); - CCB->HostAdapter = HostAdapter; - CCB->Status = BusLogic_CCB_Free; - if (BusLogic_FlashPointHostAdapterP(HostAdapter)) + BusLogic_CCB_T *CCB = (BusLogic_CCB_T *) BlockPointer; + memset(BlockPointer, 0, BlockSize); + CCB->AllocationGroupHead = true; + while ((BlockSize -= sizeof(BusLogic_CCB_T)) >= 0) { - CCB->CallbackFunction = BusLogic_QueueCompletedCCB; - CCB->BaseAddress = HostAdapter->IO_Address; + CCB->Status = BusLogic_CCB_Free; + CCB->HostAdapter = HostAdapter; + if (BusLogic_FlashPointHostAdapterP(HostAdapter)) + { + CCB->CallbackFunction = BusLogic_QueueCompletedCCB; + CCB->BaseAddress = HostAdapter->FlashPointInfo.BaseAddress; + } + CCB->Next = HostAdapter->Free_CCBs; + CCB->NextAll = HostAdapter->All_CCBs; + HostAdapter->Free_CCBs = CCB; + HostAdapter->All_CCBs = CCB; + HostAdapter->AllocatedCCBs++; + CCB++; } - CCB->Next = HostAdapter->Free_CCBs; - CCB->NextAll = HostAdapter->All_CCBs; - HostAdapter->Free_CCBs = CCB; - HostAdapter->All_CCBs = CCB; - HostAdapter->AllocatedCCBs++; - return true; } @@ -306,14 +306,21 @@ static boolean BusLogic_CreateCCB(BusLogic_HostAdapter_T *HostAdapter) static boolean BusLogic_CreateInitialCCBs(BusLogic_HostAdapter_T *HostAdapter) { - int Allocated; - for (Allocated = 0; Allocated < HostAdapter->InitialCCBs; Allocated++) - if (!BusLogic_CreateCCB(HostAdapter)) - { - BusLogic_Error("UNABLE TO ALLOCATE CCB %d - DETACHING\n", - HostAdapter, Allocated); - return false; - } + int BlockSize = BusLogic_CCB_AllocationGroupSize * sizeof(BusLogic_CCB_T); + while (HostAdapter->AllocatedCCBs < HostAdapter->InitialCCBs) + { + void *BlockPointer = kmalloc(BlockSize, + (HostAdapter->BounceBuffersRequired + ? GFP_ATOMIC | GFP_DMA + : GFP_ATOMIC)); + if (BlockPointer == NULL) + { + BusLogic_Error("UNABLE TO ALLOCATE CCB GROUP - DETACHING\n", + HostAdapter); + return false; + } + BusLogic_InitializeCCBs(HostAdapter, BlockPointer, BlockSize); + } return true; } @@ -330,7 +337,8 @@ static void BusLogic_DestroyCCBs(BusLogic_HostAdapter_T *HostAdapter) while ((CCB = NextCCB) != NULL) { NextCCB = CCB->NextAll; - scsi_init_free((char *) CCB, sizeof(BusLogic_CCB_T)); + if (CCB->AllocationGroupHead) + kfree(CCB); } } @@ -346,18 +354,35 @@ static void BusLogic_CreateAdditionalCCBs(BusLogic_HostAdapter_T *HostAdapter, int AdditionalCCBs, boolean SuccessMessageP) { - int Allocated; + int BlockSize = BusLogic_CCB_AllocationGroupSize * sizeof(BusLogic_CCB_T); + int PreviouslyAllocated = HostAdapter->AllocatedCCBs; if (AdditionalCCBs <= 0) return; - for (Allocated = 0; Allocated < AdditionalCCBs; Allocated++) - if (!BusLogic_CreateCCB(HostAdapter)) break; - if (Allocated > 0 && SuccessMessageP) - BusLogic_Notice("Allocated %d additional CCBs (total now %d)\n", - HostAdapter, Allocated, HostAdapter->AllocatedCCBs); - if (Allocated > 0) return; + while (HostAdapter->AllocatedCCBs - PreviouslyAllocated < AdditionalCCBs) + { + void *BlockPointer = kmalloc(BlockSize, + (HostAdapter->BounceBuffersRequired + ? GFP_ATOMIC | GFP_DMA + : GFP_ATOMIC)); + if (BlockPointer == NULL) break; + BusLogic_InitializeCCBs(HostAdapter, BlockPointer, BlockSize); + } + if (HostAdapter->AllocatedCCBs > PreviouslyAllocated) + { + if (SuccessMessageP) + BusLogic_Notice("Allocated %d additional CCBs (total now %d)\n", + HostAdapter, + HostAdapter->AllocatedCCBs - PreviouslyAllocated, + HostAdapter->AllocatedCCBs); + return; + } BusLogic_Notice("Failed to allocate additional CCBs\n", HostAdapter); - HostAdapter->DriverQueueDepth = - HostAdapter->AllocatedCCBs - (HostAdapter->MaxTargetDevices - 1); - HostAdapter->SCSI_Host->can_queue = HostAdapter->DriverQueueDepth; + if (HostAdapter->DriverQueueDepth > + HostAdapter->AllocatedCCBs - HostAdapter->TargetDeviceCount) + { + HostAdapter->DriverQueueDepth = + HostAdapter->AllocatedCCBs - HostAdapter->TargetDeviceCount; + HostAdapter->SCSI_Host->can_queue = HostAdapter->DriverQueueDepth; + } } @@ -412,47 +437,6 @@ static void BusLogic_DeallocateCCB(BusLogic_CCB_T *CCB) } -/* - BusLogic_CreateTargetDeviceStatistics creates the Target Device Statistics - structure for Host Adapter. -*/ - -static boolean BusLogic_CreateTargetDeviceStatistics(BusLogic_HostAdapter_T - *HostAdapter) -{ - HostAdapter->TargetDeviceStatistics = - (BusLogic_TargetDeviceStatistics_T *) - scsi_init_malloc(HostAdapter->MaxTargetDevices - * sizeof(BusLogic_TargetDeviceStatistics_T), - GFP_ATOMIC); - if (HostAdapter->TargetDeviceStatistics == NULL) - { - BusLogic_Error("UNABLE TO ALLOCATE TARGET DEVICE STATISTICS - " - "DETACHING\n", HostAdapter, HostAdapter->HostNumber); - return false; - } - memset(HostAdapter->TargetDeviceStatistics, 0, - HostAdapter->MaxTargetDevices - * sizeof(BusLogic_TargetDeviceStatistics_T)); - return true; -} - - -/* - BusLogic_DestroyTargetDeviceStatistics destroys the Target Device Statistics - structure for Host Adapter. -*/ - -static void BusLogic_DestroyTargetDeviceStatistics(BusLogic_HostAdapter_T - *HostAdapter) -{ - if (HostAdapter->TargetDeviceStatistics == NULL) return; - scsi_init_free((char *) HostAdapter->TargetDeviceStatistics, - HostAdapter->MaxTargetDevices - * sizeof(BusLogic_TargetDeviceStatistics_T)); -} - - /* BusLogic_Command sends the command OperationCode to HostAdapter, optionally providing ParameterLength bytes of ParameterData and receiving at most @@ -494,7 +478,7 @@ static int BusLogic_Command(BusLogic_HostAdapter_T *HostAdapter, If the IRQ Channel has not yet been acquired, then interrupts must be disabled while issuing host adapter commands since a Command Complete interrupt could occur if the IRQ Channel was previously enabled by another - BusLogic Host Adapter or other driver sharing the same IRQ Channel. + BusLogic Host Adapter or another driver sharing the same IRQ Channel. */ if (!HostAdapter->IRQ_ChannelAcquired) { @@ -572,7 +556,7 @@ static int BusLogic_Command(BusLogic_HostAdapter_T *HostAdapter, Result = -1; goto Done; } - if (BusLogic_GlobalOptions.Bits.TraceConfiguration) + if (BusLogic_GlobalOptions.TraceConfiguration) BusLogic_Notice("BusLogic_Command(%02X) Status = %02X: " "(Modify I/O Address)\n", HostAdapter, OperationCode, StatusRegister.All); @@ -607,9 +591,11 @@ static int BusLogic_Command(BusLogic_HostAdapter_T *HostAdapter, if (InterruptRegister.Bits.CommandComplete) break; if (HostAdapter->HostAdapterCommandCompleted) break; if (StatusRegister.Bits.DataInRegisterReady) - if (++ReplyBytes <= ReplyLength) - *ReplyPointer++ = BusLogic_ReadDataInRegister(HostAdapter); - else BusLogic_ReadDataInRegister(HostAdapter); + { + if (++ReplyBytes <= ReplyLength) + *ReplyPointer++ = BusLogic_ReadDataInRegister(HostAdapter); + else BusLogic_ReadDataInRegister(HostAdapter); + } if (OperationCode == BusLogic_FetchHostAdapterLocalRAM && StatusRegister.Bits.HostAdapterReady) break; udelay(100); @@ -620,15 +606,6 @@ static int BusLogic_Command(BusLogic_HostAdapter_T *HostAdapter, Result = -2; goto Done; } - /* - If testing Command Complete Interrupts, wait a short while in case the - loop immediately above terminated due to the Command Complete bit being - set in the Interrupt Register, but the interrupt hasn't actually been - processed yet. Otherwise, acknowledging the interrupt here could prevent - the interrupt test from succeeding. - */ - if (OperationCode == BusLogic_TestCommandCompleteInterrupt) - udelay(10000); /* Clear any pending Command Complete Interrupt. */ @@ -636,19 +613,18 @@ static int BusLogic_Command(BusLogic_HostAdapter_T *HostAdapter, /* Provide tracing information if requested. */ - if (BusLogic_GlobalOptions.Bits.TraceConfiguration) - if (OperationCode != BusLogic_TestCommandCompleteInterrupt) - { - int i; - BusLogic_Notice("BusLogic_Command(%02X) Status = %02X: %2d ==> %2d:", - HostAdapter, OperationCode, - StatusRegister.All, ReplyLength, ReplyBytes); - if (ReplyLength > ReplyBytes) ReplyLength = ReplyBytes; - for (i = 0; i < ReplyLength; i++) - BusLogic_Notice(" %02X", HostAdapter, - ((unsigned char *) ReplyData)[i]); - BusLogic_Notice("\n", HostAdapter); - } + if (BusLogic_GlobalOptions.TraceConfiguration) + { + int i; + BusLogic_Notice("BusLogic_Command(%02X) Status = %02X: %2d ==> %2d:", + HostAdapter, OperationCode, + StatusRegister.All, ReplyLength, ReplyBytes); + if (ReplyLength > ReplyBytes) ReplyLength = ReplyBytes; + for (i = 0; i < ReplyLength; i++) + BusLogic_Notice(" %02X", HostAdapter, + ((unsigned char *) ReplyData)[i]); + BusLogic_Notice("\n", HostAdapter); + } /* Process Command Invalid conditions. */ @@ -704,39 +680,64 @@ Done: } +/* + BusLogic_AppendProbeAddressISA appends a single ISA I/O Address to the list + of I/O Address and Bus Probe Information to be checked for potential BusLogic + Host Adapters. +*/ + +static void BusLogic_AppendProbeAddressISA(BusLogic_IO_Address_T IO_Address) +{ + BusLogic_ProbeInfo_T *ProbeInfo; + if (BusLogic_ProbeInfoCount >= BusLogic_MaxHostAdapters) return; + ProbeInfo = &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount++]; + ProbeInfo->HostAdapterType = BusLogic_MultiMaster; + ProbeInfo->HostAdapterBusType = BusLogic_ISA_Bus; + ProbeInfo->IO_Address = IO_Address; +} + + /* BusLogic_InitializeProbeInfoListISA initializes the list of I/O Address and Bus Probe Information to be checked for potential BusLogic SCSI Host Adapters only from the list of standard BusLogic MultiMaster ISA I/O Addresses. */ -static void BusLogic_InitializeProbeInfoListISA(void) +static void BusLogic_InitializeProbeInfoListISA(BusLogic_HostAdapter_T + *PrototypeHostAdapter) { - int StandardAddressIndex; - /* - If BusLogic_Setup has provided an I/O Address probe list, do not override - the Kernel Command Line specifications. - */ - if (BusLogic_ProbeInfoCount > 0) return; /* - If a Kernel Command Line specification has requested that ISA Bus Probes + If BusLogic Driver Options specifications requested that ISA Bus Probes be inhibited, do not proceed further. */ - if (BusLogic_ProbeOptions.Bits.NoProbeISA) return; + if (BusLogic_ProbeOptions.NoProbeISA) return; /* Append the list of standard BusLogic MultiMaster ISA I/O Addresses. */ - StandardAddressIndex = 0; - while (BusLogic_ProbeInfoCount < BusLogic_MaxHostAdapters && - StandardAddressIndex < BusLogic_ISA_StandardAddressesCount) - { - BusLogic_ProbeInfo_T *ProbeInfo = - &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount++]; - ProbeInfo->IO_Address = - BusLogic_ISA_StandardAddresses[StandardAddressIndex++]; - ProbeInfo->HostAdapterType = BusLogic_MultiMaster; - ProbeInfo->HostAdapterBusType = BusLogic_ISA_Bus; - } + if (BusLogic_ProbeOptions.LimitedProbeISA + ? BusLogic_ProbeOptions.Probe330 + : check_region(0x330, BusLogic_MultiMasterAddressCount) == 0) + BusLogic_AppendProbeAddressISA(0x330); + if (BusLogic_ProbeOptions.LimitedProbeISA + ? BusLogic_ProbeOptions.Probe334 + : check_region(0x334, BusLogic_MultiMasterAddressCount) == 0) + BusLogic_AppendProbeAddressISA(0x334); + if (BusLogic_ProbeOptions.LimitedProbeISA + ? BusLogic_ProbeOptions.Probe230 + : check_region(0x230, BusLogic_MultiMasterAddressCount) == 0) + BusLogic_AppendProbeAddressISA(0x230); + if (BusLogic_ProbeOptions.LimitedProbeISA + ? BusLogic_ProbeOptions.Probe234 + : check_region(0x234, BusLogic_MultiMasterAddressCount) == 0) + BusLogic_AppendProbeAddressISA(0x234); + if (BusLogic_ProbeOptions.LimitedProbeISA + ? BusLogic_ProbeOptions.Probe130 + : check_region(0x130, BusLogic_MultiMasterAddressCount) == 0) + BusLogic_AppendProbeAddressISA(0x130); + if (BusLogic_ProbeOptions.LimitedProbeISA + ? BusLogic_ProbeOptions.Probe134 + : check_region(0x134, BusLogic_MultiMasterAddressCount) == 0) + BusLogic_AppendProbeAddressISA(0x134); } @@ -783,25 +784,26 @@ static void BusLogic_SortProbeInfo(BusLogic_ProbeInfo_T *ProbeInfoList, I/O Addresses. It returns the number of PCI MultiMaster Host Adapters found. */ -static int BusLogic_InitializeMultiMasterProbeInfo(void) +static int BusLogic_InitializeMultiMasterProbeInfo(BusLogic_HostAdapter_T + *PrototypeHostAdapter) { - boolean StandardAddressSeen[BusLogic_ISA_StandardAddressesCount]; BusLogic_ProbeInfo_T *PrimaryProbeInfo = &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount]; int NonPrimaryPCIMultiMasterIndex = BusLogic_ProbeInfoCount + 1; int NonPrimaryPCIMultiMasterCount = 0, PCIMultiMasterCount = 0; boolean ForceBusDeviceScanningOrder = false; boolean ForceBusDeviceScanningOrderChecked = false; - unsigned char Bus, DeviceFunction, IRQ_Channel; + boolean StandardAddressSeen[6]; + unsigned char Bus, DeviceFunction; unsigned int BaseAddress0, BaseAddress1; + unsigned char IRQ_Channel; BusLogic_IO_Address_T IO_Address; BusLogic_PCI_Address_T PCI_Address; unsigned short Index = 0; - int StandardAddressIndex, i; - if (BusLogic_ProbeInfoCount >= BusLogic_MaxHostAdapters) - return 0; + int i; + if (BusLogic_ProbeInfoCount >= BusLogic_MaxHostAdapters) return 0; BusLogic_ProbeInfoCount++; - for (i = 0; i < BusLogic_ISA_StandardAddressesCount; i++) + for (i = 0; i < 6; i++) StandardAddressSeen[i] = false; /* Iterate over the MultiMaster PCI Host Adapters. For each enumerated host @@ -826,8 +828,7 @@ static int BusLogic_InitializeMultiMasterProbeInfo(void) pcibios_read_config_byte(Bus, DeviceFunction, PCI_INTERRUPT_LINE, &IRQ_Channel) == 0) { - BusLogic_HostAdapter_T HostAdapterPrototype; - BusLogic_HostAdapter_T *HostAdapter = &HostAdapterPrototype; + BusLogic_HostAdapter_T *HostAdapter = PrototypeHostAdapter; BusLogic_PCIHostAdapterInformation_T PCIHostAdapterInformation; BusLogic_ModifyIOAddressRequest_T ModifyIOAddressRequest; unsigned char Device = DeviceFunction >> 3; @@ -859,7 +860,7 @@ static int BusLogic_InitializeMultiMasterProbeInfo(void) NULL, Bus, Device, IO_Address); continue; } - if (BusLogic_GlobalOptions.Bits.TraceProbe) + if (BusLogic_GlobalOptions.TraceProbe) { BusLogic_Notice("BusLogic: PCI MultiMaster Host Adapter " "detected at\n", NULL); @@ -871,7 +872,7 @@ static int BusLogic_InitializeMultiMasterProbeInfo(void) Issue the Inquire PCI Host Adapter Information command to determine the ISA Compatible I/O Port. If the ISA Compatible I/O Port is known and enabled, note that the particular Standard ISA I/O - Address need not be probed. + Address should not be probed. */ HostAdapter->IO_Address = IO_Address; if (BusLogic_Command(HostAdapter, @@ -880,8 +881,7 @@ static int BusLogic_InitializeMultiMasterProbeInfo(void) sizeof(PCIHostAdapterInformation)) == sizeof(PCIHostAdapterInformation)) { - if (PCIHostAdapterInformation.ISACompatibleIOPort < - BusLogic_ISA_StandardAddressesCount) + if (PCIHostAdapterInformation.ISACompatibleIOPort < 6) StandardAddressSeen[PCIHostAdapterInformation .ISACompatibleIOPort] = true; } @@ -933,10 +933,10 @@ static int BusLogic_InitializeMultiMasterProbeInfo(void) */ if (PCIHostAdapterInformation.ISACompatibleIOPort == BusLogic_IO_330) { - PrimaryProbeInfo->IO_Address = IO_Address; - PrimaryProbeInfo->PCI_Address = PCI_Address; PrimaryProbeInfo->HostAdapterType = BusLogic_MultiMaster; PrimaryProbeInfo->HostAdapterBusType = BusLogic_PCI_Bus; + PrimaryProbeInfo->IO_Address = IO_Address; + PrimaryProbeInfo->PCI_Address = PCI_Address; PrimaryProbeInfo->Bus = Bus; PrimaryProbeInfo->Device = Device; PrimaryProbeInfo->IRQ_Channel = IRQ_Channel; @@ -946,10 +946,10 @@ static int BusLogic_InitializeMultiMasterProbeInfo(void) { BusLogic_ProbeInfo_T *ProbeInfo = &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount++]; - ProbeInfo->IO_Address = IO_Address; - ProbeInfo->PCI_Address = PCI_Address; ProbeInfo->HostAdapterType = BusLogic_MultiMaster; ProbeInfo->HostAdapterBusType = BusLogic_PCI_Bus; + ProbeInfo->IO_Address = IO_Address; + ProbeInfo->PCI_Address = PCI_Address; ProbeInfo->Bus = Bus; ProbeInfo->Device = Device; ProbeInfo->IRQ_Channel = IRQ_Channel; @@ -978,31 +978,48 @@ static int BusLogic_InitializeMultiMasterProbeInfo(void) then the Primary I/O Address must be probed explicitly before any PCI host adapters are probed. */ - if (PrimaryProbeInfo->IO_Address == 0 && - !BusLogic_ProbeOptions.Bits.NoProbeISA) - { - PrimaryProbeInfo->IO_Address = BusLogic_ISA_StandardAddresses[0]; - PrimaryProbeInfo->HostAdapterType = BusLogic_MultiMaster; - PrimaryProbeInfo->HostAdapterBusType = BusLogic_ISA_Bus; - } + if (!BusLogic_ProbeOptions.NoProbeISA) + if (PrimaryProbeInfo->IO_Address == 0 && + (BusLogic_ProbeOptions.LimitedProbeISA + ? BusLogic_ProbeOptions.Probe330 + : check_region(0x330, BusLogic_MultiMasterAddressCount) == 0)) + { + PrimaryProbeInfo->HostAdapterType = BusLogic_MultiMaster; + PrimaryProbeInfo->HostAdapterBusType = BusLogic_ISA_Bus; + PrimaryProbeInfo->IO_Address = 0x330; + } /* Append the list of standard BusLogic MultiMaster ISA I/O Addresses, omitting the Primary I/O Address which has already been handled. */ - if (!BusLogic_ProbeOptions.Bits.NoProbeISA) - for (StandardAddressIndex = 1; - StandardAddressIndex < BusLogic_ISA_StandardAddressesCount; - StandardAddressIndex++) - if (!StandardAddressSeen[StandardAddressIndex] && - BusLogic_ProbeInfoCount < BusLogic_MaxHostAdapters) - { - BusLogic_ProbeInfo_T *ProbeInfo = - &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount++]; - ProbeInfo->IO_Address = - BusLogic_ISA_StandardAddresses[StandardAddressIndex]; - ProbeInfo->HostAdapterType = BusLogic_MultiMaster; - ProbeInfo->HostAdapterBusType = BusLogic_ISA_Bus; - } + if (!BusLogic_ProbeOptions.NoProbeISA) + { + if (!StandardAddressSeen[1] && + (BusLogic_ProbeOptions.LimitedProbeISA + ? BusLogic_ProbeOptions.Probe334 + : check_region(0x334, BusLogic_MultiMasterAddressCount) == 0)) + BusLogic_AppendProbeAddressISA(0x334); + if (!StandardAddressSeen[2] && + (BusLogic_ProbeOptions.LimitedProbeISA + ? BusLogic_ProbeOptions.Probe230 + : check_region(0x230, BusLogic_MultiMasterAddressCount) == 0)) + BusLogic_AppendProbeAddressISA(0x230); + if (!StandardAddressSeen[3] && + (BusLogic_ProbeOptions.LimitedProbeISA + ? BusLogic_ProbeOptions.Probe234 + : check_region(0x234, BusLogic_MultiMasterAddressCount) == 0)) + BusLogic_AppendProbeAddressISA(0x234); + if (!StandardAddressSeen[4] && + (BusLogic_ProbeOptions.LimitedProbeISA + ? BusLogic_ProbeOptions.Probe130 + : check_region(0x130, BusLogic_MultiMasterAddressCount) == 0)) + BusLogic_AppendProbeAddressISA(0x130); + if (!StandardAddressSeen[5] && + (BusLogic_ProbeOptions.LimitedProbeISA + ? BusLogic_ProbeOptions.Probe134 + : check_region(0x134, BusLogic_MultiMasterAddressCount) == 0)) + BusLogic_AppendProbeAddressISA(0x134); + } return PCIMultiMasterCount; } @@ -1014,11 +1031,13 @@ static int BusLogic_InitializeMultiMasterProbeInfo(void) number of FlashPoint Host Adapters found. */ -static int BusLogic_InitializeFlashPointProbeInfo(void) +static int BusLogic_InitializeFlashPointProbeInfo(BusLogic_HostAdapter_T + *PrototypeHostAdapter) { int FlashPointIndex = BusLogic_ProbeInfoCount, FlashPointCount = 0; - unsigned char Bus, DeviceFunction, IRQ_Channel; + unsigned char Bus, DeviceFunction; unsigned int BaseAddress0, BaseAddress1; + unsigned char IRQ_Channel; BusLogic_IO_Address_T IO_Address; BusLogic_PCI_Address_T PCI_Address; unsigned short Index = 0; @@ -1065,7 +1084,7 @@ static int BusLogic_InitializeFlashPointProbeInfo(void) NULL, Bus, Device, IO_Address); continue; } - if (BusLogic_GlobalOptions.Bits.TraceProbe) + if (BusLogic_GlobalOptions.TraceProbe) { BusLogic_Notice("BusLogic: FlashPoint Host Adapter " "detected at\n", NULL); @@ -1077,10 +1096,10 @@ static int BusLogic_InitializeFlashPointProbeInfo(void) { BusLogic_ProbeInfo_T *ProbeInfo = &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount++]; - ProbeInfo->IO_Address = IO_Address; - ProbeInfo->PCI_Address = PCI_Address; ProbeInfo->HostAdapterType = BusLogic_FlashPoint; ProbeInfo->HostAdapterBusType = BusLogic_PCI_Bus; + ProbeInfo->IO_Address = IO_Address; + ProbeInfo->PCI_Address = PCI_Address; ProbeInfo->Bus = Bus; ProbeInfo->Device = Device; ProbeInfo->IRQ_Channel = IRQ_Channel; @@ -1116,44 +1135,41 @@ static int BusLogic_InitializeFlashPointProbeInfo(void) FlashPoint and PCI MultiMaster Host Adapters are present, this driver will probe for FlashPoint Host Adapters first unless the BIOS primary disk is controlled by the first PCI MultiMaster Host Adapter, in which case - MultiMaster Host Adapters will be probed first. The Kernel Command Line - options "MultiMasterFirst" and "FlashPointFirst" can be used to force a - particular probe order. + MultiMaster Host Adapters will be probed first. The BusLogic Driver Options + specifications "MultiMasterFirst" and "FlashPointFirst" can be used to force + a particular probe order. */ -static void BusLogic_InitializeProbeInfoList(void) +static void BusLogic_InitializeProbeInfoList(BusLogic_HostAdapter_T + *PrototypeHostAdapter) { - /* - If BusLogic_Setup has provided an I/O Address probe list, do not override - the Kernel Command Line specifications. - */ - if (BusLogic_ProbeInfoCount > 0) return; /* If a PCI BIOS is present, interrogate it for MultiMaster and FlashPoint Host Adapters; otherwise, default to the standard ISA MultiMaster probe. */ - if (!BusLogic_ProbeOptions.Bits.NoProbePCI && pcibios_present()) + if (!BusLogic_ProbeOptions.NoProbePCI && pcibios_present()) { - if (BusLogic_ProbeOptions.Bits.ProbeMultiMasterFirst) + if (BusLogic_ProbeOptions.MultiMasterFirst) { - BusLogic_InitializeMultiMasterProbeInfo(); - BusLogic_InitializeFlashPointProbeInfo(); + BusLogic_InitializeMultiMasterProbeInfo(PrototypeHostAdapter); + BusLogic_InitializeFlashPointProbeInfo(PrototypeHostAdapter); } - else if (BusLogic_ProbeOptions.Bits.ProbeFlashPointFirst) + else if (BusLogic_ProbeOptions.FlashPointFirst) { - BusLogic_InitializeFlashPointProbeInfo(); - BusLogic_InitializeMultiMasterProbeInfo(); + BusLogic_InitializeFlashPointProbeInfo(PrototypeHostAdapter); + BusLogic_InitializeMultiMasterProbeInfo(PrototypeHostAdapter); } else { - int FlashPointCount = BusLogic_InitializeFlashPointProbeInfo(); - int PCIMultiMasterCount = BusLogic_InitializeMultiMasterProbeInfo(); + int FlashPointCount = + BusLogic_InitializeFlashPointProbeInfo(PrototypeHostAdapter); + int PCIMultiMasterCount = + BusLogic_InitializeMultiMasterProbeInfo(PrototypeHostAdapter); if (FlashPointCount > 0 && PCIMultiMasterCount > 0) { BusLogic_ProbeInfo_T *ProbeInfo = &BusLogic_ProbeInfoList[FlashPointCount]; - BusLogic_HostAdapter_T HostAdapterPrototype; - BusLogic_HostAdapter_T *HostAdapter = &HostAdapterPrototype; + BusLogic_HostAdapter_T *HostAdapter = PrototypeHostAdapter; BusLogic_FetchHostAdapterLocalRAMRequest_T FetchHostAdapterLocalRAMRequest; BusLogic_BIOSDriveMapByte_T Drive0MapByte; @@ -1195,7 +1211,7 @@ static void BusLogic_InitializeProbeInfoList(void) } } } - else BusLogic_InitializeProbeInfoListISA(); + else BusLogic_InitializeProbeInfoListISA(PrototypeHostAdapter); } @@ -1240,20 +1256,14 @@ static boolean BusLogic_ProbeHostAdapter(BusLogic_HostAdapter_T *HostAdapter) */ if (BusLogic_FlashPointHostAdapterP(HostAdapter)) { - FlashPoint_Info_T *FlashPointInfo = (FlashPoint_Info_T *) - scsi_init_malloc(sizeof(FlashPoint_Info_T), GFP_ATOMIC); - int Retries = 10; - if (FlashPointInfo == NULL) - return BusLogic_Failure(HostAdapter, "ALLOCATING FLASHPOINT INFO"); - FlashPointInfo->BaseAddress = HostAdapter->IO_Address; + FlashPoint_Info_T *FlashPointInfo = &HostAdapter->FlashPointInfo; + FlashPointInfo->BaseAddress = + (BusLogic_Base_Address_T) HostAdapter->IO_Address; FlashPointInfo->IRQ_Channel = HostAdapter->IRQ_Channel; FlashPointInfo->Present = false; - while (!(FlashPoint_ProbeHostAdapter(FlashPointInfo) == 0 && - FlashPointInfo->Present) && - --Retries >= 0) ; - if (!FlashPointInfo->Present) + if (!(FlashPoint_ProbeHostAdapter(FlashPointInfo) == 0 && + FlashPointInfo->Present)) { - scsi_init_free((char *) FlashPointInfo, sizeof(FlashPoint_Info_T)); BusLogic_Error("BusLogic: FlashPoint Host Adapter detected at " "PCI Bus %d Device %d\n", HostAdapter, HostAdapter->Bus, HostAdapter->Device); @@ -1264,8 +1274,7 @@ static boolean BusLogic_ProbeHostAdapter(BusLogic_HostAdapter_T *HostAdapter) HostAdapter); return false; } - HostAdapter->FlashPointInfo = FlashPointInfo; - if (BusLogic_GlobalOptions.Bits.TraceProbe) + if (BusLogic_GlobalOptions.TraceProbe) BusLogic_Notice("BusLogic_Probe(0x%X): FlashPoint Found\n", HostAdapter, HostAdapter->IO_Address); /* @@ -1283,7 +1292,7 @@ static boolean BusLogic_ProbeHostAdapter(BusLogic_HostAdapter_T *HostAdapter) StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter); InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter); GeometryRegister.All = BusLogic_ReadGeometryRegister(HostAdapter); - if (BusLogic_GlobalOptions.Bits.TraceProbe) + if (BusLogic_GlobalOptions.TraceProbe) BusLogic_Notice("BusLogic_Probe(0x%X): Status 0x%02X, Interrupt 0x%02X, " "Geometry 0x%02X\n", HostAdapter, HostAdapter->IO_Address, StatusRegister.All, @@ -1318,12 +1327,16 @@ static boolean BusLogic_ProbeHostAdapter(BusLogic_HostAdapter_T *HostAdapter) /* - BusLogic_HardResetHostAdapter issues a Hard Reset to the Host Adapter, - and waits for Host Adapter Diagnostics to complete. + BusLogic_HardwareResetHostAdapter issues a Hardware Reset to the Host Adapter + and waits for Host Adapter Diagnostics to complete. If HardReset is true, a + Hard Reset is performed which also initiates a SCSI Bus Reset. Otherwise, a + Soft Reset is performed which only resets the Host Adapter without forcing a + SCSI Bus Reset. */ -static boolean BusLogic_HardResetHostAdapter(BusLogic_HostAdapter_T - *HostAdapter) +static boolean BusLogic_HardwareResetHostAdapter(BusLogic_HostAdapter_T + *HostAdapter, + boolean HardReset) { BusLogic_StatusRegister_T StatusRegister; int TimeoutCounter; @@ -1332,9 +1345,11 @@ static boolean BusLogic_HardResetHostAdapter(BusLogic_HostAdapter_T */ if (BusLogic_FlashPointHostAdapterP(HostAdapter)) { - HostAdapter->FlashPointInfo->ReportDataUnderrun = true; + FlashPoint_Info_T *FlashPointInfo = &HostAdapter->FlashPointInfo; + FlashPointInfo->HostSoftReset = !HardReset; + FlashPointInfo->ReportDataUnderrun = true; HostAdapter->CardHandle = - FlashPoint_HardResetHostAdapter(HostAdapter->FlashPointInfo); + FlashPoint_HardwareResetHostAdapter(FlashPointInfo); if (HostAdapter->CardHandle == FlashPoint_BadCardHandle) return false; /* Indicate the Host Adapter Hard Reset completed successfully. @@ -1342,10 +1357,12 @@ static boolean BusLogic_HardResetHostAdapter(BusLogic_HostAdapter_T return true; } /* - Issue a Hard Reset Command to the Host Adapter. The Host Adapter should - respond by setting Diagnostic Active in the Status Register. + Issue a Hard Reset or Soft Reset Command to the Host Adapter. The Host + Adapter should respond by setting Diagnostic Active in the Status Register. */ - BusLogic_HardReset(HostAdapter); + if (HardReset) + BusLogic_HardReset(HostAdapter); + else BusLogic_SoftReset(HostAdapter); /* Wait until Diagnostic Active is set in the Status Register. */ @@ -1356,8 +1373,8 @@ static boolean BusLogic_HardResetHostAdapter(BusLogic_HostAdapter_T if (StatusRegister.Bits.DiagnosticActive) break; udelay(100); } - if (BusLogic_GlobalOptions.Bits.TraceHardReset) - BusLogic_Notice("BusLogic_HardReset(0x%X): Diagnostic Active, " + if (BusLogic_GlobalOptions.TraceHardwareReset) + BusLogic_Notice("BusLogic_HardwareReset(0x%X): Diagnostic Active, " "Status 0x%02X\n", HostAdapter, HostAdapter->IO_Address, StatusRegister.All); if (TimeoutCounter < 0) return false; @@ -1377,8 +1394,8 @@ static boolean BusLogic_HardResetHostAdapter(BusLogic_HostAdapter_T if (!StatusRegister.Bits.DiagnosticActive) break; udelay(100); } - if (BusLogic_GlobalOptions.Bits.TraceHardReset) - BusLogic_Notice("BusLogic_HardReset(0x%X): Diagnostic Completed, " + if (BusLogic_GlobalOptions.TraceHardwareReset) + BusLogic_Notice("BusLogic_HardwareReset(0x%X): Diagnostic Completed, " "Status 0x%02X\n", HostAdapter, HostAdapter->IO_Address, StatusRegister.All); if (TimeoutCounter < 0) return false; @@ -1396,8 +1413,8 @@ static boolean BusLogic_HardResetHostAdapter(BusLogic_HostAdapter_T break; udelay(100); } - if (BusLogic_GlobalOptions.Bits.TraceHardReset) - BusLogic_Notice("BusLogic_HardReset(0x%X): Host Adapter Ready, " + if (BusLogic_GlobalOptions.TraceHardwareReset) + BusLogic_Notice("BusLogic_HardwareReset(0x%X): Host Adapter Ready, " "Status 0x%02X\n", HostAdapter, HostAdapter->IO_Address, StatusRegister.All); if (TimeoutCounter < 0) return false; @@ -1447,25 +1464,27 @@ static boolean BusLogic_CheckHostAdapter(BusLogic_HostAdapter_T *HostAdapter) Issue the Inquire Configuration command if the IRQ Channel is unknown. */ if (HostAdapter->IRQ_Channel == 0) - if (BusLogic_Command(HostAdapter, BusLogic_InquireConfiguration, - NULL, 0, &Configuration, sizeof(Configuration)) - == sizeof(Configuration)) - { - if (Configuration.IRQ_Channel9) - HostAdapter->IRQ_Channel = 9; - else if (Configuration.IRQ_Channel10) - HostAdapter->IRQ_Channel = 10; - else if (Configuration.IRQ_Channel11) - HostAdapter->IRQ_Channel = 11; - else if (Configuration.IRQ_Channel12) - HostAdapter->IRQ_Channel = 12; - else if (Configuration.IRQ_Channel14) - HostAdapter->IRQ_Channel = 14; - else if (Configuration.IRQ_Channel15) - HostAdapter->IRQ_Channel = 15; - else Result = false; - } - else Result = false; + { + if (BusLogic_Command(HostAdapter, BusLogic_InquireConfiguration, + NULL, 0, &Configuration, sizeof(Configuration)) + == sizeof(Configuration)) + { + if (Configuration.IRQ_Channel9) + HostAdapter->IRQ_Channel = 9; + else if (Configuration.IRQ_Channel10) + HostAdapter->IRQ_Channel = 10; + else if (Configuration.IRQ_Channel11) + HostAdapter->IRQ_Channel = 11; + else if (Configuration.IRQ_Channel12) + HostAdapter->IRQ_Channel = 12; + else if (Configuration.IRQ_Channel14) + HostAdapter->IRQ_Channel = 14; + else if (Configuration.IRQ_Channel15) + HostAdapter->IRQ_Channel = 15; + else Result = false; + } + else Result = false; + } /* Issue the Inquire Extended Setup Information command. Only genuine BusLogic Host Adapters and true clones support this command. Adaptec 1542C @@ -1484,7 +1503,7 @@ static boolean BusLogic_CheckHostAdapter(BusLogic_HostAdapter_T *HostAdapter) /* Provide tracing information if requested and return. */ - if (BusLogic_GlobalOptions.Bits.TraceProbe) + if (BusLogic_GlobalOptions.TraceProbe) BusLogic_Notice("BusLogic_Check(0x%X): MultiMaster %s\n", HostAdapter, HostAdapter->IO_Address, (Result ? "Found" : "Not Found")); return Result; @@ -1512,7 +1531,7 @@ static boolean BusLogic_ReadHostAdapterConfiguration(BusLogic_HostAdapter_T BusLogic_GeometryRegister_T GeometryRegister; BusLogic_RequestedReplyLength_T RequestedReplyLength; unsigned char *TargetPointer, Character; - int i; + int TargetID, i; /* Configuration Information for FlashPoint Host Adapters is provided in the FlashPoint_Info structure by the FlashPoint SCCB Manager's Probe Function. @@ -1521,7 +1540,7 @@ static boolean BusLogic_ReadHostAdapterConfiguration(BusLogic_HostAdapter_T */ if (BusLogic_FlashPointHostAdapterP(HostAdapter)) { - FlashPoint_Info_T *FlashPointInfo = HostAdapter->FlashPointInfo; + FlashPoint_Info_T *FlashPointInfo = &HostAdapter->FlashPointInfo; TargetPointer = HostAdapter->ModelName; *TargetPointer++ = 'B'; *TargetPointer++ = 'T'; @@ -1550,8 +1569,8 @@ static boolean BusLogic_ReadHostAdapterConfiguration(BusLogic_HostAdapter_T HostAdapter->DriverScatterGatherLimit = BusLogic_ScatterGatherLimit; HostAdapter->MaxTargetDevices = (HostAdapter->HostWideSCSI ? 16 : 8); HostAdapter->MaxLogicalUnits = 32; - HostAdapter->InitialCCBs = 64; - HostAdapter->IncrementalCCBs = 16; + HostAdapter->InitialCCBs = 4 * BusLogic_CCB_AllocationGroupSize; + HostAdapter->IncrementalCCBs = BusLogic_CCB_AllocationGroupSize; HostAdapter->DriverQueueDepth = 255; HostAdapter->HostAdapterQueueDepth = HostAdapter->DriverQueueDepth; HostAdapter->SynchronousPermitted = FlashPointInfo->SynchronousPermitted; @@ -1698,12 +1717,14 @@ static boolean BusLogic_ReadHostAdapterConfiguration(BusLogic_HostAdapter_T HostAdapter->HostAdapterBusType = BusLogic_HostAdapterBusTypes[HostAdapter->ModelName[3] - '4']; if (HostAdapter->HostAdapterBusType == BusLogic_ISA_Bus) - if (Configuration.DMA_Channel5) - HostAdapter->DMA_Channel = 5; - else if (Configuration.DMA_Channel6) - HostAdapter->DMA_Channel = 6; - else if (Configuration.DMA_Channel7) - HostAdapter->DMA_Channel = 7; + { + if (Configuration.DMA_Channel5) + HostAdapter->DMA_Channel = 5; + else if (Configuration.DMA_Channel6) + HostAdapter->DMA_Channel = 6; + else if (Configuration.DMA_Channel7) + HostAdapter->DMA_Channel = 7; + } /* Determine whether Extended Translation is enabled and save it in the Host Adapter structure. @@ -1837,7 +1858,7 @@ static boolean BusLogic_ReadHostAdapterConfiguration(BusLogic_HostAdapter_T HostAdapter->MaxTargetDevices = (HostAdapter->HostWideSCSI ? 16 : 8); HostAdapter->MaxLogicalUnits = (HostAdapter->ExtendedLUNSupport ? 32 : 8); /* - Select appropriate values for the Driver Queue Depth, Mailbox Count, + Select appropriate values for the Mailbox Count, Driver Queue Depth, Initial CCBs, and Incremental CCBs variables based on whether or not Strict Round Robin Mode is supported. If Strict Round Robin Mode is supported, then there is no performance degradation in using the maximum possible @@ -1868,18 +1889,16 @@ static boolean BusLogic_ReadHostAdapterConfiguration(BusLogic_HostAdapter_T if (strcmp(HostAdapter->FirmwareVersion, "3.31") >= 0) { HostAdapter->StrictRoundRobinModeSupport = true; - HostAdapter->MailboxCount = 255; - HostAdapter->InitialCCBs = 64; - HostAdapter->IncrementalCCBs = 16; + HostAdapter->MailboxCount = BusLogic_MaxMailboxes; } else { HostAdapter->StrictRoundRobinModeSupport = false; HostAdapter->MailboxCount = 32; - HostAdapter->InitialCCBs = 32; - HostAdapter->IncrementalCCBs = 8; } HostAdapter->DriverQueueDepth = HostAdapter->MailboxCount; + HostAdapter->InitialCCBs = 4 * BusLogic_CCB_AllocationGroupSize; + HostAdapter->IncrementalCCBs = BusLogic_CCB_AllocationGroupSize; /* Tagged Queuing support is available and operates properly on all "W" series MultiMaster Host Adapters, on "C" series MultiMaster Host Adapters with @@ -1931,57 +1950,32 @@ static boolean BusLogic_ReadHostAdapterConfiguration(BusLogic_HostAdapter_T */ Common: /* - Initialize the Host Adapter Name and Interrupt Label fields from the - Model Name. + Initialize the Host Adapter Full Model Name and Interrupt Label fields + from the Model Name. */ strcpy(HostAdapter->FullModelName, "BusLogic "); strcat(HostAdapter->FullModelName, HostAdapter->ModelName); strcpy(HostAdapter->InterruptLabel, HostAdapter->FullModelName); /* Select an appropriate value for the Tagged Queue Depth either from a - Command Line Entry, or based on whether this Host Adapter requires that ISA - Bounce Buffers be used. The Tagged Queue Depth is left at 0 for automatic - determination in BusLogic_SelectQueueDepths. Initialize the Untagged Queue - Depth. Tagged Queuing is disabled by default when the Tagged Queue Depth - is 1 since queuing multiple commands is not possible. - */ - if (HostAdapter->CommandLineEntry != NULL && - HostAdapter->CommandLineEntry->TaggedQueueDepth > 0) - HostAdapter->TaggedQueueDepth = - HostAdapter->CommandLineEntry->TaggedQueueDepth; - else if (HostAdapter->BounceBuffersRequired) - HostAdapter->TaggedQueueDepth = BusLogic_TaggedQueueDepthBounceBuffers; - else HostAdapter->TaggedQueueDepth = BusLogic_TaggedQueueDepthAutomatic; - HostAdapter->UntaggedQueueDepth = BusLogic_UntaggedQueueDepth; - if (HostAdapter->UntaggedQueueDepth > HostAdapter->TaggedQueueDepth && - HostAdapter->TaggedQueueDepth > 0) - HostAdapter->UntaggedQueueDepth = HostAdapter->TaggedQueueDepth; - if (HostAdapter->TaggedQueueDepth == 1) - HostAdapter->TaggedQueuingPermitted = 0; - /* - Select an appropriate value for Bus Settle Time either from a Command - Line Entry, or from BusLogic_DefaultBusSettleTime. - */ - if (HostAdapter->CommandLineEntry != NULL && - HostAdapter->CommandLineEntry->BusSettleTime > 0) - HostAdapter->BusSettleTime = HostAdapter->CommandLineEntry->BusSettleTime; - else HostAdapter->BusSettleTime = BusLogic_DefaultBusSettleTime; - /* - Select an appropriate value for Local Options from a Command Line Entry. - */ - if (HostAdapter->CommandLineEntry != NULL) - HostAdapter->LocalOptions = HostAdapter->CommandLineEntry->LocalOptions; - /* - Select appropriate values for the Error Recovery Strategy array either from - a Command Line Entry, or using BusLogic_ErrorRecovery_Default. + BusLogic Driver Options specification, or based on whether this Host + Adapter requires that ISA Bounce Buffers be used. The Tagged Queue Depth + is left at 0 for automatic determination in BusLogic_SelectQueueDepths. + Initialize the Untagged Queue Depth. */ - if (HostAdapter->CommandLineEntry != NULL) - memcpy(HostAdapter->ErrorRecoveryStrategy, - HostAdapter->CommandLineEntry->ErrorRecoveryStrategy, - sizeof(HostAdapter->ErrorRecoveryStrategy)); - else memset(HostAdapter->ErrorRecoveryStrategy, - BusLogic_ErrorRecovery_Default, - sizeof(HostAdapter->ErrorRecoveryStrategy)); + for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++) + { + unsigned char QueueDepth = 0; + if (HostAdapter->DriverOptions != NULL && + HostAdapter->DriverOptions->QueueDepth[TargetID] > 0) + QueueDepth = HostAdapter->DriverOptions->QueueDepth[TargetID]; + else if (HostAdapter->BounceBuffersRequired) + QueueDepth = BusLogic_TaggedQueueDepthBB; + HostAdapter->QueueDepth[TargetID] = QueueDepth; + } + if (HostAdapter->BounceBuffersRequired) + HostAdapter->UntaggedQueueDepth = BusLogic_UntaggedQueueDepthBB; + else HostAdapter->UntaggedQueueDepth = BusLogic_UntaggedQueueDepth; /* Tagged Queuing is only allowed if Disconnect/Reconnect is permitted. Therefore, mask the Tagged Queuing Permitted Default bits with the @@ -1989,15 +1983,34 @@ Common: */ HostAdapter->TaggedQueuingPermitted &= HostAdapter->DisconnectPermitted; /* - Combine the default Tagged Queuing Permitted bits with any Command - Line Entry Tagged Queuing specification. + Combine the default Tagged Queuing Permitted bits with any BusLogic Driver + Options Tagged Queuing specification. */ - if (HostAdapter->CommandLineEntry != NULL) + if (HostAdapter->DriverOptions != NULL) HostAdapter->TaggedQueuingPermitted = - (HostAdapter->CommandLineEntry->TaggedQueuingPermitted & - HostAdapter->CommandLineEntry->TaggedQueuingPermittedMask) | + (HostAdapter->DriverOptions->TaggedQueuingPermitted & + HostAdapter->DriverOptions->TaggedQueuingPermittedMask) | (HostAdapter->TaggedQueuingPermitted & - ~HostAdapter->CommandLineEntry->TaggedQueuingPermittedMask); + ~HostAdapter->DriverOptions->TaggedQueuingPermittedMask); + /* + Select appropriate values for the Error Recovery Strategy array + either from a BusLogic Driver Options specification, or using + BusLogic_ErrorRecovery_Default. + */ + for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++) + if (HostAdapter->DriverOptions != NULL) + HostAdapter->ErrorRecoveryStrategy[TargetID] = + HostAdapter->DriverOptions->ErrorRecoveryStrategy[TargetID]; + else HostAdapter->ErrorRecoveryStrategy[TargetID] = + BusLogic_ErrorRecovery_Default; + /* + Select an appropriate value for Bus Settle Time either from a BusLogic + Driver Options specification, or from BusLogic_DefaultBusSettleTime. + */ + if (HostAdapter->DriverOptions != NULL && + HostAdapter->DriverOptions->BusSettleTime > 0) + HostAdapter->BusSettleTime = HostAdapter->DriverOptions->BusSettleTime; + else HostAdapter->BusSettleTime = BusLogic_DefaultBusSettleTime; /* Indicate reading the Host Adapter Configuration completed successfully. */ @@ -2017,7 +2030,8 @@ static boolean BusLogic_ReportHostAdapterConfiguration(BusLogic_HostAdapter_T unsigned short SynchronousPermitted, FastPermitted; unsigned short UltraPermitted, WidePermitted; unsigned short DisconnectPermitted, TaggedQueuingPermitted; - boolean CommonSynchronousNegotiation, CommonErrorRecovery; + boolean CommonSynchronousNegotiation, CommonTaggedQueueDepth; + boolean CommonErrorRecovery; char SynchronousString[BusLogic_MaxTargetDevices+1]; char WideString[BusLogic_MaxTargetDevices+1]; char DisconnectString[BusLogic_MaxTargetDevices+1]; @@ -2083,22 +2097,26 @@ static boolean BusLogic_ReportHostAdapterConfiguration(BusLogic_HostAdapter_T CommonSynchronousNegotiation = true; } else if (SynchronousPermitted == AllTargetsMask) - if (FastPermitted == 0) - { - SynchronousMessage = "Slow"; - CommonSynchronousNegotiation = true; - } - else if (FastPermitted == AllTargetsMask) - if (UltraPermitted == 0) + { + if (FastPermitted == 0) { - SynchronousMessage = "Fast"; + SynchronousMessage = "Slow"; CommonSynchronousNegotiation = true; } - else if (UltraPermitted == AllTargetsMask) + else if (FastPermitted == AllTargetsMask) { - SynchronousMessage = "Ultra"; - CommonSynchronousNegotiation = true; + if (UltraPermitted == 0) + { + SynchronousMessage = "Fast"; + CommonSynchronousNegotiation = true; + } + else if (UltraPermitted == AllTargetsMask) + { + SynchronousMessage = "Ultra"; + CommonSynchronousNegotiation = true; + } } + } if (!CommonSynchronousNegotiation) { for (TargetID = 0; @@ -2175,9 +2193,20 @@ static boolean BusLogic_ReportHostAdapterConfiguration(BusLogic_HostAdapter_T HostAdapter, HostAdapter->DriverQueueDepth, HostAdapter->DriverScatterGatherLimit); BusLogic_Info(" Tagged Queue Depth: ", HostAdapter); - if (HostAdapter->TaggedQueueDepth > 0) - BusLogic_Info("%d", HostAdapter, HostAdapter->TaggedQueueDepth); - else BusLogic_Info("Automatic", HostAdapter); + CommonTaggedQueueDepth = true; + for (TargetID = 1; TargetID < HostAdapter->MaxTargetDevices; TargetID++) + if (HostAdapter->QueueDepth[TargetID] != HostAdapter->QueueDepth[0]) + { + CommonTaggedQueueDepth = false; + break; + } + if (CommonTaggedQueueDepth) + { + if (HostAdapter->QueueDepth[0] > 0) + BusLogic_Info("%d", HostAdapter, HostAdapter->QueueDepth[0]); + else BusLogic_Info("Automatic", HostAdapter); + } + else BusLogic_Info("Individual", HostAdapter); BusLogic_Info(", Untagged Queue Depth: %d\n", HostAdapter, HostAdapter->UntaggedQueueDepth); CommonErrorRecovery = true; @@ -2313,50 +2342,6 @@ static void BusLogic_ReleaseResources(BusLogic_HostAdapter_T *HostAdapter) } -/* - BusLogic_TestInterrupts tests for proper functioning of the Host Adapter - Interrupt Register and that interrupts generated by the Host Adapter are - getting through to the Interrupt Handler. A large proportion of initial - problems with installing PCI Host Adapters are due to configuration problems - where either the Host Adapter or Motherboard is configured incorrectly, and - interrupts do not get through as a result. -*/ - -static boolean BusLogic_TestInterrupts(BusLogic_HostAdapter_T *HostAdapter) -{ - unsigned int InitialInterruptCount, FinalInterruptCount; - int TestCount = 5, i; - /* - FlashPoint Host Adapters do not provide for an interrupt test. - */ - if (BusLogic_FlashPointHostAdapterP(HostAdapter)) return true; - /* - Inhibit the Interrupt Test if requested. - */ - if (HostAdapter->LocalOptions.Bits.InhibitInterruptTest) return true; - /* - Issue the Test Command Complete Interrupt commands. - */ - InitialInterruptCount = kstat.interrupts[HostAdapter->IRQ_Channel]; - for (i = 0; i < TestCount; i++) - BusLogic_Command(HostAdapter, BusLogic_TestCommandCompleteInterrupt, - NULL, 0, NULL, 0); - FinalInterruptCount = kstat.interrupts[HostAdapter->IRQ_Channel]; - /* - Verify that BusLogic_InterruptHandler was called at least TestCount - times. Shared IRQ Channels could cause more than TestCount interrupts to - occur, but there should never be fewer than TestCount, unless one or more - interrupts were lost. - */ - if (FinalInterruptCount < InitialInterruptCount + TestCount) - return BusLogic_Failure(HostAdapter, "HOST ADAPTER INTERRUPT TEST"); - /* - Indicate the Host Adapter Interrupt Test completed successfully. - */ - return true; -} - - /* BusLogic_InitializeHostAdapter initializes Host Adapter. This is the only function called during SCSI Host Adapter detection which modifies the state @@ -2376,19 +2361,30 @@ static boolean BusLogic_InitializeHostAdapter(BusLogic_HostAdapter_T for each Target Device. */ for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) - HostAdapter->BusDeviceResetPendingCCB[TargetID] = NULL; - memset(HostAdapter->TaggedQueuingActive, false, - sizeof(HostAdapter->TaggedQueuingActive)); - memset(HostAdapter->CommandSuccessfulFlag, false, - sizeof(HostAdapter->CommandSuccessfulFlag)); - memset(HostAdapter->ActiveCommands, 0, - sizeof(HostAdapter->ActiveCommands)); - memset(HostAdapter->CommandsSinceReset, 0, - sizeof(HostAdapter->CommandsSinceReset)); + { + HostAdapter->BusDeviceResetPendingCCB[TargetID] = NULL; + HostAdapter->TargetFlags[TargetID].TaggedQueuingActive = false; + HostAdapter->TargetFlags[TargetID].CommandSuccessfulFlag = false; + HostAdapter->ActiveCommands[TargetID] = 0; + HostAdapter->CommandsSinceReset[TargetID] = 0; + } /* FlashPoint Host Adapters do not use Outgoing and Incoming Mailboxes. */ if (BusLogic_FlashPointHostAdapterP(HostAdapter)) goto Done; + /* + Initialize the Outgoing and Incoming Mailbox pointers. + */ + HostAdapter->FirstOutgoingMailbox = + (BusLogic_OutgoingMailbox_T *) HostAdapter->MailboxSpace; + HostAdapter->LastOutgoingMailbox = + HostAdapter->FirstOutgoingMailbox + HostAdapter->MailboxCount - 1; + HostAdapter->NextOutgoingMailbox = HostAdapter->FirstOutgoingMailbox; + HostAdapter->FirstIncomingMailbox = + (BusLogic_IncomingMailbox_T *) (HostAdapter->LastOutgoingMailbox + 1); + HostAdapter->LastIncomingMailbox = + HostAdapter->FirstIncomingMailbox + HostAdapter->MailboxCount - 1; + HostAdapter->NextIncomingMailbox = HostAdapter->FirstIncomingMailbox; /* Initialize the Outgoing and Incoming Mailbox structures. */ @@ -2396,11 +2392,6 @@ static boolean BusLogic_InitializeHostAdapter(BusLogic_HostAdapter_T HostAdapter->MailboxCount * sizeof(BusLogic_OutgoingMailbox_T)); memset(HostAdapter->FirstIncomingMailbox, 0, HostAdapter->MailboxCount * sizeof(BusLogic_IncomingMailbox_T)); - /* - Initialize the pointers to the Next Mailboxes. - */ - HostAdapter->NextOutgoingMailbox = HostAdapter->FirstOutgoingMailbox; - HostAdapter->NextIncomingMailbox = HostAdapter->FirstIncomingMailbox; /* Initialize the Host Adapter's Pointer to the Outgoing/Incoming Mailboxes. */ @@ -2442,11 +2433,14 @@ static boolean BusLogic_InitializeHostAdapter(BusLogic_HostAdapter_T Announce Successful Initialization. */ Done: - if (HostAdapter->HostAdapterInitialized) - BusLogic_Warning("*** %s Initialized Successfully ***\n", - HostAdapter, HostAdapter->FullModelName); - else BusLogic_Info("*** %s Initialized Successfully ***\n", - HostAdapter, HostAdapter->FullModelName); + if (!HostAdapter->HostAdapterInitialized) + { + BusLogic_Info("*** %s Initialized Successfully ***\n", + HostAdapter, HostAdapter->FullModelName); + BusLogic_Info("\n", HostAdapter); + } + else BusLogic_Warning("*** %s Initialized Successfully ***\n", + HostAdapter, HostAdapter->FullModelName); HostAdapter->HostAdapterInitialized = true; /* Indicate the Host Adapter Initialization completed successfully. @@ -2457,7 +2451,7 @@ Done: /* BusLogic_TargetDeviceInquiry inquires about the Target Devices accessible - through Host Adapter and reports on the results. + through Host Adapter. */ static boolean BusLogic_TargetDeviceInquiry(BusLogic_HostAdapter_T @@ -2468,7 +2462,7 @@ static boolean BusLogic_TargetDeviceInquiry(BusLogic_HostAdapter_T BusLogic_SetupInformation_T SetupInformation; BusLogic_SynchronousPeriod_T SynchronousPeriod; BusLogic_RequestedReplyLength_T RequestedReplyLength; - int TargetDevicesFound = 0, TargetID; + int TargetID; /* Wait a few seconds between the Host Adapter Hard Reset which initiates a SCSI Bus Reset and issuing any SCSI Commands. Some SCSI devices get @@ -2480,13 +2474,11 @@ static boolean BusLogic_TargetDeviceInquiry(BusLogic_HostAdapter_T */ if (BusLogic_FlashPointHostAdapterP(HostAdapter)) return true; /* - Inhibit the Target Devices Inquiry if requested. + Inhibit the Target Device Inquiry if requested. */ - if (HostAdapter->LocalOptions.Bits.InhibitTargetInquiry) - { - BusLogic_Info(" Target Device Inquiry Inhibited\n", HostAdapter); - return true; - } + if (HostAdapter->DriverOptions != NULL && + HostAdapter->DriverOptions->LocalOptions.InhibitTargetInquiry) + return true; /* Issue the Inquire Target Devices command for host adapters with firmware version 4.25 or later, or the Inquire Installed Devices ID 0 to 7 command @@ -2502,6 +2494,9 @@ static boolean BusLogic_TargetDeviceInquiry(BusLogic_HostAdapter_T &InstalledDevices, sizeof(InstalledDevices)) != sizeof(InstalledDevices)) return BusLogic_Failure(HostAdapter, "INQUIRE TARGET DEVICES"); + for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) + HostAdapter->TargetFlags[TargetID].TargetExists = + (InstalledDevices & (1 << TargetID) ? true : false); } else { @@ -2511,10 +2506,9 @@ static boolean BusLogic_TargetDeviceInquiry(BusLogic_HostAdapter_T != sizeof(InstalledDevicesID0to7)) return BusLogic_Failure(HostAdapter, "INQUIRE INSTALLED DEVICES ID 0 TO 7"); - InstalledDevices = 0; for (TargetID = 0; TargetID < 8; TargetID++) - if (InstalledDevicesID0to7[TargetID] != 0) - InstalledDevices |= (1 << TargetID); + HostAdapter->TargetFlags[TargetID].TargetExists = + (InstalledDevicesID0to7[TargetID] != 0 ? true : false); } /* Issue the Inquire Setup Information command. @@ -2525,6 +2519,19 @@ static boolean BusLogic_TargetDeviceInquiry(BusLogic_HostAdapter_T &SetupInformation, sizeof(SetupInformation)) != sizeof(SetupInformation)) return BusLogic_Failure(HostAdapter, "INQUIRE SETUP INFORMATION"); + for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) + HostAdapter->SynchronousOffset[TargetID] = + (TargetID < 8 + ? SetupInformation.SynchronousValuesID0to7[TargetID].Offset + : SetupInformation.SynchronousValuesID8to15[TargetID-8].Offset); + if (strcmp(HostAdapter->FirmwareVersion, "5.06L") >= 0) + for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) + HostAdapter->TargetFlags[TargetID].WideTransfersActive = + (TargetID < 8 + ? (SetupInformation.WideTransfersActiveID0to7 & (1 << TargetID) + ? true : false) + : (SetupInformation.WideTransfersActiveID8to15 & (1 << (TargetID-8)) + ? true : false)); /* Issue the Inquire Synchronous Period command. */ @@ -2536,69 +2543,96 @@ static boolean BusLogic_TargetDeviceInquiry(BusLogic_HostAdapter_T &SynchronousPeriod, sizeof(SynchronousPeriod)) != sizeof(SynchronousPeriod)) return BusLogic_Failure(HostAdapter, "INQUIRE SYNCHRONOUS PERIOD"); + for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) + HostAdapter->SynchronousPeriod[TargetID] = SynchronousPeriod[TargetID]; } else for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) if (SetupInformation.SynchronousValuesID0to7[TargetID].Offset > 0) - SynchronousPeriod[TargetID] = + HostAdapter->SynchronousPeriod[TargetID] = 20 + 5 * SetupInformation.SynchronousValuesID0to7[TargetID] .TransferPeriod; - else SynchronousPeriod[TargetID] = 0; /* - Save the Installed Devices, Synchronous Values, and Synchronous Period - information in the Host Adapter structure. + Indicate the Target Device Inquiry completed successfully. + */ + return true; +} + + +/* + BusLogic_ReportTargetDeviceInfo reports about the Target Devices accessible + through Host Adapter. +*/ + +static void BusLogic_ReportTargetDeviceInfo(BusLogic_HostAdapter_T + *HostAdapter) +{ + int TargetID; + /* + Inhibit the Target Device Inquiry and Reporting if requested. */ - HostAdapter->InstalledDevices = InstalledDevices; - memcpy(HostAdapter->SynchronousValues, - SetupInformation.SynchronousValuesID0to7, - sizeof(BusLogic_SynchronousValues8_T)); - if (HostAdapter->HostWideSCSI) - memcpy(&HostAdapter->SynchronousValues[8], - SetupInformation.SynchronousValuesID8to15, - sizeof(BusLogic_SynchronousValues8_T)); - memcpy(HostAdapter->SynchronousPeriod, SynchronousPeriod, - sizeof(BusLogic_SynchronousPeriod_T)); + if (BusLogic_MultiMasterHostAdapterP(HostAdapter) && + HostAdapter->DriverOptions != NULL && + HostAdapter->DriverOptions->LocalOptions.InhibitTargetInquiry) + return; /* Report on the Target Devices found. */ for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) - if (HostAdapter->InstalledDevices & (1 << TargetID)) - { - int SynchronousPeriod = HostAdapter->SynchronousPeriod[TargetID]; - if (SynchronousPeriod > 10) - { - int SynchronousTransferRate = 100000000 / SynchronousPeriod; - int RoundedSynchronousTransferRate = - (SynchronousTransferRate + 5000) / 10000; - BusLogic_Info(" Target %d: Synchronous at " - "%d.%02d mega-transfers/second, offset %d\n", - HostAdapter, TargetID, - RoundedSynchronousTransferRate / 100, - RoundedSynchronousTransferRate % 100, - HostAdapter->SynchronousValues[TargetID].Offset); - } - else if (SynchronousPeriod > 0) - { - int SynchronousTransferRate = 100000000 / SynchronousPeriod; - int RoundedSynchronousTransferRate = - (SynchronousTransferRate + 50000) / 100000; - BusLogic_Info(" Target %d: Synchronous at " - "%d.%01d mega-transfers/second, offset %d\n", - HostAdapter, TargetID, - RoundedSynchronousTransferRate / 10, - RoundedSynchronousTransferRate % 10, - HostAdapter->SynchronousValues[TargetID].Offset); - } - else BusLogic_Info(" Target %d: Asynchronous\n", - HostAdapter, TargetID); - TargetDevicesFound++; - } - if (TargetDevicesFound == 0) - BusLogic_Info(" No Target Devices Found\n", HostAdapter); - /* - Indicate the Target Device Inquiry completed successfully. - */ - return true; + { + BusLogic_TargetFlags_T *TargetFlags = &HostAdapter->TargetFlags[TargetID]; + if (TargetFlags->TargetExists && !TargetFlags->TargetInfoReported) + { + int SynchronousTransferRate = 0; + if (BusLogic_FlashPointHostAdapterP(HostAdapter)) + { + boolean WideTransfersActive; + FlashPoint_InquireTargetInfo( + HostAdapter->CardHandle, TargetID, + &HostAdapter->SynchronousPeriod[TargetID], + &HostAdapter->SynchronousOffset[TargetID], + &WideTransfersActive); + TargetFlags->WideTransfersActive = WideTransfersActive; + } + else if (TargetFlags->WideTransfersSupported && + (HostAdapter->WidePermitted & (1 << TargetID)) && + strcmp(HostAdapter->FirmwareVersion, "5.06L") < 0) + TargetFlags->WideTransfersActive = true; + if (HostAdapter->SynchronousPeriod[TargetID] > 0) + SynchronousTransferRate = + 100000 / HostAdapter->SynchronousPeriod[TargetID]; + if (TargetFlags->WideTransfersActive) + SynchronousTransferRate <<= 1; + if (SynchronousTransferRate >= 9950) + { + SynchronousTransferRate = (SynchronousTransferRate + 50) / 100; + BusLogic_Info("Target %d: Queue Depth %d, %sSynchronous at " + "%d.%01d MB/sec, offset %d\n", + HostAdapter, TargetID, + HostAdapter->QueueDepth[TargetID], + (TargetFlags->WideTransfersActive ? "Wide " : ""), + SynchronousTransferRate / 10, + SynchronousTransferRate % 10, + HostAdapter->SynchronousOffset[TargetID]); + } + else if (SynchronousTransferRate > 0) + { + SynchronousTransferRate = (SynchronousTransferRate + 5) / 10; + BusLogic_Info("Target %d: Queue Depth %d, %sSynchronous at " + "%d.%02d MB/sec, offset %d\n", + HostAdapter, TargetID, + HostAdapter->QueueDepth[TargetID], + (TargetFlags->WideTransfersActive ? "Wide " : ""), + SynchronousTransferRate / 100, + SynchronousTransferRate % 100, + HostAdapter->SynchronousOffset[TargetID]); + } + else BusLogic_Info("Target %d: Queue Depth %d, Asynchronous\n", + HostAdapter, TargetID, + HostAdapter->QueueDepth[TargetID]); + TargetFlags->TargetInfoReported = true; + } + } } @@ -2628,9 +2662,11 @@ static void BusLogic_InitializeHostStructure(BusLogic_HostAdapter_T /* - BusLogic_SelectQueueDepths selects Queue Depths for each Target Device - based on the Host Adapter's Total Queue Depth and the number, type, speed, - and capabilities of the Target Devices. + BusLogic_SelectQueueDepths selects Queue Depths for each Target Device based + on the Host Adapter's Total Queue Depth and the number, type, speed, and + capabilities of the Target Devices. When called for the last Host Adapter, + it reports on the Target Device Information for all BusLogic Host Adapters + since all the Target Devices have now been probed. */ static void BusLogic_SelectQueueDepths(SCSI_Host_T *Host, @@ -2638,41 +2674,60 @@ static void BusLogic_SelectQueueDepths(SCSI_Host_T *Host, { BusLogic_HostAdapter_T *HostAdapter = (BusLogic_HostAdapter_T *) Host->hostdata; - int TaggedQueueDepth = HostAdapter->TaggedQueueDepth; - int UntaggedQueueDepth = HostAdapter->UntaggedQueueDepth; - int TaggedDeviceCount = 0, UntaggedDeviceCount = 0; - int DesiredCCBs = HostAdapter->MaxTargetDevices - 1; + int TaggedDeviceCount = 0, AutomaticTaggedDeviceCount = 0; + int UntaggedDeviceCount = 0, AutomaticTaggedQueueDepth = 0; + int AllocatedQueueDepth = 0; SCSI_Device_T *Device; - for (Device = DeviceList; Device != NULL; Device = Device->next) - if (Device->host == Host) + int TargetID; + for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) + if (HostAdapter->TargetFlags[TargetID].TargetExists) { - if (Device->tagged_supported && - (HostAdapter->TaggedQueuingPermitted & (1 << Device->id))) - TaggedDeviceCount++; + int QueueDepth = HostAdapter->UntaggedQueueDepth; + if (HostAdapter->TargetFlags[TargetID].TaggedQueuingSupported && + (HostAdapter->TaggedQueuingPermitted & (1 << TargetID))) + { + QueueDepth = HostAdapter->QueueDepth[TargetID]; + TaggedDeviceCount++; + if (QueueDepth == 0) AutomaticTaggedDeviceCount++; + } else UntaggedDeviceCount++; + HostAdapter->QueueDepth[TargetID] = QueueDepth; + AllocatedQueueDepth += QueueDepth; } - if (TaggedQueueDepth == 0 && TaggedDeviceCount > 0) + HostAdapter->TargetDeviceCount = TaggedDeviceCount + UntaggedDeviceCount; + if (AutomaticTaggedDeviceCount > 0) { - TaggedQueueDepth = - 1 + ((HostAdapter->HostAdapterQueueDepth - - UntaggedDeviceCount * UntaggedQueueDepth) - / TaggedDeviceCount); - if (TaggedQueueDepth > BusLogic_PreferredTaggedQueueDepth) - TaggedQueueDepth = BusLogic_PreferredTaggedQueueDepth; + AutomaticTaggedQueueDepth = + (HostAdapter->HostAdapterQueueDepth - AllocatedQueueDepth) + / AutomaticTaggedDeviceCount; + if (AutomaticTaggedQueueDepth > BusLogic_MaxAutomaticTaggedQueueDepth) + AutomaticTaggedQueueDepth = BusLogic_MaxAutomaticTaggedQueueDepth; + if (AutomaticTaggedQueueDepth < BusLogic_MinAutomaticTaggedQueueDepth) + AutomaticTaggedQueueDepth = BusLogic_MinAutomaticTaggedQueueDepth; + for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) + if (HostAdapter->TargetFlags[TargetID].TargetExists && + HostAdapter->QueueDepth[TargetID] == 0) + { + AllocatedQueueDepth += AutomaticTaggedQueueDepth; + HostAdapter->QueueDepth[TargetID] = AutomaticTaggedQueueDepth; + } } for (Device = DeviceList; Device != NULL; Device = Device->next) if (Device->host == Host) - { - if (Device->tagged_supported && - (HostAdapter->TaggedQueuingPermitted & (1 << Device->id))) - Device->queue_depth = TaggedQueueDepth; - else Device->queue_depth = UntaggedQueueDepth; - HostAdapter->QueueDepth[Device->id] = Device->queue_depth; - DesiredCCBs += Device->queue_depth; - } + Device->queue_depth = HostAdapter->QueueDepth[Device->id]; + /* Allocate an extra CCB for each Target Device for a Bus Device Reset. */ + AllocatedQueueDepth += HostAdapter->TargetDeviceCount; + if (AllocatedQueueDepth > HostAdapter->DriverQueueDepth) + AllocatedQueueDepth = HostAdapter->DriverQueueDepth; BusLogic_CreateAdditionalCCBs(HostAdapter, - DesiredCCBs - HostAdapter->AllocatedCCBs, + AllocatedQueueDepth + - HostAdapter->AllocatedCCBs, false); + if (HostAdapter == BusLogic_LastRegisteredHostAdapter) + for (HostAdapter = BusLogic_FirstRegisteredHostAdapter; + HostAdapter != NULL; + HostAdapter = HostAdapter->NextAll) + BusLogic_ReportTargetDeviceInfo(HostAdapter); } @@ -2686,50 +2741,48 @@ static void BusLogic_SelectQueueDepths(SCSI_Host_T *Host, int BusLogic_DetectHostAdapter(SCSI_Host_Template_T *HostTemplate) { - int BusLogicHostAdapterCount = 0, CommandLineEntryIndex = 0, ProbeIndex; - char *MessageBuffer = NULL; - if (BusLogic_ProbeOptions.Bits.NoProbe) return 0; - BusLogic_InitializeProbeInfoList(); + int BusLogicHostAdapterCount = 0, DriverOptionsIndex = 0, ProbeIndex; + BusLogic_HostAdapter_T *PrototypeHostAdapter; + if (BusLogic_ProbeOptions.NoProbe) return 0; + BusLogic_ProbeInfoList = (BusLogic_ProbeInfo_T *) + kmalloc(BusLogic_MaxHostAdapters * sizeof(BusLogic_ProbeInfo_T), + GFP_ATOMIC); + if (BusLogic_ProbeInfoList == NULL) + { + BusLogic_Error("BusLogic: Unable to allocate Probe Info List\n", NULL); + return 0; + } + memset(BusLogic_ProbeInfoList, 0, + BusLogic_MaxHostAdapters * sizeof(BusLogic_ProbeInfo_T)); + PrototypeHostAdapter = (BusLogic_HostAdapter_T *) + kmalloc(sizeof(BusLogic_HostAdapter_T), GFP_ATOMIC); + if (PrototypeHostAdapter == NULL) + { + kfree(BusLogic_ProbeInfoList); + BusLogic_Error("BusLogic: Unable to allocate Prototype " + "Host Adapter\n", NULL); + return 0; + } + memset(PrototypeHostAdapter, 0, sizeof(BusLogic_HostAdapter_T)); + if (BusLogic_Options != NULL) + BusLogic_ParseDriverOptions(BusLogic_Options); + BusLogic_InitializeProbeInfoList(PrototypeHostAdapter); for (ProbeIndex = 0; ProbeIndex < BusLogic_ProbeInfoCount; ProbeIndex++) { BusLogic_ProbeInfo_T *ProbeInfo = &BusLogic_ProbeInfoList[ProbeIndex]; - BusLogic_HostAdapter_T HostAdapterPrototype; - BusLogic_HostAdapter_T *HostAdapter = &HostAdapterPrototype; + BusLogic_HostAdapter_T *HostAdapter = PrototypeHostAdapter; SCSI_Host_T *Host; if (ProbeInfo->IO_Address == 0) continue; memset(HostAdapter, 0, sizeof(BusLogic_HostAdapter_T)); - HostAdapter->IO_Address = ProbeInfo->IO_Address; - HostAdapter->PCI_Address = ProbeInfo->PCI_Address; HostAdapter->HostAdapterType = ProbeInfo->HostAdapterType; HostAdapter->HostAdapterBusType = ProbeInfo->HostAdapterBusType; + HostAdapter->IO_Address = ProbeInfo->IO_Address; + HostAdapter->PCI_Address = ProbeInfo->PCI_Address; HostAdapter->Bus = ProbeInfo->Bus; HostAdapter->Device = ProbeInfo->Device; HostAdapter->IRQ_Channel = ProbeInfo->IRQ_Channel; HostAdapter->AddressCount = - BusLogic_HostAdapter_AddressCount[HostAdapter->HostAdapterType]; - if (MessageBuffer == NULL) - MessageBuffer = - scsi_init_malloc(BusLogic_MessageBufferSize, GFP_ATOMIC); - if (MessageBuffer == NULL) - { - BusLogic_Error("BusLogic: Unable to allocate Message Buffer\n", - HostAdapter); - return BusLogicHostAdapterCount; - } - HostAdapter->MessageBuffer = MessageBuffer; - /* - If an explicit I/O Address was specified, Initialize the Command Line - Entry field and inhibit the check for whether the I/O Address range is - already in use. - */ - if (CommandLineEntryIndex < BusLogic_CommandLineEntryCount && - BusLogic_CommandLineEntries[CommandLineEntryIndex].IO_Address == - HostAdapter->IO_Address) - HostAdapter->CommandLineEntry = - &BusLogic_CommandLineEntries[CommandLineEntryIndex++]; - else if (check_region(HostAdapter->IO_Address, - HostAdapter->AddressCount) < 0) - continue; + BusLogic_HostAdapterAddressCount[HostAdapter->HostAdapterType]; /* Probe the Host Adapter. If unsuccessful, abort further initialization. */ @@ -2738,22 +2791,20 @@ int BusLogic_DetectHostAdapter(SCSI_Host_Template_T *HostTemplate) Hard Reset the Host Adapter. If unsuccessful, abort further initialization. */ - if (!BusLogic_HardResetHostAdapter(HostAdapter)) continue; + if (!BusLogic_HardwareResetHostAdapter(HostAdapter, true)) continue; /* Check the Host Adapter. If unsuccessful, abort further initialization. */ if (!BusLogic_CheckHostAdapter(HostAdapter)) continue; /* - Initialize the Command Line Entry field if an explicit I/O Address - was not specified. + Initialize the Driver Options field if provided. */ - if (CommandLineEntryIndex < BusLogic_CommandLineEntryCount && - BusLogic_CommandLineEntries[CommandLineEntryIndex].IO_Address == 0) - HostAdapter->CommandLineEntry = - &BusLogic_CommandLineEntries[CommandLineEntryIndex++]; + if (DriverOptionsIndex < BusLogic_DriverOptionsCount) + HostAdapter->DriverOptions = + &BusLogic_DriverOptions[DriverOptionsIndex++]; /* Announce the Driver Version and Date, Author's Name, Copyright Notice, - and Contact Address. + and Electronic Mail Address. */ BusLogic_AnnounceDriver(HostAdapter); /* @@ -2771,8 +2822,7 @@ int BusLogic_DetectHostAdapter(SCSI_Host_Template_T *HostTemplate) */ Host = scsi_register(HostTemplate, sizeof(BusLogic_HostAdapter_T)); HostAdapter = (BusLogic_HostAdapter_T *) Host->hostdata; - memcpy(HostAdapter, &HostAdapterPrototype, - sizeof(BusLogic_HostAdapter_T)); + memcpy(HostAdapter, PrototypeHostAdapter, sizeof(BusLogic_HostAdapter_T)); HostAdapter->SCSI_Host = Host; HostAdapter->HostNumber = Host->host_no; Host->select_queue_depths = BusLogic_SelectQueueDepths; @@ -2785,18 +2835,14 @@ int BusLogic_DetectHostAdapter(SCSI_Host_Template_T *HostTemplate) BusLogic_RegisterHostAdapter(HostAdapter); /* Read the Host Adapter Configuration, Configure the Host Adapter, - Acquire the System Resources necessary to use the Host Adapter, - then Test Interrupts, Create the Mailboxes, Initial CCBs, and - Target Device Statistics, Initialize the Host Adapter, and - finally perform Target Device Inquiry. + Acquire the System Resources necessary to use the Host Adapter, then + Create the Initial CCBs, Initialize the Host Adapter, and finally + perform Target Device Inquiry. */ if (BusLogic_ReadHostAdapterConfiguration(HostAdapter) && BusLogic_ReportHostAdapterConfiguration(HostAdapter) && BusLogic_AcquireResources(HostAdapter) && - BusLogic_TestInterrupts(HostAdapter) && - BusLogic_CreateMailboxes(HostAdapter) && BusLogic_CreateInitialCCBs(HostAdapter) && - BusLogic_CreateTargetDeviceStatistics(HostAdapter) && BusLogic_InitializeHostAdapter(HostAdapter) && BusLogic_TargetDeviceInquiry(HostAdapter)) { @@ -2806,7 +2852,6 @@ int BusLogic_DetectHostAdapter(SCSI_Host_Template_T *HostTemplate) Name of the Host Adapter will appear, and initialize the SCSI Host structure. */ - MessageBuffer = NULL; release_region(HostAdapter->IO_Address, HostAdapter->AddressCount); request_region(HostAdapter->IO_Address, @@ -2818,24 +2863,22 @@ int BusLogic_DetectHostAdapter(SCSI_Host_Template_T *HostTemplate) else { /* - An error occurred during Host Adapter Configuration Querying, - Host Adapter Configuration, Resource Acquisition, Interrupt - Testing, CCB Creation, Host Adapter Initialization, or Target - Device Inquiry, so remove Host Adapter from the list of - registered BusLogic Host Adapters, destroy the Target Device - Statistics, CCBs, and Mailboxes, Release the System Resources, - and Unregister the SCSI Host. + An error occurred during Host Adapter Configuration Querying, Host + Adapter Configuration, Resource Acquisition, CCB Creation, Host + Adapter Initialization, or Target Device Inquiry, so remove Host + Adapter from the list of registered BusLogic Host Adapters, destroy + the CCBs, Release the System Resources, and Unregister the SCSI + Host. */ - BusLogic_DestroyTargetDeviceStatistics(HostAdapter); BusLogic_DestroyCCBs(HostAdapter); - BusLogic_DestroyMailboxes(HostAdapter); BusLogic_ReleaseResources(HostAdapter); BusLogic_UnregisterHostAdapter(HostAdapter); scsi_unregister(Host); } } - if (MessageBuffer != NULL) - scsi_init_free(MessageBuffer, BusLogic_MessageBufferSize); + kfree(PrototypeHostAdapter); + kfree(BusLogic_ProbeInfoList); + BusLogic_ProbeInfoList = NULL; return BusLogicHostAdapterCount; } @@ -2851,21 +2894,16 @@ int BusLogic_ReleaseHostAdapter(SCSI_Host_T *Host) BusLogic_HostAdapter_T *HostAdapter = (BusLogic_HostAdapter_T *) Host->hostdata; /* - FlashPoint Host Adapters must also be released by the FlashPoint + FlashPoint Host Adapters must first be released by the FlashPoint SCCB Manager. */ if (BusLogic_FlashPointHostAdapterP(HostAdapter)) - { - FlashPoint_ReleaseHostAdapter(HostAdapter->CardHandle); - scsi_init_free((char *) HostAdapter->FlashPointInfo, - sizeof(FlashPoint_Info_T)); - } + FlashPoint_ReleaseHostAdapter(HostAdapter->CardHandle); /* - Destroy the CCBs and Mailboxes, and release any system resources acquired - to support Host Adapter. + Destroy the CCBs and release any system resources acquired to + support Host Adapter. */ BusLogic_DestroyCCBs(HostAdapter); - BusLogic_DestroyMailboxes(HostAdapter); BusLogic_ReleaseResources(HostAdapter); /* Release usage of the I/O Address range. @@ -2988,27 +3026,29 @@ static void BusLogic_ScanIncomingMailboxes(BusLogic_HostAdapter_T *HostAdapter) BusLogic_CCB_T *CCB = (BusLogic_CCB_T *) Bus_to_Virtual(NextIncomingMailbox->CCB); if (CompletionCode != BusLogic_AbortedCommandNotFound) - if (CCB->Status == BusLogic_CCB_Active || - CCB->Status == BusLogic_CCB_Reset) - { - /* - Save the Completion Code for this CCB and queue the CCB - for completion processing. - */ - CCB->CompletionCode = CompletionCode; - BusLogic_QueueCompletedCCB(CCB); - } - else - { - /* - If a CCB ever appears in an Incoming Mailbox and is not marked as - status Active or Reset, then there is most likely a bug in the - Host Adapter firmware. - */ - BusLogic_Warning("Illegal CCB #%ld status %d in " - "Incoming Mailbox\n", HostAdapter, - CCB->SerialNumber, CCB->Status); - } + { + if (CCB->Status == BusLogic_CCB_Active || + CCB->Status == BusLogic_CCB_Reset) + { + /* + Save the Completion Code for this CCB and queue the CCB + for completion processing. + */ + CCB->CompletionCode = CompletionCode; + BusLogic_QueueCompletedCCB(CCB); + } + else + { + /* + If a CCB ever appears in an Incoming Mailbox and is not marked + as status Active or Reset, then there is most likely a bug in + the Host Adapter firmware. + */ + BusLogic_Warning("Illegal CCB #%ld status %d in " + "Incoming Mailbox\n", HostAdapter, + CCB->SerialNumber, CCB->Status); + } + } NextIncomingMailbox->CompletionCode = BusLogic_IncomingMailboxFree; if (++NextIncomingMailbox > HostAdapter->LastIncomingMailbox) NextIncomingMailbox = HostAdapter->FirstIncomingMailbox; @@ -3047,10 +3087,9 @@ static void BusLogic_ProcessCompletedCCBs(void) "%d Completed\n", HostAdapter, CCB->SerialNumber, TargetID); BusLogic_IncrementErrorCounter( - &HostAdapter->TargetDeviceStatistics[TargetID] - .BusDeviceResetsCompleted); + &HostAdapter->TargetStatistics[TargetID].BusDeviceResetsCompleted); + HostAdapter->TargetFlags[TargetID].TaggedQueuingActive = false; HostAdapter->CommandsSinceReset[TargetID] = 0; - HostAdapter->TaggedQueuingActive[TargetID] = false; HostAdapter->LastResetCompleted[TargetID] = jiffies; /* Place CCB back on the Host Adapter's free list. @@ -3101,16 +3140,17 @@ static void BusLogic_ProcessCompletedCCBs(void) HostAdapter, CCB->SerialNumber, CCB->TargetID); break; case BusLogic_CommandCompletedWithoutError: - HostAdapter->TargetDeviceStatistics[CCB->TargetID] + HostAdapter->TargetStatistics[CCB->TargetID] .CommandsCompleted++; - HostAdapter->CommandSuccessfulFlag[CCB->TargetID] = true; + HostAdapter->TargetFlags[CCB->TargetID] + .CommandSuccessfulFlag = true; Command->result = DID_OK << 16; break; case BusLogic_CommandAbortedAtHostRequest: BusLogic_Warning("CCB #%ld to Target %d Aborted\n", HostAdapter, CCB->SerialNumber, CCB->TargetID); BusLogic_IncrementErrorCounter( - &HostAdapter->TargetDeviceStatistics[CCB->TargetID] + &HostAdapter->TargetStatistics[CCB->TargetID] .CommandAbortsCompleted); Command->result = DID_ABORT << 16; break; @@ -3121,9 +3161,9 @@ static void BusLogic_ProcessCompletedCCBs(void) CCB->TargetDeviceStatus); if (CCB->HostAdapterStatus != BusLogic_SCSISelectionTimeout) { - HostAdapter->TargetDeviceStatistics[CCB->TargetID] + HostAdapter->TargetStatistics[CCB->TargetID] .CommandsCompleted++; - if (BusLogic_GlobalOptions.Bits.TraceErrors) + if (BusLogic_GlobalOptions.TraceErrors) { int i; BusLogic_Notice("CCB #%ld Target %d: Result %X Host " @@ -3146,6 +3186,22 @@ static void BusLogic_ProcessCompletedCCBs(void) } break; } + /* + When an INQUIRY command completes normally, save the + CmdQue (Tagged Queuing Supported) and WBus16 (16 Bit + Wide Data Transfers Supported) bits. + */ + if (CCB->CDB[0] == INQUIRY && CCB->CDB[1] == 0 && + CCB->HostAdapterStatus == BusLogic_CommandCompletedNormally) + { + BusLogic_TargetFlags_T *TargetFlags = + &HostAdapter->TargetFlags[CCB->TargetID]; + SCSI_Inquiry_T *InquiryResult = + (SCSI_Inquiry_T *) Command->request_buffer; + TargetFlags->TargetExists = true; + TargetFlags->TaggedQueuingSupported = InquiryResult->CmdQue; + TargetFlags->WideTransfersSupported = InquiryResult->WBus16; + } /* Place CCB back on the Host Adapter's free list. */ @@ -3171,7 +3227,7 @@ static void BusLogic_InterruptHandler(int IRQ_Channel, { BusLogic_HostAdapter_T *FirstHostAdapter = BusLogic_RegisteredHostAdapters[IRQ_Channel]; - boolean HostAdapterResetRequested = false; + boolean HostAdapterResetRequired = false; BusLogic_HostAdapter_T *HostAdapter; BusLogic_Lock_T Lock; /* @@ -3213,8 +3269,8 @@ static void BusLogic_InterruptHandler(int IRQ_Channel, */ if (InterruptRegister.Bits.ExternalBusReset) { - HostAdapter->HostAdapterResetRequested = true; - HostAdapterResetRequested = true; + HostAdapter->HostAdapterExternalReset = true; + HostAdapterResetRequired = true; } else if (InterruptRegister.Bits.IncomingMailboxLoaded) BusLogic_ScanIncomingMailboxes(HostAdapter); @@ -3228,11 +3284,20 @@ static void BusLogic_InterruptHandler(int IRQ_Channel, Check if there is a pending interrupt for this Host Adapter. */ if (FlashPoint_InterruptPending(HostAdapter->CardHandle)) - if (FlashPoint_HandleInterrupt(HostAdapter->CardHandle) - == FlashPoint_ExternalBusReset) + switch (FlashPoint_HandleInterrupt(HostAdapter->CardHandle)) { - HostAdapter->HostAdapterResetRequested = true; - HostAdapterResetRequested = true; + case FlashPoint_NormalInterrupt: + break; + case FlashPoint_ExternalBusReset: + HostAdapter->HostAdapterExternalReset = true; + HostAdapterResetRequired = true; + break; + case FlashPoint_InternalError: + BusLogic_Warning("Internal FlashPoint Error detected" + " - Resetting Host Adapter\n", HostAdapter); + HostAdapter->HostAdapterInternalError = true; + HostAdapterResetRequired = true; + break; } } /* @@ -3249,14 +3314,16 @@ static void BusLogic_InterruptHandler(int IRQ_Channel, Iterate over the Host Adapters performing any requested Host Adapter Resets. */ - if (HostAdapterResetRequested) + if (HostAdapterResetRequired) for (HostAdapter = FirstHostAdapter; HostAdapter != NULL; HostAdapter = HostAdapter->Next) - if (HostAdapter->HostAdapterResetRequested) + if (HostAdapter->HostAdapterExternalReset || + HostAdapter->HostAdapterInternalError) { BusLogic_ResetHostAdapter(HostAdapter, NULL, 0); - HostAdapter->HostAdapterResetRequested = false; + HostAdapter->HostAdapterExternalReset = false; + HostAdapter->HostAdapterInternalError = false; scsi_mark_host_reset(HostAdapter->SCSI_Host); } } @@ -3293,8 +3360,7 @@ static boolean BusLogic_WriteOutgoingMailbox(BusLogic_HostAdapter_T { HostAdapter->ActiveCommands[CCB->TargetID]++; if (CCB->Opcode != BusLogic_BusDeviceReset) - HostAdapter->TargetDeviceStatistics[CCB->TargetID] - .CommandsAttempted++; + HostAdapter->TargetStatistics[CCB->TargetID].CommandsAttempted++; } return true; } @@ -3312,8 +3378,10 @@ int BusLogic_QueueCommand(SCSI_Command_T *Command, { BusLogic_HostAdapter_T *HostAdapter = (BusLogic_HostAdapter_T *) Command->host->hostdata; - BusLogic_TargetDeviceStatistics_T *TargetDeviceStatistics = - HostAdapter->TargetDeviceStatistics; + BusLogic_TargetFlags_T *TargetFlags = + &HostAdapter->TargetFlags[Command->target]; + BusLogic_TargetStatistics_T *TargetStatistics = + HostAdapter->TargetStatistics; unsigned char *CDB = Command->cmnd; int CDB_Length = Command->cmd_len; int TargetID = Command->target; @@ -3371,13 +3439,9 @@ int BusLogic_QueueCommand(SCSI_Command_T *Command, int Segment; CCB->Opcode = BusLogic_InitiatorCCB_ScatterGather; CCB->DataLength = SegmentCount * sizeof(BusLogic_ScatterGatherSegment_T); -#ifndef CONFIG_SCSI_OMIT_FLASHPOINT if (BusLogic_MultiMasterHostAdapterP(HostAdapter)) CCB->DataPointer = Virtual_to_Bus(CCB->ScatterGatherList); - else CCB->DataPointer = (BusLogic_BusAddress_T) CCB->ScatterGatherList; -#else - CCB->DataPointer = Virtual_to_Bus(CCB->ScatterGatherList); -#endif + else CCB->DataPointer = Virtual_to_32Bit_Virtual(CCB->ScatterGatherList); for (Segment = 0; Segment < SegmentCount; Segment++) { CCB->ScatterGatherList[Segment].SegmentByteCount = @@ -3391,22 +3455,20 @@ int BusLogic_QueueCommand(SCSI_Command_T *Command, case READ_6: case READ_10: CCB->DataDirection = BusLogic_DataInLengthChecked; - TargetDeviceStatistics[TargetID].ReadCommands++; + TargetStatistics[TargetID].ReadCommands++; BusLogic_IncrementByteCounter( - &TargetDeviceStatistics[TargetID].TotalBytesRead, BufferLength); + &TargetStatistics[TargetID].TotalBytesRead, BufferLength); BusLogic_IncrementSizeBucket( - TargetDeviceStatistics[TargetID].ReadCommandSizeBuckets, - BufferLength); + TargetStatistics[TargetID].ReadCommandSizeBuckets, BufferLength); break; case WRITE_6: case WRITE_10: CCB->DataDirection = BusLogic_DataOutLengthChecked; - TargetDeviceStatistics[TargetID].WriteCommands++; + TargetStatistics[TargetID].WriteCommands++; BusLogic_IncrementByteCounter( - &TargetDeviceStatistics[TargetID].TotalBytesWritten, BufferLength); + &TargetStatistics[TargetID].TotalBytesWritten, BufferLength); BusLogic_IncrementSizeBucket( - TargetDeviceStatistics[TargetID].WriteCommandSizeBuckets, - BufferLength); + TargetStatistics[TargetID].WriteCommandSizeBuckets, BufferLength); break; default: CCB->DataDirection = BusLogic_UncheckedDataTransfer; @@ -3434,20 +3496,18 @@ int BusLogic_QueueCommand(SCSI_Command_T *Command, necessary to wait until there are no pending commands for a target device before queuing tagged commands. */ - HostAdapter->TaggedQueuingSupported[TargetID] = - Command->device->tagged_supported; if (HostAdapter->CommandsSinceReset[TargetID]++ >= BusLogic_MaxTaggedQueueDepth && - !HostAdapter->TaggedQueuingActive[TargetID] && + !TargetFlags->TaggedQueuingActive && HostAdapter->ActiveCommands[TargetID] == 0 && - HostAdapter->TaggedQueuingSupported[TargetID] && + TargetFlags->TaggedQueuingSupported && (HostAdapter->TaggedQueuingPermitted & (1 << TargetID))) { - HostAdapter->TaggedQueuingActive[TargetID] = true; + TargetFlags->TaggedQueuingActive = true; BusLogic_Notice("Tagged Queuing now active for Target %d\n", HostAdapter, TargetID); } - if (HostAdapter->TaggedQueuingActive[TargetID]) + if (TargetFlags->TaggedQueuingActive) { BusLogic_QueueTag_T QueueTag = BusLogic_SimpleQueueTag; /* @@ -3457,7 +3517,7 @@ int BusLogic_QueueCommand(SCSI_Command_T *Command, write nearer the head position continue to arrive without interruption. Therefore, for each Target Device this driver keeps track of the last time either the queue was empty or an Ordered Queue Tag was issued. If - more than 3 seconds (one fifth of the 15 second disk timeout) have + more than 4 seconds (one fifth of the 20 second disk timeout) have elapsed since this last sequence point, this command will be issued with an Ordered Queue Tag rather than a Simple Queue Tag, which forces the Target Device to complete all previously queued commands before @@ -3465,7 +3525,7 @@ int BusLogic_QueueCommand(SCSI_Command_T *Command, */ if (HostAdapter->ActiveCommands[TargetID] == 0) HostAdapter->LastSequencePoint[TargetID] = jiffies; - else if (jiffies - HostAdapter->LastSequencePoint[TargetID] > 3*HZ) + else if (jiffies - HostAdapter->LastSequencePoint[TargetID] > 4*HZ) { HostAdapter->LastSequencePoint[TargetID] = jiffies; QueueTag = BusLogic_OrderedQueueTag; @@ -3519,7 +3579,7 @@ int BusLogic_QueueCommand(SCSI_Command_T *Command, */ CCB->Status = BusLogic_CCB_Active; HostAdapter->ActiveCommands[TargetID]++; - TargetDeviceStatistics[TargetID].CommandsAttempted++; + TargetStatistics[TargetID].CommandsAttempted++; FlashPoint_StartCCB(HostAdapter->CardHandle, CCB); /* The Command may have already completed and BusLogic_QueueCompletedCCB @@ -3550,7 +3610,7 @@ int BusLogic_AbortCommand(SCSI_Command_T *Command) BusLogic_CCB_T *CCB; int Result; BusLogic_IncrementErrorCounter( - &HostAdapter->TargetDeviceStatistics[TargetID].CommandAbortsRequested); + &HostAdapter->TargetStatistics[TargetID].CommandAbortsRequested); /* Acquire exclusive access to Host Adapter. */ @@ -3604,7 +3664,7 @@ int BusLogic_AbortCommand(SCSI_Command_T *Command) Firmware version 5.xx does generate Abort Tag messages, so it is possible to abort commands when Tagged Queuing is active. */ - if (HostAdapter->TaggedQueuingActive[TargetID] && + if (HostAdapter->TargetFlags[TargetID].TaggedQueuingActive && HostAdapter->FirmwareVersion[0] < '5') { BusLogic_Warning("Unable to Abort CCB #%ld to Target %d - " @@ -3618,8 +3678,7 @@ int BusLogic_AbortCommand(SCSI_Command_T *Command) BusLogic_Warning("Aborting CCB #%ld to Target %d\n", HostAdapter, CCB->SerialNumber, TargetID); BusLogic_IncrementErrorCounter( - &HostAdapter->TargetDeviceStatistics[TargetID] - .CommandAbortsAttempted); + &HostAdapter->TargetStatistics[TargetID].CommandAbortsAttempted); Result = SCSI_ABORT_PENDING; } else @@ -3638,7 +3697,7 @@ int BusLogic_AbortCommand(SCSI_Command_T *Command) BusLogic_Warning("Aborting CCB #%ld to Target %d\n", HostAdapter, CCB->SerialNumber, TargetID); BusLogic_IncrementErrorCounter( - &HostAdapter->TargetDeviceStatistics[TargetID].CommandAbortsAttempted); + &HostAdapter->TargetStatistics[TargetID].CommandAbortsAttempted); FlashPoint_AbortCCB(HostAdapter->CardHandle, CCB); /* The Abort may have already been completed and @@ -3673,11 +3732,24 @@ static int BusLogic_ResetHostAdapter(BusLogic_HostAdapter_T *HostAdapter, BusLogic_Lock_T Lock; BusLogic_CCB_T *CCB; int TargetID, Result; - if (Command == NULL) - BusLogic_IncrementErrorCounter(&HostAdapter->ExternalHostAdapterResets); - else BusLogic_IncrementErrorCounter( - &HostAdapter->TargetDeviceStatistics[Command->target] - .HostAdapterResetsRequested); + boolean HardReset; + if (HostAdapter->HostAdapterExternalReset) + { + BusLogic_IncrementErrorCounter(&HostAdapter->ExternalHostAdapterResets); + HardReset = false; + } + else if (HostAdapter->HostAdapterInternalError) + { + BusLogic_IncrementErrorCounter(&HostAdapter->HostAdapterInternalErrors); + HardReset = true; + } + else + { + BusLogic_IncrementErrorCounter( + &HostAdapter->TargetStatistics[Command->target] + .HostAdapterResetsRequested); + HardReset = true; + } /* Acquire exclusive access to Host Adapter. */ @@ -3723,20 +3795,25 @@ static int BusLogic_ResetHostAdapter(BusLogic_HostAdapter_T *HostAdapter, } } if (Command == NULL) - BusLogic_Warning("Resetting %s due to External SCSI Bus Reset\n", - HostAdapter, HostAdapter->FullModelName); + { + if (HostAdapter->HostAdapterInternalError) + BusLogic_Warning("Resetting %s due to Host Adapter Internal Error\n", + HostAdapter, HostAdapter->FullModelName); + else BusLogic_Warning("Resetting %s due to External SCSI Bus Reset\n", + HostAdapter, HostAdapter->FullModelName); + } else { BusLogic_Warning("Resetting %s due to Target %d\n", HostAdapter, HostAdapter->FullModelName, Command->target); BusLogic_IncrementErrorCounter( - &HostAdapter->TargetDeviceStatistics[Command->target] + &HostAdapter->TargetStatistics[Command->target] .HostAdapterResetsAttempted); } /* Attempt to Reset and Reinitialize the Host Adapter. */ - if (!(BusLogic_HardResetHostAdapter(HostAdapter) && + if (!(BusLogic_HardwareResetHostAdapter(HostAdapter, HardReset) && BusLogic_InitializeHostAdapter(HostAdapter))) { BusLogic_Error("Resetting %s Failed\n", HostAdapter, @@ -3746,7 +3823,7 @@ static int BusLogic_ResetHostAdapter(BusLogic_HostAdapter_T *HostAdapter, } if (Command != NULL) BusLogic_IncrementErrorCounter( - &HostAdapter->TargetDeviceStatistics[Command->target] + &HostAdapter->TargetStatistics[Command->target] .HostAdapterResetsCompleted); /* Mark all currently executing CCBs as having been Reset. @@ -3761,7 +3838,8 @@ static int BusLogic_ResetHostAdapter(BusLogic_HostAdapter_T *HostAdapter, Note that a timer interrupt may occur here, but all active CCBs have already been marked Reset and so a reentrant call will return Pending. */ - BusLogic_Delay(HostAdapter->BusSettleTime); + if (HardReset) + BusLogic_Delay(HostAdapter->BusSettleTime); /* If this is a Synchronous Reset, perform completion processing for the Command being Reset. @@ -3817,7 +3895,7 @@ static int BusLogic_SendBusDeviceReset(BusLogic_HostAdapter_T *HostAdapter, BusLogic_Lock_T Lock; int Result = -1; BusLogic_IncrementErrorCounter( - &HostAdapter->TargetDeviceStatistics[TargetID].BusDeviceResetsRequested); + &HostAdapter->TargetStatistics[TargetID].BusDeviceResetsRequested); /* Acquire exclusive access to Host Adapter. */ @@ -3891,7 +3969,7 @@ static int BusLogic_SendBusDeviceReset(BusLogic_HostAdapter_T *HostAdapter, while there are tagged commands outstanding. Therefore, in that case a full Host Adapter Hard Reset and SCSI Bus Reset must be done. */ - if (HostAdapter->TaggedQueuingActive[TargetID] && + if (HostAdapter->TargetFlags[TargetID].TaggedQueuingActive && HostAdapter->ActiveCommands[TargetID] > 0 && HostAdapter->FirmwareVersion[0] < '5') goto Done; @@ -3958,7 +4036,7 @@ static int BusLogic_SendBusDeviceReset(BusLogic_HostAdapter_T *HostAdapter, processing performed. */ BusLogic_IncrementErrorCounter( - &HostAdapter->TargetDeviceStatistics[TargetID].BusDeviceResetsAttempted); + &HostAdapter->TargetStatistics[TargetID].BusDeviceResetsAttempted); HostAdapter->BusDeviceResetPendingCCB[TargetID] = CCB; HostAdapter->LastResetAttempted[TargetID] = jiffies; for (XCCB = HostAdapter->All_CCBs; XCCB != NULL; XCCB = XCCB->NextAll) @@ -4007,11 +4085,11 @@ int BusLogic_ResetCommand(SCSI_Command_T *Command, unsigned int ResetFlags) it has been less than 10 minutes since the last reset occurred, or since the system was initialized if no prior resets have occurred. */ - if (HostAdapter->TaggedQueuingActive[TargetID] && + if (HostAdapter->TargetFlags[TargetID].TaggedQueuingActive && jiffies - HostAdapter->LastResetCompleted[TargetID] < 10*60*HZ) { HostAdapter->TaggedQueuingPermitted &= ~(1 << TargetID); - HostAdapter->TaggedQueuingActive[TargetID] = false; + HostAdapter->TargetFlags[TargetID].TaggedQueuingActive = false; BusLogic_Warning("Tagged Queuing now disabled for Target %d\n", HostAdapter, TargetID); } @@ -4032,10 +4110,10 @@ int BusLogic_ResetCommand(SCSI_Command_T *Command, unsigned int ResetFlags) forcing a Hard Reset before the Bus Device Reset has had a chance to clear the error condition. */ - if (HostAdapter->CommandSuccessfulFlag[TargetID] || + if (HostAdapter->TargetFlags[TargetID].CommandSuccessfulFlag || jiffies - HostAdapter->LastResetAttempted[TargetID] < HZ/10) { - HostAdapter->CommandSuccessfulFlag[TargetID] = false; + HostAdapter->TargetFlags[TargetID].CommandSuccessfulFlag = false; return BusLogic_SendBusDeviceReset(HostAdapter, Command, ResetFlags); } /* Fall through to Hard Reset case. */ @@ -4076,16 +4154,18 @@ int BusLogic_BIOSDiskParameters(SCSI_Disk_T *Disk, KernelDevice_T Device, struct buffer_head *BufferHead; if (HostAdapter->ExtendedTranslationEnabled && Disk->capacity >= 2*1024*1024 /* 1 GB in 512 byte sectors */) - if (Disk->capacity >= 4*1024*1024 /* 2 GB in 512 byte sectors */) - { - DiskParameters->Heads = 255; - DiskParameters->Sectors = 63; - } - else - { - DiskParameters->Heads = 128; - DiskParameters->Sectors = 32; - } + { + if (Disk->capacity >= 4*1024*1024 /* 2 GB in 512 byte sectors */) + { + DiskParameters->Heads = 255; + DiskParameters->Sectors = 63; + } + else + { + DiskParameters->Heads = 128; + DiskParameters->Sectors = 32; + } + } else { DiskParameters->Heads = 64; @@ -4105,24 +4185,28 @@ int BusLogic_BIOSDiskParameters(SCSI_Disk_T *Disk, KernelDevice_T Device, */ if (*(unsigned short *) (BufferHead->b_data + 0x1FE) == 0xAA55) { - struct partition *PartitionEntry = - (struct partition *) (BufferHead->b_data + 0x1BE); + PartitionTable_T *FirstPartitionEntry = + (PartitionTable_T *) (BufferHead->b_data + 0x1BE); + PartitionTable_T *PartitionEntry = FirstPartitionEntry; int SavedCylinders = DiskParameters->Cylinders, PartitionNumber; + unsigned char PartitionEntryEndHead, PartitionEntryEndSector; for (PartitionNumber = 0; PartitionNumber < 4; PartitionNumber++) { - if (PartitionEntry->end_head == 64-1) + PartitionEntryEndHead = PartitionEntry->end_head; + PartitionEntryEndSector = PartitionEntry->end_sector & 0x3F; + if (PartitionEntryEndHead == 64-1) { DiskParameters->Heads = 64; DiskParameters->Sectors = 32; break; } - else if (PartitionEntry->end_head == 128-1) + else if (PartitionEntryEndHead == 128-1) { DiskParameters->Heads = 128; DiskParameters->Sectors = 32; break; } - else if (PartitionEntry->end_head == 255-1) + else if (PartitionEntryEndHead == 255-1) { DiskParameters->Heads = 255; DiskParameters->Sectors = 63; @@ -4130,14 +4214,29 @@ int BusLogic_BIOSDiskParameters(SCSI_Disk_T *Disk, KernelDevice_T Device, } PartitionEntry++; } + if (PartitionNumber == 4) + { + PartitionEntryEndHead = FirstPartitionEntry->end_head; + PartitionEntryEndSector = FirstPartitionEntry->end_sector & 0x3F; + } DiskParameters->Cylinders = Disk->capacity / (DiskParameters->Heads * DiskParameters->Sectors); - if (SavedCylinders != DiskParameters->Cylinders) + if (PartitionNumber < 4 && + PartitionEntryEndSector == DiskParameters->Sectors) + { + if (DiskParameters->Cylinders != SavedCylinders) + BusLogic_Warning("Adopting Geometry %d/%d from Partition Table\n", + HostAdapter, + DiskParameters->Heads, DiskParameters->Sectors); + } + else if (PartitionEntryEndHead > 0 || PartitionEntryEndSector > 0) { - BusLogic_Warning("Warning: Extended Translation Setting " - "(> 1GB Switch) does not match\n", HostAdapter); - BusLogic_Warning("Partition Table - Adopting %d/%d Geometry " - "from Partition Table\n", HostAdapter, + BusLogic_Warning("Warning: Partition Table appears to " + "have Geometry %d/%d which is\n", HostAdapter, + PartitionEntryEndHead + 1, + PartitionEntryEndSector); + BusLogic_Warning("not compatible with current BusLogic " + "Host Adapter Geometry %d/%d\n", HostAdapter, DiskParameters->Heads, DiskParameters->Sectors); } } @@ -4155,22 +4254,21 @@ int BusLogic_ProcDirectoryInfo(char *ProcBuffer, char **StartPointer, int HostNumber, int WriteFlag) { BusLogic_HostAdapter_T *HostAdapter; - BusLogic_TargetDeviceStatistics_T *TargetDeviceStatistics; - int IRQ_Channel, TargetID, Length; + BusLogic_TargetStatistics_T *TargetStatistics; + int TargetID, Length; char *Buffer; if (WriteFlag) return 0; - for (IRQ_Channel = 0; IRQ_Channel < NR_IRQS; IRQ_Channel++) + for (HostAdapter = BusLogic_FirstRegisteredHostAdapter; + HostAdapter != NULL; + HostAdapter = HostAdapter->NextAll) + if (HostAdapter->HostNumber == HostNumber) break; + if (HostAdapter == NULL) { - HostAdapter = BusLogic_RegisteredHostAdapters[IRQ_Channel]; - while (HostAdapter != NULL) - { - if (HostAdapter->HostNumber == HostNumber) break; - HostAdapter = HostAdapter->Next; - } - if (HostAdapter != NULL) break; + BusLogic_Error("Cannot find Host Adapter for SCSI Host %d\n", + NULL, HostNumber); + return 0; } - if (HostAdapter == NULL) return -1; - TargetDeviceStatistics = HostAdapter->TargetDeviceStatistics; + TargetStatistics = HostAdapter->TargetStatistics; Buffer = HostAdapter->MessageBuffer; Length = HostAdapter->MessageBufferLength; Length += sprintf(&Buffer[Length], "\n\ @@ -4181,100 +4279,105 @@ Currently Allocated CCBs: %d\n", Length += sprintf(&Buffer[Length], "\n\n\ DATA TRANSFER STATISTICS\n\ \n\ -Target Tagged Queuing Queue Depth Commands Attempted Commands Completed\n\ -====== ============== =========== ================== ==================\n"); +Target Tagged Queuing Queue Depth Active Attempted Completed\n\ +====== ============== =========== ====== ========= =========\n"); for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) - if (TargetDeviceStatistics[TargetID].CommandsCompleted > 0) - { - Length += - sprintf(&Buffer[Length], " %2d %s", TargetID, - (HostAdapter->TaggedQueuingSupported[TargetID] - ? (HostAdapter->TaggedQueuingActive[TargetID] - ? " Active" - : (HostAdapter->TaggedQueuingPermitted & (1 << TargetID) - ? " Permitted" : " Disabled")) - : "Not Supported")); - Length += sprintf(&Buffer[Length], - " %3d %9u %9u\n", - HostAdapter->QueueDepth[TargetID], - TargetDeviceStatistics[TargetID].CommandsAttempted, - TargetDeviceStatistics[TargetID].CommandsCompleted); - } + { + BusLogic_TargetFlags_T *TargetFlags = &HostAdapter->TargetFlags[TargetID]; + if (!TargetFlags->TargetExists) continue; + Length += + sprintf(&Buffer[Length], " %2d %s", TargetID, + (TargetFlags->TaggedQueuingSupported + ? (TargetFlags->TaggedQueuingActive + ? " Active" + : (HostAdapter->TaggedQueuingPermitted & (1 << TargetID) + ? " Permitted" : " Disabled")) + : "Not Supported")); + Length += sprintf(&Buffer[Length], + " %3d %3u %9u %9u\n", + HostAdapter->QueueDepth[TargetID], + HostAdapter->ActiveCommands[TargetID], + TargetStatistics[TargetID].CommandsAttempted, + TargetStatistics[TargetID].CommandsCompleted); + } Length += sprintf(&Buffer[Length], "\n\ Target Read Commands Write Commands Total Bytes Read Total Bytes Written\n\ ====== ============= ============== =================== ===================\n"); for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) - if (TargetDeviceStatistics[TargetID].CommandsCompleted > 0) - { + { + BusLogic_TargetFlags_T *TargetFlags = &HostAdapter->TargetFlags[TargetID]; + if (!TargetFlags->TargetExists) continue; + Length += + sprintf(&Buffer[Length], " %2d %9u %9u", TargetID, + TargetStatistics[TargetID].ReadCommands, + TargetStatistics[TargetID].WriteCommands); + if (TargetStatistics[TargetID].TotalBytesRead.Billions > 0) Length += - sprintf(&Buffer[Length], " %2d %9u %9u", TargetID, - TargetDeviceStatistics[TargetID].ReadCommands, - TargetDeviceStatistics[TargetID].WriteCommands); - if (TargetDeviceStatistics[TargetID].TotalBytesRead.Billions > 0) - Length += - sprintf(&Buffer[Length], " %9u%09u", - TargetDeviceStatistics[TargetID].TotalBytesRead.Billions, - TargetDeviceStatistics[TargetID].TotalBytesRead.Units); - else - Length += - sprintf(&Buffer[Length], " %9u", - TargetDeviceStatistics[TargetID].TotalBytesRead.Units); - if (TargetDeviceStatistics[TargetID].TotalBytesWritten.Billions > 0) - Length += - sprintf(&Buffer[Length], " %9u%09u\n", - TargetDeviceStatistics[TargetID].TotalBytesWritten.Billions, - TargetDeviceStatistics[TargetID].TotalBytesWritten.Units); - else - Length += - sprintf(&Buffer[Length], " %9u\n", - TargetDeviceStatistics[TargetID].TotalBytesWritten.Units); - } + sprintf(&Buffer[Length], " %9u%09u", + TargetStatistics[TargetID].TotalBytesRead.Billions, + TargetStatistics[TargetID].TotalBytesRead.Units); + else + Length += + sprintf(&Buffer[Length], " %9u", + TargetStatistics[TargetID].TotalBytesRead.Units); + if (TargetStatistics[TargetID].TotalBytesWritten.Billions > 0) + Length += + sprintf(&Buffer[Length], " %9u%09u\n", + TargetStatistics[TargetID].TotalBytesWritten.Billions, + TargetStatistics[TargetID].TotalBytesWritten.Units); + else + Length += + sprintf(&Buffer[Length], " %9u\n", + TargetStatistics[TargetID].TotalBytesWritten.Units); + } Length += sprintf(&Buffer[Length], "\n\ Target Command 0-1KB 1-2KB 2-4KB 4-8KB 8-16KB\n\ ====== ======= ========= ========= ========= ========= =========\n"); for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) - if (TargetDeviceStatistics[TargetID].CommandsCompleted > 0) - { - Length += - sprintf(&Buffer[Length], - " %2d Read %9u %9u %9u %9u %9u\n", TargetID, - TargetDeviceStatistics[TargetID].ReadCommandSizeBuckets[0], - TargetDeviceStatistics[TargetID].ReadCommandSizeBuckets[1], - TargetDeviceStatistics[TargetID].ReadCommandSizeBuckets[2], - TargetDeviceStatistics[TargetID].ReadCommandSizeBuckets[3], - TargetDeviceStatistics[TargetID].ReadCommandSizeBuckets[4]); - Length += - sprintf(&Buffer[Length], - " %2d Write %9u %9u %9u %9u %9u\n", TargetID, - TargetDeviceStatistics[TargetID].WriteCommandSizeBuckets[0], - TargetDeviceStatistics[TargetID].WriteCommandSizeBuckets[1], - TargetDeviceStatistics[TargetID].WriteCommandSizeBuckets[2], - TargetDeviceStatistics[TargetID].WriteCommandSizeBuckets[3], - TargetDeviceStatistics[TargetID].WriteCommandSizeBuckets[4]); - } + { + BusLogic_TargetFlags_T *TargetFlags = &HostAdapter->TargetFlags[TargetID]; + if (!TargetFlags->TargetExists) continue; + Length += + sprintf(&Buffer[Length], + " %2d Read %9u %9u %9u %9u %9u\n", TargetID, + TargetStatistics[TargetID].ReadCommandSizeBuckets[0], + TargetStatistics[TargetID].ReadCommandSizeBuckets[1], + TargetStatistics[TargetID].ReadCommandSizeBuckets[2], + TargetStatistics[TargetID].ReadCommandSizeBuckets[3], + TargetStatistics[TargetID].ReadCommandSizeBuckets[4]); + Length += + sprintf(&Buffer[Length], + " %2d Write %9u %9u %9u %9u %9u\n", TargetID, + TargetStatistics[TargetID].WriteCommandSizeBuckets[0], + TargetStatistics[TargetID].WriteCommandSizeBuckets[1], + TargetStatistics[TargetID].WriteCommandSizeBuckets[2], + TargetStatistics[TargetID].WriteCommandSizeBuckets[3], + TargetStatistics[TargetID].WriteCommandSizeBuckets[4]); + } Length += sprintf(&Buffer[Length], "\n\ Target Command 16-32KB 32-64KB 64-128KB 128-256KB 256KB+\n\ ====== ======= ========= ========= ========= ========= =========\n"); for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) - if (TargetDeviceStatistics[TargetID].CommandsCompleted > 0) - { - Length += - sprintf(&Buffer[Length], - " %2d Read %9u %9u %9u %9u %9u\n", TargetID, - TargetDeviceStatistics[TargetID].ReadCommandSizeBuckets[5], - TargetDeviceStatistics[TargetID].ReadCommandSizeBuckets[6], - TargetDeviceStatistics[TargetID].ReadCommandSizeBuckets[7], - TargetDeviceStatistics[TargetID].ReadCommandSizeBuckets[8], - TargetDeviceStatistics[TargetID].ReadCommandSizeBuckets[9]); - Length += - sprintf(&Buffer[Length], - " %2d Write %9u %9u %9u %9u %9u\n", TargetID, - TargetDeviceStatistics[TargetID].WriteCommandSizeBuckets[5], - TargetDeviceStatistics[TargetID].WriteCommandSizeBuckets[6], - TargetDeviceStatistics[TargetID].WriteCommandSizeBuckets[7], - TargetDeviceStatistics[TargetID].WriteCommandSizeBuckets[8], - TargetDeviceStatistics[TargetID].WriteCommandSizeBuckets[9]); - } + { + BusLogic_TargetFlags_T *TargetFlags = &HostAdapter->TargetFlags[TargetID]; + if (!TargetFlags->TargetExists) continue; + Length += + sprintf(&Buffer[Length], + " %2d Read %9u %9u %9u %9u %9u\n", TargetID, + TargetStatistics[TargetID].ReadCommandSizeBuckets[5], + TargetStatistics[TargetID].ReadCommandSizeBuckets[6], + TargetStatistics[TargetID].ReadCommandSizeBuckets[7], + TargetStatistics[TargetID].ReadCommandSizeBuckets[8], + TargetStatistics[TargetID].ReadCommandSizeBuckets[9]); + Length += + sprintf(&Buffer[Length], + " %2d Write %9u %9u %9u %9u %9u\n", TargetID, + TargetStatistics[TargetID].WriteCommandSizeBuckets[5], + TargetStatistics[TargetID].WriteCommandSizeBuckets[6], + TargetStatistics[TargetID].WriteCommandSizeBuckets[7], + TargetStatistics[TargetID].WriteCommandSizeBuckets[8], + TargetStatistics[TargetID].WriteCommandSizeBuckets[9]); + } Length += sprintf(&Buffer[Length], "\n\n\ ERROR RECOVERY STATISTICS\n\ \n\ @@ -4283,21 +4386,26 @@ Target Requested Completed Requested Completed Requested Completed\n\ ID \\\\\\\\ Attempted //// \\\\\\\\ Attempted //// \\\\\\\\ Attempted ////\n\ ====== ===== ===== ===== ===== ===== ===== ===== ===== =====\n"); for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) - if (TargetDeviceStatistics[TargetID].CommandsCompleted > 0) + { + BusLogic_TargetFlags_T *TargetFlags = &HostAdapter->TargetFlags[TargetID]; + if (!TargetFlags->TargetExists) continue; Length += sprintf(&Buffer[Length], "\ %2d %5d %5d %5d %5d %5d %5d %5d %5d %5d\n", TargetID, - TargetDeviceStatistics[TargetID].CommandAbortsRequested, - TargetDeviceStatistics[TargetID].CommandAbortsAttempted, - TargetDeviceStatistics[TargetID].CommandAbortsCompleted, - TargetDeviceStatistics[TargetID].BusDeviceResetsRequested, - TargetDeviceStatistics[TargetID].BusDeviceResetsAttempted, - TargetDeviceStatistics[TargetID].BusDeviceResetsCompleted, - TargetDeviceStatistics[TargetID].HostAdapterResetsRequested, - TargetDeviceStatistics[TargetID].HostAdapterResetsAttempted, - TargetDeviceStatistics[TargetID].HostAdapterResetsCompleted); + TargetStatistics[TargetID].CommandAbortsRequested, + TargetStatistics[TargetID].CommandAbortsAttempted, + TargetStatistics[TargetID].CommandAbortsCompleted, + TargetStatistics[TargetID].BusDeviceResetsRequested, + TargetStatistics[TargetID].BusDeviceResetsAttempted, + TargetStatistics[TargetID].BusDeviceResetsCompleted, + TargetStatistics[TargetID].HostAdapterResetsRequested, + TargetStatistics[TargetID].HostAdapterResetsAttempted, + TargetStatistics[TargetID].HostAdapterResetsCompleted); + } Length += sprintf(&Buffer[Length], "\nExternal Host Adapter Resets: %d\n", HostAdapter->ExternalHostAdapterResets); + Length += sprintf(&Buffer[Length], "Host Adapter Internal Errors: %d\n", + HostAdapter->HostAdapterInternalErrors); if (Length >= BusLogic_MessageBufferSize) BusLogic_Error("Message Buffer length %d exceeds size %d\n", HostAdapter, Length, BusLogic_MessageBufferSize); @@ -4339,17 +4447,22 @@ static void BusLogic_Message(BusLogic_MessageLevel_T MessageLevel, Buffer); HostAdapter->MessageBufferLength += Length; if (BeginningOfLine) - printk("%sscsi%d: %s", BusLogic_MessageLevelMap[MessageLevel], - HostAdapter->HostNumber, Buffer); + { + if (Buffer[0] != '\n' || Length > 1) + printk("%sscsi%d: %s", BusLogic_MessageLevelMap[MessageLevel], + HostAdapter->HostNumber, Buffer); + } else printk("%s", Buffer); } else { if (BeginningOfLine) - if (HostAdapter != NULL && HostAdapter->HostAdapterInitialized) - printk("%sscsi%d: %s", BusLogic_MessageLevelMap[MessageLevel], - HostAdapter->HostNumber, Buffer); - else printk("%s%s", BusLogic_MessageLevelMap[MessageLevel], Buffer); + { + if (HostAdapter != NULL && HostAdapter->HostAdapterInitialized) + printk("%sscsi%d: %s", BusLogic_MessageLevelMap[MessageLevel], + HostAdapter->HostNumber, Buffer); + else printk("%s%s", BusLogic_MessageLevelMap[MessageLevel], Buffer); + } else printk("%s", Buffer); } BeginningOfLine = (Buffer[Length-1] == '\n'); @@ -4357,364 +4470,548 @@ static void BusLogic_Message(BusLogic_MessageLevel_T MessageLevel, /* - BusLogic_Setup handles processing of Kernel Command Line Arguments. + BusLogic_ParseKeyword parses an individual option keyword. It returns true + and updates the pointer if the keyword is recognized and false otherwise. +*/ - For the BusLogic driver, a Kernel Command Line Entry comprises the driver - identifier "BusLogic=" optionally followed by a comma-separated sequence of - integers and then optionally followed by a comma-separated sequence of - strings. Each command line entry applies to one BusLogic Host Adapter. - Multiple command line entries may be used in systems which contain multiple - BusLogic Host Adapters. +static boolean BusLogic_ParseKeyword(char **StringPointer, char *Keyword) +{ + char *Pointer = *StringPointer; + while (*Keyword != '\0') + { + char StringChar = *Pointer++; + char KeywordChar = *Keyword++; + if (StringChar >= 'A' && StringChar <= 'Z') + StringChar += 'a' - 'Z'; + if (KeywordChar >= 'A' && KeywordChar <= 'Z') + KeywordChar += 'a' - 'Z'; + if (StringChar != KeywordChar) return false; + } + *StringPointer = Pointer; + return true; +} - The first integer specified is the I/O Address at which the Host Adapter is - located. If unspecified, it defaults to 0 which means to apply this entry to - the first BusLogic Host Adapter found during the default probe sequence. If - any I/O Address parameters are provided on the command line, then the default - probe sequence is omitted. - - The second integer specified is the Tagged Queue Depth to use for Target - Devices that support Tagged Queuing. The Queue Depth is the number of SCSI - commands that are allowed to be concurrently presented for execution. If - unspecified, it defaults to 0 which means to use a value determined - automatically based on the Host Adapter's Total Queue Depth and the number, - type, speed, and capabilities of the detected Target Devices. For Host - Adapters that require ISA Bounce Buffers, the Tagged Queue Depth is - automatically set to BusLogic_TaggedQueueDepthBounceBuffers to avoid - excessive preallocation of DMA Bounce Buffer memory. Target Devices that do - not support Tagged Queuing use a Queue Depth of BusLogic_UntaggedQueueDepth. - - The third integer specified is the Bus Settle Time in seconds. This is - the amount of time to wait between a Host Adapter Hard Reset which initiates - a SCSI Bus Reset and issuing any SCSI Commands. If unspecified, it defaults - to 0 which means to use the value of BusLogic_DefaultBusSettleTime. - - The fourth integer specified is the Local Options. If unspecified, it - defaults to 0. Note that Local Options are only applied to a specific Host - Adapter. - - The fifth integer specified is the Global Options. If unspecified, it - defaults to 0. Note that Global Options are applied across all Host - Adapters. - The string options are used to provide control over Tagged Queuing, Error - Recovery, and Host Adapter Probing. - - The Tagged Queuing specification begins with "TQ:" and allows for explicitly - specifying whether Tagged Queuing is permitted on Target Devices that support - it. The following specification options are available: - - TQ:Default Tagged Queuing will be permitted based on the firmware - version of the BusLogic Host Adapter and based on - whether the Tagged Queue Depth value allows queuing - multiple commands. - - TQ:Enable Tagged Queuing will be enabled for all Target Devices - on this Host Adapter overriding any limitation that - would otherwise be imposed based on the Host Adapter - firmware version. - - TQ:Disable Tagged Queuing will be disabled for all Target Devices - on this Host Adapter. - - TQ: Tagged Queuing will be controlled individually for each - Target Device. is a sequence of "Y", - "N", and "X" characters. "Y" enabled Tagged Queuing, - "N" disables Tagged Queuing, and "X" accepts the - default based on the firmware version. The first - character refers to Target Device 0, the second to - Target Device 1, and so on; if the sequence of "Y", - "N", and "X" characters does not cover all the Target - Devices, unspecified characters are assumed to be "X". - - Note that explicitly requesting Tagged Queuing may lead to problems; this - facility is provided primarily to allow disabling Tagged Queuing on Target - Devices that do not implement it correctly. - - The Error Recovery Strategy specification begins with "ER:" and allows for - explicitly specifying the Error Recovery action to be performed when - ResetCommand is called due to a SCSI Command failing to complete - successfully. The following specification options are available: - - ER:Default Error Recovery will select between the Hard Reset and - Bus Device Reset options based on the recommendation - of the SCSI Subsystem. - - ER:HardReset Error Recovery will initiate a Host Adapter Hard Reset - which also causes a SCSI Bus Reset. - - ER:BusDeviceReset Error Recovery will send a Bus Device Reset message to - the individual Target Device causing the error. If - Error Recovery is again initiated for this Target - Device and no SCSI Command to this Target Device has - completed successfully since the Bus Device Reset - message was sent, then a Hard Reset will be attempted. - - ER:None Error Recovery will be suppressed. This option should - only be selected if a SCSI Bus Reset or Bus Device - Reset will cause the Target Device to fail completely - and unrecoverably. - - ER: Error Recovery will be controlled individually for each - Target Device. is a sequence of "D", - "H", "B", and "N" characters. "D" selects Default, "H" - selects Hard Reset, "B" selects Bus Device Reset, and - "N" selects None. The first character refers to Target - Device 0, the second to Target Device 1, and so on; if - the sequence of "D", "H", "B", and "N" characters does - not cover all the possible Target Devices, unspecified - characters are assumed to be "D". - - The Host Adapter Probing specification comprises the following strings: - - NoProbe No probing of any kind is to be performed, and hence - no BusLogic Host Adapters will be detected. - - NoProbeISA No probing of the standard ISA I/O Addresses will - be done, and hence only PCI MultiMaster and FlashPoint - Host Adapters will be detected. - - NoProbePCI No interrogation of PCI Configuration Space will be - made, and hence only ISA Multimaster Host Adapters - will be detected, as well as PCI Multimaster Host - Adapters that have their ISA Compatible I/O Port - set to "Primary" or "Alternate". - - NoSortPCI PCI MultiMaster Host Adapters will be enumerated in - the order provided by the PCI BIOS, ignoring any - setting of the AutoSCSI "Use Bus And Device # For PCI - Scanning Seq." option. - - MultiMasterFirst By default, if both FlashPoint and PCI MultiMaster - Host Adapters are present, this driver will probe for - FlashPoint Host Adapters first unless the BIOS primary - disk is controlled by the first PCI MultiMaster Host - Adapter, in which case MultiMaster Host Adapters will - be probed first. This option forces MultiMaster Host - Adapters to be probed first. - - FlashPointFirst By default, if both FlashPoint and PCI MultiMaster - Host Adapters are present, this driver will probe for - FlashPoint Host Adapters first unless the BIOS primary - disk is controlled by the first PCI MultiMaster Host - Adapter, in which case MultiMaster Host Adapters will - be probed first. This option forces FlashPoint Host - Adapters to be probed first. - - Debug Sets all the tracing bits in BusLogic_GlobalOptions. +/* + BusLogic_ParseDriverOptions handles processing of BusLogic Driver Options + specifications. + + BusLogic Driver Options may be specified either via the Linux Kernel Command + Line or via the Loadable Kernel Module Installation Facility. Driver Options + for multiple host adapters may be specified either by separating the option + strings by a semicolon, or by specifying multiple "BusLogic=" strings on the + command line. Individual option specifications for a single host adapter are + separated by commas. The Probing and Debugging Options apply to all host + adapters whereas the remaining options apply individually only to the + selected host adapter. + + The BusLogic Driver Probing Options comprise the following: + + IO: + + The "IO:" option specifies an ISA I/O Address to be probed for a non-PCI + MultiMaster Host Adapter. If neither "IO:" nor "NoProbeISA" options are + specified, then the standard list of BusLogic MultiMaster ISA I/O Addresses + will be probed (0x330, 0x334, 0x230, 0x234, 0x130, and 0x134). Multiple + "IO:" options may be specified to precisely determine the I/O Addresses to + be probed, but the probe order will always follow the standard list. + + NoProbe + + The "NoProbe" option disables all probing and therefore no BusLogic Host + Adapters will be detected. + + NoProbeISA + + The "NoProbeISA" option disables probing of the standard BusLogic ISA I/O + Addresses and therefore only PCI MultiMaster and FlashPoint Host Adapters + will be detected. + + NoProbePCI + + The "NoProbePCI" options disables the interrogation of PCI Configuration + Space and therefore only ISA Multimaster Host Adapters will be detected, as + well as PCI Multimaster Host Adapters that have their ISA Compatible I/O + Port set to "Primary" or "Alternate". + + NoSortPCI + + The "NoSortPCI" option forces PCI MultiMaster Host Adapters to be + enumerated in the order provided by the PCI BIOS, ignoring any setting of + the AutoSCSI "Use Bus And Device # For PCI Scanning Seq." option. + + MultiMasterFirst + + The "MultiMasterFirst" option forces MultiMaster Host Adapters to be probed + before FlashPoint Host Adapters. By default, if both FlashPoint and PCI + MultiMaster Host Adapters are present, this driver will probe for + FlashPoint Host Adapters first unless the BIOS primary disk is controlled + by the first PCI MultiMaster Host Adapter, in which case MultiMaster Host + Adapters will be probed first. + + FlashPointFirst + + The "FlashPointFirst" option forces FlashPoint Host Adapters to be probed + before MultiMaster Host Adapters. + + The BusLogic Driver Tagged Queuing Options allow for explicitly specifying + the Queue Depth and whether Tagged Queuing is permitted for each Target + Device (assuming that the Target Device supports Tagged Queuing). The Queue + Depth is the number of SCSI Commands that are allowed to be concurrently + presented for execution (either to the Host Adapter or Target Device). Note + that explicitly enabling Tagged Queuing may lead to problems; the option to + enable or disable Tagged Queuing is provided primarily to allow disabling + Tagged Queuing on Target Devices that do not implement it correctly. The + following options are available: + + QueueDepth: + + The "QueueDepth:" or QD:" option specifies the Queue Depth to use for all + Target Devices that support Tagged Queuing. If no Queue Depth option is + provided, the Queue Depth will be determined automatically based on the + Host Adapter's Total Queue Depth and the number, type, speed, and + capabilities of the detected Target Devices. For Host Adapters that + require ISA Bounce Buffers, the Queue Depth is automatically set by default + to BusLogic_QueueDepthBounceBuffers to avoid excessive preallocation of DMA + Bounce Buffer memory. Target Devices that do not support Tagged Queuing + always use a Queue Depth of BusLogic_UntaggedQueueDepth. + + QueueDepth:[,...] + + The "QueueDepth:[...]" or "QD:[...]" option specifies the Queue Depth + individually for each Target Device. If an is omitted, the + associated Target Device will have its Queue Depth selected automatically. + + TaggedQueuing:Default + + The "TaggedQueuing:Default" or "TQ:Default" option permits Tagged Queuing + based on the firmware version of the BusLogic Host Adapter and based on + whether the Queue Depth allows queuing multiple commands. + + TaggedQueuing:Enable + + The "TaggedQueuing:Enable" or "TQ:Enable" option enables Tagged Queuing for + all Target Devices on this Host Adapter, overriding any limitation that + would otherwise be imposed based on the Host Adapter firmware version. + + TaggedQueuing:Disable + + The "TaggedQueuing:Disable" or "TQ:Disable" option disables Tagged Queuing + for all Target Devices on this Host Adapter. + + TaggedQueuing: + + The "TaggedQueuing:" or "TQ:" option controls + Tagged Queuing individually for each Target Device. is a + sequence of "Y", "N", and "X" characters. "Y" enables Tagged Queuing, "N" + disables Tagged Queuing, and "X" accepts the default based on the firmware + version. The first character refers to Target Device 0, the second to + Target Device 1, and so on; if the sequence of "Y", "N", and "X" characters + does not cover all the Target Devices, unspecified characters are assumed + to be "X". + + The BusLogic Driver Error Recovery Option allows for explicitly specifying + the Error Recovery action to be performed when BusLogic_ResetCommand is + called due to a SCSI Command failing to complete successfully. The following + options are available: + + ErrorRecovery:Default + + The "ErrorRecovery:Default" or "ER:Default" option selects between the Hard + Reset and Bus Device Reset options based on the recommendation of the SCSI + Subsystem. + + ErrorRecovery:HardReset + + The "ErrorRecovery:HardReset" or "ER:HardReset" option will initiate a Host + Adapter Hard Reset which also causes a SCSI Bus Reset. + + ErrorRecovery:BusDeviceReset + + The "ErrorRecovery:BusDeviceReset" or "ER:BusDeviceReset" option will send + a Bus Device Reset message to the individual Target Device causing the + error. If Error Recovery is again initiated for this Target Device and no + SCSI Command to this Target Device has completed successfully since the Bus + Device Reset message was sent, then a Hard Reset will be attempted. + + ErrorRecovery:None + + The "ErrorRecovery:None" or "ER:None" option suppresses Error Recovery. + This option should only be selected if a SCSI Bus Reset or Bus Device Reset + will cause the Target Device or a critical operation to suffer a complete + and unrecoverable failure. + + ErrorRecovery: + + The "ErrorRecovery:" or "ER:" option controls + Error Recovery individually for each Target Device. is a + sequence of "D", "H", "B", and "N" characters. "D" selects Default, "H" + selects Hard Reset, "B" selects Bus Device Reset, and "N" selects None. + The first character refers to Target Device 0, the second to Target Device + 1, and so on; if the sequence of "D", "H", "B", and "N" characters does not + cover all the possible Target Devices, unspecified characters are assumed + to be "D". + + The BusLogic Driver Miscellaneous Options comprise the following: + + BusSettleTime: + + The "BusSettleTime:" or "BST:" option specifies the Bus Settle Time in + seconds. The Bus Settle Time is the amount of time to wait between a Host + Adapter Hard Reset which initiates a SCSI Bus Reset and issuing any SCSI + Commands. If unspecified, it defaults to BusLogic_DefaultBusSettleTime. + + InhibitTargetInquiry + + The "InhibitTargetInquiry" option inhibits the execution of an Inquire + Target Devices or Inquire Installed Devices command on MultiMaster Host + Adapters. This may be necessary with some older Target Devices that do not + respond correctly when Logical Units above 0 are addressed. + + The BusLogic Driver Debugging Options comprise the following: + + TraceProbe + + The "TraceProbe" option enables tracing of Host Adapter Probing. + + TraceHardwareReset + + The "TraceHardwareReset" option enables tracing of Host Adapter Hardware + Reset. + + TraceConfiguration + + The "TraceConfiguration" option enables tracing of Host Adapter + Configuration. + + TraceErrors + + The "TraceErrors" option enables tracing of SCSI Commands that return an + error from the Target Device. The CDB and Sense Data will be printed for + each SCSI Command that fails. + + Debug + + The "Debug" option enables all debugging options. + + The following examples demonstrate setting the Queue Depth for Target Devices + 1 and 2 on the first host adapter to 7 and 15, the Queue Depth for all Target + Devices on the second host adapter to 31, and the Bus Settle Time on the + second host adapter to 30 seconds. + + Linux Kernel Command Line: + + linux BusLogic=QueueDepth:[,7,15];QueueDepth:31,BusSettleTime:30 + + LILO Linux Boot Loader (in /etc/lilo.conf): + + append = "BusLogic=QueueDepth:[,7,15];QueueDepth:31,BusSettleTime:30" + + INSMOD Loadable Kernel Module Installation Facility: + + insmod BusLogic.o \ + 'BusLogic_Options="QueueDepth:[,7,15];QueueDepth:31,BusSettleTime:30"' + + NOTE: Module Utilities 2.1.71 or later is required for correct parsing + of driver options containing commas. */ -void BusLogic_Setup(char *Strings, int *Integers) +static void BusLogic_ParseDriverOptions(char *OptionsString) { - BusLogic_CommandLineEntry_T *CommandLineEntry = - &BusLogic_CommandLineEntries[BusLogic_CommandLineEntryCount++]; - int IntegerCount = Integers[0]; - int TargetID, i; - CommandLineEntry->IO_Address = 0; - CommandLineEntry->TaggedQueueDepth = 0; - CommandLineEntry->BusSettleTime = 0; - CommandLineEntry->TaggedQueuingPermitted = 0; - CommandLineEntry->TaggedQueuingPermittedMask = 0; - CommandLineEntry->LocalOptions.All = 0; - memset(CommandLineEntry->ErrorRecoveryStrategy, - BusLogic_ErrorRecovery_Default, - sizeof(CommandLineEntry->ErrorRecoveryStrategy)); - if (IntegerCount > 5) - BusLogic_Error("BusLogic: Unexpected Command Line Integers " - "ignored\n", NULL); - if (IntegerCount >= 1) + while (true) { - BusLogic_IO_Address_T IO_Address = Integers[1]; - if (IO_Address > 0) + BusLogic_DriverOptions_T *DriverOptions = + &BusLogic_DriverOptions[BusLogic_DriverOptionsCount++]; + int TargetID; + memset(DriverOptions, 0, sizeof(BusLogic_DriverOptions_T)); + for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++) + DriverOptions->ErrorRecoveryStrategy[TargetID] = + BusLogic_ErrorRecovery_Default; + while (*OptionsString != '\0' && *OptionsString != ';') { - BusLogic_ProbeInfo_T *ProbeInfo; - for (i = 0; ; i++) - if (BusLogic_ISA_StandardAddresses[i] == 0) - { - BusLogic_Error("BusLogic: Invalid Command Line Entry " - "(illegal I/O Address 0x%X)\n", - NULL, IO_Address); - return; - } - else if (i < BusLogic_ProbeInfoCount && - IO_Address == BusLogic_ProbeInfoList[i].IO_Address) - { - BusLogic_Error("BusLogic: Invalid Command Line Entry " - "(duplicate I/O Address 0x%X)\n", - NULL, IO_Address); - return; - } - else if (IO_Address >= 0x400 || - IO_Address == BusLogic_ISA_StandardAddresses[i]) break; - ProbeInfo = &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount++]; - ProbeInfo->HostAdapterType = BusLogic_MultiMaster; - ProbeInfo->HostAdapterBusType = BusLogic_ISA_Bus; + /* Probing Options. */ + if (BusLogic_ParseKeyword(&OptionsString, "IO:")) + { + BusLogic_IO_Address_T IO_Address = + simple_strtoul(OptionsString, &OptionsString, 0); + BusLogic_ProbeOptions.LimitedProbeISA = true; + switch (IO_Address) + { + case 0x330: + BusLogic_ProbeOptions.Probe330 = true; + break; + case 0x334: + BusLogic_ProbeOptions.Probe334 = true; + break; + case 0x230: + BusLogic_ProbeOptions.Probe230 = true; + break; + case 0x234: + BusLogic_ProbeOptions.Probe234 = true; + break; + case 0x130: + BusLogic_ProbeOptions.Probe130 = true; + break; + case 0x134: + BusLogic_ProbeOptions.Probe134 = true; + break; + default: + BusLogic_Error("BusLogic: Invalid Driver Options " + "(illegal I/O Address 0x%X)\n", + NULL, IO_Address); + return; + } + } + else if (BusLogic_ParseKeyword(&OptionsString, "NoProbeISA")) + BusLogic_ProbeOptions.NoProbeISA = true; + else if (BusLogic_ParseKeyword(&OptionsString, "NoProbePCI")) + BusLogic_ProbeOptions.NoProbePCI = true; + else if (BusLogic_ParseKeyword(&OptionsString, "NoProbe")) + BusLogic_ProbeOptions.NoProbe = true; + else if (BusLogic_ParseKeyword(&OptionsString, "NoSortPCI")) + BusLogic_ProbeOptions.NoSortPCI = true; + else if (BusLogic_ParseKeyword(&OptionsString, "MultiMasterFirst")) + BusLogic_ProbeOptions.MultiMasterFirst = true; + else if (BusLogic_ParseKeyword(&OptionsString, "FlashPointFirst")) + BusLogic_ProbeOptions.FlashPointFirst = true; + /* Tagged Queuing Options. */ + else if (BusLogic_ParseKeyword(&OptionsString, "QueueDepth:[") || + BusLogic_ParseKeyword(&OptionsString, "QD:[")) + { + for (TargetID = 0; + TargetID < BusLogic_MaxTargetDevices; + TargetID++) + { + unsigned short QueueDepth = + simple_strtoul(OptionsString, &OptionsString, 0); + if (QueueDepth > BusLogic_MaxTaggedQueueDepth) + { + BusLogic_Error("BusLogic: Invalid Driver Options " + "(illegal Queue Depth %d)\n", + NULL, QueueDepth); + return; + } + DriverOptions->QueueDepth[TargetID] = QueueDepth; + if (*OptionsString == ',') + OptionsString++; + else if (*OptionsString == ']') + break; + else + { + BusLogic_Error("BusLogic: Invalid Driver Options " + "(',' or ']' expected at '%s')\n", + NULL, OptionsString); + return; + } + } + if (*OptionsString != ']') + { + BusLogic_Error("BusLogic: Invalid Driver Options " + "(']' expected at '%s')\n", + NULL, OptionsString); + return; + } + else OptionsString++; + } + else if (BusLogic_ParseKeyword(&OptionsString, "QueueDepth:") || + BusLogic_ParseKeyword(&OptionsString, "QD:")) + { + unsigned short QueueDepth = + simple_strtoul(OptionsString, &OptionsString, 0); + if (QueueDepth == 0 || QueueDepth > BusLogic_MaxTaggedQueueDepth) + { + BusLogic_Error("BusLogic: Invalid Driver Options " + "(illegal Queue Depth %d)\n", + NULL, QueueDepth); + return; + } + for (TargetID = 0; + TargetID < BusLogic_MaxTargetDevices; + TargetID++) + DriverOptions->QueueDepth[TargetID] = QueueDepth; + } + else if (BusLogic_ParseKeyword(&OptionsString, "TaggedQueuing:") || + BusLogic_ParseKeyword(&OptionsString, "TQ:")) + { + if (BusLogic_ParseKeyword(&OptionsString, "Default")) + { + DriverOptions->TaggedQueuingPermitted = 0x0000; + DriverOptions->TaggedQueuingPermittedMask = 0x0000; + } + else if (BusLogic_ParseKeyword(&OptionsString, "Enable")) + { + DriverOptions->TaggedQueuingPermitted = 0xFFFF; + DriverOptions->TaggedQueuingPermittedMask = 0xFFFF; + } + else if (BusLogic_ParseKeyword(&OptionsString, "Disable")) + { + DriverOptions->TaggedQueuingPermitted = 0x0000; + DriverOptions->TaggedQueuingPermittedMask = 0xFFFF; + } + else + { + unsigned short TargetBit; + for (TargetID = 0, TargetBit = 1; + TargetID < BusLogic_MaxTargetDevices; + TargetID++, TargetBit <<= 1) + switch (*OptionsString++) + { + case 'Y': + DriverOptions->TaggedQueuingPermitted |= TargetBit; + DriverOptions->TaggedQueuingPermittedMask |= TargetBit; + break; + case 'N': + DriverOptions->TaggedQueuingPermitted &= ~TargetBit; + DriverOptions->TaggedQueuingPermittedMask |= TargetBit; + break; + case 'X': + break; + default: + OptionsString--; + TargetID = BusLogic_MaxTargetDevices; + break; + } + } + } + /* Error Recovery Option. */ + else if (BusLogic_ParseKeyword(&OptionsString, "ErrorRecovery:") || + BusLogic_ParseKeyword(&OptionsString, "ER:")) + { + if (BusLogic_ParseKeyword(&OptionsString, "Default")) + for (TargetID = 0; + TargetID < BusLogic_MaxTargetDevices; + TargetID++) + DriverOptions->ErrorRecoveryStrategy[TargetID] = + BusLogic_ErrorRecovery_Default; + else if (BusLogic_ParseKeyword(&OptionsString, "HardReset")) + for (TargetID = 0; + TargetID < BusLogic_MaxTargetDevices; + TargetID++) + DriverOptions->ErrorRecoveryStrategy[TargetID] = + BusLogic_ErrorRecovery_HardReset; + else if (BusLogic_ParseKeyword(&OptionsString, "BusDeviceReset")) + for (TargetID = 0; + TargetID < BusLogic_MaxTargetDevices; + TargetID++) + DriverOptions->ErrorRecoveryStrategy[TargetID] = + BusLogic_ErrorRecovery_BusDeviceReset; + else if (BusLogic_ParseKeyword(&OptionsString, "None")) + for (TargetID = 0; + TargetID < BusLogic_MaxTargetDevices; + TargetID++) + DriverOptions->ErrorRecoveryStrategy[TargetID] = + BusLogic_ErrorRecovery_None; + else + for (TargetID = 0; + TargetID < BusLogic_MaxTargetDevices; + TargetID++) + switch (*OptionsString++) + { + case 'D': + DriverOptions->ErrorRecoveryStrategy[TargetID] = + BusLogic_ErrorRecovery_Default; + break; + case 'H': + DriverOptions->ErrorRecoveryStrategy[TargetID] = + BusLogic_ErrorRecovery_HardReset; + break; + case 'B': + DriverOptions->ErrorRecoveryStrategy[TargetID] = + BusLogic_ErrorRecovery_BusDeviceReset; + break; + case 'N': + DriverOptions->ErrorRecoveryStrategy[TargetID] = + BusLogic_ErrorRecovery_None; + break; + default: + OptionsString--; + TargetID = BusLogic_MaxTargetDevices; + break; + } + } + /* Miscellaneous Options. */ + else if (BusLogic_ParseKeyword(&OptionsString, "BusSettleTime:") || + BusLogic_ParseKeyword(&OptionsString, "BST:")) + { + unsigned short BusSettleTime = + simple_strtoul(OptionsString, &OptionsString, 0); + if (BusSettleTime > 5 * 60) + { + BusLogic_Error("BusLogic: Invalid Driver Options " + "(illegal Bus Settle Time %d)\n", + NULL, BusSettleTime); + return; + } + DriverOptions->BusSettleTime = BusSettleTime; + } + else if (BusLogic_ParseKeyword(&OptionsString, + "InhibitTargetInquiry")) + DriverOptions->LocalOptions.InhibitTargetInquiry = true; + /* Debugging Options. */ + else if (BusLogic_ParseKeyword(&OptionsString, "TraceProbe")) + BusLogic_GlobalOptions.TraceProbe = true; + else if (BusLogic_ParseKeyword(&OptionsString, "TraceHardwareReset")) + BusLogic_GlobalOptions.TraceHardwareReset = true; + else if (BusLogic_ParseKeyword(&OptionsString, "TraceConfiguration")) + BusLogic_GlobalOptions.TraceConfiguration = true; + else if (BusLogic_ParseKeyword(&OptionsString, "TraceErrors")) + BusLogic_GlobalOptions.TraceErrors = true; + else if (BusLogic_ParseKeyword(&OptionsString, "Debug")) + { + BusLogic_GlobalOptions.TraceProbe = true; + BusLogic_GlobalOptions.TraceHardwareReset = true; + BusLogic_GlobalOptions.TraceConfiguration = true; + BusLogic_GlobalOptions.TraceErrors = true; + } + if (*OptionsString == ',') + OptionsString++; + else if (*OptionsString != ';' && *OptionsString != '\0') + { + BusLogic_Error("BusLogic: Unexpected Driver Option '%s' " + "ignored\n", NULL, OptionsString); + *OptionsString = '\0'; + } } - CommandLineEntry->IO_Address = IO_Address; - } - if (IntegerCount >= 2) - { - unsigned short TaggedQueueDepth = Integers[2]; - if (TaggedQueueDepth > BusLogic_MaxTaggedQueueDepth) + if (!(BusLogic_DriverOptionsCount == 0 || + BusLogic_ProbeInfoCount == 0 || + BusLogic_DriverOptionsCount == BusLogic_ProbeInfoCount)) { - BusLogic_Error("BusLogic: Invalid Command Line Entry " - "(illegal Tagged Queue Depth %d)\n", - NULL, TaggedQueueDepth); + BusLogic_Error("BusLogic: Invalid Driver Options " + "(all or no I/O Addresses must be specified)\n", NULL); return; } - CommandLineEntry->TaggedQueueDepth = TaggedQueueDepth; + /* + Tagged Queuing is disabled when the Queue Depth is 1 since queuing + multiple commands is not possible. + */ + for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++) + if (DriverOptions->QueueDepth[TargetID] == 1) + { + unsigned short TargetBit = 1 << TargetID; + DriverOptions->TaggedQueuingPermitted &= ~TargetBit; + DriverOptions->TaggedQueuingPermittedMask |= TargetBit; + } + if (*OptionsString == ';') OptionsString++; + if (*OptionsString == '\0') return; } - if (IntegerCount >= 3) - CommandLineEntry->BusSettleTime = Integers[3]; - if (IntegerCount >= 4) - CommandLineEntry->LocalOptions.All = Integers[4]; - if (IntegerCount >= 5) - BusLogic_GlobalOptions.All |= Integers[5]; - if (!(BusLogic_CommandLineEntryCount == 0 || - BusLogic_ProbeInfoCount == 0 || - BusLogic_CommandLineEntryCount == BusLogic_ProbeInfoCount)) +} + + +/* + BusLogic_Setup handles processing of Kernel Command Line Arguments. +*/ + +void BusLogic_Setup(char *CommandLineString, int *CommandLineIntegers) +{ + if (CommandLineIntegers[0] != 0) { - BusLogic_Error("BusLogic: Invalid Command Line Entry " - "(all or no I/O Addresses must be specified)\n", NULL); + BusLogic_Error("BusLogic: Obsolete Command Line Entry " + "Format Ignored\n", NULL); return; } - if (Strings == NULL) return; - while (*Strings != '\0') - if (strncmp(Strings, "TQ:", 3) == 0) - { - Strings += 3; - if (strncmp(Strings, "Default", 7) == 0) - Strings += 7; - else if (strncmp(Strings, "Enable", 6) == 0) - { - Strings += 6; - CommandLineEntry->TaggedQueuingPermitted = 0xFFFF; - CommandLineEntry->TaggedQueuingPermittedMask = 0xFFFF; - } - else if (strncmp(Strings, "Disable", 7) == 0) - { - Strings += 7; - CommandLineEntry->TaggedQueuingPermitted = 0x0000; - CommandLineEntry->TaggedQueuingPermittedMask = 0xFFFF; - } - else - for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++) - switch (*Strings++) - { - case 'Y': - CommandLineEntry->TaggedQueuingPermitted |= 1 << TargetID; - CommandLineEntry->TaggedQueuingPermittedMask |= 1 << TargetID; - break; - case 'N': - CommandLineEntry->TaggedQueuingPermittedMask |= 1 << TargetID; - break; - case 'X': - break; - default: - Strings--; - TargetID = BusLogic_MaxTargetDevices; - break; - } - } - else if (strncmp(Strings, "ER:", 3) == 0) - { - Strings += 3; - if (strncmp(Strings, "Default", 7) == 0) - Strings += 7; - else if (strncmp(Strings, "HardReset", 9) == 0) - { - Strings += 9; - memset(CommandLineEntry->ErrorRecoveryStrategy, - BusLogic_ErrorRecovery_HardReset, - sizeof(CommandLineEntry->ErrorRecoveryStrategy)); - } - else if (strncmp(Strings, "BusDeviceReset", 14) == 0) - { - Strings += 14; - memset(CommandLineEntry->ErrorRecoveryStrategy, - BusLogic_ErrorRecovery_BusDeviceReset, - sizeof(CommandLineEntry->ErrorRecoveryStrategy)); - } - else if (strncmp(Strings, "None", 4) == 0) - { - Strings += 4; - memset(CommandLineEntry->ErrorRecoveryStrategy, - BusLogic_ErrorRecovery_None, - sizeof(CommandLineEntry->ErrorRecoveryStrategy)); - } - else - for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++) - switch (*Strings++) - { - case 'D': - CommandLineEntry->ErrorRecoveryStrategy[TargetID] = - BusLogic_ErrorRecovery_Default; - break; - case 'H': - CommandLineEntry->ErrorRecoveryStrategy[TargetID] = - BusLogic_ErrorRecovery_HardReset; - break; - case 'B': - CommandLineEntry->ErrorRecoveryStrategy[TargetID] = - BusLogic_ErrorRecovery_BusDeviceReset; - break; - case 'N': - CommandLineEntry->ErrorRecoveryStrategy[TargetID] = - BusLogic_ErrorRecovery_None; - break; - default: - Strings--; - TargetID = BusLogic_MaxTargetDevices; - break; - } - } - else if (strcmp(Strings, "NoProbe") == 0 || - strcmp(Strings, "noprobe") == 0) - { - Strings += 7; - BusLogic_ProbeOptions.Bits.NoProbe = true; - } - else if (strncmp(Strings, "NoProbeISA", 10) == 0) - { - Strings += 10; - BusLogic_ProbeOptions.Bits.NoProbeISA = true; - } - else if (strncmp(Strings, "NoProbePCI", 10) == 0) - { - Strings += 10; - BusLogic_ProbeOptions.Bits.NoProbePCI = true; - } - else if (strncmp(Strings, "NoSortPCI", 9) == 0) - { - Strings += 9; - BusLogic_ProbeOptions.Bits.NoSortPCI = true; - } - else if (strncmp(Strings, "MultiMasterFirst", 16) == 0) - { - Strings += 16; - BusLogic_ProbeOptions.Bits.ProbeMultiMasterFirst = true; - } - else if (strncmp(Strings, "FlashPointFirst", 15) == 0) - { - Strings += 15; - BusLogic_ProbeOptions.Bits.ProbeFlashPointFirst = true; - } - else if (strncmp(Strings, "Debug", 5) == 0) - { - Strings += 5; - BusLogic_GlobalOptions.Bits.TraceProbe = true; - BusLogic_GlobalOptions.Bits.TraceHardReset = true; - BusLogic_GlobalOptions.Bits.TraceConfiguration = true; - BusLogic_GlobalOptions.Bits.TraceErrors = true; - } - else if (*Strings == ',') - Strings++; - else - { - BusLogic_Error("BusLogic: Unexpected Command Line String '%s' " - "ignored\n", NULL, Strings); - break; - } + if (CommandLineString == NULL || *CommandLineString == '\0') return; + BusLogic_ParseDriverOptions(CommandLineString); } @@ -4724,6 +5021,8 @@ void BusLogic_Setup(char *Strings, int *Integers) #ifdef MODULE +MODULE_PARM(BusLogic_Options, "s"); + SCSI_Host_Template_T driver_template = BUSLOGIC; #include "scsi_module.c" diff --git a/drivers/scsi/BusLogic.h b/drivers/scsi/BusLogic.h index 6f62e04b0..ef7a8dcca 100644 --- a/drivers/scsi/BusLogic.h +++ b/drivers/scsi/BusLogic.h @@ -6,8 +6,7 @@ This program is free software; you may redistribute and/or modify it under the terms of the GNU General Public License Version 2 as published by the - Free Software Foundation, provided that none of the source code or runtime - copyright notices are removed or modified. + Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY @@ -38,6 +37,7 @@ typedef kdev_t KernelDevice_T; typedef struct proc_dir_entry PROC_DirectoryEntry_T; typedef struct pt_regs Registers_T; +typedef struct partition PartitionTable_T; typedef Scsi_Host_Template SCSI_Host_Template_T; typedef struct Scsi_Host SCSI_Host_T; typedef struct scsi_device SCSI_Device_T; @@ -66,28 +66,19 @@ extern int BusLogic_ProcDirectoryInfo(char *, char **, off_t, int, int, int); Define the BusLogic SCSI Host Template structure. */ -#define BUSLOGIC \ - { NULL, /* Next */ \ - NULL, /* Usage Count Pointer */ \ - &BusLogic_ProcDirectoryEntry, /* /proc Directory Entry */ \ - BusLogic_ProcDirectoryInfo, /* /proc Info Function */ \ - "BusLogic", /* Driver Name */ \ - BusLogic_DetectHostAdapter, /* Detect Host Adapter */ \ - BusLogic_ReleaseHostAdapter, /* Release Host Adapter */ \ - BusLogic_DriverInfo, /* Driver Info Function */ \ - NULL, /* Command Function */ \ - BusLogic_QueueCommand, /* Queue Command Function */ \ - BusLogic_AbortCommand, /* Abort Command Function */ \ - BusLogic_ResetCommand, /* Reset Command Function */ \ - NULL, /* Slave Attach Function */ \ - BusLogic_BIOSDiskParameters, /* BIOS Disk Parameters */ \ - 0, /* Can Queue */ \ - 0, /* This ID */ \ - 0, /* Scatter/Gather Table Size */ \ - 0, /* SCSI Commands per LUN */ \ - 0, /* Present */ \ - 1, /* Default Unchecked ISA DMA */ \ - ENABLE_CLUSTERING } /* Enable Clustering */ +#define BUSLOGIC \ + { proc_dir: &BusLogic_ProcDirectoryEntry, /* ProcFS Directory Entry */ \ + proc_info: BusLogic_ProcDirectoryInfo, /* ProcFS Info Function */ \ + name: "BusLogic", /* Driver Name */ \ + detect: BusLogic_DetectHostAdapter, /* Detect Host Adapter */ \ + release: BusLogic_ReleaseHostAdapter, /* Release Host Adapter */ \ + info: BusLogic_DriverInfo, /* Driver Info Function */ \ + queuecommand: BusLogic_QueueCommand, /* Queue Command Function */ \ + abort: BusLogic_AbortCommand, /* Abort Command Function */ \ + reset: BusLogic_ResetCommand, /* Reset Command Function */ \ + bios_param: BusLogic_BIOSDiskParameters, /* BIOS Disk Parameters */ \ + unchecked_isa_dma: 1, /* Default Initial Value */ \ + use_clustering: ENABLE_CLUSTERING } /* Enable Clustering */ /* @@ -97,6 +88,24 @@ extern int BusLogic_ProcDirectoryInfo(char *, char **, off_t, int, int, int); #ifdef BusLogic_DriverVersion +/* + FlashPoint support is only available for the Intel x86 Architecture with + CONFIG_PCI set. +*/ + +#ifndef __i386__ +#undef CONFIG_SCSI_OMIT_FLASHPOINT +#define CONFIG_SCSI_OMIT_FLASHPOINT +#endif + +#ifndef CONFIG_PCI +#undef CONFIG_SCSI_OMIT_FLASHPOINT +#define CONFIG_SCSI_OMIT_FLASHPOINT +#define BusLogic_InitializeProbeInfoListISA \ + BusLogic_InitializeProbeInfoList +#endif + + /* Define the maximum number of BusLogic Host Adapters supported by this driver. */ @@ -121,16 +130,17 @@ extern int BusLogic_ProcDirectoryInfo(char *, char **, off_t, int, int, int); /* - Define the maximum, preferred, and default Queue Depth to allow for Target - Devices depending on whether or not they support Tagged Queuing and whether - or not ISA Bounce Buffers are required. + Define the maximum, maximum automatic, minimum automatic, and default Queue + Depth to allow for Target Devices depending on whether or not they support + Tagged Queuing and whether or not ISA Bounce Buffers are required. */ -#define BusLogic_MaxTaggedQueueDepth 63 -#define BusLogic_PreferredTaggedQueueDepth 28 -#define BusLogic_TaggedQueueDepthBounceBuffers 2 -#define BusLogic_TaggedQueueDepthAutomatic 0 +#define BusLogic_MaxTaggedQueueDepth 64 +#define BusLogic_MaxAutomaticTaggedQueueDepth 28 +#define BusLogic_MinAutomaticTaggedQueueDepth 7 +#define BusLogic_TaggedQueueDepthBB 3 #define BusLogic_UntaggedQueueDepth 3 +#define BusLogic_UntaggedQueueDepthBB 2 /* @@ -143,12 +153,30 @@ extern int BusLogic_ProcDirectoryInfo(char *, char **, off_t, int, int, int); #define BusLogic_DefaultBusSettleTime 2 +/* + Define the maximum number of Mailboxes that should be used for MultiMaster + Host Adapters. This number is chosen to be larger than the maximum Host + Adapter Queue Depth and small enough so that the Host Adapter structure + does not cross an allocation block size boundary. +*/ + +#define BusLogic_MaxMailboxes 211 + + +/* + Define the number of CCBs that should be allocated as a group to optimize + Kernel memory allocation. +*/ + +#define BusLogic_CCB_AllocationGroupSize 7 + + /* Define the Host Adapter Line and Message Buffer Sizes. */ #define BusLogic_LineBufferSize 100 -#define BusLogic_MessageBufferSize 9900 +#define BusLogic_MessageBufferSize 9700 /* @@ -167,7 +195,27 @@ BusLogic_MessageLevel_T; static char *BusLogic_MessageLevelMap[] = - { KERN_INFO, KERN_INFO, KERN_NOTICE, KERN_WARNING, KERN_ERR }; + { KERN_NOTICE, KERN_NOTICE, KERN_NOTICE, KERN_WARNING, KERN_ERR }; + + +/* + Define Driver Message macros. +*/ + +#define BusLogic_Announce(Format, Arguments...) \ + BusLogic_Message(BusLogic_AnnounceLevel, Format, ##Arguments) + +#define BusLogic_Info(Format, Arguments...) \ + BusLogic_Message(BusLogic_InfoLevel, Format, ##Arguments) + +#define BusLogic_Notice(Format, Arguments...) \ + BusLogic_Message(BusLogic_NoticeLevel, Format, ##Arguments) + +#define BusLogic_Warning(Format, Arguments...) \ + BusLogic_Message(BusLogic_WarningLevel, Format, ##Arguments) + +#define BusLogic_Error(Format, Arguments...) \ + BusLogic_Message(BusLogic_ErrorLevel, Format, ##Arguments) /* @@ -187,10 +235,33 @@ BusLogic_HostAdapterType_T; #define BusLogic_FlashPointAddressCount 256 static int - BusLogic_HostAdapter_AddressCount[3] = + BusLogic_HostAdapterAddressCount[3] = { 0, BusLogic_MultiMasterAddressCount, BusLogic_FlashPointAddressCount }; +/* + Define macros for testing the Host Adapter Type. +*/ + +#ifndef CONFIG_SCSI_OMIT_FLASHPOINT + +#define BusLogic_MultiMasterHostAdapterP(HostAdapter) \ + (HostAdapter->HostAdapterType == BusLogic_MultiMaster) + +#define BusLogic_FlashPointHostAdapterP(HostAdapter) \ + (HostAdapter->HostAdapterType == BusLogic_FlashPoint) + +#else + +#define BusLogic_MultiMasterHostAdapterP(HostAdapter) \ + (true) + +#define BusLogic_FlashPointHostAdapterP(HostAdapter) \ + (false) + +#endif + + /* Define the possible Host Adapter Bus Types. */ @@ -204,6 +275,7 @@ typedef enum BusLogic_VESA_Bus = 4, BusLogic_MCA_Bus = 5 } +__attribute__ ((packed)) BusLogic_HostAdapterBusType_T; static char @@ -256,6 +328,13 @@ typedef unsigned int BusLogic_IO_Address_T; typedef unsigned int BusLogic_PCI_Address_T; +/* + Define a 32 bit Base Address data type. +*/ + +typedef unsigned int BusLogic_Base_Address_T; + + /* Define a 32 bit Bus Address data type. */ @@ -288,11 +367,10 @@ BusLogic_ByteCounter_T; typedef struct BusLogic_ProbeInfo { + BusLogic_HostAdapterType_T HostAdapterType; + BusLogic_HostAdapterBusType_T HostAdapterBusType; BusLogic_IO_Address_T IO_Address; BusLogic_PCI_Address_T PCI_Address; - BusLogic_HostAdapterType_T HostAdapterType:2; - BusLogic_HostAdapterBusType_T HostAdapterBusType:3; - unsigned char :3; unsigned char Bus; unsigned char Device; unsigned char IRQ_Channel; @@ -300,36 +378,25 @@ typedef struct BusLogic_ProbeInfo BusLogic_ProbeInfo_T; -/* - BusLogic_ISA_StandardAddresses is the list of standard ISA I/O Addresses at - which BusLogic MultiMaster Host Adapters may potentially be found. The first - I/O Address 0x330 is known as the "Primary" I/O Address. A Host Adapter - configured to use the Primary I/O Address will always be the preferred boot - device. -*/ - -#define BusLogic_ISA_StandardAddressesCount 6 - -static BusLogic_IO_Address_T - BusLogic_ISA_StandardAddresses[BusLogic_ISA_StandardAddressesCount] = - { 0x330, 0x334, 0x230, 0x234, 0x130, 0x134 }; - - /* Define the Probe Options. */ -typedef union BusLogic_ProbeOptions +typedef struct BusLogic_ProbeOptions { - unsigned short All; - struct { - boolean NoProbe:1; /* Bit 0 */ - boolean NoProbeISA:1; /* Bit 1 */ - boolean NoProbePCI:1; /* Bit 2 */ - boolean NoSortPCI:1; /* Bit 3 */ - boolean ProbeMultiMasterFirst:1; /* Bit 4 */ - boolean ProbeFlashPointFirst:1; /* Bit 5 */ - } Bits; + boolean NoProbe:1; /* Bit 0 */ + boolean NoProbeISA:1; /* Bit 1 */ + boolean NoProbePCI:1; /* Bit 2 */ + boolean NoSortPCI:1; /* Bit 3 */ + boolean MultiMasterFirst:1; /* Bit 4 */ + boolean FlashPointFirst:1; /* Bit 5 */ + boolean LimitedProbeISA:1; /* Bit 6 */ + boolean Probe330:1; /* Bit 7 */ + boolean Probe334:1; /* Bit 8 */ + boolean Probe230:1; /* Bit 9 */ + boolean Probe234:1; /* Bit 10 */ + boolean Probe130:1; /* Bit 11 */ + boolean Probe134:1; /* Bit 12 */ } BusLogic_ProbeOptions_T; @@ -338,15 +405,12 @@ BusLogic_ProbeOptions_T; Define the Global Options. */ -typedef union BusLogic_GlobalOptions +typedef struct BusLogic_GlobalOptions { - unsigned short All; - struct { - boolean TraceProbe:1; /* Bit 0 */ - boolean TraceHardReset:1; /* Bit 1 */ - boolean TraceConfiguration:1; /* Bit 2 */ - boolean TraceErrors:1; /* Bit 3 */ - } Bits; + boolean TraceProbe:1; /* Bit 0 */ + boolean TraceHardwareReset:1; /* Bit 1 */ + boolean TraceConfiguration:1; /* Bit 2 */ + boolean TraceErrors:1; /* Bit 3 */ } BusLogic_GlobalOptions_T; @@ -355,13 +419,9 @@ BusLogic_GlobalOptions_T; Define the Local Options. */ -typedef union BusLogic_LocalOptions +typedef struct BusLogic_LocalOptions { - unsigned short All; - struct { - boolean InhibitTargetInquiry:1; /* Bit 0 */ - boolean InhibitInterruptTest:1; /* Bit 1 */ - } Bits; + boolean InhibitTargetInquiry:1; /* Bit 0 */ } BusLogic_LocalOptions_T; @@ -619,10 +679,13 @@ typedef struct BusLogic_SetupInformation unsigned char Signature; /* Byte 17 */ unsigned char CharacterD; /* Byte 18 */ unsigned char HostBusType; /* Byte 19 */ - unsigned char :8; /* Byte 20 */ - unsigned char :8; /* Byte 21 */ + unsigned char WideTransfersPermittedID0to7; /* Byte 20 */ + unsigned char WideTransfersActiveID0to7; /* Byte 21 */ BusLogic_SynchronousValues8_T SynchronousValuesID8to15; /* Bytes 22-29 */ unsigned char DisconnectPermittedID8to15; /* Byte 30 */ + unsigned char :8; /* Byte 31 */ + unsigned char WideTransfersPermittedID8to15; /* Byte 32 */ + unsigned char WideTransfersActiveID8to15; /* Byte 33 */ } BusLogic_SetupInformation_T; @@ -1063,6 +1126,21 @@ typedef struct BusLogic_ScatterGatherSegment BusLogic_ScatterGatherSegment_T; +/* + Define the Driver CCB Status Codes. +*/ + +typedef enum +{ + BusLogic_CCB_Free = 0, + BusLogic_CCB_Active = 1, + BusLogic_CCB_Completed = 2, + BusLogic_CCB_Reset = 3 +} +__attribute__ ((packed)) +BusLogic_CCB_Status_T; + + /* Define the 32 Bit Mode Command Control Block (CCB) structure. The first 40 bytes are defined by and common to both the MultiMaster Firmware and the @@ -1113,27 +1191,26 @@ typedef struct BusLogic_CCB FlashPoint SCCB Manager Defined Portion. */ void (*CallbackFunction)(struct BusLogic_CCB *); /* Bytes 40-43 */ - BusLogic_IO_Address_T BaseAddress; /* Bytes 44-47 */ + BusLogic_Base_Address_T BaseAddress; /* Bytes 44-47 */ BusLogic_CompletionCode_T CompletionCode; /* Byte 48 */ +#ifndef CONFIG_SCSI_OMIT_FLASHPOINT unsigned char :8; /* Byte 49 */ unsigned short OS_Flags; /* Bytes 50-51 */ unsigned char Private[48]; /* Bytes 52-99 */ +#endif /* BusLogic Linux Driver Defined Portion. */ - struct BusLogic_HostAdapter *HostAdapter; - SCSI_Command_T *Command; - enum { BusLogic_CCB_Free = 0, - BusLogic_CCB_Active = 1, - BusLogic_CCB_Completed = 2, - BusLogic_CCB_Reset = 3 } Status; + boolean AllocationGroupHead; + BusLogic_CCB_Status_T Status; unsigned long SerialNumber; + SCSI_Command_T *Command; + struct BusLogic_HostAdapter *HostAdapter; struct BusLogic_CCB *Next; struct BusLogic_CCB *NextAll; BusLogic_ScatterGatherSegment_T ScatterGatherList[BusLogic_ScatterGatherLimit]; } -__attribute__ ((packed)) BusLogic_CCB_T; @@ -1166,32 +1243,48 @@ BusLogic_IncomingMailbox_T; /* - Define the Linux BusLogic Driver Command Line Entry structure. + Define the BusLogic Driver Options structure. */ -typedef struct BusLogic_CommandLineEntry +typedef struct BusLogic_DriverOptions { - BusLogic_IO_Address_T IO_Address; - unsigned short TaggedQueueDepth; - unsigned short BusSettleTime; unsigned short TaggedQueuingPermitted; unsigned short TaggedQueuingPermittedMask; + unsigned short BusSettleTime; BusLogic_LocalOptions_T LocalOptions; + unsigned char QueueDepth[BusLogic_MaxTargetDevices]; BusLogic_ErrorRecoveryStrategy_T ErrorRecoveryStrategy[BusLogic_MaxTargetDevices]; } -BusLogic_CommandLineEntry_T; +BusLogic_DriverOptions_T; /* - Define the Host Adapter Target Device Statistics structure. + Define the Host Adapter Target Flags structure. +*/ + +typedef struct BusLogic_TargetFlags +{ + boolean TargetExists:1; + boolean TaggedQueuingSupported:1; + boolean WideTransfersSupported:1; + boolean TaggedQueuingActive:1; + boolean WideTransfersActive:1; + boolean CommandSuccessfulFlag:1; + boolean TargetInfoReported:1; +} +BusLogic_TargetFlags_T; + + +/* + Define the Host Adapter Target Statistics structure. */ #define BusLogic_SizeBuckets 10 typedef unsigned int BusLogic_CommandSizeBuckets_T[BusLogic_SizeBuckets]; -typedef struct BusLogic_TargetDeviceStatistics +typedef struct BusLogic_TargetStatistics { unsigned int CommandsAttempted; unsigned int CommandsCompleted; @@ -1211,7 +1304,7 @@ typedef struct BusLogic_TargetDeviceStatistics unsigned short HostAdapterResetsAttempted; unsigned short HostAdapterResetsCompleted; } -BusLogic_TargetDeviceStatistics_T; +BusLogic_TargetStatistics_T; /* @@ -1230,7 +1323,7 @@ typedef unsigned int FlashPoint_CardHandle_T; typedef struct FlashPoint_Info { - BusLogic_IO_Address_T BaseAddress; /* Bytes 0-3 */ + BusLogic_Base_Address_T BaseAddress; /* Bytes 0-3 */ boolean Present; /* Byte 4 */ unsigned char IRQ_Channel; /* Byte 5 */ unsigned char SCSI_ID; /* Byte 6 */ @@ -1265,12 +1358,14 @@ FlashPoint_Info_T; /* - Define the Linux BusLogic Driver Host Adapter structure. + Define the BusLogic Driver Host Adapter structure. */ typedef struct BusLogic_HostAdapter { SCSI_Host_T *SCSI_Host; + BusLogic_HostAdapterType_T HostAdapterType; + BusLogic_HostAdapterBusType_T HostAdapterBusType; BusLogic_IO_Address_T IO_Address; BusLogic_PCI_Address_T PCI_Address; unsigned short AddressCount; @@ -1279,18 +1374,16 @@ typedef struct BusLogic_HostAdapter unsigned char FirmwareVersion[6]; unsigned char FullModelName[18]; unsigned char InterruptLabel[68]; + unsigned char Bus; + unsigned char Device; unsigned char IRQ_Channel; unsigned char DMA_Channel; unsigned char SCSI_ID; - unsigned char Bus; - unsigned char Device; - BusLogic_HostAdapterType_T HostAdapterType; - BusLogic_HostAdapterBusType_T HostAdapterBusType:3; boolean IRQ_ChannelAcquired:1; boolean DMA_ChannelAcquired:1; boolean ExtendedTranslationEnabled:1; boolean ParityCheckingEnabled:1; - boolean BusResetEnabled; + boolean BusResetEnabled:1; boolean LevelSensitiveInterrupt:1; boolean HostWideSCSI:1; boolean HostDifferentialSCSI:1; @@ -1304,8 +1397,9 @@ typedef struct BusLogic_HostAdapter boolean StrictRoundRobinModeSupport:1; boolean SCAM_Enabled:1; boolean SCAM_Level2:1; - boolean HostAdapterInitialized; - boolean HostAdapterResetRequested:1; + boolean HostAdapterInitialized:1; + boolean HostAdapterExternalReset:1; + boolean HostAdapterInternalError:1; volatile boolean HostAdapterCommandCompleted:1; unsigned short HostAdapterScatterGatherLimit; unsigned short DriverScatterGatherLimit; @@ -1317,7 +1411,6 @@ typedef struct BusLogic_HostAdapter unsigned short AllocatedCCBs; unsigned short DriverQueueDepth; unsigned short HostAdapterQueueDepth; - unsigned short TaggedQueueDepth; unsigned short UntaggedQueueDepth; unsigned short BusSettleTime; unsigned short SynchronousPermitted; @@ -1327,26 +1420,24 @@ typedef struct BusLogic_HostAdapter unsigned short DisconnectPermitted; unsigned short TaggedQueuingPermitted; unsigned short ExternalHostAdapterResets; - BusLogic_LocalOptions_T LocalOptions; + unsigned short HostAdapterInternalErrors; + unsigned short TargetDeviceCount; + unsigned short MessageBufferLength; BusLogic_BusAddress_T BIOS_Address; - BusLogic_InstalledDevices_T InstalledDevices; - BusLogic_SynchronousValues_T SynchronousValues; - BusLogic_SynchronousPeriod_T SynchronousPeriod; - BusLogic_CommandLineEntry_T *CommandLineEntry; - FlashPoint_Info_T *FlashPointInfo; + BusLogic_DriverOptions_T *DriverOptions; + FlashPoint_Info_T FlashPointInfo; FlashPoint_CardHandle_T CardHandle; struct BusLogic_HostAdapter *Next; - char *MessageBuffer; - int MessageBufferLength; + struct BusLogic_HostAdapter *NextAll; BusLogic_CCB_T *All_CCBs; BusLogic_CCB_T *Free_CCBs; BusLogic_CCB_T *BusDeviceResetPendingCCB[BusLogic_MaxTargetDevices]; BusLogic_ErrorRecoveryStrategy_T ErrorRecoveryStrategy[BusLogic_MaxTargetDevices]; - boolean TaggedQueuingSupported[BusLogic_MaxTargetDevices]; - boolean TaggedQueuingActive[BusLogic_MaxTargetDevices]; - boolean CommandSuccessfulFlag[BusLogic_MaxTargetDevices]; + BusLogic_TargetFlags_T TargetFlags[BusLogic_MaxTargetDevices]; unsigned char QueueDepth[BusLogic_MaxTargetDevices]; + unsigned char SynchronousPeriod[BusLogic_MaxTargetDevices]; + unsigned char SynchronousOffset[BusLogic_MaxTargetDevices]; unsigned char ActiveCommands[BusLogic_MaxTargetDevices]; unsigned int CommandsSinceReset[BusLogic_MaxTargetDevices]; unsigned long LastSequencePoint[BusLogic_MaxTargetDevices]; @@ -1358,7 +1449,11 @@ typedef struct BusLogic_HostAdapter BusLogic_IncomingMailbox_T *FirstIncomingMailbox; BusLogic_IncomingMailbox_T *LastIncomingMailbox; BusLogic_IncomingMailbox_T *NextIncomingMailbox; - BusLogic_TargetDeviceStatistics_T *TargetDeviceStatistics; + BusLogic_TargetStatistics_T TargetStatistics[BusLogic_MaxTargetDevices]; + unsigned char MailboxSpace[BusLogic_MaxMailboxes + * (sizeof(BusLogic_OutgoingMailbox_T) + + sizeof(BusLogic_IncomingMailbox_T))]; + char MessageBuffer[BusLogic_MessageBufferSize]; } BusLogic_HostAdapter_T; @@ -1376,6 +1471,41 @@ typedef struct BIOS_DiskParameters BIOS_DiskParameters_T; +/* + Define a structure for the SCSI Inquiry command results. +*/ + +typedef struct SCSI_Inquiry +{ + unsigned char PeripheralDeviceType:5; /* Byte 0 Bits 0-4 */ + unsigned char PeripheralQualifier:3; /* Byte 0 Bits 5-7 */ + unsigned char DeviceTypeModifier:7; /* Byte 1 Bits 0-6 */ + boolean RMB:1; /* Byte 1 Bit 7 */ + unsigned char ANSI_ApprovedVersion:3; /* Byte 2 Bits 0-2 */ + unsigned char ECMA_Version:3; /* Byte 2 Bits 3-5 */ + unsigned char ISO_Version:2; /* Byte 2 Bits 6-7 */ + unsigned char ResponseDataFormat:4; /* Byte 3 Bits 0-3 */ + unsigned char :2; /* Byte 3 Bits 4-5 */ + boolean TrmIOP:1; /* Byte 3 Bit 6 */ + boolean AENC:1; /* Byte 3 Bit 7 */ + unsigned char AdditionalLength; /* Byte 4 */ + unsigned char :8; /* Byte 5 */ + unsigned char :8; /* Byte 6 */ + boolean SftRe:1; /* Byte 7 Bit 0 */ + boolean CmdQue:1; /* Byte 7 Bit 1 */ + boolean :1; /* Byte 7 Bit 2 */ + boolean Linked:1; /* Byte 7 Bit 3 */ + boolean Sync:1; /* Byte 7 Bit 4 */ + boolean WBus16:1; /* Byte 7 Bit 5 */ + boolean WBus32:1; /* Byte 7 Bit 6 */ + boolean RelAdr:1; /* Byte 7 Bit 7 */ + unsigned char VendorIdentification[8]; /* Bytes 8-15 */ + unsigned char ProductIdentification[16]; /* Bytes 16-31 */ + unsigned char ProductRevisionLevel[4]; /* Bytes 32-35 */ +} +SCSI_Inquiry_T; + + /* BusLogic_AcquireHostAdapterLock acquires exclusive access to Host Adapter. */ @@ -1551,6 +1681,19 @@ static inline void *Bus_to_Virtual(BusLogic_BusAddress_T BusAddress) } +/* + Virtual_to_32Bit_Virtual maps between Kernel Virtual Addresses and + 32 Bit Kernel Virtual Addresses. This avoids compilation warnings + on 64 Bit architectures. +*/ + +static inline +BusLogic_BusAddress_T Virtual_to_32Bit_Virtual(void *VirtualAddress) +{ + return (BusLogic_BusAddress_T) (unsigned long) VirtualAddress; +} + + /* BusLogic_IncrementErrorCounter increments Error Counter by 1, stopping at 65535 rather than wrapping around to 0. @@ -1589,93 +1732,38 @@ static inline void BusLogic_IncrementSizeBucket(BusLogic_CommandSizeBuckets_T { int Index = 0; if (Amount < 8*1024) - if (Amount < 2*1024) - Index = (Amount < 1*1024 ? 0 : 1); - else Index = (Amount < 4*1024 ? 2 : 3); + { + if (Amount < 2*1024) + Index = (Amount < 1*1024 ? 0 : 1); + else Index = (Amount < 4*1024 ? 2 : 3); + } else if (Amount < 128*1024) - if (Amount < 32*1024) - Index = (Amount < 16*1024 ? 4 : 5); - else Index = (Amount < 64*1024 ? 6 : 7); + { + if (Amount < 32*1024) + Index = (Amount < 16*1024 ? 4 : 5); + else Index = (Amount < 64*1024 ? 6 : 7); + } else Index = (Amount < 256*1024 ? 8 : 9); CommandSizeBuckets[Index]++; } /* - If CONFIG_PCI is not set, force CONFIG_SCSI_OMIT_FLASHPOINT, and use the - ISA only probe function as the general one. + Define compatibility macros between Linux 2.0 and Linux 2.1. */ -#ifndef CONFIG_PCI - -#undef CONFIG_SCSI_OMIT_FLASHPOINT -#define CONFIG_SCSI_OMIT_FLASHPOINT +#if LINUX_VERSION_CODE < 0x20100 -#define BusLogic_InitializeProbeInfoListISA BusLogic_InitializeProbeInfoList +#define MODULE_PARM(Variable, Type) #endif -/* - FlashPoint support is only available for the Intel x86 Architecture. -*/ - -#ifndef __i386__ - -#undef CONFIG_SCSI_OMIT_FLASHPOINT -#define CONFIG_SCSI_OMIT_FLASHPOINT - -#endif - - -/* - Define macros for testing the Host Adapter Type. -*/ - -#ifndef CONFIG_SCSI_OMIT_FLASHPOINT - -#define BusLogic_MultiMasterHostAdapterP(HostAdapter) \ - (HostAdapter->HostAdapterType == BusLogic_MultiMaster) - -#define BusLogic_FlashPointHostAdapterP(HostAdapter) \ - (HostAdapter->HostAdapterType == BusLogic_FlashPoint) - -#else - -#define BusLogic_MultiMasterHostAdapterP(HostAdapter) \ - (true) - -#define BusLogic_FlashPointHostAdapterP(HostAdapter) \ - (false) - -#endif - - -/* - Define Driver Message Macros. -*/ - -#define BusLogic_Announce(Format, Arguments...) \ - BusLogic_Message(BusLogic_AnnounceLevel, Format, ##Arguments) - -#define BusLogic_Info(Format, Arguments...) \ - BusLogic_Message(BusLogic_InfoLevel, Format, ##Arguments) - -#define BusLogic_Notice(Format, Arguments...) \ - BusLogic_Message(BusLogic_NoticeLevel, Format, ##Arguments) - -#define BusLogic_Warning(Format, Arguments...) \ - BusLogic_Message(BusLogic_WarningLevel, Format, ##Arguments) - -#define BusLogic_Error(Format, Arguments...) \ - BusLogic_Message(BusLogic_ErrorLevel, Format, ##Arguments) - - /* Define the version number of the FlashPoint Firmware (SCCB Manager). */ -#define FlashPoint_FirmwareVersion "5.01" +#define FlashPoint_FirmwareVersion "5.02" /* @@ -1683,35 +1771,22 @@ static inline void BusLogic_IncrementSizeBucket(BusLogic_CommandSizeBuckets_T */ #define FlashPoint_NormalInterrupt 0x00 +#define FlashPoint_InternalError 0xFE #define FlashPoint_ExternalBusReset 0xFF -/* - Define prototypes for the FlashPoint SCCB Manager Functions. -*/ - -extern unsigned char FlashPoint_ProbeHostAdapter(FlashPoint_Info_T *); -extern FlashPoint_CardHandle_T - FlashPoint_HardResetHostAdapter(FlashPoint_Info_T *); -extern void FlashPoint_StartCCB(FlashPoint_CardHandle_T, BusLogic_CCB_T *); -extern int FlashPoint_AbortCCB(FlashPoint_CardHandle_T, BusLogic_CCB_T *); -extern boolean FlashPoint_InterruptPending(FlashPoint_CardHandle_T); -extern int FlashPoint_HandleInterrupt(FlashPoint_CardHandle_T); -extern void FlashPoint_ReleaseHostAdapter(FlashPoint_CardHandle_T); - - /* Define prototypes for the forward referenced BusLogic Driver Internal Functions. */ -static void BusLogic_QueueCompletedCCB(BusLogic_CCB_T *CCB); +static void BusLogic_QueueCompletedCCB(BusLogic_CCB_T *); static void BusLogic_InterruptHandler(int, void *, Registers_T *); static int BusLogic_ResetHostAdapter(BusLogic_HostAdapter_T *, - SCSI_Command_T *, - unsigned int); -static void BusLogic_Message(BusLogic_MessageLevel_T, char *Format, + SCSI_Command_T *, unsigned int); +static void BusLogic_Message(BusLogic_MessageLevel_T, char *, BusLogic_HostAdapter_T *, ...); +static void BusLogic_ParseDriverOptions(char *); #endif /* BusLogic_DriverVersion */ diff --git a/drivers/scsi/ChangeLog.ncr53c8xx b/drivers/scsi/ChangeLog.ncr53c8xx index 3a110ce40..e6adffd9f 100644 --- a/drivers/scsi/ChangeLog.ncr53c8xx +++ b/drivers/scsi/ChangeLog.ncr53c8xx @@ -1,3 +1,30 @@ +Fri Jan 2 18:00 1998 Gerard Roudier (groudier@club-internet.fr) + * Revision 2.5f + - Use FAST-5 instead of SLOW for slow scsi devices according to + new SPI-2 draft. + - Make some changes in order to accomodate with 875 rev <= 3 + device errata listing 397. Minor consequences are: + . Leave use of PCI Write and Invalidate under user control. + Now, by default the driver does not enable PCI MWI and option + 'specf:y' is required in order to enable this feature. + . Memory Read Line is not enabled for 875 and 875-like chips. + . Programmed burst length set to 64 DWORDS (instead of 128). + (Note: SYMBIOS uses 32 DWORDS for the SDMS BIOS) + +Sun Oct 26 12:00 1997 Gerard Roudier (groudier@club-internet.fr) + * revision 2.5e + - Add 'buschk' boot option. + This option enables checking of SCSI BUS data lines after SCSI + RESET (set by default). (Submitted by Richard Waltham). + - Update the README file. + +Sat Oct 4 18:00 1997 Gerard Roudier (groudier@club-internet.fr) + * revision 2.5d + - Dispatch CONDITION MET and RESERVATION CONFLICT scsi status + as OK driver status. + - Update the README file and the Symbios NVRAM format definition + with removable media flags values (available with SDMS 4.09). + Sat Sep 20 21:00 1997 Gerard Roudier (groudier@club-internet.fr) * revision 2.5c - Several PCI configuration registers fix-ups for powerpc. diff --git a/drivers/scsi/Config.in b/drivers/scsi/Config.in index 969ef7831..96e04f796 100644 --- a/drivers/scsi/Config.in +++ b/drivers/scsi/Config.in @@ -4,7 +4,7 @@ dep_tristate 'SCSI disk support' CONFIG_BLK_DEV_SD $CONFIG_SCSI dep_tristate 'SCSI tape support' CONFIG_CHR_DEV_ST $CONFIG_SCSI dep_tristate 'SCSI CD-ROM support' CONFIG_BLK_DEV_SR $CONFIG_SCSI if [ "$CONFIG_BLK_DEV_SR" != "n" ]; then - bool ' Enable vendor-specific extentions (for SCSI CDROM)' CONFIG_BLK_DEV_SR_VENDOR + bool ' Enable vendor-specific extensions (for SCSI CDROM)' CONFIG_BLK_DEV_SR_VENDOR fi dep_tristate 'SCSI generic support' CONFIG_CHR_DEV_SG $CONFIG_SCSI @@ -13,6 +13,7 @@ comment 'Some SCSI devices (e.g. CD jukebox) support multiple LUNs' bool 'Probe all LUNs on each SCSI device' CONFIG_SCSI_MULTI_LUN bool 'Verbose SCSI error reporting (kernel size +=12K)' CONFIG_SCSI_CONSTANTS +bool 'SCSI logging facility' CONFIG_SCSI_LOGGING mainmenu_option next_comment comment 'SCSI low-level drivers' @@ -24,7 +25,7 @@ dep_tristate 'Adaptec AHA1740 support' CONFIG_SCSI_AHA1740 $CONFIG_SCSI dep_tristate 'Adaptec AIC7xxx support' CONFIG_SCSI_AIC7XXX $CONFIG_SCSI if [ "$CONFIG_SCSI_AIC7XXX" != "n" ]; then bool ' Enable tagged command queueing' CONFIG_AIC7XXX_TAGGED_QUEUEING Y - dep_tristate ' Override driver defaults for commands per LUN' CONFIG_OVERRIDE_CMDS N + bool ' Override driver defaults for commands per LUN' CONFIG_OVERRIDE_CMDS N if [ "$CONFIG_OVERRIDE_CMDS" != "n" ]; then int ' Maximum number of commands per LUN' CONFIG_AIC7XXX_CMDS_PER_LUN 8 fi @@ -83,10 +84,11 @@ if [ "$CONFIG_PCI" = "y" -a "$CONFIG_SCSI_NCR53C7xx" != "y" ]; then fi fi if [ "$CONFIG_MCA" = "y" ]; then - dep_tristate 'IBMMCA SCSI support' CONFIG_SCSI_IBMMCA $CONFIG_SCSI - if [ "$CONFIG_SCSI_IBMMCA" != "n" ]; then - bool ' reset SCSI-devices while booting' CONFIG_SCSI_IBMMCA_DEV_RESET - fi + dep_tristate 'IBMMCA SCSI support' CONFIG_SCSI_IBMMCA $CONFIG_SCSI + if [ "$CONFIG_SCSI_IBMMCA" != "n" ]; then + bool ' Standard SCSI-order' CONFIG_IBMMCA_SCSI_ORDER_STANDARD + bool ' Reset SCSI-devices at boottime' CONFIG_IBMMCA_SCSI_DEV_RESET + fi fi if [ "$CONFIG_PARPORT" != "n" ]; then dep_tristate 'IOMEGA Parallel Port ZIP drive SCSI support' CONFIG_SCSI_PPA $CONFIG_SCSI $CONFIG_PARPORT @@ -113,7 +115,17 @@ dep_tristate 'UltraStor 14F/34F support' CONFIG_SCSI_U14_34F $CONFIG_SCSI int ' maximum number of queued commands' CONFIG_SCSI_U14_34F_MAX_TAGS 8 fi dep_tristate 'UltraStor SCSI support' CONFIG_SCSI_ULTRASTOR $CONFIG_SCSI -#dep_tristate 'SCSI debugging host adapter' CONFIG_SCSI_DEBUG $CONFIG_SCSI +# +# Note - this is a very special 'host' adapter that simulates the presence of some disks. +# It can come in very handy for troubleshooting. Anyone else is welcome to use it - all +# you do is hack it to simulate the condition you want to test for, and then use it. +# +# The actual configuration in any kernel release could change at any time as I hack it to +# simulate various conditions that I am testing. +# +if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + dep_tristate 'SCSI debugging host adapter' CONFIG_SCSI_DEBUG $CONFIG_SCSI +fi if [ "$CONFIG_PPC" = "y" ]; then dep_tristate 'MESH (Power Mac internal SCSI) support' CONFIG_SCSI_MESH $CONFIG_SCSI if [ "$CONFIG_SCSI_MESH" != "n" ]; then diff --git a/drivers/scsi/FlashPoint.c b/drivers/scsi/FlashPoint.c index c4655ec25..d94631a41 100644 --- a/drivers/scsi/FlashPoint.c +++ b/drivers/scsi/FlashPoint.c @@ -19,40 +19,15 @@ #include -/* - If CONFIG_PCI is not set, force CONFIG_SCSI_OMIT_FLASHPOINT. -*/ - -#ifndef CONFIG_PCI - -#undef CONFIG_SCSI_OMIT_FLASHPOINT -#define CONFIG_SCSI_OMIT_FLASHPOINT - -#endif - - -/* - FlashPoint support is only available for the Intel x86 Architecture. -*/ - -#ifndef __i386__ - -#undef CONFIG_SCSI_OMIT_FLASHPOINT -#define CONFIG_SCSI_OMIT_FLASHPOINT - -#endif - - #ifndef CONFIG_SCSI_OMIT_FLASHPOINT #define UNIX #define FW_TYPE _SCCB_MGR_ #define MAX_CARDS 8 +#undef BUSTYPE_PCI -#include - #define OS_InPortByte(port) inb(port) #define OS_InPortWord(port) inw(port) #define OS_InPortLong(port) inl(port) @@ -68,7 +43,7 @@ */ #define SccbMgr_sense_adapter FlashPoint_ProbeHostAdapter -#define SccbMgr_config_adapter FlashPoint_HardResetHostAdapter +#define SccbMgr_config_adapter FlashPoint_HardwareResetHostAdapter #define SccbMgr_unload_card FlashPoint_ReleaseHostAdapter #define SccbMgr_start_sccb FlashPoint_StartCCB #define SccbMgr_abort_sccb FlashPoint_AbortCCB @@ -169,6 +144,7 @@ #define stwidn FPT_stwidn #define sxfrp FPT_sxfrp #define utilEERead FPT_utilEERead +#define utilEEReadOrg FPT_utilEEReadOrg #define utilEESendCmdAddr FPT_utilEESendCmdAddr #define utilEEWrite FPT_utilEEWrite #define utilEEWriteOnOff FPT_utilEEWriteOnOff @@ -1317,9 +1293,9 @@ typedef struct SCCBscam_info { * * Description: Register definitions for HARPOON ASIC. * - * $Date: 1997/01/31 02:14:28 $ + * $Date: 1997/07/09 21:44:36 $ * - * $Revision: 1.6 $ + * $Revision: 1.9 $ * *----------------------------------------------------------------------*/ @@ -2070,9 +2046,14 @@ void schkdd(USHORT port, UCHAR p_card); UCHAR RdStack(USHORT port, UCHAR index); void WrStack(USHORT portBase, UCHAR index, UCHAR data); UCHAR ChkIfChipInitialized(USHORT ioPort); + +#if defined(V302) UCHAR GetTarLun(USHORT port, UCHAR p_card, UCHAR our_target, PSCCBcard pCurrCard, PUCHAR tag, PUCHAR lun); +#endif + void SendMsg(USHORT port, UCHAR message); void queueFlushTargSccb(UCHAR p_card, UCHAR thisTarg, UCHAR error_code); +UCHAR scsellDOS(USHORT p_port, UCHAR targ_id); #else UCHAR sfm(ULONG port, PSCCB pcurrSCCB); void scsiStartAuto(ULONG port); @@ -2090,7 +2071,11 @@ void schkdd(ULONG port, UCHAR p_card); UCHAR RdStack(ULONG port, UCHAR index); void WrStack(ULONG portBase, UCHAR index, UCHAR data); UCHAR ChkIfChipInitialized(ULONG ioPort); + +#if defined(V302) UCHAR GetTarLun(ULONG port, UCHAR p_card, UCHAR our_target, PSCCBcard pCurrCard, PUCHAR tar, PUCHAR lun); +#endif + void SendMsg(ULONG port, UCHAR message); void queueFlushTargSccb(UCHAR p_card, UCHAR thisTarg, UCHAR error_code); #endif @@ -2130,6 +2115,7 @@ void Wait(USHORT p_port, UCHAR p_delay); void utilEEWriteOnOff(USHORT p_port,UCHAR p_mode); void utilEEWrite(USHORT p_port, USHORT ee_data, USHORT ee_addr); USHORT utilEERead(USHORT p_port, USHORT ee_addr); +USHORT utilEEReadOrg(USHORT p_port, USHORT ee_addr); void utilEESendCmdAddr(USHORT p_port, UCHAR ee_cmd, USHORT ee_addr); #else void Wait1Second(ULONG p_port); @@ -2137,6 +2123,7 @@ void Wait(ULONG p_port, UCHAR p_delay); void utilEEWriteOnOff(ULONG p_port,UCHAR p_mode); void utilEEWrite(ULONG p_port, USHORT ee_data, USHORT ee_addr); USHORT utilEERead(ULONG p_port, USHORT ee_addr); +USHORT utilEEReadOrg(ULONG p_port, USHORT ee_addr); void utilEESendCmdAddr(ULONG p_port, UCHAR ee_cmd, USHORT ee_addr); #endif @@ -2339,7 +2326,7 @@ void Debug_Load(UCHAR p_card, UCHAR p_bug_data); extern unsigned int SccbGlobalFlags; -#ident "$Id: sccb.c 1.17 1997/02/11 21:06:41 mohan Exp $" +#ident "$Id: sccb.c 1.18 1997/06/10 16:47:04 mohan Exp $" /*---------------------------------------------------------------------- * * @@ -2353,9 +2340,9 @@ extern unsigned int SccbGlobalFlags; * Description: Functions relating to handling of the SCCB interface * between the device driver and the HARPOON. * - * $Date: 1997/02/11 21:06:41 $ + * $Date: 1997/06/10 16:47:04 $ * - * $Revision: 1.17 $ + * $Revision: 1.18 $ * *----------------------------------------------------------------------*/ @@ -2477,6 +2464,7 @@ int SccbMgr_sense_adapter(PSCCBMGR_INFO pCardInfo) if(ChkIfChipInitialized(ioport) == FALSE) { pCurrNvRam = NULL; + WR_HARPOON(ioport+hp_semaphore, 0x00); XbowInit(ioport, 0); /*Must Init the SCSI before attempting */ DiagEEPROM(ioport); } @@ -3036,6 +3024,7 @@ STATIC s32bits probe_adapter(PADAPTER_INFO pAdapterInfo) if(ChkIfChipInitialized(ioport) == FALSE) { pCurrNvRam = NULL; + WR_HARPOON(ioport+hp_semaphore, 0x00); XbowInit(ioport, 0); /*Must Init the SCSI before attempting */ DiagEEPROM(ioport); } @@ -4802,7 +4791,23 @@ int SccbMgr_isr(ULONG pCurrCard) may not show up if another device reselects us in 1.5us or less. SRR Wednesday, 3/8/1995. */ - while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL))) ; + while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)) && + !((RDW_HARPOON((ioport+hp_intstat)) & PHASE) && + RD_HARPOON((ioport+hp_scsisig)) == + (SCSI_BSY | SCSI_REQ | SCSI_CD | SCSI_MSG | SCSI_IOBIT))) ; + + /* + The additional loop exit condition above detects a timing problem + with the revision D/E harpoon chips. The caller should reset the + host adapter to recover when 0xFE is returned. + */ + if (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL))) + { + mOS_Lock((PSCCBcard)pCurrCard); + MENABLE_INT(ioport); + mOS_UnLock((PSCCBcard)pCurrCard); + return 0xFE; + } WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC)); @@ -5347,7 +5352,7 @@ void Debug_Load(UCHAR p_card, UCHAR p_bug_data) } #endif -#ident "$Id: sccb_dat.c 1.9 1997/01/31 02:12:58 mohan Exp $" +#ident "$Id: sccb_dat.c 1.10 1997/02/22 03:16:02 awin Exp $" /*---------------------------------------------------------------------- * * @@ -5361,9 +5366,9 @@ void Debug_Load(UCHAR p_card, UCHAR p_bug_data) * Description: Functions relating to handling of the SCCB interface * between the device driver and the HARPOON. * - * $Date: 1997/01/31 02:12:58 $ + * $Date: 1997/02/22 03:16:02 $ * - * $Revision: 1.9 $ + * $Revision: 1.10 $ * *----------------------------------------------------------------------*/ @@ -5378,18 +5383,19 @@ void Debug_Load(UCHAR p_card, UCHAR p_bug_data) /*#include */ /*#include */ +/* +** IMPORTANT NOTE!!! +** +** You MUST preassign all data to a valid value or zero. This is +** required due to the MS compiler bug under OS/2 and Solaris Real-Mode +** driver environment. +*/ + -#if defined(OS2) || defined (SOLARIS_REAL_MODE) -SCCBMGR_TAR_INFO sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR] = { 0 }; -SCCBCARD BL_Card[MAX_CARDS] = { 0 }; -SCCBSCAM_INFO scamInfo[MAX_SCSI_TAR] = { 0 }; -NVRAMINFO nvRamInfo[MAX_MB_CARDS] = { 0 }; -#else -SCCBMGR_TAR_INFO sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR]; -SCCBCARD BL_Card[MAX_CARDS]; -SCCBSCAM_INFO scamInfo[MAX_SCSI_TAR]; -NVRAMINFO nvRamInfo[MAX_MB_CARDS]; -#endif +SCCBMGR_TAR_INFO sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR] = { { { 0 } } }; +SCCBCARD BL_Card[MAX_CARDS] = { { 0 } }; +SCCBSCAM_INFO scamInfo[MAX_SCSI_TAR] = { { { 0 } } }; +NVRAMINFO nvRamInfo[MAX_MB_CARDS] = { { 0 } }; #if defined(OS2) @@ -5402,23 +5408,23 @@ void (*s_PhaseTbl[8]) (); #endif #if defined(DOS) -UCHAR first_time; +UCHAR first_time = 0; #endif -UCHAR mbCards; +UCHAR mbCards = 0; UCHAR scamHAString[] = {0x63, 0x07, 'B', 'U', 'S', 'L', 'O', 'G', 'I', 'C', \ ' ', 'B', 'T', '-', '9', '3', '0', \ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, \ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20}; -USHORT default_intena; +USHORT default_intena = 0; #if defined(BUGBUG) -UCHAR debug_int[MAX_CARDS][debug_size]; -UCHAR debug_index[MAX_CARDS]; -UCHAR reserved_1[3]; +UCHAR debug_int[MAX_CARDS][debug_size] = { 0 }; +UCHAR debug_index[MAX_CARDS] = { 0 }; +UCHAR reserved_1[3] = { 0 }; #endif -#ident "$Id: scsi.c 1.19 1997/01/31 02:08:14 mohan Exp $" +#ident "$Id: scsi.c 1.23 1997/07/09 21:42:54 mohan Exp $" /*---------------------------------------------------------------------- * * @@ -5433,9 +5439,9 @@ UCHAR reserved_1[3]; * selection/reselection, sync negotiation, message-in * decoding. * - * $Date: 1997/01/31 02:08:14 $ + * $Date: 1997/07/09 21:42:54 $ * - * $Revision: 1.19 $ + * $Revision: 1.23 $ * *----------------------------------------------------------------------*/ @@ -5483,11 +5489,13 @@ UCHAR sfm(ULONG port, PSCCB pCurrSCCB) while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) && (TimeOutLoop++ < 20000) ){} + WR_HARPOON(port+hp_portctrl_0, SCSI_PORT); message = RD_HARPOON(port+hp_scsidata_0); - WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH)); + WR_HARPOON(port+hp_scsisig, SCSI_ACK + S_MSGI_PH); + if (TimeOutLoop > 20000) message = 0x00; /* force message byte = 0 if Time Out on Req */ @@ -5495,6 +5503,10 @@ UCHAR sfm(ULONG port, PSCCB pCurrSCCB) if ((RDW_HARPOON((port+hp_intstat)) & PARITY) && (RD_HARPOON(port+hp_addstat) & SCSI_PAR_ERR)) { + WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH)); + WR_HARPOON(port+hp_xferstat, 0); + WR_HARPOON(port+hp_fiforead, 0); + WR_HARPOON(port+hp_fifowrite, 0); if (pCurrSCCB != NULL) { pCurrSCCB->Sccb_scsimsg = SMPARITY; @@ -5503,6 +5515,7 @@ UCHAR sfm(ULONG port, PSCCB pCurrSCCB) do { ACCEPT_MSG_ATN(port); + TimeOutLoop = 0; while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) && (TimeOutLoop++ < 20000) ){} if (TimeOutLoop > 20000) @@ -5524,6 +5537,10 @@ UCHAR sfm(ULONG port, PSCCB pCurrSCCB) }while(1); } + WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH)); + WR_HARPOON(port+hp_xferstat, 0); + WR_HARPOON(port+hp_fiforead, 0); + WR_HARPOON(port+hp_fifowrite, 0); return(message); } @@ -5894,12 +5911,20 @@ void sres(USHORT port, UCHAR p_card, PSCCBcard pCurrCard) void sres(ULONG port, UCHAR p_card, PSCCBcard pCurrCard) #endif { + +#if defined(V302) #ifdef DOS UCHAR our_target,message, msgRetryCount; extern UCHAR lun, tag; #else UCHAR our_target,message,lun,tag, msgRetryCount; #endif + +#else /* V302 */ + UCHAR our_target, message, lun = 0, tag, msgRetryCount; +#endif /* V302 */ + + PSCCBMgr_tar_info currTar_Info; PSCCB currSCCB; @@ -5972,7 +5997,103 @@ void sres(ULONG port, UCHAR p_card, PSCCBcard pCurrCard) msgRetryCount = 0; do { + +#if defined(V302) + message = GetTarLun(port, p_card, our_target, pCurrCard, &tag, &lun); + +#else /* V302 */ + + currTar_Info = &sccbMgrTbl[p_card][our_target]; + tag = 0; + + + while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) + { + if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) + { + + WRW_HARPOON((port+hp_intstat), PHASE); + return; + } + } + + WRW_HARPOON((port+hp_intstat), PHASE); + if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGI_PH) + { + + message = sfm(port,pCurrCard->currentSCCB); + if (message) + { + + if (message <= (0x80 | LUN_MASK)) + { + lun = message & (UCHAR)LUN_MASK; + +#if !defined(DOS) + if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING) + { + if (currTar_Info->TarTagQ_Cnt != 0) + { + + if (!(currTar_Info->TarLUN_CA)) + { + ACCEPT_MSG(port); /*Release the ACK for ID msg. */ + + + message = sfm(port,pCurrCard->currentSCCB); + if (message) + { + ACCEPT_MSG(port); + } + + else + message = FALSE; + + if(message != FALSE) + { + tag = sfm(port,pCurrCard->currentSCCB); + + if (!(tag)) + message = FALSE; + } + + } /*C.A. exists! */ + + } /*End Q cnt != 0 */ + + } /*End Tag cmds supported! */ +#endif /* !DOS */ + + } /*End valid ID message. */ + + else + { + + ACCEPT_MSG_ATN(port); + } + + } /* End good id message. */ + + else + { + + message = FALSE; + } + } + else + { + ACCEPT_MSG_ATN(port); + + while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) && + !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) && + (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ; + + return; + } + +#endif /* V302 */ + if(message == FALSE) { msgRetryCount++; @@ -6071,6 +6192,8 @@ void sres(ULONG port, UCHAR p_card, PSCCBcard pCurrCard) (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ; } +#if defined(V302) + #if defined(DOS) UCHAR GetTarLun(USHORT port, UCHAR p_card, UCHAR our_target, PSCCBcard pCurrCard, PUCHAR tag, PUCHAR lun) #else @@ -6162,6 +6285,7 @@ UCHAR GetTarLun(ULONG port, UCHAR p_card, UCHAR our_target, PSCCBcard pCurrCard, return(TRUE); } +#endif /* V302 */ #if defined(DOS) void SendMsg(USHORT port, UCHAR message) @@ -6469,6 +6593,10 @@ void shandem(ULONG port, UCHAR p_card, PSCCB pCurrSCCB) ACCEPT_MSG(port); WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START)); } + }else + { + if(pCurrSCCB->Sccb_scsimsg == SMPARITY) + WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START)); } } @@ -7386,6 +7514,7 @@ void sinits(PSCCB p_sccb, UCHAR p_card) p_sccb->Sccb_scsistat = BUS_FREE_ST; p_sccb->SccbStatus = SCCB_IN_PROCESS; p_sccb->Sccb_scsimsg = SMNO_OP; + } @@ -9222,7 +9351,7 @@ void hostDataXferRestart(PSCCB currSCCB) currSCCB->Sccb_XferCnt = currSCCB->DataLength - currSCCB->Sccb_ATC; } } -#ident "$Id: scam.c 1.16 1997/01/31 02:11:12 mohan Exp $" +#ident "$Id: scam.c 1.17 1997/03/20 23:49:37 mohan Exp $" /*---------------------------------------------------------------------- * * @@ -9237,9 +9366,9 @@ void hostDataXferRestart(PSCCB currSCCB) * and the determination of the SCSI IDs to be assigned * to all perspective SCSI targets. * - * $Date: 1997/01/31 02:11:12 $ + * $Date: 1997/03/20 23:49:37 $ * - * $Revision: 1.16 $ + * $Revision: 1.17 $ * *----------------------------------------------------------------------*/ @@ -9468,7 +9597,7 @@ void scini(UCHAR p_card, UCHAR p_our_id, UCHAR p_power_up) if (((ScamFlg & SCAM_ENABLED) && (scamInfo[i].state == LEGACY)) || (i != p_our_id)) { - scsell(p_port,i); + scsellDOS(p_port,i); } } #endif @@ -9885,6 +10014,7 @@ UCHAR sciso(ULONG p_port, UCHAR p_id_string[]) } if ((ret_data & 0x1F) == 0) + { /* if(bit_cnt != 0 || bit_cnt != 8) { @@ -9899,6 +10029,7 @@ UCHAR sciso(ULONG p_port, UCHAR p_id_string[]) return(0x00); else return(0xFF); + } } /*bit loop */ @@ -10090,6 +10221,90 @@ UCHAR scsell(ULONG p_port, UCHAR targ_id) } } +#if defined(DOS) +/*--------------------------------------------------------------------- + * + * Function: scsell for DOS + * + * Description: Select the specified device ID using a selection timeout + * less than 2ms. This was specially required to solve + * the problem with Plextor 12X CD-ROM drive. This drive + * was responding the Selection at the end of 4ms and + * hanging the system. + * + *---------------------------------------------------------------------*/ + +UCHAR scsellDOS(USHORT p_port, UCHAR targ_id) +{ + USHORT i; + + WR_HARPOON(p_port+hp_page_ctrl, + (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE)); + + ARAM_ACCESS(p_port); + + WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) | SCAM_TIMER)); + WR_HARPOON(p_port+hp_seltimeout,TO_2ms); + + + for (i = p_port+CMD_STRT; i < p_port+CMD_STRT+12; i+=2) { + WRW_HARPOON(i, (MPM_OP+ACOMMAND)); + } + WRW_HARPOON(i, (BRH_OP+ALWAYS+ NP)); + + WRW_HARPOON((p_port+hp_intstat), + (RESET | TIMEOUT | SEL | BUS_FREE | AUTO_INT)); + + WR_HARPOON(p_port+hp_select_id, targ_id); + + WR_HARPOON(p_port+hp_portctrl_0, SCSI_PORT); + WR_HARPOON(p_port+hp_autostart_3, (SELECT | CMD_ONLY_STRT)); + WR_HARPOON(p_port+hp_scsictrl_0, (SEL_TAR | ENA_RESEL)); + + + while (!(RDW_HARPOON((p_port+hp_intstat)) & + (RESET | PROG_HLT | TIMEOUT | AUTO_INT))) {} + + if (RDW_HARPOON((p_port+hp_intstat)) & RESET) + Wait(p_port, TO_250ms); + + DISABLE_AUTO(p_port); + + WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) & ~SCAM_TIMER)); + WR_HARPOON(p_port+hp_seltimeout,TO_290ms); + + SGRAM_ACCESS(p_port); + + if (RDW_HARPOON((p_port+hp_intstat)) & (RESET | TIMEOUT) ) { + + WRW_HARPOON((p_port+hp_intstat), + (RESET | TIMEOUT | SEL | BUS_FREE | PHASE)); + + WR_HARPOON(p_port+hp_page_ctrl, + (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE)); + + return(FALSE); /*No legacy device */ + } + + else { + + while(!(RDW_HARPOON((p_port+hp_intstat)) & BUS_FREE)) { + if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ) + { + WR_HARPOON(p_port+hp_scsisig, (SCSI_ACK + S_ILL_PH)); + ACCEPT_MSG(p_port); + } + } + + WRW_HARPOON((p_port+hp_intstat), CLR_ALL_INT_1); + + WR_HARPOON(p_port+hp_page_ctrl, + (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE)); + + return(TRUE); /*Found one of them oldies! */ + } +} +#endif /* DOS */ /*--------------------------------------------------------------------- * @@ -10252,10 +10467,12 @@ UCHAR scmachid(UCHAR p_card, UCHAR p_id_string[]) match--; if (match == 0xFF) + { if (p_id_string[0] & BIT(5)) match = 7; else match = MAX_SCSI_TAR-1; + } } @@ -10300,10 +10517,12 @@ UCHAR scmachid(UCHAR p_card, UCHAR p_id_string[]) match--; if (match == 0xFF) + { if (p_id_string[0] & BIT(5)) match = 7; else match = MAX_SCSI_TAR-1; + } } return(NO_ID_AVAIL); @@ -10362,7 +10581,7 @@ void scsavdi(UCHAR p_card, ULONG p_port) utilEEWrite(p_port, sum_data, EEPROM_CHECK_SUM/2); utilEEWriteOnOff(p_port,0); /* Turn off write access */ } -#ident "$Id: diagnose.c 1.9 1997/01/31 02:09:48 mohan Exp $" +#ident "$Id: diagnose.c 1.10 1997/06/10 16:51:47 mohan Exp $" /*---------------------------------------------------------------------- * * @@ -10376,9 +10595,9 @@ void scsavdi(UCHAR p_card, ULONG p_port) * Description: Diagnostic funtions for testing the integrity of * the HARPOON. * - * $Date: 1997/01/31 02:09:48 $ + * $Date: 1997/06/10 16:51:47 $ * - * $Revision: 1.9 $ + * $Revision: 1.10 $ * *----------------------------------------------------------------------*/ @@ -10419,7 +10638,7 @@ UCHAR i; WR_HARPOON(port+hp_scsireset,(DMA_RESET | HPSCSI_RESET | PROG_RESET | \ FIFO_CLR)); - WR_HARPOON(port+hp_scsireset,0x00); + WR_HARPOON(port+hp_scsireset,SCSI_INI); WR_HARPOON(port+hp_clkctrl_0,CLKCTRL_DEFAULT); @@ -10703,8 +10922,8 @@ void DiagEEPROM(ULONG p_port) temp += 0x70D3; utilEEWrite(p_port, 0x0010, BIOS_CONFIG/2); temp += 0x0010; - utilEEWrite(p_port, 0x0007, SCAM_CONFIG/2); - temp += 0x0007; + utilEEWrite(p_port, 0x0003, SCAM_CONFIG/2); + temp += 0x0003; utilEEWrite(p_port, 0x0007, ADAPTER_SCSI_ID/2); temp += 0x0007; @@ -10807,7 +11026,7 @@ void DiagEEPROM(ULONG p_port) } -#ident "$Id: utility.c 1.22 1997/01/31 02:12:23 mohan Exp $" +#ident "$Id: utility.c 1.23 1997/06/10 16:55:06 mohan Exp $" /*---------------------------------------------------------------------- * * @@ -10821,9 +11040,9 @@ void DiagEEPROM(ULONG p_port) * Description: Utility functions relating to queueing and EEPROM * manipulation and any other garbage functions. * - * $Date: 1997/01/31 02:12:23 $ + * $Date: 1997/06/10 16:55:06 $ * - * $Revision: 1.22 $ + * $Revision: 1.23 $ * *----------------------------------------------------------------------*/ /*#include */ @@ -11616,11 +11835,14 @@ void utilEEWrite(ULONG p_port, USHORT ee_data, USHORT ee_addr) else ee_value &= ~SEE_DO; + WR_HARPOON(p_port+hp_ee_ctrl, ee_value); WR_HARPOON(p_port+hp_ee_ctrl, ee_value); ee_value |= SEE_CLK; /* Clock data! */ WR_HARPOON(p_port+hp_ee_ctrl, ee_value); + WR_HARPOON(p_port+hp_ee_ctrl, ee_value); ee_value &= ~SEE_CLK; WR_HARPOON(p_port+hp_ee_ctrl, ee_value); + WR_HARPOON(p_port+hp_ee_ctrl, ee_value); } ee_value &= (EXT_ARB_ACK | SCSI_TERM_ENA_H); WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); @@ -11632,7 +11854,6 @@ void utilEEWrite(ULONG p_port, USHORT ee_data, USHORT ee_addr) WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /* Turn off Master Select */ } - /*--------------------------------------------------------------------- * * Function: Read EEPROM @@ -11647,6 +11868,40 @@ USHORT utilEERead(USHORT p_port, USHORT ee_addr) #else USHORT utilEERead(ULONG p_port, USHORT ee_addr) #endif +{ + USHORT i, ee_data1, ee_data2; + + i = 0; + ee_data1 = utilEEReadOrg(p_port, ee_addr); + do + { + ee_data2 = utilEEReadOrg(p_port, ee_addr); + + if(ee_data1 == ee_data2) + return(ee_data1); + + ee_data1 = ee_data2; + i++; + + }while(i < 4); + + return(ee_data1); +} + +/*--------------------------------------------------------------------- + * + * Function: Read EEPROM Original + * + * Description: Read a word from the EEPROM at the desired + * address. + * + *---------------------------------------------------------------------*/ + +#if defined(DOS) +USHORT utilEEReadOrg(USHORT p_port, USHORT ee_addr) +#else +USHORT utilEEReadOrg(ULONG p_port, USHORT ee_addr) +#endif { UCHAR ee_value; @@ -11666,8 +11921,10 @@ USHORT utilEERead(ULONG p_port, USHORT ee_addr) ee_value |= SEE_CLK; /* Clock data! */ WR_HARPOON(p_port+hp_ee_ctrl, ee_value); + WR_HARPOON(p_port+hp_ee_ctrl, ee_value); ee_value &= ~SEE_CLK; WR_HARPOON(p_port+hp_ee_ctrl, ee_value); + WR_HARPOON(p_port+hp_ee_ctrl, ee_value); ee_data <<= 1; @@ -11721,11 +11978,14 @@ void utilEESendCmdAddr(ULONG p_port, UCHAR ee_cmd, USHORT ee_addr) else ee_value &= ~SEE_DO; + WR_HARPOON(p_port+hp_ee_ctrl, ee_value); WR_HARPOON(p_port+hp_ee_ctrl, ee_value); ee_value |= SEE_CLK; /* Clock data! */ WR_HARPOON(p_port+hp_ee_ctrl, ee_value); + WR_HARPOON(p_port+hp_ee_ctrl, ee_value); ee_value &= ~SEE_CLK; WR_HARPOON(p_port+hp_ee_ctrl, ee_value); + WR_HARPOON(p_port+hp_ee_ctrl, ee_value); } @@ -11743,11 +12003,14 @@ void utilEESendCmdAddr(ULONG p_port, UCHAR ee_cmd, USHORT ee_addr) else ee_value &= ~SEE_DO; + WR_HARPOON(p_port+hp_ee_ctrl, ee_value); WR_HARPOON(p_port+hp_ee_ctrl, ee_value); ee_value |= SEE_CLK; /* Clock data! */ WR_HARPOON(p_port+hp_ee_ctrl, ee_value); + WR_HARPOON(p_port+hp_ee_ctrl, ee_value); ee_value &= ~SEE_CLK; WR_HARPOON(p_port+hp_ee_ctrl, ee_value); + WR_HARPOON(p_port+hp_ee_ctrl, ee_value); i >>= 1; } @@ -11785,4 +12048,112 @@ UCHAR CalcLrc(UCHAR buffer[]) +/* + The following inline definitions avoid type conflicts. +*/ + +static inline unsigned char +FlashPoint__ProbeHostAdapter(FlashPoint_Info_T *FlashPointInfo) +{ + return FlashPoint_ProbeHostAdapter((PSCCBMGR_INFO) FlashPointInfo); +} + + +static inline FlashPoint_CardHandle_T +FlashPoint__HardwareResetHostAdapter(FlashPoint_Info_T *FlashPointInfo) +{ + return FlashPoint_HardwareResetHostAdapter((PSCCBMGR_INFO) FlashPointInfo); +} + +static inline void +FlashPoint__ReleaseHostAdapter(FlashPoint_CardHandle_T CardHandle) +{ + FlashPoint_ReleaseHostAdapter(CardHandle); +} + + +static inline void +FlashPoint__StartCCB(FlashPoint_CardHandle_T CardHandle, BusLogic_CCB_T *CCB) +{ + FlashPoint_StartCCB(CardHandle, (PSCCB) CCB); +} + + +static inline void +FlashPoint__AbortCCB(FlashPoint_CardHandle_T CardHandle, BusLogic_CCB_T *CCB) +{ + FlashPoint_AbortCCB(CardHandle, (PSCCB) CCB); +} + + +static inline boolean +FlashPoint__InterruptPending(FlashPoint_CardHandle_T CardHandle) +{ + return FlashPoint_InterruptPending(CardHandle); +} + + +static inline int +FlashPoint__HandleInterrupt(FlashPoint_CardHandle_T CardHandle) +{ + return FlashPoint_HandleInterrupt(CardHandle); +} + + +#define FlashPoint_ProbeHostAdapter FlashPoint__ProbeHostAdapter +#define FlashPoint_HardwareResetHostAdapter FlashPoint__HardwareResetHostAdapter +#define FlashPoint_ReleaseHostAdapter FlashPoint__ReleaseHostAdapter +#define FlashPoint_StartCCB FlashPoint__StartCCB +#define FlashPoint_AbortCCB FlashPoint__AbortCCB +#define FlashPoint_InterruptPending FlashPoint__InterruptPending +#define FlashPoint_HandleInterrupt FlashPoint__HandleInterrupt + + +/* + FlashPoint_InquireTargetInfo returns the Synchronous Period, Synchronous + Offset, and Wide Transfers Active information for TargetID on CardHandle. +*/ + +void FlashPoint_InquireTargetInfo(FlashPoint_CardHandle_T CardHandle, + int TargetID, + unsigned char *SynchronousPeriod, + unsigned char *SynchronousOffset, + unsigned char *WideTransfersActive) +{ + SCCBMGR_TAR_INFO *TargetInfo = + &sccbMgrTbl[((SCCBCARD *)CardHandle)->cardIndex][TargetID]; + if ((TargetInfo->TarSyncCtrl & SYNC_OFFSET) > 0) + { + *SynchronousPeriod = 5 * ((TargetInfo->TarSyncCtrl >> 5) + 1); + *SynchronousOffset = TargetInfo->TarSyncCtrl & SYNC_OFFSET; + } + else + { + *SynchronousPeriod = 0; + *SynchronousOffset = 0; + } + *WideTransfersActive = (TargetInfo->TarSyncCtrl & NARROW_SCSI ? 0 : 1); +} + + +#else /* CONFIG_SCSI_OMIT_FLASHPOINT */ + + +/* + Define prototypes for the FlashPoint SCCB Manager Functions. +*/ + +extern unsigned char FlashPoint_ProbeHostAdapter(FlashPoint_Info_T *); +extern FlashPoint_CardHandle_T + FlashPoint_HardwareResetHostAdapter(FlashPoint_Info_T *); +extern void FlashPoint_StartCCB(FlashPoint_CardHandle_T, BusLogic_CCB_T *); +extern int FlashPoint_AbortCCB(FlashPoint_CardHandle_T, BusLogic_CCB_T *); +extern boolean FlashPoint_InterruptPending(FlashPoint_CardHandle_T); +extern int FlashPoint_HandleInterrupt(FlashPoint_CardHandle_T); +extern void FlashPoint_ReleaseHostAdapter(FlashPoint_CardHandle_T); +extern void FlashPoint_InquireTargetInfo(FlashPoint_CardHandle_T, + int, unsigned char *, + unsigned char *, unsigned char *); + + #endif /* CONFIG_SCSI_OMIT_FLASHPOINT */ diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile index e79d4ee24..28ef6bbad 100644 --- a/drivers/scsi/Makefile +++ b/drivers/scsi/Makefile @@ -1,4 +1,3 @@ - # Makefile for linux/drivers/scsi # # Note! Dependencies are done automagically by 'make dep', which also @@ -14,8 +13,9 @@ MIX_OBJS := MOD_LIST_NAME := SCSI_MODULES SCSI_SRCS = $(wildcard $(L_OBJS:%.o=%.c)) -AHA152X = -DDEBUG_AHA152X -DAUTOCONF -GDTH = #-DDEBUG_GDTH=2 -D__SERIAL__ -D__COM2__ -DGDTH_STATISTICS +CFLAGS_aha152x.o = -DDEBUG_AHA152X -DAUTOCONF +CFLAGS_gdth.o = # -DDEBUG_GDTH=2 -D__SERIAL__ -D__COM2__ -DGDTH_STATISTICS +CFLAGS_seagate.o = -DARBITRATE -DSLOW_HANDSHAKE -DFAST32 -DPARITY .SUFFIXES: .SUFFIXES: .c .o .h .a @@ -34,14 +34,13 @@ endif ifeq ($(CONFIG_SCSI),y) # We must attach scsi_syms.o to scsi.o, as otherwise there is nothing to # pull the object file from the archive. - SCSI=scsi.o + O_TARGET := scsi_n_syms.o + O_OBJS := scsi.o ifeq ($(CONFIG_MODULES),y) - O_TARGET := scsi_n_syms.o - O_OBJS := scsi.o OX_OBJS := scsi_syms.o - SCSI := $(O_TARGET) endif - L_OBJS += $(SCSI) hosts.o scsi_ioctl.o constants.o scsicam.o + L_OBJS += scsi_n_syms.o hosts.o scsi_ioctl.o constants.o scsicam.o + L_OBJS += scsi_error.o scsi_obsolete.o scsi_queue.o ifeq ($(CONFIG_PROC_FS),y) L_OBJS += scsi_proc.o endif @@ -439,6 +438,14 @@ else endif endif +ifeq ($(CONFIG_SCSI_PLUTO),y) +L_OBJS += pluto.o +else + ifeq ($(CONFIG_SCSI_PLUTO),m) + M_OBJS += pluto.o + endif +endif + ifeq ($(CONFIG_SCSI_EATA),y) L_OBJS += eata.o else @@ -469,24 +476,6 @@ endif include $(TOPDIR)/Rules.make -BusLogic.o: BusLogic.c FlashPoint.c - $(CC) $(CFLAGS) -c BusLogic.c -o BusLogic.O - $(CC) $(CFLAGS) -c FlashPoint.c -o FlashPoint.O - $(LD) -r -o BusLogic.o BusLogic.O FlashPoint.O - rm -f BusLogic.O FlashPoint.O - -aha152x.o: aha152x.c - $(CC) $(CFLAGS) $(AHA152X) -c aha152x.c - -gdth.o: gdth.c gdth.h gdth_proc.c gdth_proc.h - $(CC) $(CFLAGS) $(GDTH) -c gdth.c - -aic7xxx.o: aic7xxx.c aic7xxx_seq.h aic7xxx_reg.h - $(CC) $(CFLAGS) -c -o $@ aic7xxx.c - -seagate.o: seagate.c - $(CC) $(CFLAGS) -DARBITRATE -DSLOW_HANDSHAKE -DFAST32 -DPARITY -c seagate.c - 53c8xx_d.h 53c8xx_u.h : 53c7,8xx.scr script_asm.pl ln -sf 53c7,8xx.scr fake.c $(CPP) -traditional -DCHIP=810 fake.c | grep -v '^#' | perl script_asm.pl @@ -502,8 +491,10 @@ seagate.o: seagate.c rm fake.c scsi_mod.o: $(MIX_OBJS) hosts.o scsi.o scsi_ioctl.o constants.o \ - scsicam.o scsi_proc.o - $(LD) $(LD_RFLAG) -r -o $@ $(MIX_OBJS) hosts.o scsi.o scsi_ioctl.o constants.o scsicam.o scsi_proc.o + scsicam.o scsi_proc.o scsi_error.o scsi_obsolete.o scsi_queue.o + $(LD) $(LD_RFLAG) -r -o $@ $(MIX_OBJS) hosts.o scsi.o scsi_ioctl.o \ + constants.o scsicam.o scsi_proc.o \ + scsi_error.o scsi_obsolete.o scsi_queue.o \ sr_mod.o: sr.o sr_ioctl.o sr_vendor.o $(LD) $(LD_RFLAG) -r -o $@ sr.o sr_ioctl.o sr_vendor.o diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c index 6ecc0f1aa..ba1753147 100644 --- a/drivers/scsi/NCR5380.c +++ b/drivers/scsi/NCR5380.c @@ -625,7 +625,8 @@ static inline void NCR5380_all_init (void) { */ -static int probe_irq __initdata; +static int probe_irq __initdata = 0; + __initfunc(static void probe_intr (int irq, void *dev_id, struct pt_regs * regs)) { probe_irq = irq; }; diff --git a/drivers/scsi/NCR53c406a.c b/drivers/scsi/NCR53c406a.c index e29af7ad8..d2529b17e 100644 --- a/drivers/scsi/NCR53c406a.c +++ b/drivers/scsi/NCR53c406a.c @@ -1012,7 +1012,7 @@ static void chip_init() outb(SYNC_MODE, SYNCOFF); /* synchronous mode */ } -__initfunc(void calc_port_addr()) +__initfunc(void calc_port_addr(void)) { /* Control Register Set 0 */ TC_LSB = (port_base+0x00); diff --git a/drivers/scsi/NCR53c406a.h b/drivers/scsi/NCR53c406a.h index 88e45e5e6..4ec3abbd5 100644 --- a/drivers/scsi/NCR53c406a.h +++ b/drivers/scsi/NCR53c406a.h @@ -26,27 +26,21 @@ * Use SG_NONE if DMA mode is enabled! */ #define NCR53c406a { \ - NULL /* next */, \ - NULL /* usage count */, \ - &proc_scsi_NCR53c406a /* proc_dir */, \ - NULL /* proc_info */, \ - "NCR53c406a" /* name */, \ - NCR53c406a_detect /* detect */, \ - NULL /* release */, \ - NCR53c406a_info /* info */, \ - NCR53c406a_command /* command */, \ - NCR53c406a_queue /* queuecommand */, \ - NCR53c406a_abort /* abort */, \ - NCR53c406a_reset /* reset */, \ - NULL /* slave_attach */, \ - NCR53c406a_biosparm /* biosparm */, \ - 1 /* can_queue */, \ - 7 /* SCSI ID of the chip */, \ - 32 /*SG_ALL*/ /*SG_NONE*/, \ - 1 /* commands per lun */, \ - 0 /* number of boards in system */, \ - 1 /* unchecked_isa_dma */, \ - ENABLE_CLUSTERING \ + proc_dir: &proc_scsi_NCR53c406a /* proc_dir */, \ + name: "NCR53c406a" /* name */, \ + detect: NCR53c406a_detect /* detect */, \ + info: NCR53c406a_info /* info */, \ + command: NCR53c406a_command /* command */, \ + queuecommand: NCR53c406a_queue /* queuecommand */, \ + abort: NCR53c406a_abort /* abort */, \ + reset: NCR53c406a_reset /* reset */, \ + bios_param: NCR53c406a_biosparm /* biosparm */, \ + can_queue: 1 /* can_queue */, \ + this_id: 7 /* SCSI ID of the chip */, \ + sg_tablesize: 32 /*SG_ALL*/ /*SG_NONE*/, \ + cmd_per_lun: 1 /* commands per lun */, \ + unchecked_isa_dma: 1 /* unchecked_isa_dma */, \ + use_clustering: ENABLE_CLUSTERING \ } extern struct proc_dir_entry proc_scsi_NCR53c406a; diff --git a/drivers/scsi/README.BusLogic b/drivers/scsi/README.BusLogic index a9962dbbc..60fa4011c 100644 --- a/drivers/scsi/README.BusLogic +++ b/drivers/scsi/README.BusLogic @@ -1,10 +1,10 @@ BusLogic MultiMaster and FlashPoint SCSI Driver for Linux - Version 2.0.10 for Linux 2.0 + Version 2.0.11 for Linux 2.0 PRODUCTION RELEASE - 11 August 1997 + 31 January 1998 Leonard N. Zubkoff Dandelion Digital @@ -15,27 +15,34 @@ INTRODUCTION -BusLogic, Inc. designs and manufactures a variety of high performance SCSI host -adapters which share a common programming interface across a diverse collection -of bus architectures by virtue of their MultiMaster ASIC technology. This -driver supports all present BusLogic MultiMaster Host Adapters, and should +BusLogic, Inc. designed and manufactured a variety of high performance SCSI +host adapters which share a common programming interface across a diverse +collection of bus architectures by virtue of their MultiMaster ASIC technology. +BusLogic was acquired by Mylex Corporation in February 1996, but the products +supported by this driver originated under the BusLogic name and so that name is +retained in the source code and documentation. + +This driver supports all present BusLogic MultiMaster Host Adapters, and should support any future MultiMaster designs with little or no modification. More -recently, BusLogic has introduced the FlashPoint Host Adapters, which are less +recently, BusLogic introduced the FlashPoint Host Adapters, which are less costly and rely on the host CPU, rather than including an onboard processor. -Mylex/BusLogic has recently provided me with the FlashPoint Driver Developer's -Kit, which comprises documentation and freely redistributable source code for -the FlashPoint SCCB Manager. The SCCB Manager is the library of code that runs -on the host CPU and performs functions analogous to the firmware on the -MultiMaster Host Adapters. Thanks to their having provided the SCCB Manager, -this driver now supports the FlashPoint Host Adapters as well. +Despite not having an onboard CPU, the FlashPoint Host Adapters perform very +well and have very low command latency. BusLogic has recently provided me with +the FlashPoint Driver Developer's Kit, which comprises documentation and freely +redistributable source code for the FlashPoint SCCB Manager. The SCCB Manager +is the library of code that runs on the host CPU and performs functions +analogous to the firmware on the MultiMaster Host Adapters. Thanks to their +having provided the SCCB Manager, this driver now supports the FlashPoint Host +Adapters as well. My primary goals in writing this completely new BusLogic driver for Linux are to achieve the full performance that BusLogic SCSI Host Adapters and modern SCSI peripherals are capable of, and to provide a highly robust driver that can be depended upon for high performance mission critical applications. All of the major performance and error recovery features can be configured from the -Linux kernel command line, allowing individual installations to tune driver -performance and error recovery to their particular needs. +Linux kernel command line or at module initialization time, allowing individual +installations to tune driver performance and error recovery to their particular +needs. The latest information on Linux support for BusLogic SCSI Host Adapters, as well as the most recent release of this driver and the latest firmware for the @@ -48,33 +55,35 @@ driver and SCSI subsystem at startup, along with any subsequent system messages relevant to SCSI operations, and a detailed description of your system's hardware configuration. -BusLogic has been an excellent company to work with and I highly recommend -their products to the Linux community. In November 1995, I was offered the +Mylex has been an excellent company to work with and I highly recommend their +products to the Linux community. In November 1995, I was offered the opportunity to become a beta test site for their latest MultiMaster product, the BT-948 PCI Ultra SCSI Host Adapter, and then again for the BT-958 PCI Wide Ultra SCSI Host Adapter in January 1996. This was mutually beneficial since -BusLogic received a degree and kind of testing that their own testing group -cannot readily achieve, and the Linux community has available high performance -host adapters that have been well tested with Linux even before being brought -to market. This relationship has also given me the opportunity to interact +Mylex received a degree and kind of testing that their own testing group cannot +readily achieve, and the Linux community has available high performance host +adapters that have been well tested with Linux even before being brought to +market. This relationship has also given me the opportunity to interact directly with their technical staff, to understand more about the internal workings of their products, and in turn to educate them about the needs and -potential of the Linux community. Their interest and support is greatly -appreciated. +potential of the Linux community. + +More recently, Mylex has reaffirmed the company's interest in supporting the +Linux community, and I am now working on a Linux driver for the DAC960 PCI RAID +Controllers. Mylex's interest and support is greatly appreciated. -Unlike some other vendors, if you contact BusLogic Technical Support with a +Unlike some other vendors, if you contact Mylex Technical Support with a problem and are running Linux, they will not tell you that your use of their products is unsupported. Their latest product marketing literature even states -"BusLogic SCSI host adapters are compatible with all major operating systems +"Mylex SCSI host adapters are compatible with all major operating systems including: ... Linux ...". -BusLogic, Inc. is located at 4151 Burton Drive, Santa Clara, California, 95054, -USA and can be reached by Voice at 408/492-9090 or by FAX at 408/492-1542. -BusLogic maintains a World Wide Web site at http://www.buslogic.com, an -anonymous FTP site at ftp.buslogic.com, and a BBS at 408/492-1984. BusLogic -Technical Support can be reached by electronic mail at techsup@buslogic.com, by -Voice at 408/654-0760, or by FAX at 408/492-1542. Contact information for -offices in Europe and Japan is available on the Web site. +Mylex Corporation is located at 34551 Ardenwood Blvd., Fremont, California +94555, USA and can be reached at 510/796-6100 or on the World Wide Web at +http://www.mylex.com. Mylex Technical Support can be reached by electronic +mail at techsup@mylex.com, by Voice at 510/608-2400, or by FAX at 510/745-7715. +Contact information for offices in Europe and Japan is available on the Web +site. DRIVER FEATURES @@ -83,15 +92,46 @@ o Configuration Reporting and Testing During system initialization, the driver reports extensively on the host adapter hardware configuration, including the synchronous transfer parameters - negotiated with each target device. In addition, the driver tests the - hardware interrupt configuration to verify that interrupts are actually - delivered correctly to the interrupt handler. This should catch a high - percentage of PCI motherboard configuration errors early, because when the - host adapter is probed successfully, most of the remaining problems appear to - be related to interrupts. Most often, any remaining hardware problems are - related to the specific configuration of devices on the SCSI bus, and the - quality of cabling and termination used. Finally, this BusLogic driver - should never incorrectly attempt to support an Adaptec 154x Host Adapter. + requested and negotiated with each target device. AutoSCSI settings for + Synchronous Negotiation, Wide Negotiation, and Disconnect/Reconnect are + reported for each target device, as well as the status of Tagged Queuing and + Error Recovery. If the same setting is in effect for all target devices, + then a single word or phrase is used; otherwise, a letter is provided for + each target device to indicate the individual status. The following examples + should clarify this reporting format: + + Synchronous Negotiation: Ultra + + Synchronous negotiation is enabled for all target devices and the host + adapter will attempt to negotiate for 20.0 mega-transfers/second. + + Synchronous Negotiation: Fast + + Synchronous negotiation is enabled for all target devices and the host + adapter will attempt to negotiate for 10.0 mega-transfers/second. + + Synchronous Negotiation: Slow + + Synchronous negotiation is enabled for all target devices and the host + adapter will attempt to negotiate for 5.0 mega-transfers/second. + + Synchronous Negotiation: Disabled + + Synchronous negotiation is disabled and all target devices are limited to + asynchronous operation. + + Synchronous Negotiation: UFSNUUU#UUUUUUUU + + Synchronous negotiation to Ultra speed is enabled for target devices 0 + and 4 through 15, to Fast speed for target device 1, to Slow speed for + target device 2, and is not permitted to target device 3. The host + adapter's SCSI ID is represented by the "#". + + The status of Wide Negotiation, Disconnect/Reconnect, and Tagged Queuing + are reported as "Enabled", Disabled", or a sequence of "Y" and "N" letters. + + The Error Recovery option is reported as "Default", "Hard Reset", + "Bus Device Reset", "None" or a sequence of "D", "H", "B", and "N" letters. o Performance Features @@ -103,16 +143,15 @@ o Performance Features addition, BusLogic's Strict Round Robin Mode is used to optimize host adapter performance, and scatter/gather I/O can support as many segments as can be effectively utilized by the Linux I/O subsystem. Control over the use of - tagged queuing for each target device as well as selection of the tagged - queue depth is available from the kernel command line. By default, the queue - depth is automatically determined based on the number, type, speed, and - capabilities of the target devices found. In addition, tagged queuing is - automatically disabled whenever the host adapter firmware version is known - not to implement it correctly, or whenever a tagged queue depth of 1 is - selected. Tagged queuing is also disabled for individual target devices if - disconnect/reconnect is disabled for that device. In performance testing, - sustained disk writes of 7.3MB per second have been observed to a /dev/sd - device. + tagged queuing for each target device as well as individual selection of the + tagged queue depth is available through driver options provided on the kernel + command line or at module initialization time. By default, the queue depth + is determined automatically based on the host adapter's total queue depth and + the number, type, speed, and capabilities of the target devices found. In + addition, tagged queuing is automatically disabled whenever the host adapter + firmware version is known not to implement it correctly, or whenever a tagged + queue depth of 1 is selected. Tagged queuing is also disabled for individual + target devices if disconnect/reconnect is disabled for that device. o Robustness Features @@ -121,15 +160,15 @@ o Robustness Features a selection is made between a full host adapter hard reset and SCSI bus reset versus sending a bus device reset message to the individual target device based on the recommendation of the SCSI subsystem. Error recovery strategies - are selectable from the kernel command line individually for each target - device, and also include sending a bus device reset to the specific target - device associated with the command being reset, as well as suppressing error + are selectable through driver options individually for each target device, + and also include sending a bus device reset to the specific target device + associated with the command being reset, as well as suppressing error recovery entirely to avoid perturbing an improperly functioning device. If the bus device reset error recovery strategy is selected and sending a bus device reset does not restore correct operation, the next command that is reset will force a full host adapter hard reset and SCSI bus reset. SCSI bus resets caused by other devices and detected by the host adapter are also - handled by issuing a hard reset to the host adapter and re-initialization. + handled by issuing a soft reset to the host adapter and re-initialization. Finally, if tagged queuing is active and more than one command reset occurs in a 10 minute interval, or if a command reset occurs within the first 10 minutes of operation, then tagged queuing will be disabled for that target @@ -138,15 +177,6 @@ o Robustness Features lock up or crash, and thereby allowing a clean shutdown and restart after the offending component is removed. -o Extensive Testing - - This driver has undergone extensive testing and improvement over a period of - several months, and is routinely being used on heavily loaded systems. Over - 300 people retrieved the driver during the beta test period. In addition to - testing in normal system operation, error recovery tests have been performed - to verify proper system recovery in the case of simulated dropped interrupts, - external SCSI bus resets, and SCSI command errors due to bad CD-ROM media. - o PCI Configuration Support On PCI systems running kernels compiled with PCI BIOS support enabled, this @@ -159,8 +189,8 @@ o PCI Configuration Support o /proc File System Support - Copies of the host adapter configuration information together with data - transfer and error recovery statistics are now available through the + Copies of the host adapter configuration information together with updated + data transfer and error recovery statistics are available through the /proc/scsi/BusLogic/ interface. o Shared Interrupts Support @@ -168,16 +198,6 @@ o Shared Interrupts Support On systems that support shared interrupts, any number of BusLogic Host Adapters may share the same interrupt request channel. -o Wide SCSI Support - - All BusLogic MultiMaster SCSI Host Adapters share a common programming - interface, except for the inevitable improvements and extensions as new - models are released, so support for Wide SCSI data transfer has automatically - been available without explicit driver support. When used with Linux 2.0.x, - this driver adds explicit support for up to 15 target devices and 64 logical - units per target device, to fully exploit the capabilities of the newest - BusLogic Wide SCSI Host Adapters. - SUPPORTED HOST ADAPTERS @@ -188,16 +208,21 @@ that it is or will be supported. FlashPoint Series PCI Host Adapters: -FlashPoint LT (BT-930) Ultra SCSI-2 -FlashPoint DL (BT-932) Dual Channel Ultra SCSI-2 -FlashPoint LW (BT-950) Wide Ultra SCSI-2 -FlashPoint DW (BT-952) Dual Channel Wide Ultra SCSI-2 +FlashPoint LT (BT-930) Ultra SCSI-3 +FlashPoint LT (BT-930R) Ultra SCSI-3 with RAIDPlus +FlashPoint LT (BT-920) Ultra SCSI-3 (BT-930 without BIOS) +FlashPoint DL (BT-932) Dual Channel Ultra SCSI-3 +FlashPoint DL (BT-932R) Dual Channel Ultra SCSI-3 with RAIDPlus +FlashPoint LW (BT-950) Wide Ultra SCSI-3 +FlashPoint LW (BT-950R) Wide Ultra SCSI-3 with RAIDPlus +FlashPoint DW (BT-952) Dual Channel Wide Ultra SCSI-3 +FlashPoint DW (BT-952R) Dual Channel Wide Ultra SCSI-3 with RAIDPlus MultiMaster "W" Series Host Adapters: -BT-948 PCI Ultra SCSI-2 -BT-958 PCI Wide Ultra SCSI-2 -BT-958D PCI Wide Differential Ultra SCSI-2 +BT-948 PCI Ultra SCSI-3 +BT-958 PCI Wide Ultra SCSI-3 +BT-958D PCI Wide Differential Ultra SCSI-3 MultiMaster "C" Series Host Adapters: @@ -231,6 +256,39 @@ BT-542B ISA SCSI-2 (542B revisions A - G) AMI FastDisk Host Adapters that are true BusLogic MultiMaster clones are also supported by this driver. +BusLogic SCSI Host Adapters are available packaged both as bare boards and as +retail kits. The BT- model numbers above refer to the bare board packaging. +The retail kit model numbers are found by replacing BT- with KT- in the above +list. The retail kit includes the bare board and manual as well as cabling and +driver media and documentation that are not provided with bare boards. + + + FLASHPOINT INSTALLATION NOTES + +o RAIDPlus Support + + FlashPoint Host Adapters now include RAIDPlus, Mylex's bootable software + RAID. RAIDPlus is not supported on Linux, and there are no plans to support + it. The MD driver in Linux 2.0 provides for concatenation (LINEAR) and + striping (RAID-0), and support for mirroring (RAID-1), fixed parity (RAID-4), + and distributed parity (RAID-5) is available separately. The built-in Linux + RAID support is generally more flexible and is expected to perform better + than RAIDPlus, so there is little impetus to include RAIDPlus support in the + BusLogic driver. + +o Enabling UltraSCSI Transfers + + FlashPoint Host Adapters ship with their configuration set to "Factory + Default" settings that are conservative and do not allow for UltraSCSI speed + to be negotiated. This results in fewer problems when these host adapters + are installed in systems with cabling or termination that is not sufficient + for UltraSCSI operation, or where existing SCSI devices do not properly + respond to synchronous transfer negotiation for UltraSCSI speed. AutoSCSI + may be used to load "Optimum Performance" settings which allow UltraSCSI + speed to be negotiated with all devices, or UltraSCSI speed can be enabled on + an individual basis. It is recommended that SCAM be manually disabled after + the "Optimum Performance" settings are loaded. + BT-948/958/958D INSTALLATION NOTES @@ -284,113 +342,254 @@ o PCI Slot Scanning Order so as to recognize the host adapters in the same order as they are enumerated by the host adapter's BIOS. -o Mega-Transfers/Second +o Enabling UltraSCSI Transfers + + The BT-948/958/958D ship with their configuration set to "Factory Default" + settings that are conservative and do not allow for UltraSCSI speed to be + negotiated. This results in fewer problems when these host adapters are + installed in systems with cabling or termination that is not sufficient for + UltraSCSI operation, or where existing SCSI devices do not properly respond + to synchronous transfer negotiation for UltraSCSI speed. AutoSCSI may be + used to load "Optimum Performance" settings which allow UltraSCSI speed to be + negotiated with all devices, or UltraSCSI speed can be enabled on an + individual basis. It is recommended that SCAM be manually disabled after the + "Optimum Performance" settings are loaded. + + + DRIVER OPTIONS + +BusLogic Driver Options may be specified either via the Linux Kernel Command +Line or via the Loadable Kernel Module Installation Facility. Driver Options +for multiple host adapters may be specified either by separating the option +strings by a semicolon, or by specifying multiple "BusLogic=" strings on the +command line. Individual option specifications for a single host adapter are +separated by commas. The Probing and Debugging Options apply to all host +adapters whereas the remaining options apply individually only to the +selected host adapter. + +The BusLogic Driver Probing Options comprise the following: + +IO: + + The "IO:" option specifies an ISA I/O Address to be probed for a non-PCI + MultiMaster Host Adapter. If neither "IO:" nor "NoProbeISA" options are + specified, then the standard list of BusLogic MultiMaster ISA I/O Addresses + will be probed (0x330, 0x334, 0x230, 0x234, 0x130, and 0x134). Multiple + "IO:" options may be specified to precisely determine the I/O Addresses to + be probed, but the probe order will always follow the standard list. + +NoProbe - The driver reports on the synchronous transfer parameters negotiated between - the host adapter and target devices in units of "mega-transfers/second". For - wide devices, the unit of transfer is 16 bits if wide negotiation has been - successfully completed. Therefore, the total transfer rate to wide devices - will generally be twice the synchronous tranfer rate reported by the driver. + The "NoProbe" option disables all probing and therefore no BusLogic Host + Adapters will be detected. +NoProbeISA - COMMAND LINE OPTIONS + The "NoProbeISA" option disables probing of the standard BusLogic ISA I/O + Addresses and therefore only PCI MultiMaster and FlashPoint Host Adapters + will be detected. -Many features of this driver are configurable by specification of appropriate -kernel command line options. A full description of the command line options -may be found in the comments before BusLogic_Setup in the kernel source code -file "BusLogic.c". The following examples may be useful as a starting point: +NoProbePCI - "BusLogic=NoProbe" + The "NoProbePCI" options disables the interrogation of PCI Configuration + Space and therefore only ISA Multimaster Host Adapters will be detected, as + well as PCI Multimaster Host Adapters that have their ISA Compatible I/O + Port set to "Primary" or "Alternate". - No probing of any kind is to be performed, and hence no BusLogic Host - Adapters will be detected. +NoSortPCI - "BusLogic=NoProbeISA" + The "NoSortPCI" option forces PCI MultiMaster Host Adapters to be + enumerated in the order provided by the PCI BIOS, ignoring any setting of + the AutoSCSI "Use Bus And Device # For PCI Scanning Seq." option. - No probing of the standard ISA I/O Addresses will be done, and hence only - PCI Host Adapters will be detected. +MultiMasterFirst - "BusLogic=NoProbePCI" + The "MultiMasterFirst" option forces MultiMaster Host Adapters to be probed + before FlashPoint Host Adapters. By default, if both FlashPoint and PCI + MultiMaster Host Adapters are present, this driver will probe for + FlashPoint Host Adapters first unless the BIOS primary disk is controlled + by the first PCI MultiMaster Host Adapter, in which case MultiMaster Host + Adapters will be probed first. - No interrogation of PCI Configuration Space will be made, and hence only - ISA Multimaster Host Adapters will be detected, as well as PCI Multimaster - Host Adapters that have their ISA Compatible I/O Port set to "Primary" or - "Alternate". +FlashPointFirst - "BusLogic=NoSortPCI" + The "FlashPointFirst" option forces FlashPoint Host Adapters to be probed + before MultiMaster Host Adapters. - PCI MultiMaster Host Adapters will be enumerated in the order provided by - the PCI BIOS, ignoring any setting of the AutoSCSI "Use Bus And Device # - For PCI Scanning Seq." option. +The BusLogic Driver Tagged Queuing Options allow for explicitly specifying +the Queue Depth and whether Tagged Queuing is permitted for each Target +Device (assuming that the Target Device supports Tagged Queuing). The Queue +Depth is the number of SCSI Commands that are allowed to be concurrently +presented for execution (either to the Host Adapter or Target Device). Note +that explicitly enabling Tagged Queuing may lead to problems; the option to +enable or disable Tagged Queuing is provided primarily to allow disabling +Tagged Queuing on Target Devices that do not implement it correctly. The +following options are available: - "BusLogic=MultiMasterFirst" +QueueDepth: - By default, if both FlashPoint and PCI MultiMaster Host Adapters are - present, this driver will probe for FlashPoint Host Adapters first unless - the BIOS primary disk is controlled by the first PCI MultiMaster Host - Adapter, in which case MultiMaster Host Adapters will be probed first. - This option forces MultiMaster Host Adapters to be probed first. + The "QueueDepth:" or QD:" option specifies the Queue Depth to use for all + Target Devices that support Tagged Queuing. If no Queue Depth option is + provided, the Queue Depth will be determined automatically based on the + Host Adapter's Total Queue Depth and the number, type, speed, and + capabilities of the detected Target Devices. For Host Adapters that + require ISA Bounce Buffers, the Queue Depth is automatically set by default + to BusLogic_QueueDepthBounceBuffers to avoid excessive preallocation of DMA + Bounce Buffer memory. Target Devices that do not support Tagged Queuing + always use a Queue Depth of BusLogic_UntaggedQueueDepth. - "BusLogic=FlashPointFirst" +QueueDepth:[,...] - By default, if both FlashPoint and PCI MultiMaster Host Adapters are - present, this driver will probe for FlashPoint Host Adapters first unless - the BIOS primary disk is controlled by the first PCI MultiMaster Host - Adapter, in which case MultiMaster Host Adapters will be probed first. - This option forces FlashPoint Host Adapters to be probed first. + The "QueueDepth:[...]" or "QD:[...]" option specifies the Queue Depth + individually for each Target Device. If an is omitted, the + associated Target Device will have its Queue Depth selected automatically. - "BusLogic=0x330" +TaggedQueuing:Default - This command line limits probing to the single I/O port at 0x330. + The "TaggedQueuing:Default" or "TQ:Default" option permits Tagged Queuing + based on the firmware version of the BusLogic Host Adapter and based on + whether the Queue Depth allows queuing multiple commands. - "BusLogic=0,1" +TaggedQueuing:Enable - This command line selects default probing and a tagged queue depth of 1 - which also disables tagged queuing. It may be useful if problems arise - during installation on a system with a flaky SCSI configuration. In cases - of a marginal SCSI configuration it may also be beneficial to disable fast - transfers and/or synchronous negotiation using AutoSCSI on FlashPoint and - "W" and "C" series MultiMaster host adapters. Disconnect/reconnect may - also be disabled for fast devices such as disk drives, but should not be - disabled for tape drives or other devices where a single command may take - over a second to execute. + The "TaggedQueuing:Enable" or "TQ:Enable" option enables Tagged Queuing for + all Target Devices on this Host Adapter, overriding any limitation that + would otherwise be imposed based on the Host Adapter firmware version. - "BusLogic=0,0,30" +TaggedQueuing:Disable - This command line selects default probing and automatic tagged queue depth - selection, but changes the bus settle time to 30 seconds. It may be useful - with SCSI devices that take an unusually long time to become ready to - accept commands after a SCSI bus reset. Some tape drives will not respond - properly immediately after a SCSI bus reset, especially if a tape is - present in the drive. + The "TaggedQueuing:Disable" or "TQ:Disable" option disables Tagged Queuing + for all Target Devices on this Host Adapter. - "BusLogic=TQ:Disable" +TaggedQueuing: - This command line selects default probing and disables tagged queuing. + The "TaggedQueuing:" or "TQ:" option controls + Tagged Queuing individually for each Target Device. is a + sequence of "Y", "N", and "X" characters. "Y" enables Tagged Queuing, "N" + disables Tagged Queuing, and "X" accepts the default based on the firmware + version. The first character refers to Target Device 0, the second to + Target Device 1, and so on; if the sequence of "Y", "N", and "X" characters + does not cover all the Target Devices, unspecified characters are assumed + to be "X". - "BusLogic=0,15,TQ:N" +The BusLogic Driver Error Recovery Option allows for explicitly specifying +the Error Recovery action to be performed when BusLogic_ResetCommand is +called due to a SCSI Command failing to complete successfully. The following +options are available: - This command line selects a tagged queue depth of 15 and disables tagged - queuing for target 0, while allowing tagged queuing for all other target - devices. +ErrorRecovery:Default -Note that limiting the tagged queue depth or disabling tagged queuing can -substantially impact performance. + The "ErrorRecovery:Default" or "ER:Default" option selects between the Hard + Reset and Bus Device Reset options based on the recommendation of the SCSI + Subsystem. +ErrorRecovery:HardReset - INSTALLATION + The "ErrorRecovery:HardReset" or "ER:HardReset" option will initiate a Host + Adapter Hard Reset which also causes a SCSI Bus Reset. -This distribution was prepared for Linux kernel version 2.0.30, but should be -compatible with 2.0.4 or any later 2.0 series kernel if BusLogic.patch is also -applied. +ErrorRecovery:BusDeviceReset + + The "ErrorRecovery:BusDeviceReset" or "ER:BusDeviceReset" option will send + a Bus Device Reset message to the individual Target Device causing the + error. If Error Recovery is again initiated for this Target Device and no + SCSI Command to this Target Device has completed successfully since the Bus + Device Reset message was sent, then a Hard Reset will be attempted. + +ErrorRecovery:None + + The "ErrorRecovery:None" or "ER:None" option suppresses Error Recovery. + This option should only be selected if a SCSI Bus Reset or Bus Device Reset + will cause the Target Device or a critical operation to suffer a complete + and unrecoverable failure. + +ErrorRecovery: + + The "ErrorRecovery:" or "ER:" option controls + Error Recovery individually for each Target Device. is a + sequence of "D", "H", "B", and "N" characters. "D" selects Default, "H" + selects Hard Reset, "B" selects Bus Device Reset, and "N" selects None. + The first character refers to Target Device 0, the second to Target Device + 1, and so on; if the sequence of "D", "H", "B", and "N" characters does not + cover all the possible Target Devices, unspecified characters are assumed + to be "D". + +The BusLogic Driver Miscellaneous Options comprise the following: + +BusSettleTime: + + The "BusSettleTime:" or "BST:" option specifies the Bus Settle Time in + seconds. The Bus Settle Time is the amount of time to wait between a Host + Adapter Hard Reset which initiates a SCSI Bus Reset and issuing any SCSI + Commands. If unspecified, it defaults to BusLogic_DefaultBusSettleTime. + +InhibitTargetInquiry + + The "InhibitTargetInquiry" option inhibits the execution of an Inquire + Target Devices or Inquire Installed Devices command on MultiMaster Host + Adapters. This may be necessary with some older Target Devices that do not + respond correctly when Logical Units above 0 are addressed. + +The BusLogic Driver Debugging Options comprise the following: + +TraceProbe + + The "TraceProbe" option enables tracing of Host Adapter Probing. + +TraceHardwareReset + + The "TraceHardwareReset" option enables tracing of Host Adapter Hardware + Reset. + +TraceConfiguration + + The "TraceConfiguration" option enables tracing of Host Adapter + Configuration. + +TraceErrors + + The "TraceErrors" option enables tracing of SCSI Commands that return an + error from the Target Device. The CDB and Sense Data will be printed for + each SCSI Command that fails. + +Debug + + The "Debug" option enables all debugging options. + +The following examples demonstrate setting the Queue Depth for Target Devices +1 and 2 on the first host adapter to 7 and 15, the Queue Depth for all Target +Devices on the second host adapter to 31, and the Bus Settle Time on the +second host adapter to 30 seconds. + +Linux Kernel Command Line: + + linux BusLogic=QueueDepth:[,7,15];QueueDepth:31,BusSettleTime:30 + +LILO Linux Boot Loader (in /etc/lilo.conf): + + append = "BusLogic=QueueDepth:[,7,15];QueueDepth:31,BusSettleTime:30" + +INSMOD Loadable Kernel Module Installation Facility: + + insmod BusLogic.o \ + 'BusLogic_Options="QueueDepth:[,7,15];QueueDepth:31,BusSettleTime:30"' + +NOTE: Module Utilities 2.1.71 or later is required for correct parsing + of driver options containing commas. + + + DRIVER INSTALLATION + +This distribution was prepared for Linux kernel version 2.0.33, but should be +compatible with 2.0.4 or any later 2.0 series kernel. To install the new BusLogic SCSI driver, you may use the following commands, replacing "/usr/src" with wherever you keep your Linux kernel source tree: cd /usr/src - tar -xvzf BusLogic-2.0.10.tar.gz + tar -xvzf BusLogic-2.0.11.tar.gz mv README.* LICENSE.* BusLogic.[ch] FlashPoint.c linux/drivers/scsi - patch -p < BusLogic.patch # Only for kernels prior to 2.0.30 + patch -p < BusLogic.patch cd linux make config make depend @@ -399,11 +598,6 @@ replacing "/usr/src" with wherever you keep your Linux kernel source tree: Then install "arch/i386/boot/zImage" as your standard kernel, run lilo if appropriate, and reboot. -Be sure to answer "y" to the "BusLogic SCSI support" query during the "make -config" step. If your system was already configured for the old BusLogic -driver or for an older version of this driver, you may omit the "make config" -step above. - BUSLOGIC ANNOUNCEMENTS MAILING LIST diff --git a/drivers/scsi/README.Mylex b/drivers/scsi/README.Mylex new file mode 100644 index 000000000..a786fabc6 --- /dev/null +++ b/drivers/scsi/README.Mylex @@ -0,0 +1,6 @@ +Please see the file README.BusLogic for information about Linux support for +Mylex (formerly BusLogic) MultiMaster and FlashPoint SCSI Host Adapters. + +The Mylex DAC960 PCI RAID Controllers are not supported at the present time, +but work on a Linux driver for the DAC960 is in progress. Please consult +http://www.dandelion.com/Linux/ for further information on the DAC960 driver. diff --git a/drivers/scsi/README.ncr53c8xx b/drivers/scsi/README.ncr53c8xx index ab12ed995..4b179a318 100644 --- a/drivers/scsi/README.ncr53c8xx +++ b/drivers/scsi/README.ncr53c8xx @@ -4,7 +4,7 @@ Written by Gerard Roudier 21 Rue Carnot 95170 DEUIL LA BARRE - FRANCE -23 August 1997 +2 January 1998 =============================================================================== 1. Introduction @@ -30,6 +30,7 @@ Written by Gerard Roudier 10.3 Advised boot setup commands 10.4 PCI configuration fix-up boot option 10.5 Serial NVRAM support boot option + 10.6 SCSI BUS checking boot option 11. Some constants and flags of the ncr53c8xx.h header file 12. Installation 12.1 Provided files @@ -38,6 +39,8 @@ Written by Gerard Roudier 14. Known problems 14.1 Tagged commands with Iomega Jaz device 14.2 Device names change when another controller is added + 14.3 Using only 8 bit devices with a WIDE SCSI controller. + 14.4 Possible data corruption during a Memory Write and Invalidate 15. SCSI problem troubleshooting 16. Synchonous transfer negotiation tables 16.1 Synchronous timings for 53C875 and 53C860 Ultra-SCSI controllers @@ -490,7 +493,9 @@ CONFIG_SCSI_NCR53C8XX_NVRAM_DETECT 10.1 Syntax -Setup commands can be passed to the driver at boot time. +Setup commands can be passed to the driver either at boot time or as a +string variable using 'insmod'. + A boot setup command for the ncr53c8xx driver begins with the driver name "ncr53c8xx=". The kernel syntax parser then expects an optionnal list of integers separated with comma followed by an optionnal list of comma- @@ -502,7 +507,14 @@ lilo: linux root=/dev/hda2 ncr53c8xx=tags:4,sync:10,debug:0x200 - set synchronous negotiation speed to 10 Mega-transfers / second. - set DEBUG_NEGO flag. -For the moment, the integer list of arguments is disgarded by the driver. +Since comma seems not to be allowed when defining a string variable using +'insmod', the driver also accepts as option separator. +The following command will install driver module with the same options as +above. + +insmod ncr53c8xx.o ncr53c8xx="tags:4 sync:10 debug:0x200" + +For the moment, the integer list of arguments is discarded by the driver. It will be used in the future in order to allow a per controller setup. Each string argument must be specified as "keyword:value". Only lower-case @@ -525,8 +537,12 @@ Scsi disconnections Special features Only apply to 810A, 825A, 860 and 875 controllers. Have no effect with normal 810 and 825. - specf:y enabled - specf:n disabled + specf:y (or 1) enabled + specf:n (or 0) disabled + specf:3 enabled except Memory Write And Invalidate + The default driver setup is 'specf:3'. As a consequence, option 'specf:y' + must be specified in the boot setup command to enable Memory Write And + Invalidate. Ultra SCSI support Only apply to 860 and 875 controllers. @@ -628,6 +644,7 @@ Fix up PCI configuration space pcifix: