diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2001-01-10 05:27:25 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2001-01-10 05:27:25 +0000 |
commit | c9c06167e7933d93a6e396174c68abf242294abb (patch) | |
tree | d9a8bb30663e9a3405a1ef37ffb62bc14b9f019f /drivers/scsi | |
parent | f79e8cc3c34e4192a3e5ef4cc9c6542fdef703c0 (diff) |
Merge with Linux 2.4.0-test12.
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/Makefile | 4 | ||||
-rw-r--r-- | drivers/scsi/a2091.c | 2 | ||||
-rw-r--r-- | drivers/scsi/a2091.h | 1 | ||||
-rw-r--r-- | drivers/scsi/a3000.c | 21 | ||||
-rw-r--r-- | drivers/scsi/a3000.h | 3 | ||||
-rw-r--r-- | drivers/scsi/aha1542.c | 11 | ||||
-rw-r--r-- | drivers/scsi/atari_scsi.c | 2 | ||||
-rw-r--r-- | drivers/scsi/eata.c | 287 | ||||
-rw-r--r-- | drivers/scsi/eata.h | 11 | ||||
-rw-r--r-- | drivers/scsi/gvp11.c | 2 | ||||
-rw-r--r-- | drivers/scsi/ide-scsi.c | 2 | ||||
-rw-r--r-- | drivers/scsi/imm.c | 21 | ||||
-rw-r--r-- | drivers/scsi/imm.h | 5 | ||||
-rw-r--r-- | drivers/scsi/ips.h | 2 | ||||
-rw-r--r-- | drivers/scsi/megaraid.c | 3 | ||||
-rw-r--r-- | drivers/scsi/mvme147.c | 116 | ||||
-rw-r--r-- | drivers/scsi/mvme147.h | 50 | ||||
-rw-r--r-- | drivers/scsi/ppa.c | 18 | ||||
-rw-r--r-- | drivers/scsi/ppa.h | 5 | ||||
-rw-r--r-- | drivers/scsi/qla1280.c | 9 | ||||
-rw-r--r-- | drivers/scsi/u14-34f.c | 284 | ||||
-rw-r--r-- | drivers/scsi/u14-34f.h | 13 | ||||
-rw-r--r-- | drivers/scsi/wd33c93.c | 75 | ||||
-rw-r--r-- | drivers/scsi/wd33c93.h | 3 |
24 files changed, 382 insertions, 568 deletions
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile index 50d26c7e4..f8a982527 100644 --- a/drivers/scsi/Makefile +++ b/drivers/scsi/Makefile @@ -30,7 +30,7 @@ CFLAGS_aha152x.o = -DAHA152X_STAT -DAUTOCONF CFLAGS_gdth.o = # -DDEBUG_GDTH=2 -D__SERIAL__ -D__COM2__ -DGDTH_STATISTICS CFLAGS_seagate.o = -DARBITRATE -DPARITY -DSEAGATE_USE_ASM -obj-$(CONFIG_SCSI) += scsi_mod.o scsi_syms.o +obj-$(CONFIG_SCSI) += scsi_mod.o obj-$(CONFIG_A4000T_SCSI) += amiga7xx.o 53c7xx.o obj-$(CONFIG_A4091_SCSI) += amiga7xx.o 53c7xx.o @@ -39,6 +39,7 @@ obj-$(CONFIG_WARPENGINE_SCSI) += amiga7xx.o 53c7xx.o obj-$(CONFIG_A3000_SCSI) += a3000.o wd33c93.o obj-$(CONFIG_A2091_SCSI) += a2091.o wd33c93.o obj-$(CONFIG_GVP11_SCSI) += gvp11.o wd33c93.o +obj-$(CONFIG_MVME147_SCSI) += mvme147.o wd33c93.o obj-$(CONFIG_SGIWD93_SCSI) += sgiwd93.o wd33c93.o obj-$(CONFIG_CYBERSTORM_SCSI) += NCR53C9x.o cyberstorm.o obj-$(CONFIG_CYBERSTORMII_SCSI) += NCR53C9x.o cyberstormII.o @@ -123,6 +124,7 @@ scsi_mod-objs := scsi.o hosts.o scsi_ioctl.o constants.o \ scsicam.o scsi_proc.o scsi_error.o \ scsi_obsolete.o scsi_queue.o scsi_lib.o \ scsi_merge.o scsi_dma.o scsi_scan.o \ + scsi_syms.o sr_mod-objs := sr.o sr_ioctl.o sr_vendor.o initio-objs := ini9100u.o i91uscsi.o diff --git a/drivers/scsi/a2091.c b/drivers/scsi/a2091.c index 5c657b2e5..64da3a507 100644 --- a/drivers/scsi/a2091.c +++ b/drivers/scsi/a2091.c @@ -231,8 +231,6 @@ int __init a2091_detect(Scsi_Host_Template *tpnt) #define HOSTS_C -#include "a2091.h" - static Scsi_Host_Template driver_template = A2091_SCSI; #include "scsi_module.c" diff --git a/drivers/scsi/a2091.h b/drivers/scsi/a2091.h index 97beba146..b0bcaa4b1 100644 --- a/drivers/scsi/a2091.h +++ b/drivers/scsi/a2091.h @@ -1,4 +1,5 @@ #ifndef A2091_H +#define A2091_H /* $Id: a2091.h,v 1.4 1997/01/19 23:07:09 davem Exp $ * diff --git a/drivers/scsi/a3000.c b/drivers/scsi/a3000.c index c9a4253f0..ddb65b250 100644 --- a/drivers/scsi/a3000.c +++ b/drivers/scsi/a3000.c @@ -3,6 +3,7 @@ #include <linux/blk.h> #include <linux/sched.h> #include <linux/version.h> +#include <linux/ioport.h> #include <linux/init.h> #include <linux/spinlock.h> @@ -100,7 +101,9 @@ static int dma_setup (Scsi_Cmnd *cmd, int dir_in) cache_push (addr, cmd->SCp.this_residual); /* start DMA */ + mb(); /* make sure setup is completed */ DMA(a3000_host)->ST_DMA = 1; + mb(); /* make sure DMA has started before next IO */ /* return success */ return 0; @@ -116,12 +119,15 @@ static void dma_stop (struct Scsi_Host *instance, Scsi_Cmnd *SCpnt, cntr |= CNTR_DDIR; DMA(instance)->CNTR = cntr; + mb(); /* make sure CNTR is updated before next IO */ /* flush if we were reading */ if (HDATA(instance)->dma_dir) { DMA(instance)->FLUSH = 1; + mb(); /* don't allow prefetch */ while (!(DMA(instance)->ISTR & ISTR_FE_FLG)) - ; + barrier(); + mb(); /* no IO until FLUSH is done */ } /* clear a possible interrupt */ @@ -132,9 +138,11 @@ static void dma_stop (struct Scsi_Host *instance, Scsi_Cmnd *SCpnt, /* stop DMA */ DMA(instance)->SP_DMA = 1; + mb(); /* make sure DMA is stopped before next IO */ /* restore the CONTROL bits (minus the direction flag) */ DMA(instance)->CNTR = CNTR_PDMD | CNTR_INTEN; + mb(); /* make sure CNTR is updated before next IO */ /* copy from a bounce buffer, if necessary */ if (status && HDATA(instance)->dma_bounce_buffer) { @@ -170,13 +178,17 @@ int __init a3000_detect(Scsi_Host_Template *tpnt) if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(A3000_SCSI)) return 0; + if (!request_mem_region(0xDD0000, 256, "wd33c93")) + return -EBUSY; tpnt->proc_name = "A3000"; tpnt->proc_info = &wd33c93_proc_info; a3000_host = scsi_register (tpnt, sizeof(struct WD33C93_hostdata)); - if(a3000_host == NULL) + if (a3000_host == NULL) { + release_mem_region(0xDD0000, 256); return 0; + } a3000_host->base = ZTWO_VADDR(0xDD0000); a3000_host->irq = IRQ_AMIGA_PORTS; DMA(a3000_host)->DAWR = DAWR_A3000; @@ -192,9 +204,7 @@ int __init a3000_detect(Scsi_Host_Template *tpnt) #define HOSTS_C -#include "a3000.h" - -static Scsi_Host_Template driver_template = A3000_SCSI; +static Scsi_Host_Template driver_template = _A3000_SCSI; #include "scsi_module.c" @@ -203,6 +213,7 @@ int a3000_release(struct Scsi_Host *instance) #ifdef MODULE wd33c93_release(); DMA(instance)->CNTR = 0; + release_mem_region(0xDD0000, 256); free_irq(IRQ_AMIGA_PORTS, a3000_intr); #endif return 1; diff --git a/drivers/scsi/a3000.h b/drivers/scsi/a3000.h index 478c3d39a..78f51c8e0 100644 --- a/drivers/scsi/a3000.h +++ b/drivers/scsi/a3000.h @@ -1,4 +1,5 @@ #ifndef A3000_H +#define A3000_H /* $Id: a3000.h,v 1.4 1997/01/19 23:07:10 davem Exp $ * @@ -29,7 +30,7 @@ int wd33c93_reset(Scsi_Cmnd *, unsigned int); #define CAN_QUEUE 16 #endif -#define A3000_SCSI { proc_name: "A3000", \ +#define _A3000_SCSI { proc_name: "A3000", \ proc_info: NULL, \ name: "Amiga 3000 built-in SCSI", \ detect: a3000_detect, \ diff --git a/drivers/scsi/aha1542.c b/drivers/scsi/aha1542.c index 9d3584a25..dd5f627d3 100644 --- a/drivers/scsi/aha1542.c +++ b/drivers/scsi/aha1542.c @@ -1416,6 +1416,7 @@ int aha1542_dev_reset(Scsi_Cmnd * SCpnt) SCtmp = HOSTDATA(SCpnt->host)->SCint[i]; if (SCtmp->host_scribble) { scsi_free(SCtmp->host_scribble, 512); + SCtmp->host_scribble = NULL; } HOSTDATA(SCpnt->host)->SCint[i] = NULL; HOSTDATA(SCpnt->host)->mb[i].status = 0; @@ -1478,6 +1479,7 @@ int aha1542_bus_reset(Scsi_Cmnd * SCpnt) } if (SCtmp->host_scribble) { scsi_free(SCtmp->host_scribble, 512); + SCtmp->host_scribble = NULL; } HOSTDATA(SCpnt->host)->SCint[i] = NULL; HOSTDATA(SCpnt->host)->mb[i].status = 0; @@ -1546,6 +1548,7 @@ int aha1542_host_reset(Scsi_Cmnd * SCpnt) } if (SCtmp->host_scribble) { scsi_free(SCtmp->host_scribble, 512); + SCtmp->host_scribble = NULL; } HOSTDATA(SCpnt->host)->SCint[i] = NULL; HOSTDATA(SCpnt->host)->mb[i].status = 0; @@ -1681,8 +1684,10 @@ int aha1542_old_reset(Scsi_Cmnd * SCpnt, unsigned int reset_flags) Scsi_Cmnd *SCtmp; SCtmp = HOSTDATA(SCpnt->host)->SCint[i]; SCtmp->result = DID_RESET << 16; - if (SCtmp->host_scribble) + if (SCtmp->host_scribble) { scsi_free(SCtmp->host_scribble, 512); + SCtmp->host_scribble = NULL; + } printk(KERN_WARNING "Sending DID_RESET for target %d\n", SCpnt->target); SCtmp->scsi_done(SCpnt); @@ -1725,8 +1730,10 @@ fail: Scsi_Cmnd *SCtmp; SCtmp = HOSTDATA(SCpnt->host)->SCint[i]; SCtmp->result = DID_RESET << 16; - if (SCtmp->host_scribble) + if (SCtmp->host_scribble) { scsi_free(SCtmp->host_scribble, 512); + SCtmp->host_scribble = NULL; + } printk(KERN_WARNING "Sending DID_RESET for target %d\n", SCpnt->target); SCtmp->scsi_done(SCpnt); diff --git a/drivers/scsi/atari_scsi.c b/drivers/scsi/atari_scsi.c index 77feb1cbc..449b74013 100644 --- a/drivers/scsi/atari_scsi.c +++ b/drivers/scsi/atari_scsi.c @@ -656,7 +656,7 @@ int atari_scsi_detect (Scsi_Host_Template *host) */ if (MACH_IS_ATARI && ATARIHW_PRESENT(ST_SCSI) && !ATARIHW_PRESENT(EXTD_DMA) && m68k_num_memory > 1) { - atari_dma_buffer = atari_stram_alloc( STRAM_BUFFER_SIZE, NULL, "SCSI" ); + atari_dma_buffer = atari_stram_alloc(STRAM_BUFFER_SIZE, "SCSI"); if (!atari_dma_buffer) { printk( KERN_ERR "atari_scsi_detect: can't allocate ST-RAM " "double buffer\n" ); diff --git a/drivers/scsi/eata.c b/drivers/scsi/eata.c index a1f277e8d..9436e6a65 100644 --- a/drivers/scsi/eata.c +++ b/drivers/scsi/eata.c @@ -1,12 +1,26 @@ /* * eata.c - Low-level driver for EATA/DMA SCSI host adapters. * + * 22 Nov 2000 Rev. 6.02 for linux 2.4.0-test11 + * + Return code checked when calling pci_enable_device. + * + Removed old scsi error handling support. + * + The obsolete boot option flag eh:n is silently ignored. + * + Removed error messages while a disk drive is powered up at + * boot time. + * + Improved boot messages: all tagged capable device are + * indicated as "tagged" or "soft-tagged" : + * - "soft-tagged" means that the driver is trying to do its + * own tagging (i.e. the tc:y option is in effect); + * - "tagged" means that the device supports tagged commands, + * but the driver lets the HBA be responsible for tagging + * support. + * * 16 Sep 1999 Rev. 5.11 for linux 2.2.12 and 2.3.18 * + Updated to the new __setup interface for boot command line options. * + When loaded as a module, accepts the new parameter boot_options * which value is a string with the same format of the kernel boot * command line options. A valid example is: - * modprobe eata 'boot_options=\"0x7410,0x230,lc:y,tc:n,mq:4\"' + * modprobe eata boot_options=\"0x7410,0x230,lc:y,tc:n,mq:4\" * * 9 Sep 1999 Rev. 5.10 for linux 2.2.12 and 2.3.17 * + 64bit cleanup for Linux/Alpha platform support @@ -196,7 +210,9 @@ * This driver is based on the CAM (Common Access Method Committee) * EATA (Enhanced AT Bus Attachment) rev. 2.0A, using DMA protocol. * - * Copyright (C) 1994-1999 Dario Ballabio (dario@milano.europe.dg.com) + * Copyright (C) 1994-2000 Dario Ballabio (ballabio_dario@emc.com) + * + * Alternate email: dario.ballabio@inwind.it, dario.ballabio@tiscalinet.it * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that redistributions of source @@ -288,8 +304,6 @@ * After the optional list of detection probes, other possible command line * options are: * - * eh:y use new scsi code; - * eh:n use old scsi code; * et:y force use of extended translation (255 heads, 63 sectors); * et:n use disk geometry detected by scsicam_bios_param; * rs:y reverse scan order while detecting PCI boards; @@ -306,13 +320,13 @@ * * The default value is: "eata=lc:n,tc:n,mq:16,tm:0,et:n,rs:n". * An example using the list of detection probes could be: - * "eata=0x7410,0x230,lc:y,tc:n,mq:4,eh:n,et:n". + * "eata=0x7410,0x230,lc:y,tc:n,mq:4,et:n". * * When loading as a module, parameters can be specified as well. * The above example would be (use 1 in place of y and 0 in place of n): * * modprobe eata io_port=0x7410,0x230 linked_comm=1 tagged_comm=0 \ - * max_queue_depth=4 tag_mode=0 use_new_eh_code=0 \ + * max_queue_depth=4 tag_mode=0 \ * ext_tran=0 rev_scan=1 * * ---------------------------------------------------------------------------- @@ -369,7 +383,10 @@ #include <linux/version.h> +#ifndef LinuxVersionCode #define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s)) +#endif + #define MAX_INT_PARAM 10 #if defined(MODULE) @@ -382,7 +399,6 @@ MODULE_PARM(tagged_comm, "i"); MODULE_PARM(link_statistics, "i"); MODULE_PARM(max_queue_depth, "i"); MODULE_PARM(tag_mode, "i"); -MODULE_PARM(use_new_eh_code, "i"); MODULE_PARM(ext_tran, "i"); MODULE_PARM(rev_scan, "i"); MODULE_AUTHOR("Dario Ballabio"); @@ -410,12 +426,7 @@ MODULE_AUTHOR("Dario Ballabio"); #include <linux/pci.h> #include <linux/init.h> #include <linux/ctype.h> - -#if LINUX_VERSION_CODE < LinuxVersionCode(2,3,18) -#include <asm/spinlock.h> -#else #include <linux/spinlock.h> -#endif #define SPIN_FLAGS unsigned long spin_flags; #define SPIN_LOCK spin_lock_irq(&io_request_lock); @@ -501,10 +512,6 @@ MODULE_AUTHOR("Dario Ballabio"); #define ASOK 0x00 #define ASST 0x01 -#if LINUX_VERSION_CODE < LinuxVersionCode(2,3,18) -#define ARRAY_SIZE(x) (sizeof (x) / sizeof((x)[0])) -#endif - #define YESNO(a) ((a) ? 'y' : 'n') #define TLDEV(type) ((type) == TYPE_DISK || (type) == TYPE_ROM) @@ -693,7 +700,6 @@ static int link_statistics; static int tag_mode = TAG_MIXED; static int ext_tran = FALSE; static int rev_scan = TRUE; -static int use_new_eh_code = TRUE; static char *boot_options; #if defined(CONFIG_SCSI_EATA_TAGGED_QUEUE) @@ -761,9 +767,9 @@ static void select_queue_depths(struct Scsi_Host *host, Scsi_Device *devlist) { } if (dev->tagged_supported && TLDEV(dev->type) && dev->tagged_queue) - tag_suffix = ", tagged"; + tag_suffix = ", soft-tagged"; else if (dev->tagged_supported && TLDEV(dev->type)) - tag_suffix = ", untagged"; + tag_suffix = ", tagged"; printk("%s: scsi%d, channel %d, id %d, lun %d, cmds/lun %d%s%s.\n", BN(j), host->host_no, dev->channel, dev->id, dev->lun, @@ -831,7 +837,7 @@ static inline void tune_pci_port(unsigned long port_base) { addr = pci_resource_start (dev, 0); - pci_enable_device (dev); /* XXX handle error */ + if (pci_enable_device (dev)) continue; #if defined(DEBUG_PCI_DETECT) printk("%s: tune_pci_port, bus %d, devfn 0x%x, addr 0x%x.\n", @@ -1122,13 +1128,11 @@ static inline int port_detect \ } else tag_type = 'n'; - sh[j]->hostt->use_new_eh_code = use_new_eh_code; - if (j == 0) { - printk("EATA/DMA 2.0x: Copyright (C) 1994-1999 Dario Ballabio.\n"); - printk("%s config options -> tc:%c, lc:%c, mq:%d, eh:%c, rs:%c, et:%c.\n", + printk("EATA/DMA 2.0x: Copyright (C) 1994-2000 Dario Ballabio.\n"); + printk("%s config options -> tc:%c, lc:%c, mq:%d, rs:%c, et:%c.\n", driver_name, tag_type, YESNO(linked_comm), max_queue_depth, - YESNO(use_new_eh_code), YESNO(rev_scan), YESNO(ext_tran)); + YESNO(rev_scan), YESNO(ext_tran)); } printk("%s: 2.0%c, %s 0x%03lx, IRQ %u, %s, SG %d, MB %d.\n", @@ -1191,7 +1195,6 @@ static void internal_setup(char *str, int *ints) { else if (!strncmp(cur, "tm:", 3)) tag_mode = val; else if (!strncmp(cur, "mq:", 3)) max_queue_depth = val; else if (!strncmp(cur, "ls:", 3)) link_statistics = val; - else if (!strncmp(cur, "eh:", 3)) use_new_eh_code = val; else if (!strncmp(cur, "et:", 3)) ext_tran = val; else if (!strncmp(cur, "rs:", 3)) rev_scan = val; @@ -1439,79 +1442,6 @@ int eata2x_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) { return rtn; } -static inline int do_old_abort(Scsi_Cmnd *SCarg) { - unsigned int i, j; - - j = ((struct hostdata *) SCarg->host->hostdata)->board_number; - - if (SCarg->host_scribble == NULL || - (SCarg->serial_number_at_timeout && - (SCarg->serial_number != SCarg->serial_number_at_timeout))) { - printk("%s: abort, target %d.%d:%d, pid %ld inactive.\n", - BN(j), SCarg->channel, SCarg->target, SCarg->lun, SCarg->pid); - return SCSI_ABORT_NOT_RUNNING; - } - - i = *(unsigned int *)SCarg->host_scribble; - printk("%s: abort, mbox %d, target %d.%d:%d, pid %ld.\n", - BN(j), i, SCarg->channel, SCarg->target, SCarg->lun, SCarg->pid); - - if (i >= sh[j]->can_queue) - panic("%s: abort, invalid SCarg->host_scribble.\n", BN(j)); - - if (wait_on_busy(sh[j]->io_port, MAXLOOP)) { - printk("%s: abort, timeout error.\n", BN(j)); - return SCSI_ABORT_ERROR; - } - - if (HD(j)->cp_stat[i] == FREE) { - printk("%s: abort, mbox %d is free.\n", BN(j), i); - return SCSI_ABORT_NOT_RUNNING; - } - - if (HD(j)->cp_stat[i] == IN_USE) { - printk("%s: abort, mbox %d is in use.\n", BN(j), i); - - if (SCarg != HD(j)->cp[i].SCpnt) - panic("%s: abort, mbox %d, SCarg %p, cp SCpnt %p.\n", - BN(j), i, SCarg, HD(j)->cp[i].SCpnt); - - if (inb(sh[j]->io_port + REG_AUX_STATUS) & IRQ_ASSERTED) - printk("%s: abort, mbox %d, interrupt pending.\n", BN(j), i); - - return SCSI_ABORT_SNOOZE; - } - - if (HD(j)->cp_stat[i] == IN_RESET) { - printk("%s: abort, mbox %d is in reset.\n", BN(j), i); - return SCSI_ABORT_ERROR; - } - - if (HD(j)->cp_stat[i] == LOCKED) { - printk("%s: abort, mbox %d is locked.\n", BN(j), i); - return SCSI_ABORT_NOT_RUNNING; - } - - if (HD(j)->cp_stat[i] == READY || HD(j)->cp_stat[i] == ABORTING) { - SCarg->result = DID_ABORT << 16; - SCarg->host_scribble = NULL; - HD(j)->cp_stat[i] = FREE; - printk("%s, abort, mbox %d ready, DID_ABORT, pid %ld done.\n", - BN(j), i, SCarg->pid); - SCarg->scsi_done(SCarg); - return SCSI_ABORT_SUCCESS; - } - - panic("%s: abort, mbox %d, invalid cp_stat.\n", BN(j), i); -} - -int eata2x_old_abort(Scsi_Cmnd *SCarg) { - int rtn; - - rtn = do_old_abort(SCarg); - return rtn; -} - static inline int do_abort(Scsi_Cmnd *SCarg) { unsigned int i, j; @@ -1589,151 +1519,6 @@ int eata2x_abort(Scsi_Cmnd *SCarg) { return do_abort(SCarg); } -static inline int do_old_reset(Scsi_Cmnd *SCarg) { - unsigned int i, j, time, k, c, limit = 0; - int arg_done = FALSE; - Scsi_Cmnd *SCpnt; - - j = ((struct hostdata *) SCarg->host->hostdata)->board_number; - printk("%s: reset, enter, target %d.%d:%d, pid %ld.\n", - BN(j), SCarg->channel, SCarg->target, SCarg->lun, SCarg->pid); - - if (SCarg->host_scribble == NULL) - printk("%s: reset, pid %ld inactive.\n", BN(j), SCarg->pid); - - if (SCarg->serial_number_at_timeout && - (SCarg->serial_number != SCarg->serial_number_at_timeout)) { - printk("%s: reset, pid %ld, reset not running.\n", BN(j), SCarg->pid); - return SCSI_RESET_NOT_RUNNING; - } - - if (HD(j)->in_reset) { - printk("%s: reset, exit, already in reset.\n", BN(j)); - return SCSI_RESET_ERROR; - } - - if (wait_on_busy(sh[j]->io_port, MAXLOOP)) { - printk("%s: reset, exit, timeout error.\n", BN(j)); - return SCSI_RESET_ERROR; - } - - HD(j)->retries = 0; - - for (c = 0; c <= sh[j]->max_channel; c++) - for (k = 0; k < sh[j]->max_id; k++) { - HD(j)->target_redo[k][c] = TRUE; - HD(j)->target_to[k][c] = 0; - } - - for (i = 0; i < sh[j]->can_queue; i++) { - - if (HD(j)->cp_stat[i] == FREE) continue; - - if (HD(j)->cp_stat[i] == LOCKED) { - HD(j)->cp_stat[i] = FREE; - printk("%s: reset, locked mbox %d forced free.\n", BN(j), i); - continue; - } - - if (!(SCpnt = HD(j)->cp[i].SCpnt)) - panic("%s: reset, mbox %d, SCpnt == NULL.\n", BN(j), i); - - if (HD(j)->cp_stat[i] == READY || HD(j)->cp_stat[i] == ABORTING) { - HD(j)->cp_stat[i] = ABORTING; - printk("%s: reset, mbox %d aborting, pid %ld.\n", - BN(j), i, SCpnt->pid); - } - - else { - HD(j)->cp_stat[i] = IN_RESET; - printk("%s: reset, mbox %d in reset, pid %ld.\n", - BN(j), i, SCpnt->pid); - } - - if (SCpnt->host_scribble == NULL) - panic("%s: reset, mbox %d, garbled SCpnt.\n", BN(j), i); - - if (*(unsigned int *)SCpnt->host_scribble != i) - panic("%s: reset, mbox %d, index mismatch.\n", BN(j), i); - - if (SCpnt->scsi_done == NULL) - panic("%s: reset, mbox %d, SCpnt->scsi_done == NULL.\n", BN(j), i); - - if (SCpnt == SCarg) arg_done = TRUE; - } - - if (do_dma(sh[j]->io_port, 0, RESET_PIO)) { - printk("%s: reset, cannot reset, timeout error.\n", BN(j)); - return SCSI_RESET_ERROR; - } - - printk("%s: reset, board reset done, enabling interrupts.\n", BN(j)); - -#if defined(DEBUG_RESET) - do_trace = TRUE; -#endif - - HD(j)->in_reset = TRUE; - SPIN_UNLOCK - time = jiffies; - while ((jiffies - time) < (10 * HZ) && limit++ < 200000) udelay(100L); - SPIN_LOCK - printk("%s: reset, interrupts disabled, loops %d.\n", BN(j), limit); - - for (i = 0; i < sh[j]->can_queue; i++) { - - if (HD(j)->cp_stat[i] == IN_RESET) { - SCpnt = HD(j)->cp[i].SCpnt; - SCpnt->result = DID_RESET << 16; - SCpnt->host_scribble = NULL; - - /* This mailbox is still waiting for its interrupt */ - HD(j)->cp_stat[i] = LOCKED; - - printk("%s, reset, mbox %d locked, DID_RESET, pid %ld done.\n", - BN(j), i, SCpnt->pid); - } - - else if (HD(j)->cp_stat[i] == ABORTING) { - SCpnt = HD(j)->cp[i].SCpnt; - SCpnt->result = DID_RESET << 16; - SCpnt->host_scribble = NULL; - - /* This mailbox was never queued to the adapter */ - HD(j)->cp_stat[i] = FREE; - - printk("%s, reset, mbox %d aborting, DID_RESET, pid %ld done.\n", - BN(j), i, SCpnt->pid); - } - - else - - /* Any other mailbox has already been set free by interrupt */ - continue; - - SCpnt->scsi_done(SCpnt); - } - - HD(j)->in_reset = FALSE; - do_trace = FALSE; - - if (arg_done) { - printk("%s: reset, exit, success.\n", BN(j)); - return SCSI_RESET_SUCCESS; - } - else { - printk("%s: reset, exit, wakeup.\n", BN(j)); - return SCSI_RESET_PUNT; - } -} - -int eata2x_old_reset(Scsi_Cmnd *SCarg, unsigned int reset_flags) { - int rtn; - - rtn = do_old_reset(SCarg); - return rtn; -} - static inline int do_reset(Scsi_Cmnd *SCarg) { unsigned int i, j, time, k, c, limit = 0; int arg_done = FALSE; @@ -1983,7 +1768,7 @@ static inline int reorder(unsigned int j, unsigned long cursec, if (link_statistics) { if (cursec > sl[0]) iseek = cursec - sl[0]; else iseek = sl[0] - cursec; - batchcount++; readycount += n_ready, seeknosort += seek / 1024; + batchcount++; readycount += n_ready; seeknosort += seek / 1024; if (input_only) inputcount++; if (overlap) { ovlcount++; seeksorted += iseek / 1024; } else seeksorted += (iseek + maxsec - minsec) / 1024; @@ -2169,7 +1954,9 @@ static inline void ihdlr(int irq, unsigned int j) { if (tstatus == GOOD) HD(j)->target_redo[SCpnt->target][SCpnt->channel] = FALSE; - if (spp->target_status && SCpnt->device->type == TYPE_DISK) + if (spp->target_status && SCpnt->device->type == TYPE_DISK && + (!(tstatus == CHECK_CONDITION && HD(j)->iocount <= 1000 && + (SCpnt->sense_buffer[2] & 0xf) == NOT_READY))) printk("%s: ihdlr, target %d.%d:%d, pid %ld, "\ "target_status 0x%x, sense key 0x%x.\n", BN(j), SCpnt->channel, SCpnt->target, SCpnt->lun, @@ -2297,13 +2084,5 @@ static Scsi_Host_Template driver_template = EATA; #include "scsi_module.c" #ifndef MODULE - -#if LINUX_VERSION_CODE < LinuxVersionCode(2,3,18) -void eata2x_setup(char *str, int *ints) { - internal_setup(str, ints); -} -#else __setup("eata=", option_setup); -#endif - #endif /* end MODULE */ diff --git a/drivers/scsi/eata.h b/drivers/scsi/eata.h index 6c00ca0a2..5b3216e60 100644 --- a/drivers/scsi/eata.h +++ b/drivers/scsi/eata.h @@ -5,28 +5,23 @@ #define _EATA_H #include <scsi/scsicam.h> -#include <linux/version.h> int eata2x_detect(Scsi_Host_Template *); int eata2x_release(struct Scsi_Host *); int eata2x_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); int eata2x_abort(Scsi_Cmnd *); -int eata2x_old_abort(Scsi_Cmnd *); int eata2x_reset(Scsi_Cmnd *); -int eata2x_old_reset(Scsi_Cmnd *, unsigned int); int eata2x_biosparam(Disk *, kdev_t, int *); -#define EATA_VERSION "5.11.00" - -#define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s)) +#define EATA_VERSION "6.02.00" #define EATA { \ name: "EATA/DMA 2.0x rev. " EATA_VERSION " ", \ detect: eata2x_detect, \ release: eata2x_release, \ queuecommand: eata2x_queuecommand, \ - abort: eata2x_old_abort, \ - reset: eata2x_old_reset, \ + abort: NULL, \ + reset: NULL, \ eh_abort_handler: eata2x_abort, \ eh_device_reset_handler: NULL, \ eh_bus_reset_handler: NULL, \ diff --git a/drivers/scsi/gvp11.c b/drivers/scsi/gvp11.c index e6d5b2942..116ddbb58 100644 --- a/drivers/scsi/gvp11.c +++ b/drivers/scsi/gvp11.c @@ -346,7 +346,7 @@ int __init gvp11_detect(Scsi_Host_Template *tpnt) continue; release: - release_mem_region(ZTWO_PADDR(instance->base), 256); + release_mem_region(address, 256); } return num_gvp11; diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index 2b51924cf..5d4031055 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c @@ -840,7 +840,7 @@ static void __exit exit_idescsi_module(void) failed = 0; while ((drive = ide_scan_devices (media[i], idescsi_driver.name, &idescsi_driver, failed)) != NULL) if (idescsi_cleanup (drive)) { - printk ("%s: cleanup_module() called while still busy\n", drive->name); + printk ("%s: exit_idescsi_module() called while still busy\n", drive->name); failed++; } } diff --git a/drivers/scsi/imm.c b/drivers/scsi/imm.c index 61298e9c0..cdc3f8989 100644 --- a/drivers/scsi/imm.c +++ b/drivers/scsi/imm.c @@ -51,7 +51,7 @@ typedef struct { mode: IMM_AUTODETECT, \ host: -1, \ cur_cmd: NULL, \ - imm_tq: {0, 0, imm_interrupt, NULL}, \ + imm_tq: { routine: imm_interrupt }, \ jstart: 0, \ failed: 0, \ dp: 0, \ @@ -122,7 +122,14 @@ int imm_detect(Scsi_Host_Template * host) struct Scsi_Host *hreg; int ports; int i, nhosts, try_again; - struct parport *pb = parport_enumerate(); + struct parport *pb; + + /* + * unlock to allow the lowlevel parport driver to probe + * the irqs + */ + spin_unlock_irq(&io_request_lock); + pb = parport_enumerate(); printk("imm: Version %s\n", IMM_VERSION); nhosts = 0; @@ -130,6 +137,7 @@ int imm_detect(Scsi_Host_Template * host) if (!pb) { printk("imm: parport reports no devices.\n"); + spin_lock_irq(&io_request_lock); return 0; } retry_entry: @@ -154,6 +162,7 @@ int imm_detect(Scsi_Host_Template * host) printk(KERN_ERR "imm%d: failed to claim parport because a " "pardevice is owning the port for too longtime!\n", i); + spin_lock_irq(&io_request_lock); return 0; } } @@ -208,12 +217,16 @@ int imm_detect(Scsi_Host_Template * host) nhosts++; } if (nhosts == 0) { - if (try_again == 1) + if (try_again == 1) { + spin_lock_irq(&io_request_lock); return 0; + } try_again = 1; goto retry_entry; - } else + } else { + spin_lock_irq (&io_request_lock); return 1; /* return number of hosts detected */ + } } /* This is to give the imm driver a way to modify the timings (and other diff --git a/drivers/scsi/imm.h b/drivers/scsi/imm.h index 7b8c9df55..8c3d65bb8 100644 --- a/drivers/scsi/imm.h +++ b/drivers/scsi/imm.h @@ -10,7 +10,7 @@ #ifndef _IMM_H #define _IMM_H -#define IMM_VERSION "2.04 (for Linux 2.4.0)" +#define IMM_VERSION "2.05 (for Linux 2.4.0)" /* * 10 Apr 1998 (Good Friday) - Received EN144302 by email from Iomega. @@ -60,6 +60,9 @@ * added CONFIG_SCSI_IZIP_SLOW_CTR option * [2.03] * Fix kernel panic on scsi timeout. 20Aug00 [2.04] + * + * Avoid io_request_lock problems. + * John Cavan <johncavan@home.com> 16Nov00 [2.05] */ /* ------ END OF USER CONFIGURABLE PARAMETERS ----- */ diff --git a/drivers/scsi/ips.h b/drivers/scsi/ips.h index e55b26a0e..4d84fabc9 100644 --- a/drivers/scsi/ips.h +++ b/drivers/scsi/ips.h @@ -929,7 +929,7 @@ typedef struct ips_ha { char *ioctl_data; /* IOCTL data area */ u32 ioctl_datasize; /* IOCTL data size */ u32 cmd_in_progress; /* Current command in progress*/ - u32 flags; /* HA flags */ + long flags; /* HA flags */ u8 waitflag; /* are we waiting for cmd */ u8 active; u16 reset_count; /* number of resets */ diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c index 0e1dec169..264ae2fe0 100644 --- a/drivers/scsi/megaraid.c +++ b/drivers/scsi/megaraid.c @@ -194,9 +194,6 @@ MODULE_DESCRIPTION ("AMI MegaRAID driver"); *================================================================ */ -#define queue_task_irq(a,b) queue_task(a,b) -#define queue_task_irq_off(a,b) queue_task(a,b) - #define MAX_SERBUF 160 #define COM_BASE 0x2f8 diff --git a/drivers/scsi/mvme147.c b/drivers/scsi/mvme147.c new file mode 100644 index 000000000..26e3a277d --- /dev/null +++ b/drivers/scsi/mvme147.c @@ -0,0 +1,116 @@ +#include <linux/types.h> +#include <linux/mm.h> +#include <linux/blk.h> +#include <linux/sched.h> +#include <linux/version.h> + +#include <asm/page.h> +#include <asm/pgtable.h> +#include <asm/mvme147hw.h> +#include <asm/irq.h> + +#include "scsi.h" +#include "hosts.h" +#include "wd33c93.h" +#include "mvme147.h" + +#include<linux/stat.h> + +#define HDATA(ptr) ((struct WD33C93_hostdata *)((ptr)->hostdata)) + +static struct Scsi_Host *mvme147_host = NULL; + +static void mvme147_intr (int irq, void *dummy, struct pt_regs *fp) +{ + if (irq == MVME147_IRQ_SCSI_PORT) + wd33c93_intr (mvme147_host); + else + m147_pcc->dma_intr = 0x89; /* Ack and enable ints */ +} + +static int dma_setup (Scsi_Cmnd *cmd, int dir_in) +{ + unsigned char flags = 0x01; + unsigned long addr = virt_to_bus(cmd->SCp.ptr); + + /* setup dma direction */ + if (!dir_in) + flags |= 0x04; + + /* remember direction */ + HDATA(mvme147_host)->dma_dir = dir_in; + + if (dir_in) + /* invalidate any cache */ + cache_clear (addr, cmd->SCp.this_residual); + else + /* push any dirty cache */ + cache_push (addr, cmd->SCp.this_residual); + + /* start DMA */ + m147_pcc->dma_bcr = cmd->SCp.this_residual | (1<<24); + m147_pcc->dma_dadr = addr; + m147_pcc->dma_cntrl = flags; + + /* return success */ + return 0; +} + +static void dma_stop (struct Scsi_Host *instance, Scsi_Cmnd *SCpnt, + int status) +{ + m147_pcc->dma_cntrl = 0; +} + +int mvme147_detect(Scsi_Host_Template *tpnt) +{ + static unsigned char called = 0; + + if (!MACH_IS_MVME147 || called) + return 0; + called++; + + tpnt->proc_name = "MVME147"; + tpnt->proc_info = &wd33c93_proc_info; + + mvme147_host = scsi_register (tpnt, sizeof(struct WD33C93_hostdata)); + mvme147_host->base = 0xfffe4000; + mvme147_host->irq = MVME147_IRQ_SCSI_PORT; + wd33c93_init(mvme147_host, (wd33c93_regs *)0xfffe4000, + dma_setup, dma_stop, WD33C93_FS_8_10); + + request_irq(MVME147_IRQ_SCSI_PORT, mvme147_intr, 0, "MVME147 SCSI PORT", mvme147_intr); + request_irq(MVME147_IRQ_SCSI_DMA, mvme147_intr, 0, "MVME147 SCSI DMA", mvme147_intr); +#if 0 /* Disabled; causes problems booting */ + m147_pcc->scsi_interrupt = 0x10; /* Assert SCSI bus reset */ + udelay(100); + m147_pcc->scsi_interrupt = 0x00; /* Negate SCSI bus reset */ + udelay(2000); + m147_pcc->scsi_interrupt = 0x40; /* Clear bus reset interrupt */ +#endif + m147_pcc->scsi_interrupt = 0x09; /* Enable interrupt */ + + m147_pcc->dma_cntrl = 0x00; /* ensure DMA is stopped */ + m147_pcc->dma_intr = 0x89; /* Ack and enable ints */ + + return 1; +} + +#define HOSTS_C + +#include "mvme147.h" + +static Scsi_Host_Template driver_template = MVME147_SCSI; + +#include "scsi_module.c" + +int mvme147_release(struct Scsi_Host *instance) +{ +#ifdef MODULE + /* XXX Make sure DMA is stopped! */ + wd33c93_release(); + free_irq(MVME147_IRQ_SCSI_PORT, mvme147_intr); + free_irq(MVME147_IRQ_SCSI_DMA, mvme147_intr); +#endif + return 1; +} diff --git a/drivers/scsi/mvme147.h b/drivers/scsi/mvme147.h new file mode 100644 index 000000000..dabde1baf --- /dev/null +++ b/drivers/scsi/mvme147.h @@ -0,0 +1,50 @@ +#ifndef MVME147_H + +/* $Id: mvme147.h,v 1.4 1997/01/19 23:07:10 davem Exp $ + * + * Header file for the MVME147 built-in SCSI controller for Linux + * + * Written and (C) 1993, Hamish Macdonald, see mvme147.c for more info + * + */ + +#include <linux/types.h> + +int mvme147_detect(Scsi_Host_Template *); +int mvme147_release(struct Scsi_Host *); +const char *wd33c93_info(void); +int wd33c93_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); +int wd33c93_abort(Scsi_Cmnd *); +int wd33c93_reset(Scsi_Cmnd *, unsigned int); + +#ifndef NULL +#define NULL 0 +#endif + +#ifndef CMD_PER_LUN +#define CMD_PER_LUN 2 +#endif + +#ifndef CAN_QUEUE +#define CAN_QUEUE 16 +#endif + +#ifdef HOSTS_C + +#define MVME147_SCSI {proc_name: "MVME147", \ + proc_info: NULL, \ + name: "MVME147 built-in SCSI", \ + detect: mvme147_detect, \ + release: mvme147_release, \ + queuecommand: wd33c93_queuecommand, \ + abort: wd33c93_abort, \ + reset: wd33c93_reset, \ + can_queue: CAN_QUEUE, \ + this_id: 7, \ + sg_tablesize: SG_ALL, \ + cmd_per_lun: CMD_PER_LUN, \ + use_clustering: ENABLE_CLUSTERING } + +#endif /* else def HOSTS_C */ + +#endif /* MVME147_H */ diff --git a/drivers/scsi/ppa.c b/drivers/scsi/ppa.c index 661316cac..e85391bd1 100644 --- a/drivers/scsi/ppa.c +++ b/drivers/scsi/ppa.c @@ -41,7 +41,7 @@ typedef struct { mode: PPA_AUTODETECT, \ host: -1, \ cur_cmd: NULL, \ - ppa_tq: {0, 0, ppa_interrupt, NULL}, \ + ppa_tq: { routine: ppa_interrupt }, \ jstart: 0, \ failed: 0, \ p_busy: 0 \ @@ -111,7 +111,14 @@ int ppa_detect(Scsi_Host_Template * host) struct Scsi_Host *hreg; int ports; int i, nhosts, try_again; - struct parport *pb = parport_enumerate(); + struct parport *pb; + + /* + * unlock to allow the lowlevel parport driver to probe + * the irqs + */ + spin_unlock_irq(&io_request_lock); + pb = parport_enumerate(); printk("ppa: Version %s\n", PPA_VERSION); nhosts = 0; @@ -119,6 +126,7 @@ int ppa_detect(Scsi_Host_Template * host) if (!pb) { printk("ppa: parport reports no devices.\n"); + spin_lock_irq(&io_request_lock); return 0; } retry_entry: @@ -143,6 +151,7 @@ int ppa_detect(Scsi_Host_Template * host) printk(KERN_ERR "ppa%d: failed to claim parport because a " "pardevice is owning the port for too longtime!\n", i); + spin_lock_irq(&io_request_lock); return 0; } } @@ -212,11 +221,14 @@ int ppa_detect(Scsi_Host_Template * host) printk(" cable is marked with \"AutoDetect\", this is what has\n"); printk(" happened.\n"); return 0; + spin_lock_irq(&io_request_lock); } try_again = 1; goto retry_entry; - } else + } else { + spin_lock_irq(&io_request_lock); return 1; /* return number of hosts detected */ + } } /* This is to give the ppa driver a way to modify the timings (and other diff --git a/drivers/scsi/ppa.h b/drivers/scsi/ppa.h index 74147c329..0c03366dc 100644 --- a/drivers/scsi/ppa.h +++ b/drivers/scsi/ppa.h @@ -10,7 +10,7 @@ #ifndef _PPA_H #define _PPA_H -#define PPA_VERSION "2.05 (for Linux 2.2.x)" +#define PPA_VERSION "2.06 (for Linux 2.2.x)" /* * this driver has been hacked by Matteo Frigo (athena@theory.lcs.mit.edu) @@ -58,6 +58,9 @@ * Tim Waugh <twaugh@redhat.com> * [2.04] * Fix kernel panic on scsi timeout, 2000-08-18 [2.05] + * + * Avoid io_request_lock problems. + * John Cavan <johncavan@home.com> [2.06] */ /* ------ END OF USER CONFIGURABLE PARAMETERS ----- */ diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c index 12c0c9256..50db38c97 100644 --- a/drivers/scsi/qla1280.c +++ b/drivers/scsi/qla1280.c @@ -312,7 +312,7 @@ STATIC void qla1280_abort_queue_single(scsi_qla_host_t *,uint32_t,uint32_t,uint3 STATIC int qla1280_return_status( sts_entry_t *sts, Scsi_Cmnd *cp); STATIC void qla1280_removeq(scsi_lu_t *q, srb_t *sp); STATIC void qla1280_mem_free(scsi_qla_host_t *ha); -void qla1280_do_dpc(void *p); +static void qla1280_do_dpc(void *p); #ifdef QLA1280_UNUSED static void qla1280_set_flags(char * s); #endif @@ -1082,7 +1082,8 @@ qla1280_queuecommand(Scsi_Cmnd *cmd, void (*fn)(Scsi_Cmnd *)) { CMD_RESULT(cmd) = (int) (DID_BUS_BUSY << 16); qla1280_done_q_put(sp, &ha->done_q_first, &ha->done_q_last); - queue_task(&ha->run_qla_bh,&tq_scheduler); + + schedule_task(&ha->run_qla_bh); ha->flags.dpc_sched = TRUE; DRIVER_UNLOCK return(0); @@ -1580,7 +1581,7 @@ void qla1280_intr_handler(int irq, void *dev_id, struct pt_regs *regs) ha->run_qla_bh.routine = qla1280_do_dpc; COMTRACE('P') - queue_task_irq(&ha->run_qla_bh,&tq_scheduler); + schedule_task(&ha->run_qla_bh); ha->flags.dpc_sched = TRUE; } clear_bit(QLA1280_IN_ISR_BIT, (int *)&ha->flags); @@ -1604,7 +1605,7 @@ void qla1280_intr_handler(int irq, void *dev_id, struct pt_regs *regs) * "host->can_queue". This can cause a panic if we were in our interrupt * code . **************************************************************************/ -void qla1280_do_dpc(void *p) +static void qla1280_do_dpc(void *p) { scsi_qla_host_t *ha = (scsi_qla_host_t *) p; #if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,95) diff --git a/drivers/scsi/u14-34f.c b/drivers/scsi/u14-34f.c index c99853935..0aa622002 100644 --- a/drivers/scsi/u14-34f.c +++ b/drivers/scsi/u14-34f.c @@ -1,12 +1,20 @@ /* * u14-34f.c - Low-level driver for UltraStor 14F/34F SCSI host adapters. * + * 01 Nov 2000 Rev. 6.02 for linux 2.4.0-test11 + * + Removed old scsi error handling support. + * + The obsolete boot option flag eh:n is silently ignored. + * + Removed error messages while a disk drive is powered up at + * boot time. + * + Improved boot messages: all tagged capable device are + * indicated as "tagged". + * * 16 Sep 1999 Rev. 5.11 for linux 2.2.12 and 2.3.18 * + Updated to the new __setup interface for boot command line options. * + When loaded as a module, accepts the new parameter boot_options * which value is a string with the same format of the kernel boot * command line options. A valid example is: - * modprobe u14-34f 'boot_options=\"0x230,0x340,lc:y,mq:4\"' + * modprobe u14-34f boot_options=\"0x230,0x340,lc:y,mq:4\" * * 22 Jul 1999 Rev. 5.00 for linux 2.2.10 and 2.3.11 * + Removed pre-2.2 source code compatibility. @@ -169,7 +177,9 @@ * * Multiple U14F and/or U34F host adapters are supported. * - * Copyright (C) 1994-1999 Dario Ballabio (dario@milano.europe.dg.com) + * Copyright (C) 1994-2000 Dario Ballabio (ballabio_dario@emc.com) + * + * Alternate email: dario.ballabio@inwind.it, dario.ballabio@tiscalinet.it * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that redistributions of source @@ -261,8 +271,6 @@ * After the optional list of detection probes, other possible command line * options are: * - * eh:y use new scsi code; - * eh:n use old scsi code; * et:y use disk geometry returned by scsicam_bios_param; * et:n use disk geometry jumpered on the board; * lc:y enables linked commands; @@ -273,13 +281,13 @@ * * The default value is: "u14-34f=lc:n,of:n,mq:8,et:n". * An example using the list of detection probes could be: - * "u14-34f=0x230,0x340,lc:y,of:n,mq:4,eh:n,et:n". + * "u14-34f=0x230,0x340,lc:y,of:n,mq:4,et:n". * * When loading as a module, parameters can be specified as well. * The above example would be (use 1 in place of y and 0 in place of n): * * modprobe u14-34f io_port=0x230,0x340 linked_comm=1 have_old_firmware=0 \ - * max_queue_depth=4 use_new_eh_code=0 ext_tran=0 + * max_queue_depth=4 ext_tran=0 * * ---------------------------------------------------------------------------- * In this implementation, linked commands are designed to work with any DISK @@ -322,7 +330,10 @@ #include <linux/version.h> +#ifndef LinuxVersionCode #define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s)) +#endif + #define MAX_INT_PARAM 10 #if defined(MODULE) @@ -334,7 +345,6 @@ MODULE_PARM(linked_comm, "i"); MODULE_PARM(have_old_firmware, "i"); MODULE_PARM(link_statistics, "i"); MODULE_PARM(max_queue_depth, "i"); -MODULE_PARM(use_new_eh_code, "i"); MODULE_PARM(ext_tran, "i"); MODULE_AUTHOR("Dario Ballabio"); @@ -360,12 +370,7 @@ MODULE_AUTHOR("Dario Ballabio"); #include <linux/config.h> #include <linux/init.h> #include <linux/ctype.h> - -#if LINUX_VERSION_CODE < LinuxVersionCode(2,3,18) -#include <asm/spinlock.h> -#else #include <linux/spinlock.h> -#endif #define SPIN_FLAGS unsigned long spin_flags; #define SPIN_LOCK spin_lock_irq(&io_request_lock); @@ -450,10 +455,6 @@ MODULE_AUTHOR("Dario Ballabio"); #define ASOK 0x00 #define ASST 0x91 -#if LINUX_VERSION_CODE < LinuxVersionCode(2,3,18) -#define ARRAY_SIZE(x) (sizeof (x) / sizeof((x)[0])) -#endif - #define YESNO(a) ((a) ? 'y' : 'n') #define TLDEV(type) ((type) == TYPE_DISK || (type) == TYPE_ROM) @@ -554,10 +555,9 @@ static void do_interrupt_handler(int, void *, struct pt_regs *); static void flush_dev(Scsi_Device *, unsigned long, unsigned int, unsigned int); static int do_trace = FALSE; static int setup_done = FALSE; -static int link_statistics = 0; +static int link_statistics; static int ext_tran = FALSE; -static int use_new_eh_code = TRUE; -static char *boot_options = NULL; +static char *boot_options; #if defined(HAVE_OLD_UX4F_FIRMWARE) static int have_old_firmware = TRUE; @@ -619,9 +619,9 @@ static void select_queue_depths(struct Scsi_Host *host, Scsi_Device *devlist) { } if (dev->tagged_supported && TLDEV(dev->type) && dev->tagged_queue) - tag_suffix = ", tagged"; + tag_suffix = ", soft-tagged"; else if (dev->tagged_supported && TLDEV(dev->type)) - tag_suffix = ", untagged"; + tag_suffix = ", tagged"; printk("%s: scsi%d, channel %d, id %d, lun %d, cmds/lun %d%s%s.\n", BN(j), host->host_no, dev->channel, dev->id, dev->lun, @@ -766,8 +766,6 @@ static inline int port_detect \ if (have_old_firmware) tpnt->use_clustering = DISABLE_CLUSTERING; - tpnt->use_new_eh_code = use_new_eh_code; - sh[j] = scsi_register(tpnt, sizeof(struct hostdata)); if (sh[j] == NULL) { @@ -875,10 +873,10 @@ static inline int port_detect \ if (max_queue_depth < MAX_CMD_PER_LUN) max_queue_depth = MAX_CMD_PER_LUN; if (j == 0) { - printk("UltraStor 14F/34F: Copyright (C) 1994-1999 Dario Ballabio.\n"); - printk("%s config options -> of:%c, lc:%c, mq:%d, eh:%c, et:%c.\n", + printk("UltraStor 14F/34F: Copyright (C) 1994-2000 Dario Ballabio.\n"); + printk("%s config options -> of:%c, lc:%c, mq:%d, et:%c.\n", driver_name, YESNO(have_old_firmware), YESNO(linked_comm), - max_queue_depth, YESNO(use_new_eh_code), YESNO(ext_tran)); + max_queue_depth, YESNO(ext_tran)); } printk("%s: %s 0x%03lx, BIOS 0x%05x, IRQ %u, %s, SG %d, MB %d.\n", @@ -921,7 +919,6 @@ static void internal_setup(char *str, int *ints) { else if (!strncmp(cur, "of:", 3)) have_old_firmware = val; else if (!strncmp(cur, "mq:", 3)) max_queue_depth = val; else if (!strncmp(cur, "ls:", 3)) link_statistics = val; - else if (!strncmp(cur, "eh:", 3)) use_new_eh_code = val; else if (!strncmp(cur, "et:", 3)) ext_tran = val; if ((cur = strchr(cur, ','))) ++cur; @@ -1112,79 +1109,6 @@ int u14_34f_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) { return rtn; } -static inline int do_old_abort(Scsi_Cmnd *SCarg) { - unsigned int i, j; - - j = ((struct hostdata *) SCarg->host->hostdata)->board_number; - - if (SCarg->host_scribble == NULL || - (SCarg->serial_number_at_timeout && - (SCarg->serial_number != SCarg->serial_number_at_timeout))) { - printk("%s: abort, target %d.%d:%d, pid %ld inactive.\n", - BN(j), SCarg->channel, SCarg->target, SCarg->lun, SCarg->pid); - return SCSI_ABORT_NOT_RUNNING; - } - - i = *(unsigned int *)SCarg->host_scribble; - printk("%s: abort, mbox %d, target %d.%d:%d, pid %ld.\n", - BN(j), i, SCarg->channel, SCarg->target, SCarg->lun, SCarg->pid); - - if (i >= sh[j]->can_queue) - panic("%s: abort, invalid SCarg->host_scribble.\n", BN(j)); - - if (wait_on_busy(sh[j]->io_port, MAXLOOP)) { - printk("%s: abort, timeout error.\n", BN(j)); - return SCSI_ABORT_ERROR; - } - - if (HD(j)->cp_stat[i] == FREE) { - printk("%s: abort, mbox %d is free.\n", BN(j), i); - return SCSI_ABORT_NOT_RUNNING; - } - - if (HD(j)->cp_stat[i] == IN_USE) { - printk("%s: abort, mbox %d is in use.\n", BN(j), i); - - if (SCarg != HD(j)->cp[i].SCpnt) - panic("%s: abort, mbox %d, SCarg %p, cp SCpnt %p.\n", - BN(j), i, SCarg, HD(j)->cp[i].SCpnt); - - if (inb(sh[j]->io_port + REG_SYS_INTR) & IRQ_ASSERTED) - printk("%s: abort, mbox %d, interrupt pending.\n", BN(j), i); - - return SCSI_ABORT_SNOOZE; - } - - if (HD(j)->cp_stat[i] == IN_RESET) { - printk("%s: abort, mbox %d is in reset.\n", BN(j), i); - return SCSI_ABORT_ERROR; - } - - if (HD(j)->cp_stat[i] == LOCKED) { - printk("%s: abort, mbox %d is locked.\n", BN(j), i); - return SCSI_ABORT_NOT_RUNNING; - } - - if (HD(j)->cp_stat[i] == READY || HD(j)->cp_stat[i] == ABORTING) { - SCarg->result = DID_ABORT << 16; - SCarg->host_scribble = NULL; - HD(j)->cp_stat[i] = FREE; - printk("%s, abort, mbox %d ready, DID_ABORT, pid %ld done.\n", - BN(j), i, SCarg->pid); - SCarg->scsi_done(SCarg); - return SCSI_ABORT_SUCCESS; - } - - panic("%s: abort, mbox %d, invalid cp_stat.\n", BN(j), i); -} - -int u14_34f_old_abort(Scsi_Cmnd *SCarg) { - int rtn; - - rtn = do_old_abort(SCarg); - return rtn; -} - static inline int do_abort(Scsi_Cmnd *SCarg) { unsigned int i, j; @@ -1262,152 +1186,6 @@ int u14_34f_abort(Scsi_Cmnd *SCarg) { return do_abort(SCarg); } -static inline int do_old_reset(Scsi_Cmnd *SCarg) { - unsigned int i, j, time, k, c, limit = 0; - int arg_done = FALSE; - Scsi_Cmnd *SCpnt; - - j = ((struct hostdata *) SCarg->host->hostdata)->board_number; - printk("%s: reset, enter, target %d.%d:%d, pid %ld.\n", - BN(j), SCarg->channel, SCarg->target, SCarg->lun, SCarg->pid); - - if (SCarg->host_scribble == NULL) - printk("%s: reset, pid %ld inactive.\n", BN(j), SCarg->pid); - - if (SCarg->serial_number_at_timeout && - (SCarg->serial_number != SCarg->serial_number_at_timeout)) { - printk("%s: reset, pid %ld, reset not running.\n", BN(j), SCarg->pid); - return SCSI_RESET_NOT_RUNNING; - } - - if (HD(j)->in_reset) { - printk("%s: reset, exit, already in reset.\n", BN(j)); - return SCSI_RESET_ERROR; - } - - if (wait_on_busy(sh[j]->io_port, MAXLOOP)) { - printk("%s: reset, exit, timeout error.\n", BN(j)); - return SCSI_RESET_ERROR; - } - - HD(j)->retries = 0; - - for (c = 0; c <= sh[j]->max_channel; c++) - for (k = 0; k < sh[j]->max_id; k++) { - HD(j)->target_redo[k][c] = TRUE; - HD(j)->target_to[k][c] = 0; - } - - for (i = 0; i < sh[j]->can_queue; i++) { - - if (HD(j)->cp_stat[i] == FREE) continue; - - if (HD(j)->cp_stat[i] == LOCKED) { - HD(j)->cp_stat[i] = FREE; - printk("%s: reset, locked mbox %d forced free.\n", BN(j), i); - continue; - } - - if (!(SCpnt = HD(j)->cp[i].SCpnt)) - panic("%s: reset, mbox %d, SCpnt == NULL.\n", BN(j), i); - - if (HD(j)->cp_stat[i] == READY || HD(j)->cp_stat[i] == ABORTING) { - HD(j)->cp_stat[i] = ABORTING; - printk("%s: reset, mbox %d aborting, pid %ld.\n", - BN(j), i, SCpnt->pid); - } - - else { - HD(j)->cp_stat[i] = IN_RESET; - printk("%s: reset, mbox %d in reset, pid %ld.\n", - BN(j), i, SCpnt->pid); - } - - if (SCpnt->host_scribble == NULL) - panic("%s: reset, mbox %d, garbled SCpnt.\n", BN(j), i); - - if (*(unsigned int *)SCpnt->host_scribble != i) - panic("%s: reset, mbox %d, index mismatch.\n", BN(j), i); - - if (SCpnt->scsi_done == NULL) - panic("%s: reset, mbox %d, SCpnt->scsi_done == NULL.\n", BN(j), i); - - if (SCpnt == SCarg) arg_done = TRUE; - } - - if (wait_on_busy(sh[j]->io_port, MAXLOOP)) { - printk("%s: reset, cannot reset, timeout error.\n", BN(j)); - return SCSI_RESET_ERROR; - } - - outb(CMD_RESET, sh[j]->io_port + REG_LCL_INTR); - printk("%s: reset, board reset done, enabling interrupts.\n", BN(j)); - -#if defined(DEBUG_RESET) - do_trace = TRUE; -#endif - - HD(j)->in_reset = TRUE; - SPIN_UNLOCK - time = jiffies; - while ((jiffies - time) < (10 * HZ) && limit++ < 200000) udelay(100L); - SPIN_LOCK - printk("%s: reset, interrupts disabled, loops %d.\n", BN(j), limit); - - for (i = 0; i < sh[j]->can_queue; i++) { - - if (HD(j)->cp_stat[i] == IN_RESET) { - SCpnt = HD(j)->cp[i].SCpnt; - SCpnt->result = DID_RESET << 16; - SCpnt->host_scribble = NULL; - - /* This mailbox is still waiting for its interrupt */ - HD(j)->cp_stat[i] = LOCKED; - - printk("%s, reset, mbox %d locked, DID_RESET, pid %ld done.\n", - BN(j), i, SCpnt->pid); - } - - else if (HD(j)->cp_stat[i] == ABORTING) { - SCpnt = HD(j)->cp[i].SCpnt; - SCpnt->result = DID_RESET << 16; - SCpnt->host_scribble = NULL; - - /* This mailbox was never queued to the adapter */ - HD(j)->cp_stat[i] = FREE; - - printk("%s, reset, mbox %d aborting, DID_RESET, pid %ld done.\n", - BN(j), i, SCpnt->pid); - } - - else - - /* Any other mailbox has already been set free by interrupt */ - continue; - - SCpnt->scsi_done(SCpnt); - } - - HD(j)->in_reset = FALSE; - do_trace = FALSE; - - if (arg_done) { - printk("%s: reset, exit, success.\n", BN(j)); - return SCSI_RESET_SUCCESS; - } - else { - printk("%s: reset, exit, wakeup.\n", BN(j)); - return SCSI_RESET_PUNT; - } -} - -int u14_34f_old_reset(Scsi_Cmnd *SCarg, unsigned int reset_flags) { - int rtn; - - rtn = do_old_reset(SCarg); - return rtn; -} - static inline int do_reset(Scsi_Cmnd *SCarg) { unsigned int i, j, time, k, c, limit = 0; int arg_done = FALSE; @@ -1663,7 +1441,7 @@ static inline int reorder(unsigned int j, unsigned long cursec, if (link_statistics) { if (cursec > sl[0]) iseek = cursec - sl[0]; else iseek = sl[0] - cursec; - batchcount++; readycount += n_ready, seeknosort += seek / 1024; + batchcount++; readycount += n_ready; seeknosort += seek / 1024; if (input_only) inputcount++; if (overlap) { ovlcount++; seeksorted += iseek / 1024; } else seeksorted += (iseek + maxsec - minsec) / 1024; @@ -1837,7 +1615,9 @@ static inline void ihdlr(int irq, unsigned int j) { if (tstatus == GOOD) HD(j)->target_redo[SCpnt->target][SCpnt->channel] = FALSE; - if (spp->target_status && SCpnt->device->type == TYPE_DISK) + if (spp->target_status && SCpnt->device->type == TYPE_DISK && + (!(tstatus == CHECK_CONDITION && HD(j)->iocount <= 1000 && + (SCpnt->sense_buffer[2] & 0xf) == NOT_READY))) printk("%s: ihdlr, target %d.%d:%d, pid %ld, "\ "target_status 0x%x, sense key 0x%x.\n", BN(j), SCpnt->channel, SCpnt->target, SCpnt->lun, @@ -1969,13 +1749,5 @@ static Scsi_Host_Template driver_template = ULTRASTOR_14_34F; #include "scsi_module.c" #ifndef MODULE - -#if LINUX_VERSION_CODE < LinuxVersionCode(2,3,18) -void u14_34f_setup(char *str, int *ints) { - internal_setup(str, ints); -} -#else __setup("u14-34f=", option_setup); -#endif - #endif /* end MODULE */ diff --git a/drivers/scsi/u14-34f.h b/drivers/scsi/u14-34f.h index ff49b56ea..5e481ea40 100644 --- a/drivers/scsi/u14-34f.h +++ b/drivers/scsi/u14-34f.h @@ -5,30 +5,23 @@ #define _U14_34F_H #include <scsi/scsicam.h> -#include <linux/version.h> int u14_34f_detect(Scsi_Host_Template *); int u14_34f_release(struct Scsi_Host *); int u14_34f_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); int u14_34f_abort(Scsi_Cmnd *); -int u14_34f_old_abort(Scsi_Cmnd *); int u14_34f_reset(Scsi_Cmnd *); -int u14_34f_old_reset(Scsi_Cmnd *, unsigned int); int u14_34f_biosparam(Disk *, kdev_t, int *); -#define U14_34F_VERSION "5.11.00" - -#ifndef LinuxVersionCode -#define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s)) -#endif +#define U14_34F_VERSION "6.02.00" #define ULTRASTOR_14_34F { \ name: "UltraStor 14F/34F rev. " U14_34F_VERSION " ", \ detect: u14_34f_detect, \ release: u14_34f_release, \ queuecommand: u14_34f_queuecommand, \ - abort: u14_34f_old_abort, \ - reset: u14_34f_old_reset, \ + abort: NULL, \ + reset: NULL, \ eh_abort_handler: u14_34f_abort, \ eh_device_reset_handler: NULL, \ eh_bus_reset_handler: NULL, \ diff --git a/drivers/scsi/wd33c93.c b/drivers/scsi/wd33c93.c index 9d6d45e03..bed2b06a2 100644 --- a/drivers/scsi/wd33c93.c +++ b/drivers/scsi/wd33c93.c @@ -66,8 +66,14 @@ * this thing into as good a shape as possible, and I'm positive * there are lots of lurking bugs and "Stupid Places". * + * Updates: + * + * Added support for pre -A chips, which don't have advanced features + * and will generate CSR_RESEL rather than CSR_RESEL_AM. + * Richard Hirst <richard@sleepie.demon.co.uk> August 2000 */ +#include <linux/config.h> #include <linux/module.h> #include <asm/system.h> @@ -1249,11 +1255,16 @@ DB(DB_INTR,printk(":%d",cmd->SCp.Status)) case CSR_RESEL_AM: -DB(DB_INTR,printk("RESEL")) - - /* First we have to make sure this reselection didn't */ - /* happen during Arbitration/Selection of some other device. */ - /* If yes, put losing command back on top of input_Q. */ + case CSR_RESEL: +DB(DB_INTR,printk("RESEL%s", sr == CSR_RESEL_AM ? "_AM" : "")) + + /* Old chips (pre -A ???) don't have advanced features and will + * generate CSR_RESEL. In that case we have to extract the LUN the + * hard way (see below). + * First we have to make sure this reselection didn't + * happen during Arbitration/Selection of some other device. + * If yes, put losing command back on top of input_Q. + */ if (hostdata->level2 <= L2_NONE) { @@ -1293,10 +1304,53 @@ DB(DB_INTR,printk("RESEL")) * not the right way to go, but...) */ - lun = read_wd33c93(regp, WD_DATA); - if (hostdata->level2 < L2_RESELECT) - write_wd33c93_cmd(regp,WD_CMD_NEGATE_ACK); - lun &= 7; + if (sr == CSR_RESEL_AM) { + lun = read_wd33c93(regp, WD_DATA); + if (hostdata->level2 < L2_RESELECT) + write_wd33c93_cmd(regp,WD_CMD_NEGATE_ACK); + lun &= 7; + } + else { + /* Old chip; wait for msgin phase to pick up the LUN. */ + for (lun = 255; lun; lun--) { + if ((asr = READ_AUX_STAT()) & ASR_INT) + break; + udelay(10); + } + if (!(asr & ASR_INT)) { + printk("wd33c93: Reselected without IDENTIFY\n"); + lun = 0; + } + else { + /* Verify this is a change to MSG_IN and read the message */ + sr = read_wd33c93(regp, WD_SCSI_STATUS); + if (sr == (CSR_ABORT | PHS_MESS_IN) || + sr == (CSR_UNEXP | PHS_MESS_IN) || + sr == (CSR_SRV_REQ | PHS_MESS_IN)) { + /* Got MSG_IN, grab target LUN */ + lun = read_1_byte(regp); + /* Now we expect a 'paused with ACK asserted' int.. */ + asr = READ_AUX_STAT(); + if (!(asr & ASR_INT)) { + udelay(10); + asr = READ_AUX_STAT(); + if (!(asr & ASR_INT)) + printk("wd33c93: No int after LUN on RESEL (%02x)\n", + asr); + } + sr = read_wd33c93(regp, WD_SCSI_STATUS); + if (sr != CSR_MSGIN) + printk("wd33c93: Not paused with ACK on RESEL (%02x)\n", + sr); + lun &= 7; + write_wd33c93_cmd(regp,WD_CMD_NEGATE_ACK); + } + else { + printk("wd33c93: Not MSG_IN on reselect (%02x)\n", sr); + lun = 0; + } + } + } /* Now we look for the command that's reconnecting. */ @@ -1391,6 +1445,9 @@ extern void sgiwd93_reset(unsigned long); write_wd33c93(regp, WD_SYNCHRONOUS_TRANSFER, calc_sync_xfer(hostdata->default_sx_per/4,DEFAULT_SX_OFF)); write_wd33c93(regp, WD_COMMAND, WD_CMD_RESET); +#ifdef CONFIG_MVME147_SCSI + udelay(25); /* The old wd33c93 on MVME147 needs this, at least */ +#endif while (!(READ_AUX_STAT() & ASR_INT)) ; diff --git a/drivers/scsi/wd33c93.h b/drivers/scsi/wd33c93.h index 203c7d980..83e131918 100644 --- a/drivers/scsi/wd33c93.h +++ b/drivers/scsi/wd33c93.h @@ -190,7 +190,9 @@ /* This is what the 3393 chip looks like to us */ typedef struct { volatile unsigned char SASR; +#if !defined(CONFIG_MVME147_SCSI) char pad; +#endif #ifdef CONFIG_SGI_IP22 char pad2,pad3; #endif @@ -341,5 +343,6 @@ int wd33c93_queuecommand (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *)); void wd33c93_intr (struct Scsi_Host *instance); int wd33c93_proc_info(char *, char **, off_t, int, int, int); int wd33c93_reset (Scsi_Cmnd *, unsigned int); +void wd33c93_release(void); #endif /* WD33C93_H */ |