diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-01-11 18:07:41 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-01-11 18:07:41 -0800 |
commit | aae7d141676c5d83dbc97732f1cf48839f404774 (patch) | |
tree | 3fc97207fa257a4fd8b0f5893e76d515fe96095d /drivers | |
parent | 8d3f522381071d2847aea15f0ef5ac66c9a3c93a (diff) | |
parent | e47da19362bec6bc9d7e17a599cc9eb6fd144eed (diff) | |
download | history-aae7d141676c5d83dbc97732f1cf48839f404774.tar.gz |
Merge bk://linux-scsi.bkbits.net/scsi-for-linus-2.6
into ppc970.osdl.org:/home/torvalds/v2.6/linux
Diffstat (limited to 'drivers')
39 files changed, 1523 insertions, 2179 deletions
diff --git a/drivers/block/scsi_ioctl.c b/drivers/block/scsi_ioctl.c index 1fe57c940d2e62..cdb11fc7ad2513 100644 --- a/drivers/block/scsi_ioctl.c +++ b/drivers/block/scsi_ioctl.c @@ -339,7 +339,8 @@ static int sg_scsi_ioctl(struct file *file, request_queue_t *q, struct gendisk *bd_disk, Scsi_Ioctl_Command __user *sic) { struct request *rq; - int err, in_len, out_len, bytes, opcode, cmdlen; + int err; + unsigned int in_len, out_len, bytes, opcode, cmdlen; char *buffer = NULL, sense[SCSI_SENSE_BUFFERSIZE]; /* diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index f53956f77f283e..a379bc9a1276b7 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c @@ -768,28 +768,6 @@ void aac_printf(struct aac_dev *dev, u32 val) memset(cp, 0, 256); } - -/** - * aac_handle_aif - Handle a message from the firmware - * @dev: Which adapter this fib is from - * @fibptr: Pointer to fibptr from adapter - * - * This routine handles a driver notify fib from the adapter and - * dispatches it to the appropriate routine for handling. - */ - -static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr) -{ - struct hw_fib * hw_fib = fibptr->hw_fib; - /* - * Set the status of this FIB to be Invalid parameter. - * - * *(u32 *)fib->data = ST_INVAL; - */ - *(u32 *)hw_fib->data = cpu_to_le32(ST_OK); - fib_adapter_complete(fibptr, sizeof(u32)); -} - /** * aac_command_thread - command processing thread * @dev: Adapter to monitor @@ -859,7 +837,6 @@ int aac_command_thread(struct aac_dev * dev) aifcmd = (struct aac_aifcmd *) hw_fib->data; if (aifcmd->command == cpu_to_le32(AifCmdDriverNotify)) { /* Handle Driver Notify Events */ - aac_handle_aif(dev, fib); *(u32 *)hw_fib->data = cpu_to_le32(ST_OK); fib_adapter_complete(fib, sizeof(u32)); } else { @@ -870,10 +847,6 @@ int aac_command_thread(struct aac_dev * dev) u32 time_now, time_last; unsigned long flagv; - /* Sniff events */ - if (aifcmd->command == cpu_to_le32(AifCmdEventNotify)) - aac_handle_aif(dev, fib); - time_now = jiffies/HZ; spin_lock_irqsave(&dev->fib_lock, flagv); diff --git a/drivers/scsi/aic7xxx/aic7770_osm.c b/drivers/scsi/aic7xxx/aic7770_osm.c index d97a8b137fe050..c2b47f2bdffdf4 100644 --- a/drivers/scsi/aic7xxx/aic7770_osm.c +++ b/drivers/scsi/aic7xxx/aic7770_osm.c @@ -125,14 +125,8 @@ ahc_linux_eisa_init(void) uint32_t eisa_id; size_t id_size; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) - if (check_region(eisaBase, AHC_EISA_IOSIZE) != 0) - continue; - request_region(eisaBase, AHC_EISA_IOSIZE, "aic7xxx"); -#else if (request_region(eisaBase, AHC_EISA_IOSIZE, "aic7xxx") == 0) continue; -#endif eisa_id = 0; id_size = sizeof(eisa_id); @@ -207,14 +201,8 @@ aic7770_map_registers(struct ahc_softc *ahc, u_int port) /* * Lock out other contenders for our i/o space. */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) - if (check_region(port, AHC_EISA_IOSIZE) != 0) - return (ENOMEM); - request_region(port, AHC_EISA_IOSIZE, "aic7xxx"); -#else if (request_region(port, AHC_EISA_IOSIZE, "aic7xxx") == 0) return (ENOMEM); -#endif ahc->tag = BUS_SPACE_PIO; ahc->bsh.ioport = port; return (0); diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.h b/drivers/scsi/aic7xxx/aic7xxx_osm.h index 539ae081f15303..db3bd6321dd4b2 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.h +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.h @@ -831,8 +831,6 @@ static inline void ahc_linux_eisa_exit(void) { /******************************* PCI Routines *********************************/ #ifdef CONFIG_PCI -void ahc_power_state_change(struct ahc_softc *ahc, - ahc_power_state new_state); int ahc_linux_pci_init(void); void ahc_linux_pci_exit(void); int ahc_pci_map_registers(struct ahc_softc *ahc); diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c b/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c index 49d799ac61e8c4..6f6674aa31ef43 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c +++ b/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c @@ -42,12 +42,6 @@ #include "aic7xxx_osm.h" #include "aic7xxx_pci.h" -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) -struct pci_device_id -{ -}; -#endif - static int ahc_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent); static int ahc_linux_pci_reserve_io_region(struct ahc_softc *ahc, @@ -55,7 +49,6 @@ static int ahc_linux_pci_reserve_io_region(struct ahc_softc *ahc, static int ahc_linux_pci_reserve_mem_region(struct ahc_softc *ahc, u_long *bus_addr, uint8_t __iomem **maddr); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) static void ahc_linux_pci_dev_remove(struct pci_dev *pdev); /* Define the macro locally since it's different for different class of chips. @@ -169,7 +162,6 @@ ahc_linux_pci_dev_remove(struct pci_dev *pdev) } else ahc_list_unlock(&l); } -#endif /* !LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) */ static int ahc_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent) @@ -219,7 +211,6 @@ ahc_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ahc = ahc_alloc(NULL, name); if (ahc == NULL) return (-ENOMEM); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) if (pci_enable_device(pdev)) { ahc_free(ahc); return (-ENODEV); @@ -238,14 +229,12 @@ ahc_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent) } ahc->platform_data->hw_dma_mask = DMA_32BIT_MASK; } -#endif ahc->dev_softc = pci; error = ahc_pci_config(ahc, entry); if (error != 0) { ahc_free(ahc); return (-error); } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) pci_set_drvdata(pdev, ahc); if (aic7xxx_detect_complete) { #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) @@ -256,39 +245,14 @@ ahc_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent) return (-ENODEV); #endif } -#endif return (0); } int ahc_linux_pci_init(void) { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) /* Translate error or zero return into zero or one */ return pci_module_init(&aic7xxx_pci_driver) ? 0 : 1; -#else - struct pci_dev *pdev; - u_int class; - int found; - - /* If we don't have a PCI bus, we can't find any adapters. */ - if (pci_present() == 0) - return (0); - - found = 0; - pdev = NULL; - class = PCI_CLASS_STORAGE_SCSI << 8; - while ((pdev = pci_find_class(class, pdev)) != NULL) { - ahc_dev_softc_t pci; - int error; - - pci = pdev; - error = ahc_linux_pci_dev_probe(pdev, /*pci_devid*/NULL); - if (error == 0) - found++; - } - return (found); -#endif } void @@ -303,22 +267,11 @@ ahc_linux_pci_reserve_io_region(struct ahc_softc *ahc, u_long *base) if (aic7xxx_allow_memio == 0) return (ENOMEM); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) *base = pci_resource_start(ahc->dev_softc, 0); -#else - *base = ahc_pci_read_config(ahc->dev_softc, PCIR_MAPS, 4); - *base &= PCI_BASE_ADDRESS_IO_MASK; -#endif if (*base == 0) return (ENOMEM); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) - if (check_region(*base, 256) != 0) - return (ENOMEM); - request_region(*base, 256, "aic7xxx"); -#else if (request_region(*base, 256, "aic7xxx") == 0) return (ENOMEM); -#endif return (0); } @@ -334,17 +287,13 @@ ahc_linux_pci_reserve_mem_region(struct ahc_softc *ahc, start = pci_resource_start(ahc->dev_softc, 1); if (start != 0) { *bus_addr = start; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) if (request_mem_region(start, 0x1000, "aic7xxx") == 0) error = ENOMEM; -#endif if (error == 0) { *maddr = ioremap_nocache(start, 256); if (*maddr == NULL) { error = ENOMEM; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) release_mem_region(start, 0x1000); -#endif } } } else @@ -387,10 +336,8 @@ ahc_pci_map_registers(struct ahc_softc *ahc) ahc_get_pci_slot(ahc->dev_softc), ahc_get_pci_function(ahc->dev_softc)); iounmap(maddr); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) release_mem_region(ahc->platform_data->mem_busaddr, 0x1000); -#endif ahc->bsh.maddr = NULL; maddr = NULL; } else @@ -440,41 +387,3 @@ ahc_pci_map_int(struct ahc_softc *ahc) return (-error); } -void -ahc_power_state_change(struct ahc_softc *ahc, ahc_power_state new_state) -{ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) - pci_set_power_state(ahc->dev_softc, new_state); -#else - uint32_t cap; - u_int cap_offset; - - /* - * Traverse the capability list looking for - * the power management capability. - */ - cap = 0; - cap_offset = ahc_pci_read_config(ahc->dev_softc, - PCIR_CAP_PTR, /*bytes*/1); - while (cap_offset != 0) { - - cap = ahc_pci_read_config(ahc->dev_softc, - cap_offset, /*bytes*/4); - if ((cap & 0xFF) == 1 - && ((cap >> 16) & 0x3) > 0) { - uint32_t pm_control; - - pm_control = ahc_pci_read_config(ahc->dev_softc, - cap_offset + 4, - /*bytes*/4); - pm_control &= ~0x3; - pm_control |= new_state; - ahc_pci_write_config(ahc->dev_softc, - cap_offset + 4, - pm_control, /*bytes*/2); - break; - } - cap_offset = (cap >> 8) & 0xFF; - } -#endif -} diff --git a/drivers/scsi/aic7xxx/aic7xxx_pci.c b/drivers/scsi/aic7xxx/aic7xxx_pci.c index e3b50fcf62f7a9..7ddcc97fb243f7 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_pci.c +++ b/drivers/scsi/aic7xxx/aic7xxx_pci.c @@ -721,7 +721,7 @@ ahc_pci_config(struct ahc_softc *ahc, struct ahc_pci_identity *entry) ahc->chip |= AHC_PCI; ahc->description = entry->name; - ahc_power_state_change(ahc, AHC_POWER_STATE_D0); + pci_set_power_state(ahc->dev_softc, AHC_POWER_STATE_D0); error = ahc_pci_map_registers(ahc); if (error != 0) @@ -2016,7 +2016,7 @@ static int ahc_pci_resume(struct ahc_softc *ahc) { - ahc_power_state_change(ahc, AHC_POWER_STATE_D0); + pci_set_power_state(ahc->dev_softc, AHC_POWER_STATE_D0); /* * We assume that the OS has restored our register diff --git a/drivers/scsi/constants.c b/drivers/scsi/constants.c index e710da4d00e1ed..d625fdebe052bd 100644 --- a/drivers/scsi/constants.c +++ b/drivers/scsi/constants.c @@ -1156,17 +1156,14 @@ scsi_show_extd_sense(unsigned char asc, unsigned char ascq) } /* Print sense information */ -static void -print_sense_internal(const char *devclass, - const unsigned char *sense_buffer, - int sense_len, - struct request *req) +void +__scsi_print_sense(const char *name, const unsigned char *sense_buffer, + int sense_len) { int k, num, res; unsigned int info; const char *error; const char *sense_txt; - const char *name = req->rq_disk ? req->rq_disk->disk_name : devclass; struct scsi_sense_hdr ssh; res = scsi_normalize_sense(sense_buffer, sense_len, &ssh); @@ -1254,18 +1251,25 @@ print_sense_internal(const char *devclass, printk("\n"); } } +EXPORT_SYMBOL(__scsi_print_sense); void scsi_print_sense(const char *devclass, struct scsi_cmnd *cmd) { - print_sense_internal(devclass, cmd->sense_buffer, - SCSI_SENSE_BUFFERSIZE, cmd->request); + const char *name = devclass; + + if (cmd->request->rq_disk) + name = cmd->request->rq_disk->disk_name; + __scsi_print_sense(name, cmd->sense_buffer, SCSI_SENSE_BUFFERSIZE); } EXPORT_SYMBOL(scsi_print_sense); void scsi_print_req_sense(const char *devclass, struct scsi_request *sreq) { - print_sense_internal(devclass, sreq->sr_sense_buffer, - SCSI_SENSE_BUFFERSIZE, sreq->sr_request); + const char *name = devclass; + + if (sreq->sr_request->rq_disk) + name = sreq->sr_request->rq_disk->disk_name; + __scsi_print_sense(name, sreq->sr_sense_buffer, SCSI_SENSE_BUFFERSIZE); } EXPORT_SYMBOL(scsi_print_req_sense); diff --git a/drivers/scsi/fd_mcs.c b/drivers/scsi/fd_mcs.c index 32e0cd59752ca7..770930e2aec336 100644 --- a/drivers/scsi/fd_mcs.c +++ b/drivers/scsi/fd_mcs.c @@ -96,7 +96,6 @@ #include "scsi.h" #include <scsi/scsi_host.h> -#include "fd_mcs.h" #define DRIVER_VERSION "v0.2 by ZP Gu<zpg@castle.net>" @@ -104,14 +103,12 @@ #define DEBUG 0 /* Enable debugging output */ #define ENABLE_PARITY 1 /* Enable SCSI Parity */ -#define DO_DETECT 0 /* Do device detection here (see scsi.c) */ /* END OF USER DEFINABLE OPTIONS */ #if DEBUG #define EVERY_ACCESS 0 /* Write a line on every scsi access */ #define ERRORS_ONLY 1 /* Only write a line if there is an error */ -#define DEBUG_DETECT 1 /* Debug fd_mcs_detect() */ #define DEBUG_MESSAGES 1 /* Debug MESSAGE IN phase */ #define DEBUG_ABORT 1 /* Debug abort() routine */ #define DEBUG_RESET 1 /* Debug reset() routine */ @@ -119,7 +116,6 @@ #else #define EVERY_ACCESS 0 /* LEAVE THESE ALONE--CHANGE THE ONES ABOVE */ #define ERRORS_ONLY 0 -#define DEBUG_DETECT 0 #define DEBUG_MESSAGES 0 #define DEBUG_ABORT 0 #define DEBUG_RESET 0 @@ -432,6 +428,7 @@ static int fd_mcs_detect(Scsi_Host_Template * tpnt) FIFO_COUNT = user_fifo_count ? user_fifo_count : fd_mcs_adapters[loop].fifo_count; FIFO_Size = user_fifo_size ? user_fifo_size : fd_mcs_adapters[loop].fifo_size; +/* FIXME: Do we need to keep this bit of code inside NOT_USED around at all? */ #ifdef NOT_USED /* *************************************************** */ /* Try to toggle 32-bit mode. This only @@ -510,59 +507,6 @@ static int fd_mcs_detect(Scsi_Host_Template * tpnt) outb(0, SCSI_Mode_Cntl_port); outb(PARITY_MASK, TMC_Cntl_port); /* done reset */ - -#if DO_DETECT - /* scan devices attached */ - { - const int buflen = 255; - int i, j, retcode; - Scsi_Cmnd SCinit; - unsigned char do_inquiry[] = { INQUIRY, 0, 0, 0, buflen, 0 }; - unsigned char do_request_sense[] = { REQUEST_SENSE, - 0, 0, 0, buflen, 0 - }; - unsigned char do_read_capacity[] = { READ_CAPACITY, - 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; - unsigned char buf[buflen]; - - SCinit.request_buffer = SCinit.buffer = buf; - SCinit.request_bufflen = SCinit.bufflen = sizeof(buf) - 1; - SCinit.use_sg = 0; - SCinit.lun = 0; - SCinit.host = shpnt; - - printk("fd_mcs: detection routine scanning for devices:\n"); - for (i = 0; i < 8; i++) { - if (i == shpnt->this_id) /* Skip host adapter */ - continue; - SCinit.target = i; - memcpy(SCinit.cmnd, do_request_sense, sizeof(do_request_sense)); - retcode = fd_mcs_command(&SCinit); - if (!retcode) { - memcpy(SCinit.cmnd, do_inquiry, sizeof(do_inquiry)); - retcode = fd_mcs_command(&SCinit); - if (!retcode) { - printk(" SCSI ID %d: ", i); - for (j = 8; j < (buf[4] < 32 ? buf[4] : 32); j++) - printk("%c", buf[j] >= 20 ? buf[j] : ' '); - memcpy(SCinit.cmnd, do_read_capacity, sizeof(do_read_capacity)); - retcode = fd_mcs_command(&SCinit); - if (!retcode) { - unsigned long blocks, size, capacity; - - blocks = (buf[0] << 24) | (buf[1] << 16) - | (buf[2] << 8) | buf[3]; - size = (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7]; - capacity = +(+(blocks / 1024L) * +(size * 10L)) / 1024L; - - printk("%lu MB (%lu byte blocks)\n", ((capacity + 5L) / 10L), size); - } - } - } - } - } -#endif } } diff --git a/drivers/scsi/fd_mcs.h b/drivers/scsi/fd_mcs.h deleted file mode 100644 index 011a7878a2017a..00000000000000 --- a/drivers/scsi/fd_mcs.h +++ /dev/null @@ -1,37 +0,0 @@ -/* fd_mcs.h -- Header for Future Domain MCS 600/700 (or IBM OEM) driver - * - * fd_mcs.h v0.2 03/11/1998 ZP Gu (zpg@castle.net) - * - - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - - */ - -#ifndef _FD_MCS_H -#define _FD_MCS_H - -static int fd_mcs_detect(Scsi_Host_Template *); -static int fd_mcs_release(struct Scsi_Host *); -static int fd_mcs_command(Scsi_Cmnd *); -static int fd_mcs_abort(Scsi_Cmnd *); -static int fd_mcs_bus_reset(Scsi_Cmnd *); -static int fd_mcs_device_reset(Scsi_Cmnd *); -static int fd_mcs_host_reset(Scsi_Cmnd *); -static int fd_mcs_queue(Scsi_Cmnd *, void (*done) (Scsi_Cmnd *)); -static int fd_mcs_biosparam(struct scsi_device *, struct block_device *, - sector_t, int *); -static const char *fd_mcs_info(struct Scsi_Host *); - -#endif /* _FD_MCS_H */ diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c index 2442ca46aeb0fb..4a092bec4bb7a9 100644 --- a/drivers/scsi/gdth.c +++ b/drivers/scsi/gdth.c @@ -397,11 +397,7 @@ #include <asm/system.h> #include <asm/io.h> #include <asm/uaccess.h> -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) #include <linux/spinlock.h> -#else -#include <asm/spinlock.h> -#endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) #include <linux/blkdev.h> #else @@ -412,14 +408,11 @@ #include "scsi.h" #include <scsi/scsi_host.h> #include "gdth.h" +#include "gdth_kcompat.h" static void gdth_delay(int milliseconds); static void gdth_eval_mapping(ulong32 size, ulong32 *cyls, int *heads, int *secs); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) static irqreturn_t gdth_interrupt(int irq, void *dev_id, struct pt_regs *regs); -#else -static void gdth_interrupt(int irq, void *dev_id, struct pt_regs *regs); -#endif static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp); static int gdth_async_event(int hanum); static void gdth_log_event(gdth_evt_data *dvr, char *buffer); @@ -617,32 +610,6 @@ static unchar gdth_direction_tab[0x100] = { DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN }; -/* __initfunc, __initdata macros */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) -#define GDTH_INITFUNC(type, func) type __init func -#include <linux/init.h> -#else -#define GDTH_INITFUNC(type, func) __initfunc(type func) -#include <linux/init.h> -#endif - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) -#define GDTH_INIT_LOCK_HA(ha) spin_lock_init(&(ha)->smp_lock) -#define GDTH_LOCK_HA(ha,flags) spin_lock_irqsave(&(ha)->smp_lock,flags) -#define GDTH_UNLOCK_HA(ha,flags) spin_unlock_irqrestore(&(ha)->smp_lock,flags) - -#define GDTH_LOCK_SCSI_DONE(dev, flags) spin_lock_irqsave(dev->host_lock,flags) -#define GDTH_UNLOCK_SCSI_DONE(dev, flags) spin_unlock_irqrestore(dev->host_lock,flags) - -#else -#define GDTH_INIT_LOCK_HA(ha) spin_lock_init(&(ha)->smp_lock) -#define GDTH_LOCK_HA(ha,flags) spin_lock_irqsave(&(ha)->smp_lock,flags) -#define GDTH_UNLOCK_HA(ha,flags) spin_unlock_irqrestore(&(ha)->smp_lock,flags) - -#define GDTH_LOCK_SCSI_DONE(flags) spin_lock_irqsave(&io_request_lock,flags) -#define GDTH_UNLOCK_SCSI_DONE(flags) spin_unlock_irqrestore(&io_request_lock,flags) -#endif - /* LILO and modprobe/insmod parameters */ /* IRQ list for GDT3000/3020 EISA controllers */ static int irq[MAXHA] __initdata = @@ -674,7 +641,6 @@ static int probe_eisa_isa = 0; /* 64 bit DMA mode, support for drives > 2 TB, if force_dma32 = 0 */ static int force_dma32 = 0; -#ifdef MODULE /* parameters for modprobe/insmod */ module_param(irq, int, 0); module_param(disable, int, 0); @@ -689,33 +655,15 @@ module_param(shared_access, int, 0); module_param(probe_eisa_isa, int, 0); module_param(force_dma32, int, 0); MODULE_AUTHOR("Achim Leubner"); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,11) MODULE_LICENSE("GPL"); -#endif -#endif /* ioctl interface */ static struct file_operations gdth_fops = { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) .ioctl = gdth_ioctl, .open = gdth_open, .release = gdth_close, -#else - ioctl:gdth_ioctl, - open:gdth_open, - release:gdth_close, -#endif }; -/* /proc support */ -#include <linux/stat.h> -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) -struct proc_dir_entry proc_scsi_gdth = { - PROC_SCSI_GDTH, 4, "gdth", - S_IFDIR | S_IRUGO | S_IXUGO, 2 -}; -#endif - #include "gdth_proc.h" #include "gdth_proc.c" @@ -755,7 +703,7 @@ static void gdth_eval_mapping(ulong32 size, ulong32 *cyls, int *heads, int *secs /* controller search and initialization functions */ -GDTH_INITFUNC(static int, gdth_search_eisa(ushort eisa_adr)) +static int __init gdth_search_eisa(ushort eisa_adr) { ulong32 id; @@ -773,7 +721,7 @@ GDTH_INITFUNC(static int, gdth_search_eisa(ushort eisa_adr)) } -GDTH_INITFUNC(static int, gdth_search_isa(ulong32 bios_adr)) +static int __init gdth_search_isa(ulong32 bios_adr) { void __iomem *addr; ulong32 id; @@ -789,7 +737,7 @@ GDTH_INITFUNC(static int, gdth_search_isa(ulong32 bios_adr)) } -GDTH_INITFUNC(static int, gdth_search_pci(gdth_pci_str *pcistr)) +static int __init gdth_search_pci(gdth_pci_str *pcistr) { ushort device, cnt; @@ -812,21 +760,19 @@ GDTH_INITFUNC(static int, gdth_search_pci(gdth_pci_str *pcistr)) return cnt; } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) /* Vortex only makes RAID controllers. * We do not really want to specify all 550 ids here, so wildcard match. */ -static struct pci_device_id gdthtable[] __devinitdata = { +static struct pci_device_id gdthtable[] __attribute_used__ = { {PCI_VENDOR_ID_VORTEX,PCI_ANY_ID,PCI_ANY_ID, PCI_ANY_ID}, {PCI_VENDOR_ID_INTEL,PCI_DEVICE_ID_INTEL_SRC,PCI_ANY_ID,PCI_ANY_ID}, {PCI_VENDOR_ID_INTEL,PCI_DEVICE_ID_INTEL_SRC_XSCALE,PCI_ANY_ID,PCI_ANY_ID}, {0} }; MODULE_DEVICE_TABLE(pci,gdthtable); -#endif -GDTH_INITFUNC(static void, gdth_search_dev(gdth_pci_str *pcistr, ushort *cnt, - ushort vendor, ushort device)) +static void __init gdth_search_dev(gdth_pci_str *pcistr, ushort *cnt, + ushort vendor, ushort device) { ulong base0, base1, base2; struct pci_dev *pdev; @@ -834,7 +780,6 @@ GDTH_INITFUNC(static void, gdth_search_dev(gdth_pci_str *pcistr, ushort *cnt, TRACE(("gdth_search_dev() cnt %d vendor %x device %x\n", *cnt, vendor, device)); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) pdev = NULL; while ((pdev = pci_find_device(vendor, device, pdev)) != NULL) { @@ -872,52 +817,10 @@ GDTH_INITFUNC(static void, gdth_search_dev(gdth_pci_str *pcistr, ushort *cnt, pcistr[*cnt].irq, pcistr[*cnt].dpmem)); (*cnt)++; } -#else - pdev = NULL; - while ((pdev = pci_find_device(vendor, device, pdev)) - != NULL) { - if (*cnt >= MAXHA) - return; - /* GDT PCI controller found, resources are already in pdev */ - pcistr[*cnt].pdev = pdev; - pcistr[*cnt].vendor_id = vendor; - pcistr[*cnt].device_id = device; - pcistr[*cnt].bus = pdev->bus->number; - pcistr[*cnt].device_fn = pdev->devfn; - pcibios_read_config_word(pcistr[*cnt].bus, pcistr[*cnt].device_fn, - PCI_SUBSYSTEM_ID, &pcistr[*cnt].subdevice_id); - pcistr[*cnt].irq = pdev->irq; - base0 = pdev->base_address[0]; - base1 = pdev->base_address[1]; - base2 = pdev->base_address[2]; - if (device <= PCI_DEVICE_ID_VORTEX_GDT6000B || /* GDT6000/B */ - device >= PCI_DEVICE_ID_VORTEX_GDT6x17RP) { /* MPR */ - if ((base0 & PCI_BASE_ADDRESS_SPACE) != - PCI_BASE_ADDRESS_SPACE_MEMORY) - continue; - pcistr[*cnt].dpmem = base0 & PCI_BASE_ADDRESS_MEM_MASK; - } else { /* GDT6110, GDT6120, .. */ - if ((base0 & PCI_BASE_ADDRESS_SPACE) != - PCI_BASE_ADDRESS_SPACE_MEMORY || - (base2 & PCI_BASE_ADDRESS_SPACE) != - PCI_BASE_ADDRESS_SPACE_MEMORY || - (base1 & PCI_BASE_ADDRESS_SPACE) != - PCI_BASE_ADDRESS_SPACE_IO) - continue; - pcistr[*cnt].dpmem = base2 & PCI_BASE_ADDRESS_MEM_MASK; - pcistr[*cnt].io_mm = base0 & PCI_BASE_ADDRESS_MEM_MASK; - pcistr[*cnt].io = base1 & PCI_BASE_ADDRESS_IO_MASK; - } - TRACE2(("Controller found at %d/%d, irq %d, dpmem 0x%lx\n", - pcistr[*cnt].bus, PCI_SLOT(pcistr[*cnt].device_fn), - pcistr[*cnt].irq, pcistr[*cnt].dpmem)); - (*cnt)++; - } -#endif } -GDTH_INITFUNC(static void, gdth_sort_pci(gdth_pci_str *pcistr, int cnt)) +static void __init gdth_sort_pci(gdth_pci_str *pcistr, int cnt) { gdth_pci_str temp; int i, changed; @@ -955,7 +858,7 @@ GDTH_INITFUNC(static void, gdth_sort_pci(gdth_pci_str *pcistr, int cnt)) } -GDTH_INITFUNC(static int, gdth_init_eisa(ushort eisa_adr,gdth_ha_str *ha)) +static int __init gdth_init_eisa(ushort eisa_adr,gdth_ha_str *ha) { ulong32 retries,id; unchar prot_ver,eisacf,i,irq_found; @@ -1048,7 +951,7 @@ GDTH_INITFUNC(static int, gdth_init_eisa(ushort eisa_adr,gdth_ha_str *ha)) } -GDTH_INITFUNC(static int, gdth_init_isa(ulong32 bios_adr,gdth_ha_str *ha)) +static int __init gdth_init_isa(ulong32 bios_adr,gdth_ha_str *ha) { register gdt2_dpram_str __iomem *dp2_ptr; int i; @@ -1148,7 +1051,7 @@ GDTH_INITFUNC(static int, gdth_init_isa(ulong32 bios_adr,gdth_ha_str *ha)) } -GDTH_INITFUNC(static int, gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha)) +static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) { register gdt6_dpram_str __iomem *dp6_ptr; register gdt6c_dpram_str __iomem *dp6c_ptr; @@ -1168,9 +1071,7 @@ GDTH_INITFUNC(static int, gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha)) ha->stype = (ulong32)pcistr->device_id; ha->subdevice_id = pcistr->subdevice_id; ha->irq = pcistr->irq; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) ha->pdev = pcistr->pdev; -#endif if (ha->stype <= PCI_DEVICE_ID_VORTEX_GDT6000B) { /* GDT6000/B */ TRACE2(("init_pci() dpmem %lx irq %d\n",pcistr->dpmem,ha->irq)); @@ -1401,7 +1302,6 @@ GDTH_INITFUNC(static int, gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha)) } /* manipulate config. space to enable DPMEM, start RP controller */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) pci_read_config_word(pcistr->pdev, PCI_COMMAND, &command); command |= 6; pci_write_config_word(pcistr->pdev, PCI_COMMAND, command); @@ -1412,18 +1312,6 @@ GDTH_INITFUNC(static int, gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha)) gdth_delay(1); pci_write_config_dword(pcistr->pdev, PCI_ROM_ADDRESS, pci_resource_start(pcistr->pdev, 8)); -#else - pci_read_config_word(pcistr->pdev, PCI_COMMAND, &command); - command |= 6; - pci_write_config_word(pcistr->pdev, PCI_COMMAND, command); - if (pcistr->pdev->rom_address == 1UL) - pcistr->pdev->rom_address = 0UL; - i = 0xFEFF0001UL; - pci_write_config_dword(pcistr->pdev, PCI_ROM_ADDRESS, i); - gdth_delay(1); - pci_write_config_dword(pcistr->pdev, PCI_ROM_ADDRESS, - pcistr->pdev->rom_address); -#endif dp6m_ptr = ha->brd; @@ -1550,7 +1438,7 @@ GDTH_INITFUNC(static int, gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha)) /* controller protocol functions */ -GDTH_INITFUNC(static void, gdth_enable_int(int hanum)) +static void __init gdth_enable_int(int hanum) { gdth_ha_str *ha; ulong flags; @@ -1560,7 +1448,7 @@ GDTH_INITFUNC(static void, gdth_enable_int(int hanum)) TRACE(("gdth_enable_int() hanum %d\n",hanum)); ha = HADATA(gdth_ctr_tab[hanum]); - GDTH_LOCK_HA(ha, flags); + spin_lock_irqsave(&ha->smp_lock, flags); if (ha->type == GDT_EISA) { outb(0xff, ha->bmic + EDOORREG); @@ -1585,7 +1473,7 @@ GDTH_INITFUNC(static void, gdth_enable_int(int hanum)) gdth_writeb(gdth_readb(&dp6m_ptr->i960r.edoor_en_reg) & ~4, &dp6m_ptr->i960r.edoor_en_reg); } - GDTH_UNLOCK_HA(ha, flags); + spin_unlock_irqrestore(&ha->smp_lock, flags); } @@ -1897,7 +1785,7 @@ static int gdth_internal_cmd(int hanum,unchar service,ushort opcode,ulong32 p1, /* search for devices */ -GDTH_INITFUNC(static int, gdth_search_drives(int hanum)) +static int __init gdth_search_drives(int hanum) { register gdth_ha_str *ha; ushort cdev_cnt, i; @@ -2357,16 +2245,11 @@ static void gdth_putq(int hanum,Scsi_Cmnd *scp,unchar priority) TRACE(("gdth_putq() priority %d\n",priority)); ha = HADATA(gdth_ctr_tab[hanum]); - GDTH_LOCK_HA(ha, flags); + spin_lock_irqsave(&ha->smp_lock, flags); scp->SCp.this_residual = (int)priority; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel; t = scp->device->id; -#else - b = virt_ctr ? NUMDATA(scp->host)->busnum : scp->channel; - t = scp->target; -#endif if (priority >= DEFAULT_PRI) { if ((b != ha->virt_bus && ha->raw[BUS_L2P(ha,b)].lock) || (b == ha->virt_bus && t < MAX_HDRIVES && ha->hdr[t].lock)) { @@ -2389,7 +2272,7 @@ static void gdth_putq(int hanum,Scsi_Cmnd *scp,unchar priority) pscp->SCp.ptr = (char *)scp; scp->SCp.ptr = (char *)nscp; } - GDTH_UNLOCK_HA(ha, flags); + spin_unlock_irqrestore(&ha->smp_lock, flags); #ifdef GDTH_STATISTICS flags = 0; @@ -2415,7 +2298,7 @@ static void gdth_next(int hanum) TRACE(("gdth_next() hanum %d\n",hanum)); ha = HADATA(gdth_ctr_tab[hanum]); if (!gdth_polling) - GDTH_LOCK_HA(ha, flags); + spin_lock_irqsave(&ha->smp_lock, flags); ha->cmd_cnt = ha->cmd_offs_dpmem = 0; this_cmd = firsttime = TRUE; @@ -2425,15 +2308,9 @@ static void gdth_next(int hanum) for (nscp = pscp = ha->req_first; nscp; nscp = (Scsi_Cmnd *)nscp->SCp.ptr) { if (nscp != pscp && nscp != (Scsi_Cmnd *)pscp->SCp.ptr) pscp = (Scsi_Cmnd *)pscp->SCp.ptr; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) b = virt_ctr ? NUMDATA(nscp->device->host)->busnum : nscp->device->channel; t = nscp->device->id; l = nscp->device->lun; -#else - b = virt_ctr ? NUMDATA(nscp->host)->busnum : nscp->channel; - t = nscp->target; - l = nscp->lun; -#endif if (nscp->SCp.this_residual >= DEFAULT_PRI) { if ((b != ha->virt_bus && ha->raw[BUS_L2P(ha,b)].lock) || (b == ha->virt_bus && t < MAX_HDRIVES && ha->hdr[t].lock)) @@ -2444,7 +2321,7 @@ static void gdth_next(int hanum) if (gdth_test_busy(hanum)) { /* controller busy ? */ TRACE(("gdth_next() controller %d busy !\n",hanum)); if (!gdth_polling) { - GDTH_UNLOCK_HA(ha, flags); + spin_unlock_irqrestore(&ha->smp_lock, flags); return; } while (gdth_test_busy(hanum)) @@ -2513,14 +2390,8 @@ static void gdth_next(int hanum) nscp->result = (DID_OK << 16) | (CHECK_CONDITION << 1); if (!nscp->SCp.have_data_in) nscp->SCp.have_data_in++; - else { - if (!gdth_polling) - GDTH_UNLOCK_HA(ha,flags); - /* io_request_lock already active ! */ + else nscp->scsi_done(nscp); - if (!gdth_polling) - GDTH_LOCK_HA(ha,flags); - } } } else if (nscp->done == gdth_scsi_done && nscp->cmnd[0] == 0xff) { if (!(cmd_index=gdth_special_cmd(hanum,nscp))) @@ -2538,14 +2409,8 @@ static void gdth_next(int hanum) nscp->result = DID_BAD_TARGET << 16; if (!nscp->SCp.have_data_in) nscp->SCp.have_data_in++; - else { - if (!gdth_polling) - GDTH_UNLOCK_HA(ha,flags); - /* io_request_lock already active ! */ + else nscp->scsi_done(nscp); - if (!gdth_polling) - GDTH_LOCK_HA(ha,flags); - } } else { switch (nscp->cmnd[0]) { case TEST_UNIT_READY: @@ -2555,9 +2420,7 @@ static void gdth_next(int hanum) case VERIFY: case START_STOP: case MODE_SENSE: -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) case SERVICE_ACTION_IN: -#endif TRACE(("cache cmd %x/%x/%x/%x/%x/%x\n",nscp->cmnd[0], nscp->cmnd[1],nscp->cmnd[2],nscp->cmnd[3], nscp->cmnd[4],nscp->cmnd[5])); @@ -2572,22 +2435,10 @@ static void gdth_next(int hanum) nscp->result = (DID_OK << 16) | (CHECK_CONDITION << 1); if (!nscp->SCp.have_data_in) nscp->SCp.have_data_in++; - else { - if (!gdth_polling) - GDTH_UNLOCK_HA(ha,flags); - /* io_request_lock already active ! */ + else nscp->scsi_done(nscp); - if (!gdth_polling) - GDTH_LOCK_HA(ha,flags); - } - } else if (gdth_internal_cache_cmd(hanum,nscp)) { - if (!gdth_polling) - GDTH_UNLOCK_HA(ha,flags); - /* io_request_lock already active ! */ + } else if (gdth_internal_cache_cmd(hanum,nscp)) nscp->scsi_done(nscp); - if (!gdth_polling) - GDTH_LOCK_HA(ha,flags); - } break; case ALLOW_MEDIUM_REMOVAL: @@ -2600,14 +2451,8 @@ static void gdth_next(int hanum) nscp->sense_buffer[0] = 0; if (!nscp->SCp.have_data_in) nscp->SCp.have_data_in++; - else { - if (!gdth_polling) - GDTH_UNLOCK_HA(ha,flags); - /* io_request_lock already active ! */ + else nscp->scsi_done(nscp); - if (!gdth_polling) - GDTH_LOCK_HA(ha,flags); - } } else { nscp->cmnd[3] = (ha->hdr[t].devtype&1) ? 1:0; TRACE(("Prevent/allow r. %d rem. drive %d\n", @@ -2629,10 +2474,8 @@ static void gdth_next(int hanum) case WRITE_6: case READ_10: case WRITE_10: -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) case READ_16: case WRITE_16: -#endif if (ha->hdr[t].media_changed) { /* return UNIT_ATTENTION */ TRACE2(("cmd 0x%x target %d: UNIT_ATTENTION\n", @@ -2644,14 +2487,8 @@ static void gdth_next(int hanum) nscp->result = (DID_OK << 16) | (CHECK_CONDITION << 1); if (!nscp->SCp.have_data_in) nscp->SCp.have_data_in++; - else { - if (!gdth_polling) - GDTH_UNLOCK_HA(ha,flags); - /* io_request_lock already active ! */ + else nscp->scsi_done(nscp); - if (!gdth_polling) - GDTH_LOCK_HA(ha,flags); - } } else if (!(cmd_index=gdth_fill_cache_cmd(hanum,nscp,t))) this_cmd = FALSE; break; @@ -2665,14 +2502,8 @@ static void gdth_next(int hanum) nscp->result = DID_ABORT << 16; if (!nscp->SCp.have_data_in) nscp->SCp.have_data_in++; - else { - if (!gdth_polling) - GDTH_UNLOCK_HA(ha,flags); - /* io_request_lock already active ! */ + else nscp->scsi_done(nscp); - if (!gdth_polling) - GDTH_LOCK_HA(ha,flags); - } break; } } @@ -2692,7 +2523,7 @@ static void gdth_next(int hanum) } if (!gdth_polling) - GDTH_UNLOCK_HA(ha, flags); + spin_unlock_irqrestore(&ha->smp_lock, flags); if (gdth_polling && ha->cmd_cnt > 0) { if (!gdth_wait(hanum,cmd_index,POLL_TIMEOUT)) @@ -2708,7 +2539,6 @@ static void gdth_copy_internal_data(int hanum,Scsi_Cmnd *scp, ushort cpsum,cpnow; struct scatterlist *sl; gdth_ha_str *ha; - int sgcnt; char *address; cpcount = count<=(ushort)scp->bufflen ? count:(ushort)scp->bufflen; @@ -2716,10 +2546,9 @@ static void gdth_copy_internal_data(int hanum,Scsi_Cmnd *scp, if (scp->use_sg) { sl = (struct scatterlist *)scp->request_buffer; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,13) - sgcnt = pci_map_sg(ha->pdev,sl,scp->use_sg,PCI_DMA_FROMDEVICE); - for (i=0,cpsum=0; i<sgcnt; ++i,++sl) { - cpnow = (ushort)sg_dma_len(sl); + for (i=0,cpsum=0; i<scp->use_sg; ++i,++sl) { + unsigned long flags; + cpnow = (ushort)sl->length; TRACE(("copy_internal() now %d sum %d count %d %d\n", cpnow,cpsum,cpcount,(ushort)scp->bufflen)); if (cpsum+cpnow > cpcount) @@ -2730,30 +2559,16 @@ static void gdth_copy_internal_data(int hanum,Scsi_Cmnd *scp, hanum); return; } - address = (char *)(page_address(sl->page) + sl->offset); - memcpy(address,buffer,cpnow); - if (cpsum == cpcount) - break; - buffer += cpnow; - } - pci_unmap_sg(ha->pdev,scp->request_buffer, - scp->use_sg,PCI_DMA_FROMDEVICE); -#else - sgcnt = scp->use_sg; - for (i=0,cpsum=0; i<sgcnt; ++i,++sl) { - cpnow = (ushort)sl->length; - TRACE(("copy_internal() now %d sum %d count %d %d\n", - cpnow,cpsum,cpcount,(ushort)scp->bufflen)); - if (cpsum+cpnow > cpcount) - cpnow = cpcount - cpsum; - cpsum += cpnow; - address = (char *)sl->address; + local_irq_save(flags); + address = kmap_atomic(sl->page, KM_BIO_SRC_IRQ) + sl->offset; memcpy(address,buffer,cpnow); + flush_dcache_page(sl->page); + kunmap_atomic(address, KM_BIO_SRC_IRQ); + local_irq_restore(flags); if (cpsum == cpcount) break; buffer += cpnow; } -#endif } else { TRACE(("copy_internal() count %d\n",cpcount)); memcpy((char*)scp->request_buffer,buffer,cpcount); @@ -2770,11 +2585,7 @@ static int gdth_internal_cache_cmd(int hanum,Scsi_Cmnd *scp) gdth_modep_data mpd; ha = HADATA(gdth_ctr_tab[hanum]); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) t = scp->device->id; -#else - t = scp->target; -#endif TRACE(("gdth_internal_cache_cmd() cmd 0x%x hdrive %d\n", scp->cmnd[0],t)); @@ -2839,7 +2650,6 @@ static int gdth_internal_cache_cmd(int hanum,Scsi_Cmnd *scp) gdth_copy_internal_data(hanum,scp,(char*)&rdc,sizeof(gdth_rdcap_data)); break; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) case SERVICE_ACTION_IN: if ((scp->cmnd[1] & 0x1f) == SAI_READ_CAPACITY_16 && (ha->cache_feat & GDT_64BIT)) { @@ -2853,7 +2663,6 @@ static int gdth_internal_cache_cmd(int hanum,Scsi_Cmnd *scp) scp->result = DID_ABORT << 16; } break; -#endif default: TRACE2(("Internal cache cmd 0x%x unknown\n",scp->cmnd[0])); @@ -2877,10 +2686,8 @@ static int gdth_fill_cache_cmd(int hanum,Scsi_Cmnd *scp,ushort hdrive) ulong64 no, blockno; dma_addr_t phys_addr; int i, cmd_index, read_write, sgcnt, mode64; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,13) struct page *page; ulong offset; -#endif ha = HADATA(gdth_ctr_tab[hanum]); cmdp = ha->pccb; @@ -2922,10 +2729,7 @@ static int gdth_fill_cache_cmd(int hanum,Scsi_Cmnd *scp,ushort hdrive) else cmdp->OpCode = GDT_FLUSH; } else if (scp->cmnd[0] == WRITE_6 || scp->cmnd[0] == WRITE_10 || - scp->cmnd[0] == WRITE_12 -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) - || scp->cmnd[0] == WRITE_16 -#endif + scp->cmnd[0] == WRITE_12 || scp->cmnd[0] == WRITE_16 ) { read_write = 1; if (gdth_write_through || ((ha->hdr[hdrive].rw_attribs & 1) && @@ -2976,7 +2780,6 @@ static int gdth_fill_cache_cmd(int hanum,Scsi_Cmnd *scp,ushort hdrive) if (scp->use_sg) { sl = (struct scatterlist *)scp->request_buffer; sgcnt = scp->use_sg; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,13) scp->SCp.Status = GDTH_MAP_SG; scp->SCp.Message = (read_write == 1 ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); @@ -3005,23 +2808,6 @@ static int gdth_fill_cache_cmd(int hanum,Scsi_Cmnd *scp,ushort hdrive) cmdp->u.cache.sg_lst[i].sg_len = sg_dma_len(sl); } } -#else - if (mode64) { - cmdp->u.cache64.DestAddr= (ulong64)-1; - cmdp->u.cache64.sg_canz = sgcnt; - for (i=0; i<sgcnt; ++i,++sl) { - cmdp->u.cache64.sg_lst[i].sg_ptr = virt_to_bus(sl->address); - cmdp->u.cache64.sg_lst[i].sg_len = (ulong32)sl->length; - } - } else { - cmdp->u.cache.DestAddr= 0xffffffff; - cmdp->u.cache.sg_canz = sgcnt; - for (i=0; i<sgcnt; ++i,++sl) { - cmdp->u.cache.sg_lst[i].sg_ptr = virt_to_bus(sl->address); - cmdp->u.cache.sg_lst[i].sg_len = (ulong32)sl->length; - } - } -#endif #ifdef GDTH_STATISTICS if (max_sg < (ulong32)sgcnt) { @@ -3031,7 +2817,6 @@ static int gdth_fill_cache_cmd(int hanum,Scsi_Cmnd *scp,ushort hdrive) #endif } else { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,13) scp->SCp.Status = GDTH_MAP_SINGLE; scp->SCp.Message = (read_write == 1 ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); @@ -3040,9 +2825,6 @@ static int gdth_fill_cache_cmd(int hanum,Scsi_Cmnd *scp,ushort hdrive) phys_addr = pci_map_page(ha->pdev,page,offset, scp->request_bufflen,scp->SCp.Message); scp->SCp.dma_handle = phys_addr; -#else - phys_addr = virt_to_bus(scp->request_buffer); -#endif if (mode64) { if (ha->cache_feat & SCATTER_GATHER) { cmdp->u.cache64.DestAddr = (ulong64)-1; @@ -3114,19 +2896,12 @@ static int gdth_fill_raw_cmd(int hanum,Scsi_Cmnd *scp,unchar b) dma_addr_t phys_addr, sense_paddr; int cmd_index, sgcnt, mode64; unchar t,l; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,13) struct page *page; ulong offset; -#endif ha = HADATA(gdth_ctr_tab[hanum]); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) t = scp->device->id; l = scp->device->lun; -#else - t = scp->target; - l = scp->lun; -#endif cmdp = ha->pccb; TRACE(("gdth_fill_raw_cmd() cmd 0x%x bus %d ID %d LUN %d\n", scp->cmnd[0],b,t,l)); @@ -3166,7 +2941,6 @@ static int gdth_fill_raw_cmd(int hanum,Scsi_Cmnd *scp,unchar b) } } else { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,13) page = virt_to_page(scp->sense_buffer); offset = (ulong)scp->sense_buffer & ~PAGE_MASK; sense_paddr = pci_map_page(ha->pdev,page,offset, @@ -3174,9 +2948,6 @@ static int gdth_fill_raw_cmd(int hanum,Scsi_Cmnd *scp,unchar b) scp->SCp.buffer = (struct scatterlist *)((ulong32)sense_paddr); /* high part, if 64bit */ scp->host_scribble = (char *)(ulong32)((ulong64)sense_paddr >> 32); -#else - sense_paddr = virt_to_bus(scp->sense_buffer); -#endif cmdp->OpCode = GDT_WRITE; /* always */ cmdp->BoardNode = LOCALBOARD; if (mode64) { @@ -3215,7 +2986,6 @@ static int gdth_fill_raw_cmd(int hanum,Scsi_Cmnd *scp,unchar b) if (scp->use_sg) { sl = (struct scatterlist *)scp->request_buffer; sgcnt = scp->use_sg; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,13) scp->SCp.Status = GDTH_MAP_SG; scp->SCp.Message = PCI_DMA_BIDIRECTIONAL; sgcnt = pci_map_sg(ha->pdev,sl,scp->use_sg,scp->SCp.Message); @@ -3243,23 +3013,6 @@ static int gdth_fill_raw_cmd(int hanum,Scsi_Cmnd *scp,unchar b) cmdp->u.raw.sg_lst[i].sg_len = sg_dma_len(sl); } } -#else - if (mode64) { - cmdp->u.raw64.sdata = (ulong64)-1; - cmdp->u.raw64.sg_ranz = sgcnt; - for (i=0; i<sgcnt; ++i,++sl) { - cmdp->u.raw64.sg_lst[i].sg_ptr = virt_to_bus(sl->address); - cmdp->u.raw64.sg_lst[i].sg_len = (ulong32)sl->length; - } - } else { - cmdp->u.raw.sdata = 0xffffffff; - cmdp->u.raw.sg_ranz = sgcnt; - for (i=0; i<sgcnt; ++i,++sl) { - cmdp->u.raw.sg_lst[i].sg_ptr = virt_to_bus(sl->address); - cmdp->u.raw.sg_lst[i].sg_len = (ulong32)sl->length; - } - } -#endif #ifdef GDTH_STATISTICS if (max_sg < sgcnt) { @@ -3269,7 +3022,6 @@ static int gdth_fill_raw_cmd(int hanum,Scsi_Cmnd *scp,unchar b) #endif } else { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,13) scp->SCp.Status = GDTH_MAP_SINGLE; scp->SCp.Message = PCI_DMA_BIDIRECTIONAL; page = virt_to_page(scp->request_buffer); @@ -3277,9 +3029,7 @@ static int gdth_fill_raw_cmd(int hanum,Scsi_Cmnd *scp,unchar b) phys_addr = pci_map_page(ha->pdev,page,offset, scp->request_bufflen,scp->SCp.Message); scp->SCp.dma_handle = phys_addr; -#else - phys_addr = virt_to_bus(scp->request_buffer); -#endif + if (mode64) { if (ha->raw_feat & SCATTER_GATHER) { cmdp->u.raw64.sdata = (ulong64)-1; @@ -3461,7 +3211,7 @@ static int gdth_read_event(gdth_ha_str *ha, int handle, gdth_evt_str *estr) ulong flags; TRACE2(("gdth_read_event() handle %d\n", handle)); - GDTH_LOCK_HA(ha, flags); + spin_lock_irqsave(&ha->smp_lock, flags); if (handle == -1) eindex = eoldidx; else @@ -3469,7 +3219,7 @@ static int gdth_read_event(gdth_ha_str *ha, int handle, gdth_evt_str *estr) estr->event_source = 0; if (eindex >= MAX_EVENTS) { - GDTH_UNLOCK_HA(ha, flags); + spin_unlock_irqrestore(&ha->smp_lock, flags); return eindex; } e = &ebuffer[eindex]; @@ -3482,7 +3232,7 @@ static int gdth_read_event(gdth_ha_str *ha, int handle, gdth_evt_str *estr) } memcpy(estr, e, sizeof(gdth_evt_str)); } - GDTH_UNLOCK_HA(ha, flags); + spin_unlock_irqrestore(&ha->smp_lock, flags); return eindex; } @@ -3495,7 +3245,7 @@ static void gdth_readapp_event(gdth_ha_str *ha, unchar found = FALSE; TRACE2(("gdth_readapp_event() app. %d\n", application)); - GDTH_LOCK_HA(ha, flags); + spin_lock_irqsave(&ha->smp_lock, flags); eindex = eoldidx; for (;;) { e = &ebuffer[eindex]; @@ -3515,7 +3265,7 @@ static void gdth_readapp_event(gdth_ha_str *ha, memcpy(estr, e, sizeof(gdth_evt_str)); else estr->event_source = 0; - GDTH_UNLOCK_HA(ha, flags); + spin_unlock_irqrestore(&ha->smp_lock, flags); } static void gdth_clear_events(void) @@ -3529,12 +3279,9 @@ static void gdth_clear_events(void) /* SCSI interface functions */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) static irqreturn_t gdth_interrupt(int irq,void *dev_id,struct pt_regs *regs) -#else -static void gdth_interrupt(int irq,void *dev_id,struct pt_regs *regs) -#endif { + gdth_ha_str *ha2 = (gdth_ha_str *)dev_id; register gdth_ha_str *ha; gdt6m_dpram_str __iomem *dp6m_ptr = NULL; gdt6_dpram_str __iomem *dp6_ptr; @@ -3556,28 +3303,20 @@ static void gdth_interrupt(int irq,void *dev_id,struct pt_regs *regs) /* if polling and not from gdth_wait() -> return */ if (gdth_polling) { if (!gdth_from_wait) { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) return IRQ_HANDLED; -#else - return; -#endif } } if (!gdth_polling) - GDTH_LOCK_HA((gdth_ha_str *)dev_id,flags); + spin_lock_irqsave(&ha2->smp_lock, flags); wait_index = 0; /* search controller */ if ((hanum = gdth_get_status(&IStatus,irq)) == -1) { /* spurious interrupt */ if (!gdth_polling) - GDTH_UNLOCK_HA((gdth_ha_str *)dev_id,flags); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + spin_unlock_irqrestore(&ha2->smp_lock, flags); return IRQ_HANDLED; -#else - return; -#endif } ha = HADATA(gdth_ctr_tab[hanum]); @@ -3711,12 +3450,8 @@ static void gdth_interrupt(int irq,void *dev_id,struct pt_regs *regs) } else { TRACE2(("gdth_interrupt() unknown controller type\n")); if (!gdth_polling) - GDTH_UNLOCK_HA((gdth_ha_str *)dev_id,flags); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + spin_unlock_irqrestore(&ha2->smp_lock, flags); return IRQ_HANDLED; -#else - return; -#endif } TRACE(("gdth_interrupt() index %d stat %d info %d\n", @@ -3731,13 +3466,9 @@ static void gdth_interrupt(int irq,void *dev_id,struct pt_regs *regs) TRACE2(("gdth_interrupt() async. event\n")); gdth_async_event(hanum); if (!gdth_polling) - GDTH_UNLOCK_HA((gdth_ha_str *)dev_id,flags); + spin_unlock_irqrestore(&ha2->smp_lock, flags); gdth_next(hanum); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) return IRQ_HANDLED; -#else - return; -#endif } if (IStatus == SPEZINDEX) { @@ -3746,12 +3477,8 @@ static void gdth_interrupt(int irq,void *dev_id,struct pt_regs *regs) ha->dvr.eu.driver.ionode = hanum; gdth_store_event(ha, ES_DRIVER, 4, &ha->dvr); if (!gdth_polling) - GDTH_UNLOCK_HA((gdth_ha_str *)dev_id,flags); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + spin_unlock_irqrestore(&ha2->smp_lock, flags); return IRQ_HANDLED; -#else - return; -#endif } scp = ha->cmd_tab[IStatus-2].cmnd; Service = ha->cmd_tab[IStatus-2].service; @@ -3763,40 +3490,24 @@ static void gdth_interrupt(int irq,void *dev_id,struct pt_regs *regs) ha->dvr.eu.driver.index = IStatus; gdth_store_event(ha, ES_DRIVER, 1, &ha->dvr); if (!gdth_polling) - GDTH_UNLOCK_HA((gdth_ha_str *)dev_id,flags); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + spin_unlock_irqrestore(&ha2->smp_lock, flags); return IRQ_HANDLED; -#else - return; -#endif } if (scp == INTERNAL_CMND) { TRACE(("gdth_interrupt() answer to internal command\n")); if (!gdth_polling) - GDTH_UNLOCK_HA((gdth_ha_str *)dev_id,flags); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + spin_unlock_irqrestore(&ha2->smp_lock, flags); return IRQ_HANDLED; -#else - return; -#endif } TRACE(("gdth_interrupt() sync. status\n")); rval = gdth_sync_event(hanum,Service,IStatus,scp); if (!gdth_polling) - GDTH_UNLOCK_HA((gdth_ha_str *)dev_id,flags); + spin_unlock_irqrestore(&ha2->smp_lock, flags); if (rval == 2) { gdth_putq(hanum,scp,scp->SCp.this_residual); } else if (rval == 1) { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) - GDTH_LOCK_SCSI_DONE(scp->device->host, flags); - scp->scsi_done(scp); - GDTH_UNLOCK_SCSI_DONE(scp->device->host, flags); -#else - GDTH_LOCK_SCSI_DONE(flags); scp->scsi_done(scp); - GDTH_UNLOCK_SCSI_DONE(flags); -#endif } #ifdef INT_COAL @@ -3825,9 +3536,7 @@ static void gdth_interrupt(int irq,void *dev_id,struct pt_regs *regs) #endif gdth_next(hanum); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) return IRQ_HANDLED; -#endif } static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp) @@ -3911,13 +3620,8 @@ static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp) printk("\n"); } else { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel; t = scp->device->id; -#else - b = virt_ctr ? NUMDATA(scp->host)->busnum : scp->channel; - t = scp->target; -#endif if (scp->SCp.sent_command == -1 && b != ha->virt_bus) { ha->raw[BUS_L2P(ha,b)].io_cnt[t]--; } @@ -3929,7 +3633,6 @@ static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp) /* retry */ return 2; } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,13) if (scp->SCp.Status == GDTH_MAP_SG) pci_unmap_sg(ha->pdev,scp->request_buffer, scp->use_sg,scp->SCp.Message); @@ -3943,7 +3646,7 @@ static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp) addr += (dma_addr_t)((ulong64)(ulong32)scp->host_scribble << 32); pci_unmap_page(ha->pdev,addr,16,PCI_DMA_FROMDEVICE); } -#endif + if (ha->status == S_OK) { scp->SCp.Status = S_OK; scp->SCp.Message = ha->info; @@ -4340,7 +4043,7 @@ void gdth_timeout(ulong data) int hanum = 0; ha = HADATA(gdth_ctr_tab[hanum]); - GDTH_LOCK_HA(ha, flags); + spin_lock_irqsave(&ha->smp_lock, flags); for (act_stats=0,i=0; i<GDTH_MAXCMDS; ++i) if (ha->cmd_tab[i].cmnd != UNUSED_CMND) @@ -4355,11 +4058,11 @@ void gdth_timeout(ulong data) gdth_timer.expires = jiffies + 30 * HZ; add_timer(&gdth_timer); - GDTH_UNLOCK_HA(ha, flags); + spin_unlock_irqrestore(&ha->smp_lock, flags); } #endif -GDTH_INITFUNC(void, internal_setup(char *str,int *ints)) +void __init internal_setup(char *str,int *ints) { int i, argc; char *cur_str, *argv; @@ -4432,7 +4135,7 @@ GDTH_INITFUNC(void, internal_setup(char *str,int *ints)) } } -GDTH_INITFUNC(int, option_setup(char *str)) +int __init option_setup(char *str) { int ints[MAXHA]; char *cur = str; @@ -4450,7 +4153,7 @@ GDTH_INITFUNC(int, option_setup(char *str)) return 1; } -GDTH_INITFUNC(int, gdth_detect(Scsi_Host_Template *shtp)) +int __init gdth_detect(Scsi_Host_Template *shtp) { struct Scsi_Host *shp; gdth_pci_str pcistr[MAXHA]; @@ -4540,7 +4243,6 @@ GDTH_INITFUNC(int, gdth_detect(Scsi_Host_Template *shtp)) ha->pccb = CMDDATA(shp); ha->ccb_phys = 0L; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) ha->pdev = NULL; ha->pscratch = pci_alloc_consistent(ha->pdev, GDTH_SCRATCH, &scratch_dma_handle); @@ -4554,21 +4256,7 @@ GDTH_INITFUNC(int, gdth_detect(Scsi_Host_Template *shtp)) MAXOFFSETS, &scratch_dma_handle); ha->coal_stat_phys = scratch_dma_handle; #endif -#else - ha->pscratch = scsi_init_malloc(GDTH_SCRATCH, GFP_ATOMIC | GFP_DMA); - if (ha->pscratch) - ha->scratch_phys = virt_to_bus(ha->pscratch); - ha->pmsg = scsi_init_malloc(sizeof(gdth_msg_str), GFP_ATOMIC | GFP_DMA); - if (ha->pmsg) - ha->msg_phys = virt_to_bus(ha->pmsg); -#ifdef INT_COAL - ha->coal_stat = - scsi_init_malloc(sizeof(gdth_coal_status) * MAXOFFSETS, - GFP_ATOMIC | GFP_DMA); - if (ha->coal_stat) - ha->coal_stat_phys = virt_to_bus(ha->coal_stat); -#endif -#endif + ha->scratch_busy = FALSE; ha->req_first = NULL; ha->tid_cnt = MAX_HDRIVES; @@ -4583,7 +4271,7 @@ GDTH_INITFUNC(int, gdth_detect(Scsi_Host_Template *shtp)) printk("GDT-ISA: Error during device scan\n"); --gdth_ctr_count; --gdth_ctr_vcount; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + #ifdef INT_COAL if (ha->coal_stat) pci_free_consistent(ha->pdev, sizeof(gdth_coal_status) * @@ -4596,17 +4284,7 @@ GDTH_INITFUNC(int, gdth_detect(Scsi_Host_Template *shtp)) if (ha->pmsg) pci_free_consistent(ha->pdev, sizeof(gdth_msg_str), ha->pmsg, ha->msg_phys); -#else -#ifdef INT_COAL - if (ha->coal_stat) - scsi_init_free((void *)ha->coal_stat, - sizeof(gdth_coal_status) * MAXOFFSETS); -#endif - if (ha->pscratch) - scsi_init_free((void *)ha->pscratch, GDTH_SCRATCH); - if (ha->pmsg) - scsi_init_free((void *)ha->pmsg, sizeof(gdth_msg_str)); -#endif + free_irq(ha->irq,ha); scsi_unregister(shp); continue; @@ -4615,14 +4293,13 @@ GDTH_INITFUNC(int, gdth_detect(Scsi_Host_Template *shtp)) hdr_channel = ha->bus_cnt; ha->virt_bus = hdr_channel; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20) && \ LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) shp->highmem_io = 0; #endif if (ha->cache_feat & ha->raw_feat & ha->screen_feat & GDT_64BIT) shp->max_cmd_len = 16; -#endif + shp->max_id = ha->tid_cnt; shp->max_lun = MAXLUN; shp->max_channel = virt_ctr ? 0 : ha->bus_cnt; @@ -4640,7 +4317,7 @@ GDTH_INITFUNC(int, gdth_detect(Scsi_Host_Template *shtp)) } } - GDTH_INIT_LOCK_HA(ha); + spin_lock_init(&ha->smp_lock); gdth_enable_int(hanum); #endif /* !__ia64__ */ } @@ -4686,7 +4363,7 @@ GDTH_INITFUNC(int, gdth_detect(Scsi_Host_Template *shtp)) ha->pccb = CMDDATA(shp); ha->ccb_phys = 0L; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + ha->pdev = NULL; ha->pscratch = pci_alloc_consistent(ha->pdev, GDTH_SCRATCH, &scratch_dma_handle); @@ -4703,22 +4380,6 @@ GDTH_INITFUNC(int, gdth_detect(Scsi_Host_Template *shtp)) ha->ccb_phys = pci_map_single(ha->pdev,ha->pccb, sizeof(gdth_cmd_str),PCI_DMA_BIDIRECTIONAL); -#else - ha->pscratch = scsi_init_malloc(GDTH_SCRATCH, GFP_ATOMIC | GFP_DMA); - if (ha->pscratch) - ha->scratch_phys = virt_to_bus(ha->pscratch); - ha->pmsg = scsi_init_malloc(sizeof(gdth_msg_str), GFP_ATOMIC | GFP_DMA); - if (ha->pmsg) - ha->msg_phys = virt_to_bus(ha->pmsg); -#ifdef INT_COAL - ha->coal_stat = - scsi_init_malloc(sizeof(gdth_coal_status) * MAXOFFSETS, - GFP_ATOMIC | GFP_DMA); - if (ha->coal_stat) - ha->coal_stat_phys = virt_to_bus(ha->coal_stat); -#endif - ha->ccb_phys = virt_to_bus(ha->pccb); -#endif ha->scratch_busy = FALSE; ha->req_first = NULL; ha->tid_cnt = MAX_HDRIVES; @@ -4733,7 +4394,6 @@ GDTH_INITFUNC(int, gdth_detect(Scsi_Host_Template *shtp)) printk("GDT-EISA: Error during device scan\n"); --gdth_ctr_count; --gdth_ctr_vcount; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) #ifdef INT_COAL if (ha->coal_stat) pci_free_consistent(ha->pdev, sizeof(gdth_coal_status) * @@ -4749,17 +4409,6 @@ GDTH_INITFUNC(int, gdth_detect(Scsi_Host_Template *shtp)) if (ha->ccb_phys) pci_unmap_single(ha->pdev,ha->ccb_phys, sizeof(gdth_cmd_str),PCI_DMA_BIDIRECTIONAL); -#else -#ifdef INT_COAL - if (ha->coal_stat) - scsi_init_free((void *)ha->coal_stat, - sizeof(gdth_coal_status) * MAXOFFSETS); -#endif - if (ha->pscratch) - scsi_init_free((void *)ha->pscratch, GDTH_SCRATCH); - if (ha->pmsg) - scsi_init_free((void *)ha->pmsg, sizeof(gdth_msg_str)); -#endif free_irq(ha->irq,ha); scsi_unregister(shp); continue; @@ -4768,14 +4417,13 @@ GDTH_INITFUNC(int, gdth_detect(Scsi_Host_Template *shtp)) hdr_channel = ha->bus_cnt; ha->virt_bus = hdr_channel; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20) && \ LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) shp->highmem_io = 0; #endif if (ha->cache_feat & ha->raw_feat & ha->screen_feat & GDT_64BIT) shp->max_cmd_len = 16; -#endif + shp->max_id = ha->tid_cnt; shp->max_lun = MAXLUN; shp->max_channel = virt_ctr ? 0 : ha->bus_cnt; @@ -4793,7 +4441,7 @@ GDTH_INITFUNC(int, gdth_detect(Scsi_Host_Template *shtp)) } } - GDTH_INIT_LOCK_HA(ha); + spin_lock_init(&ha->smp_lock); gdth_enable_int(hanum); } } @@ -4841,7 +4489,7 @@ GDTH_INITFUNC(int, gdth_detect(Scsi_Host_Template *shtp)) ha->pccb = CMDDATA(shp); ha->ccb_phys = 0L; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + ha->pscratch = pci_alloc_consistent(ha->pdev, GDTH_SCRATCH, &scratch_dma_handle); ha->scratch_phys = scratch_dma_handle; @@ -4854,21 +4502,6 @@ GDTH_INITFUNC(int, gdth_detect(Scsi_Host_Template *shtp)) MAXOFFSETS, &scratch_dma_handle); ha->coal_stat_phys = scratch_dma_handle; #endif -#else - ha->pscratch = scsi_init_malloc(GDTH_SCRATCH, GFP_ATOMIC | GFP_DMA); - if (ha->pscratch) - ha->scratch_phys = virt_to_bus(ha->pscratch); - ha->pmsg = scsi_init_malloc(sizeof(gdth_msg_str), GFP_ATOMIC | GFP_DMA); - if (ha->pmsg) - ha->msg_phys = virt_to_bus(ha->pmsg); -#ifdef INT_COAL - ha->coal_stat = - scsi_init_malloc(sizeof(gdth_coal_status) * MAXOFFSETS, - GFP_ATOMIC | GFP_DMA); - if (ha->coal_stat) - ha->coal_stat_phys = virt_to_bus(ha->coal_stat); -#endif -#endif ha->scratch_busy = FALSE; ha->req_first = NULL; ha->tid_cnt = pcistr[ctr].device_id >= 0x200 ? MAXID : MAX_HDRIVES; @@ -4887,7 +4520,7 @@ GDTH_INITFUNC(int, gdth_detect(Scsi_Host_Template *shtp)) hdr_channel = ha->bus_cnt; ha->virt_bus = hdr_channel; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) scsi_set_device(shp, &pcistr[ctr].pdev->dev); #else @@ -4909,14 +4542,12 @@ GDTH_INITFUNC(int, gdth_detect(Scsi_Host_Template *shtp)) err = TRUE; } } -#endif } if (err) { printk("GDT-PCI %d: Error during device scan\n", hanum); --gdth_ctr_count; --gdth_ctr_vcount; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) #ifdef INT_COAL if (ha->coal_stat) pci_free_consistent(ha->pdev, sizeof(gdth_coal_status) * @@ -4929,17 +4560,6 @@ GDTH_INITFUNC(int, gdth_detect(Scsi_Host_Template *shtp)) if (ha->pmsg) pci_free_consistent(ha->pdev, sizeof(gdth_msg_str), ha->pmsg, ha->msg_phys); -#else -#ifdef INT_COAL - if (ha->coal_stat) - scsi_init_free((void *)ha->coal_stat, - sizeof(gdth_coal_status) * MAXOFFSETS); -#endif - if (ha->pscratch) - scsi_init_free((void *)ha->pscratch, GDTH_SCRATCH); - if (ha->pmsg) - scsi_init_free((void *)ha->pmsg, sizeof(gdth_msg_str)); -#endif free_irq(ha->irq,ha); scsi_unregister(shp); continue; @@ -4962,8 +4582,7 @@ GDTH_INITFUNC(int, gdth_detect(Scsi_Host_Template *shtp)) } } - - GDTH_INIT_LOCK_HA(ha); + spin_lock_init(&ha->smp_lock); gdth_enable_int(hanum); } @@ -4994,12 +4613,10 @@ int gdth_release(struct Scsi_Host *shp) if (NUMDATA(shp)->busnum == 0) { hanum = NUMDATA(shp)->hanum; ha = HADATA(gdth_ctr_tab[hanum]); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) if (ha->sdev) { scsi_free_host_dev(ha->sdev); ha->sdev = NULL; } -#endif gdth_flush(hanum); if (shp->irq) { @@ -5010,7 +4627,6 @@ int gdth_release(struct Scsi_Host *shp) free_dma(shp->dma_channel); } #endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) #ifdef INT_COAL if (ha->coal_stat) pci_free_consistent(ha->pdev, sizeof(gdth_coal_status) * @@ -5025,17 +4641,6 @@ int gdth_release(struct Scsi_Host *shp) if (ha->ccb_phys) pci_unmap_single(ha->pdev,ha->ccb_phys, sizeof(gdth_cmd_str),PCI_DMA_BIDIRECTIONAL); -#else -#ifdef INT_COAL - if (ha->coal_stat) - scsi_init_free((void *)ha->coal_stat, - sizeof(gdth_coal_status) * MAXOFFSETS); -#endif - if (ha->pscratch) - scsi_init_free((void *)ha->pscratch, GDTH_SCRATCH); - if (ha->pmsg) - scsi_init_free((void *)ha->pmsg, sizeof(gdth_msg_str)); -#endif gdth_ctr_released++; TRACE2(("gdth_release(): HA %d of %d\n", gdth_ctr_released, gdth_ctr_count)); @@ -5098,21 +4703,6 @@ const char *gdth_info(struct Scsi_Host *shp) return ((const char *)ha->binfo.type_string); } -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) -/* old error handling */ -int gdth_abort(Scsi_Cmnd *scp) -{ - TRACE2(("gdth_abort() reason %d\n",scp->abort_reason)); - return SCSI_ABORT_SNOOZE; -} - -int gdth_reset(Scsi_Cmnd *scp, unsigned int reset_flags) -{ - TRACE2(("gdth_reset()\n")); - return SCSI_RESET_PUNT; -} -#endif - /* new error handling */ int gdth_eh_abort(Scsi_Cmnd *scp) { @@ -5135,33 +4725,25 @@ int gdth_eh_bus_reset(Scsi_Cmnd *scp) unchar b; TRACE2(("gdth_eh_bus_reset()\n")); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + hanum = NUMDATA(scp->device->host)->hanum; b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel; -#else - hanum = NUMDATA(scp->host)->hanum; - b = virt_ctr ? NUMDATA(scp->host)->busnum : scp->channel; -#endif ha = HADATA(gdth_ctr_tab[hanum]); /* clear command tab */ - GDTH_LOCK_HA(ha, flags); + spin_lock_irqsave(&ha->smp_lock, flags); for (i = 0; i < GDTH_MAXCMDS; ++i) { cmnd = ha->cmd_tab[i].cmnd; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) if (!SPECIAL_SCP(cmnd) && cmnd->device->channel == b) -#else - if (!SPECIAL_SCP(cmnd) && cmnd->channel == b) -#endif ha->cmd_tab[i].cmnd = UNUSED_CMND; } - GDTH_UNLOCK_HA(ha, flags); + spin_unlock_irqrestore(&ha->smp_lock, flags); if (b == ha->virt_bus) { /* host drives */ for (i = 0; i < MAX_HDRIVES; ++i) { if (ha->hdr[i].present) { - GDTH_LOCK_HA(ha, flags); + spin_lock_irqsave(&ha->smp_lock, flags); gdth_polling = TRUE; while (gdth_test_busy(hanum)) gdth_delay(0); @@ -5169,12 +4751,12 @@ int gdth_eh_bus_reset(Scsi_Cmnd *scp) GDT_CLUST_RESET, i, 0, 0)) ha->hdr[i].cluster_type &= ~CLUSTER_RESERVED; gdth_polling = FALSE; - GDTH_UNLOCK_HA(ha, flags); + spin_unlock_irqrestore(&ha->smp_lock, flags); } } } else { /* raw devices */ - GDTH_LOCK_HA(ha, flags); + spin_lock_irqsave(&ha->smp_lock, flags); for (i = 0; i < MAXID; ++i) ha->raw[BUS_L2P(ha,b)].io_cnt[i] = 0; gdth_polling = TRUE; @@ -5183,7 +4765,7 @@ int gdth_eh_bus_reset(Scsi_Cmnd *scp) gdth_internal_cmd(hanum, SCSIRAWSERVICE, GDT_RESET_BUS, BUS_L2P(ha,b), 0, 0); gdth_polling = FALSE; - GDTH_UNLOCK_HA(ha, flags); + spin_unlock_irqrestore(&ha->smp_lock, flags); } return SUCCESS; } @@ -5249,11 +4831,8 @@ int gdth_queuecommand(Scsi_Cmnd *scp,void (*done)(Scsi_Cmnd *)) scp->SCp.sent_command = -1; scp->SCp.Status = GDTH_MAP_NONE; scp->SCp.buffer = (struct scatterlist *)NULL; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + hanum = NUMDATA(scp->device->host)->hanum; -#else - hanum = NUMDATA(scp->host)->hanum; -#endif #ifdef GDTH_STATISTICS ++act_ios; #endif @@ -5270,7 +4849,6 @@ int gdth_queuecommand(Scsi_Cmnd *scp,void (*done)(Scsi_Cmnd *)) static int gdth_open(struct inode *inode, struct file *filep) { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) gdth_ha_str *ha; int i; @@ -5279,7 +4857,6 @@ static int gdth_open(struct inode *inode, struct file *filep) if (!ha->sdev) ha->sdev = scsi_get_host_dev(gdth_ctr_tab[i]); } -#endif TRACE(("gdth_open()\n")); return 0; @@ -5311,10 +4888,10 @@ static int ioc_event(void __user *arg) evt.event.event_data.size=sizeof(evt.event.event_data.eu.sync); else evt.event.event_data.size=sizeof(evt.event.event_data.eu.async); - GDTH_LOCK_HA(ha, flags); + spin_lock_irqsave(&ha->smp_lock, flags); gdth_store_event(ha, evt.event.event_source, evt.event.event_idx, &evt.event.event_data); - GDTH_UNLOCK_HA(ha, flags); + spin_unlock_irqrestore(&ha->smp_lock, flags); } else if (evt.erase == 0xfe) { gdth_clear_events(); } else if (evt.erase == 0) { @@ -5344,15 +4921,15 @@ static int ioc_lockdrv(void __user *arg) if (j >= MAX_HDRIVES || !ha->hdr[j].present) continue; if (ldrv.lock) { - GDTH_LOCK_HA(ha, flags); + spin_lock_irqsave(&ha->smp_lock, flags); ha->hdr[j].lock = 1; - GDTH_UNLOCK_HA(ha, flags); + spin_unlock_irqrestore(&ha->smp_lock, flags); gdth_wait_completion(ldrv.ionode, ha->bus_cnt, j); gdth_stop_timeout(ldrv.ionode, ha->bus_cnt, j); } else { - GDTH_LOCK_HA(ha, flags); + spin_lock_irqsave(&ha->smp_lock, flags); ha->hdr[j].lock = 0; - GDTH_UNLOCK_HA(ha, flags); + spin_unlock_irqrestore(&ha->smp_lock, flags); gdth_start_timeout(ldrv.ionode, ha->bus_cnt, j); gdth_next(ldrv.ionode); } @@ -5367,11 +4944,9 @@ static int ioc_resetdrv(void __user *arg, char *cmnd) int hanum; gdth_ha_str *ha; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) - Scsi_Request *srp; -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) - Scsi_Cmnd *scp; + Scsi_Request *srp; #else - Scsi_Cmnd scp; + Scsi_Cmnd *scp; #endif if (copy_from_user(&res, arg, sizeof(gdth_ioctl_reset)) || @@ -5398,7 +4973,7 @@ static int ioc_resetdrv(void __user *arg, char *cmnd) gdth_do_req(srp, &cmd, cmnd, 30); res.status = (ushort)srp->sr_command->SCp.Status; scsi_release_request(srp); -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) +#else scp = scsi_allocate_device(ha->sdev, 1, FALSE); if (!scp) return -ENOMEM; @@ -5407,15 +4982,8 @@ static int ioc_resetdrv(void __user *arg, char *cmnd) gdth_do_cmd(scp, &cmd, cmnd, 30); res.status = (ushort)scp->SCp.Status; scsi_release_command(scp); -#else - memset(&ha->sdev,0,sizeof(Scsi_Device)); - memset(&scp, 0,sizeof(Scsi_Cmnd)); - ha->sdev.host = scp.host = gdth_ctr_tab[hanum]; - ha->sdev.id = scp.target = ha->sdev.host->this_id; - scp.device = &ha->sdev; - gdth_do_cmd(&scp, &cmd, cmnd, 30); - res.status = (ushort)scp.SCp.Status; #endif + if (copy_to_user(arg, &res, sizeof(gdth_ioctl_reset))) return -EFAULT; return 0; @@ -5430,10 +4998,8 @@ static int ioc_general(void __user *arg, char *cmnd) gdth_ha_str *ha; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) Scsi_Request *srp; -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) - Scsi_Cmnd *scp; #else - Scsi_Cmnd scp; + Scsi_Cmnd *scp; #endif if (copy_from_user(&gen, arg, sizeof(gdth_ioctl_general)) || @@ -5536,7 +5102,7 @@ static int ioc_general(void __user *arg, char *cmnd) gen.status = srp->sr_command->SCp.Status; gen.info = srp->sr_command->SCp.Message; scsi_release_request(srp); -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) +#else scp = scsi_allocate_device(ha->sdev, 1, FALSE); if (!scp) return -ENOMEM; @@ -5546,15 +5112,6 @@ static int ioc_general(void __user *arg, char *cmnd) gen.status = scp->SCp.Status; gen.info = scp->SCp.Message; scsi_release_command(scp); -#else - memset(&ha->sdev,0,sizeof(Scsi_Device)); - memset(&scp, 0,sizeof(Scsi_Cmnd)); - ha->sdev.host = scp.host = gdth_ctr_tab[hanum]; - ha->sdev.id = scp.target = ha->sdev.host->this_id; - scp.device = &ha->sdev; - gdth_do_cmd(&scp, &gen.command, cmnd, gen.timeout); - gen.status = scp.SCp.Status; - gen.info = scp.SCp.Message; #endif if (copy_to_user(arg + sizeof(gdth_ioctl_general), buf, @@ -5573,185 +5130,183 @@ static int ioc_general(void __user *arg, char *cmnd) static int ioc_hdrlist(void __user *arg, char *cmnd) { - gdth_ioctl_rescan rsc; - gdth_cmd_str cmd; + gdth_ioctl_rescan *rsc; + gdth_cmd_str *cmd; gdth_ha_str *ha; unchar i; - int hanum; + int hanum, rc = -ENOMEM; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) Scsi_Request *srp; -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) - Scsi_Cmnd *scp; #else - Scsi_Cmnd scp; + Scsi_Cmnd *scp; #endif - if (copy_from_user(&rsc, arg, sizeof(gdth_ioctl_rescan)) || - rsc.ionode >= gdth_ctr_count) - return -EFAULT; - hanum = rsc.ionode; + rsc = kmalloc(sizeof(*rsc), GFP_KERNEL); + cmd = kmalloc(sizeof(*cmd), GFP_KERNEL); + if (!rsc || !cmd) + goto free_fail; + + if (copy_from_user(rsc, arg, sizeof(gdth_ioctl_rescan)) || + rsc->ionode >= gdth_ctr_count) { + rc = -EFAULT; + goto free_fail; + } + hanum = rsc->ionode; ha = HADATA(gdth_ctr_tab[hanum]); - memset(&cmd, 0, sizeof(gdth_cmd_str)); + memset(cmd, 0, sizeof(gdth_cmd_str)); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) srp = scsi_allocate_request(ha->sdev, GFP_KERNEL); if (!srp) - return -ENOMEM; + goto free_fail; srp->sr_cmd_len = 12; srp->sr_use_sg = 0; -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) +#else scp = scsi_allocate_device(ha->sdev, 1, FALSE); if (!scp) - return -ENOMEM; + goto free_fail; scp->cmd_len = 12; scp->use_sg = 0; -#else - memset(&ha->sdev,0,sizeof(Scsi_Device)); - memset(&scp, 0,sizeof(Scsi_Cmnd)); - ha->sdev.host = scp.host = gdth_ctr_tab[hanum]; - ha->sdev.id = scp.target = ha->sdev.host->this_id; - scp.device = &ha->sdev; #endif for (i = 0; i < MAX_HDRIVES; ++i) { if (!ha->hdr[i].present) { - rsc.hdr_list[i].bus = 0xff; + rsc->hdr_list[i].bus = 0xff; continue; } - rsc.hdr_list[i].bus = ha->virt_bus; - rsc.hdr_list[i].target = i; - rsc.hdr_list[i].lun = 0; - rsc.hdr_list[i].cluster_type = ha->hdr[i].cluster_type; + rsc->hdr_list[i].bus = ha->virt_bus; + rsc->hdr_list[i].target = i; + rsc->hdr_list[i].lun = 0; + rsc->hdr_list[i].cluster_type = ha->hdr[i].cluster_type; if (ha->hdr[i].cluster_type & CLUSTER_DRIVE) { - cmd.Service = CACHESERVICE; - cmd.OpCode = GDT_CLUST_INFO; + cmd->Service = CACHESERVICE; + cmd->OpCode = GDT_CLUST_INFO; if (ha->cache_feat & GDT_64BIT) - cmd.u.cache64.DeviceNo = i; + cmd->u.cache64.DeviceNo = i; else - cmd.u.cache.DeviceNo = i; + cmd->u.cache.DeviceNo = i; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) - gdth_do_req(srp, &cmd, cmnd, 30); + gdth_do_req(srp, cmd, cmnd, 30); if (srp->sr_command->SCp.Status == S_OK) - rsc.hdr_list[i].cluster_type = srp->sr_command->SCp.Message; -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) - gdth_do_cmd(scp, &cmd, cmnd, 30); - if (scp->SCp.Status == S_OK) - rsc.hdr_list[i].cluster_type = scp->SCp.Message; + rsc->hdr_list[i].cluster_type = srp->sr_command->SCp.Message; #else - gdth_do_cmd(&scp, &cmd, cmnd, 30); - if (scp.SCp.Status == S_OK) - rsc.hdr_list[i].cluster_type = scp.SCp.Message; + gdth_do_cmd(scp, cmd, cmnd, 30); + if (scp->SCp.Status == S_OK) + rsc->hdr_list[i].cluster_type = scp->SCp.Message; #endif } } #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) scsi_release_request(srp); -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) +#else scsi_release_command(scp); #endif - if (copy_to_user(arg, &rsc, sizeof(gdth_ioctl_rescan))) - return -EFAULT; - return 0; + if (copy_to_user(arg, rsc, sizeof(gdth_ioctl_rescan))) + rc = -EFAULT; + else + rc = 0; + +free_fail: + kfree(rsc); + kfree(cmd); + return rc; } static int ioc_rescan(void __user *arg, char *cmnd) { - gdth_ioctl_rescan rsc; - gdth_cmd_str cmd; + gdth_ioctl_rescan *rsc; + gdth_cmd_str *cmd; ushort i, status, hdr_cnt; ulong32 info; int hanum, cyls, hds, secs; + int rc = -ENOMEM; ulong flags; gdth_ha_str *ha; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) Scsi_Request *srp; -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) - Scsi_Cmnd *scp; #else - Scsi_Cmnd scp; + Scsi_Cmnd *scp; #endif - - if (copy_from_user(&rsc, arg, sizeof(gdth_ioctl_rescan)) || - rsc.ionode >= gdth_ctr_count) - return -EFAULT; - hanum = rsc.ionode; + + rsc = kmalloc(sizeof(*rsc), GFP_KERNEL); + cmd = kmalloc(sizeof(*cmd), GFP_KERNEL); + if (!cmd || !rsc) + goto free_fail; + + if (copy_from_user(rsc, arg, sizeof(gdth_ioctl_rescan)) || + rsc->ionode >= gdth_ctr_count) { + rc = -EFAULT; + goto free_fail; + } + hanum = rsc->ionode; ha = HADATA(gdth_ctr_tab[hanum]); - memset(&cmd, 0, sizeof(gdth_cmd_str)); + memset(cmd, 0, sizeof(gdth_cmd_str)); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) srp = scsi_allocate_request(ha->sdev, GFP_KERNEL); if (!srp) - return -ENOMEM; + goto free_fail; srp->sr_cmd_len = 12; srp->sr_use_sg = 0; -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) +#else scp = scsi_allocate_device(ha->sdev, 1, FALSE); if (!scp) - return -ENOMEM; + goto free_fail; scp->cmd_len = 12; scp->use_sg = 0; -#else - memset(&ha->sdev,0,sizeof(Scsi_Device)); - memset(&scp, 0,sizeof(Scsi_Cmnd)); - ha->sdev.host = scp.host = gdth_ctr_tab[hanum]; - ha->sdev.id = scp.target = ha->sdev.host->this_id; - scp.device = &ha->sdev; #endif - if (rsc.flag == 0) { + if (rsc->flag == 0) { /* old method: re-init. cache service */ - cmd.Service = CACHESERVICE; + cmd->Service = CACHESERVICE; if (ha->cache_feat & GDT_64BIT) { - cmd.OpCode = GDT_X_INIT_HOST; - cmd.u.cache64.DeviceNo = LINUX_OS; + cmd->OpCode = GDT_X_INIT_HOST; + cmd->u.cache64.DeviceNo = LINUX_OS; } else { - cmd.OpCode = GDT_INIT; - cmd.u.cache.DeviceNo = LINUX_OS; + cmd->OpCode = GDT_INIT; + cmd->u.cache.DeviceNo = LINUX_OS; } #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) - gdth_do_req(srp, &cmd, cmnd, 30); + gdth_do_req(srp, cmd, cmnd, 30); status = (ushort)srp->sr_command->SCp.Status; info = (ulong32)srp->sr_command->SCp.Message; #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) - gdth_do_cmd(scp, &cmd, cmnd, 30); + gdth_do_cmd(scp, cmd, cmnd, 30); status = (ushort)scp->SCp.Status; info = (ulong32)scp->SCp.Message; #else - gdth_do_cmd(&scp, &cmd, cmnd, 30); + gdth_do_cmd(&scp, cmd, cmnd, 30); status = (ushort)scp.SCp.Status; info = (ulong32)scp.SCp.Message; #endif i = 0; hdr_cnt = (status == S_OK ? (ushort)info : 0); } else { - i = rsc.hdr_no; + i = rsc->hdr_no; hdr_cnt = i + 1; } + for (; i < hdr_cnt && i < MAX_HDRIVES; ++i) { - cmd.Service = CACHESERVICE; - cmd.OpCode = GDT_INFO; + cmd->Service = CACHESERVICE; + cmd->OpCode = GDT_INFO; if (ha->cache_feat & GDT_64BIT) - cmd.u.cache64.DeviceNo = i; + cmd->u.cache64.DeviceNo = i; else - cmd.u.cache.DeviceNo = i; + cmd->u.cache.DeviceNo = i; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) - gdth_do_req(srp, &cmd, cmnd, 30); + gdth_do_req(srp, cmd, cmnd, 30); status = (ushort)srp->sr_command->SCp.Status; info = (ulong32)srp->sr_command->SCp.Message; -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) - gdth_do_cmd(scp, &cmd, cmnd, 30); +#else + gdth_do_cmd(scp, cmd, cmnd, 30); status = (ushort)scp->SCp.Status; info = (ulong32)scp->SCp.Message; -#else - gdth_do_cmd(&scp, &cmd, cmnd, 30); - status = (ushort)scp.SCp.Status; - info = (ulong32)scp.SCp.Message; #endif - GDTH_LOCK_HA(ha, flags); - rsc.hdr_list[i].bus = ha->virt_bus; - rsc.hdr_list[i].target = i; - rsc.hdr_list[i].lun = 0; + spin_lock_irqsave(&ha->smp_lock, flags); + rsc->hdr_list[i].bus = ha->virt_bus; + rsc->hdr_list[i].target = i; + rsc->hdr_list[i].lun = 0; if (status != S_OK) { ha->hdr[i].present = FALSE; } else { @@ -5765,7 +5320,7 @@ static int ioc_rescan(void __user *arg, char *cmnd) /* round size */ ha->hdr[i].size = cyls * hds * secs; } - GDTH_UNLOCK_HA(ha, flags); + spin_unlock_irqrestore(&ha->smp_lock, flags); if (status != S_OK) continue; @@ -5773,99 +5328,87 @@ static int ioc_rescan(void __user *arg, char *cmnd) /* but we need ha->info2, not yet stored in scp->SCp */ /* devtype, cluster info, R/W attribs */ - cmd.Service = CACHESERVICE; - cmd.OpCode = GDT_DEVTYPE; + cmd->Service = CACHESERVICE; + cmd->OpCode = GDT_DEVTYPE; if (ha->cache_feat & GDT_64BIT) - cmd.u.cache64.DeviceNo = i; + cmd->u.cache64.DeviceNo = i; else - cmd.u.cache.DeviceNo = i; + cmd->u.cache.DeviceNo = i; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) - gdth_do_req(srp, &cmd, cmnd, 30); + gdth_do_req(srp, cmd, cmnd, 30); status = (ushort)srp->sr_command->SCp.Status; info = (ulong32)srp->sr_command->SCp.Message; -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) - gdth_do_cmd(scp, &cmd, cmnd, 30); +#else + gdth_do_cmd(scp, cmd, cmnd, 30); status = (ushort)scp->SCp.Status; info = (ulong32)scp->SCp.Message; -#else - gdth_do_cmd(&scp, &cmd, cmnd, 30); - status = (ushort)scp.SCp.Status; - info = (ulong32)scp.SCp.Message; #endif - GDTH_LOCK_HA(ha, flags); + spin_lock_irqsave(&ha->smp_lock, flags); ha->hdr[i].devtype = (status == S_OK ? (ushort)info : 0); - GDTH_UNLOCK_HA(ha, flags); + spin_unlock_irqrestore(&ha->smp_lock, flags); - cmd.Service = CACHESERVICE; - cmd.OpCode = GDT_CLUST_INFO; + cmd->Service = CACHESERVICE; + cmd->OpCode = GDT_CLUST_INFO; if (ha->cache_feat & GDT_64BIT) - cmd.u.cache64.DeviceNo = i; + cmd->u.cache64.DeviceNo = i; else - cmd.u.cache.DeviceNo = i; + cmd->u.cache.DeviceNo = i; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) - gdth_do_req(srp, &cmd, cmnd, 30); + gdth_do_req(srp, cmd, cmnd, 30); status = (ushort)srp->sr_command->SCp.Status; info = (ulong32)srp->sr_command->SCp.Message; -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) - gdth_do_cmd(scp, &cmd, cmnd, 30); +#else + gdth_do_cmd(scp, cmd, cmnd, 30); status = (ushort)scp->SCp.Status; info = (ulong32)scp->SCp.Message; -#else - gdth_do_cmd(&scp, &cmd, cmnd, 30); - status = (ushort)scp.SCp.Status; - info = (ulong32)scp.SCp.Message; #endif - GDTH_LOCK_HA(ha, flags); + spin_lock_irqsave(&ha->smp_lock, flags); ha->hdr[i].cluster_type = ((status == S_OK && !shared_access) ? (ushort)info : 0); - GDTH_UNLOCK_HA(ha, flags); - rsc.hdr_list[i].cluster_type = ha->hdr[i].cluster_type; + spin_unlock_irqrestore(&ha->smp_lock, flags); + rsc->hdr_list[i].cluster_type = ha->hdr[i].cluster_type; - cmd.Service = CACHESERVICE; - cmd.OpCode = GDT_RW_ATTRIBS; + cmd->Service = CACHESERVICE; + cmd->OpCode = GDT_RW_ATTRIBS; if (ha->cache_feat & GDT_64BIT) - cmd.u.cache64.DeviceNo = i; + cmd->u.cache64.DeviceNo = i; else - cmd.u.cache.DeviceNo = i; + cmd->u.cache.DeviceNo = i; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) - gdth_do_req(srp, &cmd, cmnd, 30); + gdth_do_req(srp, cmd, cmnd, 30); status = (ushort)srp->sr_command->SCp.Status; info = (ulong32)srp->sr_command->SCp.Message; -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) - gdth_do_cmd(scp, &cmd, cmnd, 30); +#else + gdth_do_cmd(scp, cmd, cmnd, 30); status = (ushort)scp->SCp.Status; info = (ulong32)scp->SCp.Message; -#else - gdth_do_cmd(&scp, &cmd, cmnd, 30); - status = (ushort)scp.SCp.Status; - info = (ulong32)scp.SCp.Message; #endif - GDTH_LOCK_HA(ha, flags); + spin_lock_irqsave(&ha->smp_lock, flags); ha->hdr[i].rw_attribs = (status == S_OK ? (ushort)info : 0); - GDTH_UNLOCK_HA(ha, flags); + spin_unlock_irqrestore(&ha->smp_lock, flags); } #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) scsi_release_request(srp); -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) +#else scsi_release_command(scp); #endif - if (copy_to_user(arg, &rsc, sizeof(gdth_ioctl_rescan))) - return -EFAULT; - return 0; + if (copy_to_user(arg, rsc, sizeof(gdth_ioctl_rescan))) + rc = -EFAULT; + else + rc = 0; + +free_fail: + kfree(rsc); + kfree(cmd); + return rc; } static int gdth_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, unsigned long arg) { gdth_ha_str *ha; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) Scsi_Cmnd *scp; -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) - Scsi_Cmnd *scp; -#else - Scsi_Cmnd scp; -#endif ulong flags; char cmnd[MAX_COMMAND_SIZE]; void __user *argp = (void __user *)arg; @@ -5956,17 +5499,17 @@ static int gdth_ioctl(struct inode *inode, struct file *filep, i = lchn.channel; if (i < ha->bus_cnt) { if (lchn.lock) { - GDTH_LOCK_HA(ha, flags); + spin_lock_irqsave(&ha->smp_lock, flags); ha->raw[i].lock = 1; - GDTH_UNLOCK_HA(ha, flags); + spin_unlock_irqrestore(&ha->smp_lock, flags); for (j = 0; j < ha->tid_cnt; ++j) { gdth_wait_completion(lchn.ionode, i, j); gdth_stop_timeout(lchn.ionode, i, j); } } else { - GDTH_LOCK_HA(ha, flags); + spin_lock_irqsave(&ha->smp_lock, flags); ha->raw[i].lock = 0; - GDTH_UNLOCK_HA(ha, flags); + spin_unlock_irqrestore(&ha->smp_lock, flags); for (j = 0; j < ha->tid_cnt; ++j) { gdth_start_timeout(lchn.ionode, i, j); gdth_next(lchn.ionode); @@ -6004,7 +5547,7 @@ static int gdth_ioctl(struct inode *inode, struct file *filep, rval = gdth_eh_bus_reset(scp); res.status = (rval == SUCCESS ? S_OK : S_GENERR); scsi_put_command(scp); -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) +#else scp = scsi_allocate_device(ha->sdev, 1, FALSE); if (!scp) return -ENOMEM; @@ -6014,15 +5557,6 @@ static int gdth_ioctl(struct inode *inode, struct file *filep, rval = gdth_eh_bus_reset(scp); res.status = (rval == SUCCESS ? S_OK : S_GENERR); scsi_release_command(scp); -#else - memset(&ha->sdev,0,sizeof(Scsi_Device)); - memset(&scp, 0,sizeof(Scsi_Cmnd)); - ha->sdev.host = scp.host = gdth_ctr_tab[hanum]; - ha->sdev.id = scp.target = ha->sdev.host->this_id; - scp.device = &ha->sdev; - scp.channel = virt_ctr ? 0 : res.number; - rval = gdth_eh_bus_reset(&scp); - res.status = (rval == SUCCESS ? S_OK : S_GENERR); #endif if (copy_to_user(argp, &res, sizeof(gdth_ioctl_reset))) return -EFAULT; @@ -6047,14 +5581,10 @@ static void gdth_flush(int hanum) gdth_cmd_str gdtcmd; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) Scsi_Request *srp; - Scsi_Device *sdev; -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) - Scsi_Cmnd *scp; - Scsi_Device *sdev; #else - Scsi_Cmnd scp; - Scsi_Device sdev; + Scsi_Cmnd *scp; #endif + Scsi_Device *sdev; char cmnd[MAX_COMMAND_SIZE]; memset(cmnd, 0xff, MAX_COMMAND_SIZE); @@ -6068,19 +5598,13 @@ static void gdth_flush(int hanum) return; srp->sr_cmd_len = 12; srp->sr_use_sg = 0; -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) +#else sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]); scp = scsi_allocate_device(sdev, 1, FALSE); if (!scp) return; scp->cmd_len = 12; scp->use_sg = 0; -#else - memset(&sdev,0,sizeof(Scsi_Device)); - memset(&scp, 0,sizeof(Scsi_Cmnd)); - sdev.host = scp.host = gdth_ctr_tab[hanum]; - sdev.id = scp.target = sdev.host->this_id; - scp.device = &sdev; #endif for (i = 0; i < MAX_HDRIVES; ++i) { @@ -6100,17 +5624,15 @@ static void gdth_flush(int hanum) TRACE2(("gdth_flush(): flush ha %d drive %d\n", hanum, i)); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) gdth_do_req(srp, &gdtcmd, cmnd, 30); -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) - gdth_do_cmd(scp, &gdtcmd, cmnd, 30); #else - gdth_do_cmd(&scp, &gdtcmd, cmnd, 30); + gdth_do_cmd(scp, &gdtcmd, cmnd, 30); #endif } } #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) scsi_release_request(srp); scsi_free_host_dev(sdev); -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) +#else scsi_release_command(scp); scsi_free_host_dev(sdev); #endif @@ -6125,12 +5647,9 @@ static int gdth_halt(struct notifier_block *nb, ulong event, void *buf) #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) Scsi_Request *srp; Scsi_Device *sdev; -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) +#else Scsi_Cmnd *scp; Scsi_Device *sdev; -#else - Scsi_Cmnd scp; - Scsi_Device sdev; #endif char cmnd[MAX_COMMAND_SIZE]; #endif @@ -6162,7 +5681,7 @@ static int gdth_halt(struct notifier_block *nb, ulong event, void *buf) gdth_do_req(srp, &gdtcmd, cmnd, 10); scsi_release_request(srp); scsi_free_host_dev(sdev); -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) +#else sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]); scp = scsi_allocate_device(sdev, 1, FALSE); if (!scp) { @@ -6174,13 +5693,6 @@ static int gdth_halt(struct notifier_block *nb, ulong event, void *buf) gdth_do_cmd(scp, &gdtcmd, cmnd, 10); scsi_release_command(scp); scsi_free_host_dev(sdev); -#else - memset(&sdev,0,sizeof(Scsi_Device)); - memset(&scp, 0,sizeof(Scsi_Cmnd)); - sdev.host = scp.host = gdth_ctr_tab[hanum]; - sdev.id = scp.target = sdev.host->this_id; - scp.device = &sdev; - gdth_do_cmd(&scp, &gdtcmd, cmnd, 10); #endif #endif } @@ -6193,19 +5705,6 @@ static int gdth_halt(struct notifier_block *nb, ulong event, void *buf) return NOTIFY_OK; } - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) && !defined(MODULE) - -GDTH_INITFUNC(void, gdth_setup(char *str,int *ints)) -{ - TRACE2(("gdth_setup() str %s ints[0] %d\n", - str ? str:"NULL", ints ? ints[0]:0)); - internal_setup(str, ints); -} - -#else - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) static Scsi_Host_Template driver_template = { .proc_name = "gdth", .proc_info = gdth_proc_info, @@ -6232,13 +5731,8 @@ static Scsi_Host_Template driver_template = { #endif #endif }; -#else -static Scsi_Host_Template driver_template = GDTH; -#endif #include "scsi_module.c" #ifndef MODULE __setup("gdth=", option_setup); #endif - -#endif diff --git a/drivers/scsi/gdth_kcompat.h b/drivers/scsi/gdth_kcompat.h new file mode 100644 index 00000000000000..e6cf0edfa0caef --- /dev/null +++ b/drivers/scsi/gdth_kcompat.h @@ -0,0 +1,21 @@ + + +#ifndef IRQ_HANDLED +typedef void irqreturn_t; +#define IRQ_NONE +#define IRQ_HANDLED +#endif + +#ifndef MODULE_LICENSE +#define MODULE_LICENSE(x) +#endif + +#ifndef SERVICE_ACTION_IN +#define SERVICE_ACTION_IN 0x9e +#endif +#ifndef READ_16 +#define READ_16 0x88 +#endif +#ifndef WRITE_16 +#define WRITE_16 0x8a +#endif diff --git a/drivers/scsi/gdth_proc.c b/drivers/scsi/gdth_proc.c index e37faaaeb0e541..1bd02f8d1e6a21 100644 --- a/drivers/scsi/gdth_proc.c +++ b/drivers/scsi/gdth_proc.c @@ -2,9 +2,7 @@ * $Id: gdth_proc.c,v 1.42 2004/03/05 15:50:20 achim Exp $ */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,7) #include <linux/completion.h> -#endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) int gdth_proc_info(struct Scsi_Host *host, char *buffer,char **start,off_t offset,int length, @@ -57,12 +55,9 @@ static int gdth_set_info(char *buffer,int length,struct Scsi_Host *host, #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) Scsi_Request *scp; Scsi_Device *sdev; -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) +#else Scsi_Cmnd *scp; Scsi_Device *sdev; -#else - Scsi_Cmnd scp; - Scsi_Device sdev; #endif TRACE2(("gdth_set_info() ha %d bus %d\n",hanum,busnum)); @@ -73,19 +68,13 @@ static int gdth_set_info(char *buffer,int length,struct Scsi_Host *host, return -ENOMEM; scp->sr_cmd_len = 12; scp->sr_use_sg = 0; -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) +#else sdev = scsi_get_host_dev(host); scp = scsi_allocate_device(sdev, 1, FALSE); if (!scp) return -ENOMEM; scp->cmd_len = 12; scp->use_sg = 0; -#else - memset(&sdev,0,sizeof(Scsi_Device)); - memset(&scp, 0,sizeof(Scsi_Cmnd)); - sdev.host = scp.host = host; - sdev.id = scp.target = sdev.host->this_id; - scp.device = &sdev; #endif if (length >= 4) { @@ -98,7 +87,7 @@ static int gdth_set_info(char *buffer,int length,struct Scsi_Host *host, #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) scsi_release_request(scp); scsi_free_host_dev(sdev); -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) +#else scsi_release_command(scp); scsi_free_host_dev(sdev); #endif @@ -107,10 +96,8 @@ static int gdth_set_info(char *buffer,int length,struct Scsi_Host *host, #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Request *scp) -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) -static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Cmnd *scp) #else -static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Cmnd scp) +static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Cmnd *scp) #endif { int orig_length, drive, wb_mode; @@ -161,10 +148,8 @@ static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Cmnd scp) } #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) gdth_do_req(scp, &gdtcmd, cmnd, 30); -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) - gdth_do_cmd(scp, &gdtcmd, cmnd, 30); #else - gdth_do_cmd(&scp, &gdtcmd, cmnd, 30); + gdth_do_cmd(scp, &gdtcmd, cmnd, 30); #endif } } @@ -219,10 +204,8 @@ static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Cmnd scp) pcpar->write_back = wb_mode==1 ? 0:1; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) gdth_do_req(scp, &gdtcmd, cmnd, 30); -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) - gdth_do_cmd(scp, &gdtcmd, cmnd, 30); #else - gdth_do_cmd(&scp, &gdtcmd, cmnd, 30); + gdth_do_cmd(scp, &gdtcmd, cmnd, 30); #endif gdth_ioctl_free(hanum, GDTH_SCRATCH, ha->pscratch, paddr); printk("Done.\n"); @@ -243,18 +226,16 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length, int no_mdrv = 0, drv_no, is_mirr; ulong32 cnt; ulong64 paddr; + int rc = -ENOMEM; - gdth_cmd_str gdtcmd; - gdth_evt_str estr; + gdth_cmd_str *gdtcmd; + gdth_evt_str *estr; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) Scsi_Request *scp; Scsi_Device *sdev; -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) +#else Scsi_Cmnd *scp; Scsi_Device *sdev; -#else - Scsi_Cmnd scp; - Scsi_Device sdev; #endif char hrec[161]; struct timeval tv; @@ -266,10 +247,15 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length, gdth_defcnt_str *pdef; gdth_cdrinfo_str *pcdi; gdth_hget_str *phg; - char cmnd[MAX_COMMAND_SIZE]; + + gdtcmd = kmalloc(sizeof(*gdtcmd), GFP_KERNEL); + estr = kmalloc(sizeof(*estr), GFP_KERNEL); + if (!gdtcmd || !estr) + goto free_fail; + memset(cmnd, 0xff, 12); - memset(&gdtcmd, 0, sizeof(gdth_cmd_str)); + memset(gdtcmd, 0, sizeof(gdth_cmd_str)); TRACE2(("gdth_get_info() ha %d bus %d\n",hanum,busnum)); ha = HADATA(gdth_ctr_tab[hanum]); @@ -278,14 +264,14 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length, sdev = scsi_get_host_dev(host); scp = scsi_allocate_request(sdev, GFP_KERNEL); if (!scp) - return -ENOMEM; + goto free_fail; scp->sr_cmd_len = 12; scp->sr_use_sg = 0; #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) sdev = scsi_get_host_dev(host); scp = scsi_allocate_device(sdev, 1, FALSE); if (!scp) - return -ENOMEM; + goto free_fail; scp->cmd_len = 12; scp->use_sg = 0; #else @@ -387,12 +373,12 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length, /* 2.a statistics (and retries/reassigns) */ TRACE2(("pdr_statistics() chn %d\n",i)); pds = (gdth_dskstat_str *)(buf + GDTH_SCRATCH/4); - gdtcmd.Service = CACHESERVICE; - gdtcmd.OpCode = GDT_IOCTL; - gdtcmd.u.ioctl.p_param = paddr + GDTH_SCRATCH/4; - gdtcmd.u.ioctl.param_size = 3*GDTH_SCRATCH/4; - gdtcmd.u.ioctl.subfunc = DSK_STATISTICS | L_CTRL_PATTERN; - gdtcmd.u.ioctl.channel = ha->raw[i].address | INVALID_CHANNEL; + gdtcmd->Service = CACHESERVICE; + gdtcmd->OpCode = GDT_IOCTL; + gdtcmd->u.ioctl.p_param = paddr + GDTH_SCRATCH/4; + gdtcmd->u.ioctl.param_size = 3*GDTH_SCRATCH/4; + gdtcmd->u.ioctl.subfunc = DSK_STATISTICS | L_CTRL_PATTERN; + gdtcmd->u.ioctl.channel = ha->raw[i].address | INVALID_CHANNEL; pds->bid = ha->raw[i].local_no; pds->first = 0; pds->entries = ha->raw[i].pdev_cnt; @@ -401,14 +387,11 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length, if (pds->entries > cnt) pds->entries = cnt; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) - gdth_do_req(scp, &gdtcmd, cmnd, 30); + gdth_do_req(scp, gdtcmd, cmnd, 30); if (scp->sr_command->SCp.Status != S_OK) -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) - gdth_do_cmd(scp, &gdtcmd, cmnd, 30); - if (scp->SCp.Status != S_OK) #else - gdth_do_cmd(&scp, &gdtcmd, cmnd, 30); - if (scp.SCp.Status != S_OK) + gdth_do_cmd(scp, gdtcmd, cmnd, 30); + if (scp->SCp.Status != S_OK) #endif { pds->count = 0; @@ -420,22 +403,19 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length, TRACE2(("scsi_drv_info() chn %d dev %d\n", i, ha->raw[i].id_list[j])); pdi = (gdth_diskinfo_str *)buf; - gdtcmd.Service = CACHESERVICE; - gdtcmd.OpCode = GDT_IOCTL; - gdtcmd.u.ioctl.p_param = paddr; - gdtcmd.u.ioctl.param_size = sizeof(gdth_diskinfo_str); - gdtcmd.u.ioctl.subfunc = SCSI_DR_INFO | L_CTRL_PATTERN; - gdtcmd.u.ioctl.channel = + gdtcmd->Service = CACHESERVICE; + gdtcmd->OpCode = GDT_IOCTL; + gdtcmd->u.ioctl.p_param = paddr; + gdtcmd->u.ioctl.param_size = sizeof(gdth_diskinfo_str); + gdtcmd->u.ioctl.subfunc = SCSI_DR_INFO | L_CTRL_PATTERN; + gdtcmd->u.ioctl.channel = ha->raw[i].address | ha->raw[i].id_list[j]; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) - gdth_do_req(scp, &gdtcmd, cmnd, 30); + gdth_do_req(scp, gdtcmd, cmnd, 30); if (scp->sr_command->SCp.Status == S_OK) -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) - gdth_do_cmd(scp, &gdtcmd, cmnd, 30); - if (scp->SCp.Status == S_OK) #else - gdth_do_cmd(&scp, &gdtcmd, cmnd, 30); - if (scp.SCp.Status == S_OK) + gdth_do_cmd(scp, gdtcmd, cmnd, 30); + if (scp->SCp.Status == S_OK) #endif { strncpy(hrec,pdi->vendor,8); @@ -478,23 +458,20 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length, TRACE2(("scsi_drv_defcnt() chn %d dev %d\n", i, ha->raw[i].id_list[j])); pdef = (gdth_defcnt_str *)buf; - gdtcmd.Service = CACHESERVICE; - gdtcmd.OpCode = GDT_IOCTL; - gdtcmd.u.ioctl.p_param = paddr; - gdtcmd.u.ioctl.param_size = sizeof(gdth_defcnt_str); - gdtcmd.u.ioctl.subfunc = SCSI_DEF_CNT | L_CTRL_PATTERN; - gdtcmd.u.ioctl.channel = + gdtcmd->Service = CACHESERVICE; + gdtcmd->OpCode = GDT_IOCTL; + gdtcmd->u.ioctl.p_param = paddr; + gdtcmd->u.ioctl.param_size = sizeof(gdth_defcnt_str); + gdtcmd->u.ioctl.subfunc = SCSI_DEF_CNT | L_CTRL_PATTERN; + gdtcmd->u.ioctl.channel = ha->raw[i].address | ha->raw[i].id_list[j]; pdef->sddc_type = 0x08; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) - gdth_do_req(scp, &gdtcmd, cmnd, 30); + gdth_do_req(scp, gdtcmd, cmnd, 30); if (scp->sr_command->SCp.Status == S_OK) -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) - gdth_do_cmd(scp, &gdtcmd, cmnd, 30); - if (scp->SCp.Status == S_OK) #else - gdth_do_cmd(&scp, &gdtcmd, cmnd, 30); - if (scp.SCp.Status == S_OK) + gdth_do_cmd(scp, gdtcmd, cmnd, 30); + if (scp->SCp.Status == S_OK) #endif { size = sprintf(buffer+len, @@ -536,21 +513,18 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length, /* 3.a log. drive info */ TRACE2(("cache_drv_info() drive no %d\n",drv_no)); pcdi = (gdth_cdrinfo_str *)buf; - gdtcmd.Service = CACHESERVICE; - gdtcmd.OpCode = GDT_IOCTL; - gdtcmd.u.ioctl.p_param = paddr; - gdtcmd.u.ioctl.param_size = sizeof(gdth_cdrinfo_str); - gdtcmd.u.ioctl.subfunc = CACHE_DRV_INFO; - gdtcmd.u.ioctl.channel = drv_no; + gdtcmd->Service = CACHESERVICE; + gdtcmd->OpCode = GDT_IOCTL; + gdtcmd->u.ioctl.p_param = paddr; + gdtcmd->u.ioctl.param_size = sizeof(gdth_cdrinfo_str); + gdtcmd->u.ioctl.subfunc = CACHE_DRV_INFO; + gdtcmd->u.ioctl.channel = drv_no; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) - gdth_do_req(scp, &gdtcmd, cmnd, 30); + gdth_do_req(scp, gdtcmd, cmnd, 30); if (scp->sr_command->SCp.Status != S_OK) -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) - gdth_do_cmd(scp, &gdtcmd, cmnd, 30); - if (scp->SCp.Status != S_OK) #else - gdth_do_cmd(&scp, &gdtcmd, cmnd, 30); - if (scp.SCp.Status != S_OK) + gdth_do_cmd(scp, gdtcmd, cmnd, 30); + if (scp->SCp.Status != S_OK) #endif { break; @@ -649,21 +623,18 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length, /* 4.a array drive info */ TRACE2(("array_info() drive no %d\n",i)); pai = (gdth_arrayinf_str *)buf; - gdtcmd.Service = CACHESERVICE; - gdtcmd.OpCode = GDT_IOCTL; - gdtcmd.u.ioctl.p_param = paddr; - gdtcmd.u.ioctl.param_size = sizeof(gdth_arrayinf_str); - gdtcmd.u.ioctl.subfunc = ARRAY_INFO | LA_CTRL_PATTERN; - gdtcmd.u.ioctl.channel = i; + gdtcmd->Service = CACHESERVICE; + gdtcmd->OpCode = GDT_IOCTL; + gdtcmd->u.ioctl.p_param = paddr; + gdtcmd->u.ioctl.param_size = sizeof(gdth_arrayinf_str); + gdtcmd->u.ioctl.subfunc = ARRAY_INFO | LA_CTRL_PATTERN; + gdtcmd->u.ioctl.channel = i; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) - gdth_do_req(scp, &gdtcmd, cmnd, 30); + gdth_do_req(scp, gdtcmd, cmnd, 30); if (scp->sr_command->SCp.Status == S_OK) -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) - gdth_do_cmd(scp, &gdtcmd, cmnd, 30); - if (scp->SCp.Status == S_OK) #else - gdth_do_cmd(&scp, &gdtcmd, cmnd, 30); - if (scp.SCp.Status == S_OK) + gdth_do_cmd(scp, gdtcmd, cmnd, 30); + if (scp->SCp.Status == S_OK) #endif { if (pai->ai_state == 0) @@ -731,23 +702,20 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length, /* 5.a get host drive list */ TRACE2(("host_get() drv_no %d\n",i)); phg = (gdth_hget_str *)buf; - gdtcmd.Service = CACHESERVICE; - gdtcmd.OpCode = GDT_IOCTL; - gdtcmd.u.ioctl.p_param = paddr; - gdtcmd.u.ioctl.param_size = sizeof(gdth_hget_str); - gdtcmd.u.ioctl.subfunc = HOST_GET | LA_CTRL_PATTERN; - gdtcmd.u.ioctl.channel = i; + gdtcmd->Service = CACHESERVICE; + gdtcmd->OpCode = GDT_IOCTL; + gdtcmd->u.ioctl.p_param = paddr; + gdtcmd->u.ioctl.param_size = sizeof(gdth_hget_str); + gdtcmd->u.ioctl.subfunc = HOST_GET | LA_CTRL_PATTERN; + gdtcmd->u.ioctl.channel = i; phg->entries = MAX_HDRIVES; phg->offset = GDTOFFSOF(gdth_hget_str, entry[0]); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) - gdth_do_req(scp, &gdtcmd, cmnd, 30); + gdth_do_req(scp, gdtcmd, cmnd, 30); if (scp->sr_command->SCp.Status != S_OK) -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) - gdth_do_cmd(scp, &gdtcmd, cmnd, 30); - if (scp->SCp.Status != S_OK) #else - gdth_do_cmd(&scp, &gdtcmd, cmnd, 30); - if (scp.SCp.Status != S_OK) + gdth_do_cmd(scp, gdtcmd, cmnd, 30); + if (scp->SCp.Status != S_OK) #endif { ha->hdr[i].ldr_no = i; @@ -799,14 +767,14 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length, len += size; pos = begin + len; for (id = -1;;) { - id = gdth_read_event(ha, id, &estr); - if (estr.event_source == 0) + id = gdth_read_event(ha, id, estr); + if (estr->event_source == 0) break; - if (estr.event_data.eu.driver.ionode == hanum && - estr.event_source == ES_ASYNC) { - gdth_log_event(&estr.event_data, hrec); + if (estr->event_data.eu.driver.ionode == hanum && + estr->event_source == ES_ASYNC) { + gdth_log_event(&estr->event_data, hrec); do_gettimeofday(&tv); - sec = (int)(tv.tv_sec - estr.first_stamp); + sec = (int)(tv.tv_sec - estr->first_stamp); if (sec < 0) sec = 0; size = sprintf(buffer+len," date- %02d:%02d:%02d\t%s\n", sec/3600, sec%3600/60, sec%60, hrec); @@ -826,7 +794,7 @@ stop_output: #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) scsi_release_request(scp); scsi_free_host_dev(sdev); -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) +#else scsi_release_command(scp); scsi_free_host_dev(sdev); #endif @@ -836,7 +804,12 @@ stop_output: len = length; TRACE2(("get_info() len %d pos %d begin %d offset %d length %d size %d\n", len,(int)pos,(int)begin,(int)offset,length,size)); - return(len); + rc = len; + +free_fail: + kfree(gdtcmd); + kfree(estr); + return rc; } @@ -864,13 +837,7 @@ static void gdth_do_cmd(Scsi_Cmnd *scp, gdth_cmd_str *gdtcmd, char *cmnd, int timeout) { unsigned bufflen; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,7) DECLARE_COMPLETION(wait); -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) - DECLARE_MUTEX_LOCKED(sem); -#else - struct semaphore sem = MUTEX_LOCKED; -#endif TRACE2(("gdth_do_cmd()\n")); if (gdtcmd != NULL) { @@ -880,22 +847,11 @@ static void gdth_do_cmd(Scsi_Cmnd *scp, gdth_cmd_str *gdtcmd, scp->SCp.this_residual = DEFAULT_PRI; bufflen = 0; } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,7) + scp->request.rq_status = RQ_SCSI_BUSY; scp->request.waiting = &wait; scsi_do_cmd(scp, cmnd, gdtcmd, bufflen, gdth_scsi_done, timeout*HZ, 1); wait_for_completion(&wait); -#else - scp->request.sem = &sem; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) - scsi_do_cmd(scp, cmnd, gdtcmd, bufflen, gdth_scsi_done, timeout*HZ, 1); -#else - spin_lock_irq(&io_request_lock); - scsi_do_cmd(scp, cmnd, gdtcmd, bufflen, gdth_scsi_done, timeout*HZ, 1); - spin_unlock_irq(&io_request_lock); -#endif - down(&sem); -#endif } #endif @@ -907,14 +863,10 @@ void gdth_scsi_done(Scsi_Cmnd *scp) scp->request->rq_status = RQ_SCSI_DONE; if (scp->request->waiting != NULL) complete(scp->request->waiting); -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,7) +#else scp->request.rq_status = RQ_SCSI_DONE; if (scp->request.waiting != NULL) complete(scp->request.waiting); -#else - scp->request.rq_status = RQ_SCSI_DONE; - if (scp->request.sem != NULL) - up(scp->request.sem); #endif } @@ -929,7 +881,7 @@ static char *gdth_ioctl_alloc(int hanum, int size, int scratch, return NULL; ha = HADATA(gdth_ctr_tab[hanum]); - GDTH_LOCK_HA(ha, flags); + spin_lock_irqsave(&ha->smp_lock, flags); if (!ha->scratch_busy && size <= GDTH_SCRATCH) { ha->scratch_busy = TRUE; @@ -938,19 +890,13 @@ static char *gdth_ioctl_alloc(int hanum, int size, int scratch, } else if (scratch) { ret_val = NULL; } else { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) dma_addr_t dma_addr; ret_val = pci_alloc_consistent(ha->pdev, size, &dma_addr); *paddr = dma_addr; -#else - ret_val = scsi_init_malloc(size, GFP_ATOMIC | GFP_DMA); - if (ret_val) - *paddr = virt_to_bus(ret_val); -#endif } - GDTH_UNLOCK_HA(ha, flags); + spin_unlock_irqrestore(&ha->smp_lock, flags); return ret_val; } @@ -960,19 +906,15 @@ static void gdth_ioctl_free(int hanum, int size, char *buf, ulong64 paddr) ulong flags; ha = HADATA(gdth_ctr_tab[hanum]); - GDTH_LOCK_HA(ha, flags); + spin_lock_irqsave(&ha->smp_lock, flags); if (buf == ha->pscratch) { ha->scratch_busy = FALSE; } else { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) pci_free_consistent(ha->pdev, size, buf, paddr); -#else - scsi_init_free((void *)buf, size); -#endif } - GDTH_UNLOCK_HA(ha, flags); + spin_unlock_irqrestore(&ha->smp_lock, flags); } #ifdef GDTH_IOCTL_PROC @@ -983,14 +925,14 @@ static int gdth_ioctl_check_bin(int hanum, ushort size) int ret_val; ha = HADATA(gdth_ctr_tab[hanum]); - GDTH_LOCK_HA(ha, flags); + spin_lock_irqsave(&ha->smp_lock, flags); ret_val = FALSE; if (ha->scratch_busy) { if (((gdth_iord_str *)ha->pscratch)->size == (ulong32)size) ret_val = TRUE; } - GDTH_UNLOCK_HA(ha, flags); + spin_unlock_irqrestore(&ha->smp_lock, flags); return ret_val; } #endif @@ -1004,36 +946,23 @@ static void gdth_wait_completion(int hanum, int busnum, int id) unchar b, t; ha = HADATA(gdth_ctr_tab[hanum]); - GDTH_LOCK_HA(ha, flags); + spin_lock_irqsave(&ha->smp_lock, flags); for (i = 0; i < GDTH_MAXCMDS; ++i) { scp = ha->cmd_tab[i].cmnd; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel; t = scp->device->id; -#else - b = virt_ctr ? NUMDATA(scp->host)->busnum : scp->channel; - t = scp->target; -#endif if (!SPECIAL_SCP(scp) && t == (unchar)id && b == (unchar)busnum) { scp->SCp.have_data_in = 0; - GDTH_UNLOCK_HA(ha, flags); + spin_unlock_irqrestore(&ha->smp_lock, flags); while (!scp->SCp.have_data_in) barrier(); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) - GDTH_LOCK_SCSI_DONE(scp->device->host, flags); - scp->scsi_done(scp); - GDTH_UNLOCK_SCSI_DONE(scp->device->host, flags); -#else - GDTH_LOCK_SCSI_DONE(flags); - scp->scsi_done(scp); - GDTH_UNLOCK_SCSI_DONE(flags); -#endif - GDTH_LOCK_HA(ha, flags); + spin_lock_irqsave(&ha->smp_lock, flags); } } - GDTH_UNLOCK_HA(ha, flags); + spin_unlock_irqrestore(&ha->smp_lock, flags); } static void gdth_stop_timeout(int hanum, int busnum, int id) @@ -1044,22 +973,17 @@ static void gdth_stop_timeout(int hanum, int busnum, int id) unchar b, t; ha = HADATA(gdth_ctr_tab[hanum]); - GDTH_LOCK_HA(ha, flags); + spin_lock_irqsave(&ha->smp_lock, flags); for (scp = ha->req_first; scp; scp = (Scsi_Cmnd *)scp->SCp.ptr) { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel; t = scp->device->id; -#else - b = virt_ctr ? NUMDATA(scp->host)->busnum : scp->channel; - t = scp->target; -#endif if (t == (unchar)id && b == (unchar)busnum) { TRACE2(("gdth_stop_timeout(): update_timeout()\n")); scp->SCp.buffers_residual = gdth_update_timeout(hanum, scp, 0); } } - GDTH_UNLOCK_HA(ha, flags); + spin_unlock_irqrestore(&ha->smp_lock, flags); } static void gdth_start_timeout(int hanum, int busnum, int id) @@ -1070,22 +994,17 @@ static void gdth_start_timeout(int hanum, int busnum, int id) unchar b, t; ha = HADATA(gdth_ctr_tab[hanum]); - GDTH_LOCK_HA(ha, flags); + spin_lock_irqsave(&ha->smp_lock, flags); for (scp = ha->req_first; scp; scp = (Scsi_Cmnd *)scp->SCp.ptr) { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel; t = scp->device->id; -#else - b = virt_ctr ? NUMDATA(scp->host)->busnum : scp->channel; - t = scp->target; -#endif if (t == (unchar)id && b == (unchar)busnum) { TRACE2(("gdth_start_timeout(): update_timeout()\n")); gdth_update_timeout(hanum, scp, scp->SCp.buffers_residual); } } - GDTH_UNLOCK_HA(ha, flags); + spin_unlock_irqrestore(&ha->smp_lock, flags); } static int gdth_update_timeout(int hanum, Scsi_Cmnd *scp, int timeout) diff --git a/drivers/scsi/gdth_proc.h b/drivers/scsi/gdth_proc.h index 5fb191625c3339..295e825e2c6006 100644 --- a/drivers/scsi/gdth_proc.h +++ b/drivers/scsi/gdth_proc.h @@ -14,14 +14,10 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length, static void gdth_do_req(Scsi_Request *srp, gdth_cmd_str *cmd, char *cmnd, int timeout); static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Request *scp); -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) +#else static void gdth_do_cmd(Scsi_Cmnd *scp, gdth_cmd_str *cmd, char *cmnd, int timeout); static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Cmnd *scp); -#else -static void gdth_do_cmd(Scsi_Cmnd *scp, gdth_cmd_str *cmd, - char *cmnd, int timeout); -static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Cmnd scp); #endif static char *gdth_ioctl_alloc(int hanum, int size, int scratch, diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c index f8721d9f558fb4..e89f76e5dd531f 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/drivers/scsi/ibmvscsi/ibmvscsi.c @@ -87,7 +87,7 @@ static int max_channel = 3; static int init_timeout = 5; static int max_requests = 50; -#define IBMVSCSI_VERSION "1.5.1" +#define IBMVSCSI_VERSION "1.5.5" MODULE_DESCRIPTION("IBM Virtual SCSI"); MODULE_AUTHOR("Dave Boutcher"); @@ -256,6 +256,7 @@ static void init_event_struct(struct srp_event_struct *evt_struct, { evt_struct->cmnd = NULL; evt_struct->cmnd_done = NULL; + evt_struct->sync_srp = NULL; evt_struct->crq.format = format; evt_struct->crq.timeout = timeout; evt_struct->done = done; @@ -467,7 +468,7 @@ static int map_data_for_srp_cmd(struct scsi_cmnd *cmd, static int ibmvscsi_send_srp_event(struct srp_event_struct *evt_struct, struct ibmvscsi_host_data *hostdata) { - struct scsi_cmnd *cmnd = evt_struct->cmnd; + struct scsi_cmnd *cmnd; u64 *crq_as_u64 = (u64 *) &evt_struct->crq; int rc; @@ -479,22 +480,15 @@ static int ibmvscsi_send_srp_event(struct srp_event_struct *evt_struct, if ((evt_struct->crq.format == VIOSRP_SRP_FORMAT) && (atomic_dec_if_positive(&hostdata->request_limit) < 0)) { /* See if the adapter is disabled */ - if (atomic_read(&hostdata->request_limit) < 0) { - if (cmnd) - cmnd->result = DID_ERROR << 16; - if (evt_struct->cmnd_done) - evt_struct->cmnd_done(cmnd); - unmap_cmd_data(&evt_struct->iu.srp.cmd, - hostdata->dev); - free_event_struct(&hostdata->pool, evt_struct); - return 0; - } else { - printk("ibmvscsi: Warning, request_limit exceeded\n"); - unmap_cmd_data(&evt_struct->iu.srp.cmd, - hostdata->dev); - free_event_struct(&hostdata->pool, evt_struct); - return SCSI_MLQUEUE_HOST_BUSY; - } + if (atomic_read(&hostdata->request_limit) < 0) + goto send_error; + + printk(KERN_WARNING + "ibmvscsi: Warning, request_limit exceeded\n"); + unmap_cmd_data(&evt_struct->iu.srp.cmd, + hostdata->dev); + free_event_struct(&hostdata->pool, evt_struct); + return SCSI_MLQUEUE_HOST_BUSY; } /* Copy the IU into the transfer area */ @@ -511,18 +505,24 @@ static int ibmvscsi_send_srp_event(struct srp_event_struct *evt_struct, ibmvscsi_send_crq(hostdata, crq_as_u64[0], crq_as_u64[1])) != 0) { list_del(&evt_struct->list); - cmnd = evt_struct->cmnd; printk(KERN_ERR "ibmvscsi: failed to send event struct rc %d\n", rc); - unmap_cmd_data(&evt_struct->iu.srp.cmd, hostdata->dev); - free_event_struct(&hostdata->pool, evt_struct); - if (cmnd) - cmnd->result = DID_ERROR << 16; - if (evt_struct->cmnd_done) - evt_struct->cmnd_done(cmnd); + goto send_error; } return 0; + + send_error: + unmap_cmd_data(&evt_struct->iu.srp.cmd, hostdata->dev); + + if ((cmnd = evt_struct->cmnd) != NULL) { + cmnd->result = DID_ERROR << 16; + evt_struct->cmnd_done(cmnd); + } else if (evt_struct->done) + evt_struct->done(evt_struct); + + free_event_struct(&hostdata->pool, evt_struct); + return 0; } /** @@ -537,6 +537,13 @@ static void handle_cmd_rsp(struct srp_event_struct *evt_struct) struct srp_rsp *rsp = &evt_struct->xfer_iu->srp.rsp; struct scsi_cmnd *cmnd = evt_struct->cmnd; + if (unlikely(rsp->type != SRP_RSP_TYPE)) { + if (printk_ratelimit()) + printk(KERN_WARNING + "ibmvscsi: bad SRP RSP type %d\n", + rsp->type); + } + if (cmnd) { cmnd->result = rsp->status; if (((cmnd->result >> 1) & 0x1f) == CHECK_CONDITION) @@ -641,11 +648,16 @@ static void adapter_info_rsp(struct srp_event_struct *evt_struct) evt_struct->xfer_iu->mad.adapter_info.common.status); } else { printk("ibmvscsi: host srp version: %s, " - "host partition %s (%d), OS %d\n", + "host partition %s (%d), OS %d, max io %u\n", hostdata->madapter_info.srp_version, hostdata->madapter_info.partition_name, hostdata->madapter_info.partition_number, - hostdata->madapter_info.os_type); + hostdata->madapter_info.os_type, + hostdata->madapter_info.port_max_txu[0]); + + if (hostdata->madapter_info.port_max_txu[0]) + hostdata->host->max_sectors = + hostdata->madapter_info.port_max_txu[0] >> 9; } } @@ -796,6 +808,10 @@ static int send_srp_login(struct ibmvscsi_host_data *hostdata) */ static void sync_completion(struct srp_event_struct *evt_struct) { + /* copy the response back */ + if (evt_struct->sync_srp) + *evt_struct->sync_srp = *evt_struct->xfer_iu; + complete(&evt_struct->comp); } @@ -810,6 +826,8 @@ static int ibmvscsi_eh_abort_handler(struct scsi_cmnd *cmd) struct srp_tsk_mgmt *tsk_mgmt; struct srp_event_struct *evt; struct srp_event_struct *tmp_evt, *found_evt; + union viosrp_iu srp_rsp; + int rsp_rc; u16 lun = lun_from_dev(cmd->device); /* First, find this command in our sent list so we can figure @@ -849,6 +867,7 @@ static int ibmvscsi_eh_abort_handler(struct scsi_cmnd *cmd) printk(KERN_INFO "ibmvscsi: aborting command. lun 0x%lx, tag 0x%lx\n", tsk_mgmt->lun, tsk_mgmt->managed_task_tag); + evt->sync_srp = &srp_rsp; init_completion(&evt->comp); if (ibmvscsi_send_srp_event(evt, hostdata) != 0) { printk(KERN_ERR "ibmvscsi: failed to send abort() event\n"); @@ -859,6 +878,29 @@ static int ibmvscsi_eh_abort_handler(struct scsi_cmnd *cmd) wait_for_completion(&evt->comp); spin_lock_irq(hostdata->host->host_lock); + /* make sure we got a good response */ + if (unlikely(srp_rsp.srp.generic.type != SRP_RSP_TYPE)) { + if (printk_ratelimit()) + printk(KERN_WARNING + "ibmvscsi: abort bad SRP RSP type %d\n", + srp_rsp.srp.generic.type); + return FAILED; + } + + if (srp_rsp.srp.rsp.rspvalid) + rsp_rc = *((int *)srp_rsp.srp.rsp.sense_and_response_data); + else + rsp_rc = srp_rsp.srp.rsp.status; + + if (rsp_rc) { + if (printk_ratelimit()) + printk(KERN_WARNING + "ibmvscsi: abort code %d for task tag 0x%lx\n", + rsp_rc, + tsk_mgmt->managed_task_tag); + return FAILED; + } + /* Because we dropped the spinlock above, it's possible * The event is no longer in our list. Make sure it didn't * complete while we were aborting @@ -871,13 +913,17 @@ static int ibmvscsi_eh_abort_handler(struct scsi_cmnd *cmd) } } + if (found_evt == NULL) { + printk(KERN_INFO + "ibmvscsi: aborted task tag 0x%lx completed\n", + tsk_mgmt->managed_task_tag); + return SUCCESS; + } + printk(KERN_INFO "ibmvscsi: successfully aborted task tag 0x%lx\n", tsk_mgmt->managed_task_tag); - if (found_evt == NULL) - return SUCCESS; - cmd->result = (DID_ABORT << 16); list_del(&found_evt->list); unmap_cmd_data(&found_evt->iu.srp.cmd, found_evt->hostdata->dev); @@ -899,6 +945,8 @@ static int ibmvscsi_eh_device_reset_handler(struct scsi_cmnd *cmd) struct srp_tsk_mgmt *tsk_mgmt; struct srp_event_struct *evt; struct srp_event_struct *tmp_evt, *pos; + union viosrp_iu srp_rsp; + int rsp_rc; u16 lun = lun_from_dev(cmd->device); evt = get_event_struct(&hostdata->pool); @@ -923,6 +971,7 @@ static int ibmvscsi_eh_device_reset_handler(struct scsi_cmnd *cmd) printk(KERN_INFO "ibmvscsi: resetting device. lun 0x%lx\n", tsk_mgmt->lun); + evt->sync_srp = &srp_rsp; init_completion(&evt->comp); if (ibmvscsi_send_srp_event(evt, hostdata) != 0) { printk(KERN_ERR "ibmvscsi: failed to send reset event\n"); @@ -933,6 +982,29 @@ static int ibmvscsi_eh_device_reset_handler(struct scsi_cmnd *cmd) wait_for_completion(&evt->comp); spin_lock_irq(hostdata->host->host_lock); + /* make sure we got a good response */ + if (unlikely(srp_rsp.srp.generic.type != SRP_RSP_TYPE)) { + if (printk_ratelimit()) + printk(KERN_WARNING + "ibmvscsi: reset bad SRP RSP type %d\n", + srp_rsp.srp.generic.type); + return FAILED; + } + + if (srp_rsp.srp.rsp.rspvalid) + rsp_rc = *((int *)srp_rsp.srp.rsp.sense_and_response_data); + else + rsp_rc = srp_rsp.srp.rsp.status; + + if (rsp_rc) { + if (printk_ratelimit()) + printk(KERN_WARNING + "ibmvscsi: reset code %d for task tag 0x%lx\n", + rsp_rc, + tsk_mgmt->managed_task_tag); + return FAILED; + } + /* We need to find all commands for this LUN that have not yet been * responded to, and fail them with DID_RESET */ @@ -1048,6 +1120,13 @@ void ibmvscsi_handle_crq(struct viosrp_crq *crq, return; } + if (atomic_read(&evt_struct->free)) { + printk(KERN_ERR + "ibmvscsi: received duplicate correlation_token 0x%p!\n", + (void *)crq->IU_data_ptr); + return; + } + if (crq->format == VIOSRP_SRP_FORMAT) atomic_add(evt_struct->xfer_iu->srp.rsp.request_limit_delta, &hostdata->request_limit); @@ -1295,6 +1374,7 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id) hostdata->host = host; hostdata->dev = dev; atomic_set(&hostdata->request_limit, -1); + hostdata->host->max_sectors = 32 * 8; /* default max I/O 32 pages */ if (ibmvscsi_init_crq_queue(&hostdata->queue, hostdata, max_requests) != 0) { @@ -1326,7 +1406,7 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id) */ for (wait_switch = jiffies + (init_timeout * HZ); time_before(jiffies, wait_switch) && - atomic_read(&hostdata->request_limit) < 0;) { + atomic_read(&hostdata->request_limit) < 2;) { msleep(10); } diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.h b/drivers/scsi/ibmvscsi/ibmvscsi.h index dbe1735e593422..1030b703c30e93 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.h +++ b/drivers/scsi/ibmvscsi/ibmvscsi.h @@ -67,6 +67,7 @@ struct srp_event_struct { union viosrp_iu iu; void (*cmnd_done) (struct scsi_cmnd *); struct completion comp; + union viosrp_iu *sync_srp; }; /* a pool of event structs for use */ diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index ad8a86184dea54..f0059b1f7a01af 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -2610,23 +2610,19 @@ static int ipr_free_dump(struct ipr_ioa_cfg *ioa_cfg) { return 0; }; #endif /** - * ipr_store_queue_depth - Change the device's queue depth - * @dev: device struct - * @buf: buffer + * ipr_change_queue_depth - Change the device's queue depth + * @sdev: scsi device struct + * @qdepth: depth to set * * Return value: - * number of bytes printed to buffer + * actual depth set **/ -static ssize_t ipr_store_queue_depth(struct device *dev, - const char *buf, size_t count) +static int ipr_change_queue_depth(struct scsi_device *sdev, int qdepth) { - struct scsi_device *sdev = to_scsi_device(dev); struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *)sdev->host->hostdata; struct ipr_resource_entry *res; - int qdepth = simple_strtoul(buf, NULL, 10); int tagged = 0; unsigned long lock_flags = 0; - ssize_t len = -ENXIO; spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); res = (struct ipr_resource_entry *)sdev->hostdata; @@ -2635,23 +2631,13 @@ static ssize_t ipr_store_queue_depth(struct device *dev, if (ipr_is_gscsi(res) && res->tcq_active) tagged = MSG_ORDERED_TAG; - - len = strlen(buf); } spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); scsi_adjust_queue_depth(sdev, tagged, qdepth); - return len; + return qdepth; } -static struct device_attribute ipr_queue_depth_attr = { - .attr = { - .name = "queue_depth", - .mode = S_IRUSR | S_IWUSR, - }, - .store = ipr_store_queue_depth -}; - /** * ipr_show_tcq_enable - Show if the device is enabled for tcqing * @dev: device struct @@ -2760,7 +2746,6 @@ static struct device_attribute ipr_adapter_handle_attr = { }; static struct device_attribute *ipr_dev_attrs[] = { - &ipr_queue_depth_attr, &ipr_tcqing_attr, &ipr_adapter_handle_attr, NULL, @@ -3961,6 +3946,7 @@ static struct scsi_host_template driver_template = { .slave_alloc = ipr_slave_alloc, .slave_configure = ipr_slave_configure, .slave_destroy = ipr_slave_destroy, + .change_queue_depth = ipr_change_queue_depth, .bios_param = ipr_biosparam, .can_queue = IPR_MAX_COMMANDS, .this_id = -1, diff --git a/drivers/scsi/lasi700.c b/drivers/scsi/lasi700.c index 35110f4d13c514..25729f3f81648b 100644 --- a/drivers/scsi/lasi700.c +++ b/drivers/scsi/lasi700.c @@ -54,13 +54,33 @@ #include <scsi/scsi_transport.h> #include <scsi/scsi_transport_spi.h> -#include "lasi700.h" #include "53c700.h" MODULE_AUTHOR("James Bottomley"); MODULE_DESCRIPTION("lasi700 SCSI Driver"); MODULE_LICENSE("GPL"); +#define LASI_700_SVERSION 0x00071 +#define LASI_710_SVERSION 0x00082 + +#define LASI700_ID_TABLE { \ + .hw_type = HPHW_FIO, \ + .sversion = LASI_700_SVERSION, \ + .hversion = HVERSION_ANY_ID, \ + .hversion_rev = HVERSION_REV_ANY_ID, \ +} + +#define LASI710_ID_TABLE { \ + .hw_type = HPHW_FIO, \ + .sversion = LASI_710_SVERSION, \ + .hversion = HVERSION_ANY_ID, \ + .hversion_rev = HVERSION_REV_ANY_ID, \ +} + +#define LASI700_CLOCK 25 +#define LASI710_CLOCK 40 +#define LASI_SCSI_CORE_OFFSET 0x100 + static struct parisc_device_id lasi700_ids[] = { LASI700_ID_TABLE, LASI710_ID_TABLE, diff --git a/drivers/scsi/lasi700.h b/drivers/scsi/lasi700.h deleted file mode 100644 index 244a648824ee36..00000000000000 --- a/drivers/scsi/lasi700.h +++ /dev/null @@ -1,49 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8 -*- */ - -/* PARISC LASI driver for the 53c700 chip - * - * Copyright (C) 2001 by James.Bottomley@HansenPartnership.com -**----------------------------------------------------------------------------- -** -** This program is free software; you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation; either version 2 of the License, or -** (at your option) any later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with this program; if not, write to the Free Software -** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -** -**----------------------------------------------------------------------------- - */ - -#ifndef _LASI700_H -#define _LASI700_H - -#define LASI_710_SVERSION 0x082 -#define LASI_700_SVERSION 0x071 - -#define LASI700_ID_TABLE { \ - .hw_type = HPHW_FIO, \ - .sversion = LASI_700_SVERSION, \ - .hversion = HVERSION_ANY_ID, \ - .hversion_rev = HVERSION_REV_ANY_ID, \ -} - -#define LASI710_ID_TABLE { \ - .hw_type = HPHW_FIO, \ - .sversion = LASI_710_SVERSION, \ - .hversion = HVERSION_ANY_ID, \ - .hversion_rev = HVERSION_REV_ANY_ID, \ -} - -#define LASI700_CLOCK 25 -#define LASI710_CLOCK 40 -#define LASI_SCSI_CORE_OFFSET 0x100 - -#endif diff --git a/drivers/scsi/osst.c b/drivers/scsi/osst.c index 8b81553a3ab6c4..4aff0d68298d20 100644 --- a/drivers/scsi/osst.c +++ b/drivers/scsi/osst.c @@ -13,18 +13,18 @@ order) Klaus Ehrenfried, Wolfgang Denk, Steve Hirsch, Andreas Koppenh"ofer, Michael Leodolter, Eyal Lebedinsky, J"org Weule, and Eric Youngdale. - Copyright 1992 - 2002 Kai Makisara / Willem Riede - email Kai.Makisara@metla.fi / osst@riede.org + Copyright 1992 - 2002 Kai Makisara / 2000 - 2004 Willem Riede + email osst@riede.org - $Header: /cvsroot/osst/Driver/osst.c,v 1.70 2003/12/23 14:22:12 wriede Exp $ + $Header: /cvsroot/osst/Driver/osst.c,v 1.73 2005/01/01 21:13:34 wriede Exp $ Microscopic alterations - Rik Ling, 2000/12/21 Last st.c sync: Tue Oct 15 22:01:04 2002 by makisara Some small formal changes - aeb, 950809 */ -static const char * cvsid = "$Id: osst.c,v 1.70 2003/12/23 14:22:12 wriede Exp $"; -const char * osst_version = "0.99.1"; +static const char * cvsid = "$Id: osst.c,v 1.73 2005/01/01 21:13:34 wriede Exp $"; +const char * osst_version = "0.99.3"; /* The "failure to reconnect" firmware bug */ #define OSST_FW_NEED_POLL_MIN 10601 /*(107A)*/ @@ -36,6 +36,7 @@ const char * osst_version = "0.99.1"; #include <linux/fs.h> #include <linux/kernel.h> #include <linux/sched.h> +#include <linux/proc_fs.h> #include <linux/mm.h> #include <linux/init.h> #include <linux/string.h> @@ -46,6 +47,7 @@ const char * osst_version = "0.99.1"; #include <linux/spinlock.h> #include <linux/vmalloc.h> #include <linux/blkdev.h> +#include <linux/moduleparam.h> #include <linux/devfs_fs_kernel.h> #include <linux/delay.h> #include <asm/uaccess.h> @@ -82,13 +84,13 @@ MODULE_AUTHOR("Willem Riede"); MODULE_DESCRIPTION("OnStream {DI-|FW-|SC-|USB}{30|50} Tape Driver"); MODULE_LICENSE("GPL"); -module_param(max_dev, int, 0); +module_param(max_dev, int, 0444); MODULE_PARM_DESC(max_dev, "Maximum number of OnStream Tape Drives to attach (4)"); -module_param(write_threshold_kbs, int, 0); +module_param(write_threshold_kbs, int, 0644); MODULE_PARM_DESC(write_threshold_kbs, "Asynchronous write threshold (KB; 32)"); -module_param(max_sg_segs, int, 0); +module_param(max_sg_segs, int, 0644); MODULE_PARM_DESC(max_sg_segs, "Maximum number of scatter/gather segments to use (9)"); #else static struct osst_dev_parm { @@ -119,10 +121,10 @@ static int debugging = 1; // #define OSST_INJECT_ERRORS 1 #endif -#define MAX_RETRIES 2 -#define MAX_READ_RETRIES 0 -#define MAX_WRITE_RETRIES 0 -#define MAX_READY_RETRIES 0 +/* Do not retry! The drive firmware already retries when appropriate, + and when it tries to tell us something, we had better listen... */ +#define MAX_RETRIES 0 + #define NO_TAPE NOT_READY #define OSST_WAIT_POSITION_COMPLETE (HZ > 200 ? HZ / 200 : 1) @@ -147,19 +149,19 @@ static int osst_max_sg_segs = OSST_MAX_SG; static int osst_max_dev = OSST_MAX_TAPES; static int osst_nr_dev; -static OS_Scsi_Tape **os_scsi_tapes = NULL; -static rwlock_t os_scsi_tapes_lock = RW_LOCK_UNLOCKED; +static struct osst_tape **os_scsi_tapes = NULL; +static rwlock_t os_scsi_tapes_lock = RW_LOCK_UNLOCKED; static int modes_defined = FALSE; -static OSST_buffer *new_tape_buffer(int, int, int); -static int enlarge_buffer(OSST_buffer *, int); -static void normalize_buffer(OSST_buffer *); -static int append_to_buffer(const char __user *, OSST_buffer *, int); -static int from_buffer(OSST_buffer *, char __user *, int); -static int osst_zero_buffer_tail(OSST_buffer *); -static int osst_copy_to_buffer(OSST_buffer *, unsigned char *); -static int osst_copy_from_buffer(OSST_buffer *, unsigned char *); +static struct osst_buffer *new_tape_buffer(int, int, int); +static int enlarge_buffer(struct osst_buffer *, int); +static void normalize_buffer(struct osst_buffer *); +static int append_to_buffer(const char __user *, struct osst_buffer *, int); +static int from_buffer(struct osst_buffer *, char __user *, int); +static int osst_zero_buffer_tail(struct osst_buffer *); +static int osst_copy_to_buffer(struct osst_buffer *, unsigned char *); +static int osst_copy_from_buffer(struct osst_buffer *, unsigned char *); static int osst_probe(struct device *); static int osst_remove(struct device *); @@ -173,17 +175,18 @@ struct scsi_driver osst_template = { } }; -static int osst_int_ioctl(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt, unsigned int cmd_in,unsigned long arg); +static int osst_int_ioctl(struct osst_tape *STp, struct scsi_request ** aSRpnt, + unsigned int cmd_in, unsigned long arg); -static int osst_set_frame_position(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt, int frame, int skip); +static int osst_set_frame_position(struct osst_tape *STp, struct scsi_request ** aSRpnt, int frame, int skip); -static int osst_get_frame_position(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt); +static int osst_get_frame_position(struct osst_tape *STp, struct scsi_request ** aSRpnt); -static int osst_flush_write_buffer(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt); +static int osst_flush_write_buffer(struct osst_tape *STp, struct scsi_request ** aSRpnt); -static int osst_write_error_recovery(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int pending); +static int osst_write_error_recovery(struct osst_tape * STp, struct scsi_request ** aSRpnt, int pending); -static inline char *tape_name(OS_Scsi_Tape *tape) +static inline char *tape_name(struct osst_tape *tape) { return tape->drive->disk_name; } @@ -191,7 +194,7 @@ static inline char *tape_name(OS_Scsi_Tape *tape) /* Routines that handle the interaction with mid-layer SCSI routines */ /* Convert the result to success code */ -static int osst_chk_result(OS_Scsi_Tape * STp, Scsi_Request * SRpnt) +static int osst_chk_result(struct osst_tape * STp, struct scsi_request * SRpnt) { char *name = tape_name(STp); int result = SRpnt->sr_result; @@ -222,7 +225,7 @@ static int osst_chk_result(OS_Scsi_Tape * STp, Scsi_Request * SRpnt) if (driver_byte(result) & DRIVER_SENSE) print_req_sense("osst ", SRpnt); } -// else + else #endif if (!(driver_byte(result) & DRIVER_SENSE) || ((sense[0] & 0x70) == 0x70 && @@ -234,7 +237,7 @@ static int osst_chk_result(OS_Scsi_Tape * STp, Scsi_Request * SRpnt) SRpnt->sr_cmnd[0] != MODE_SENSE && SRpnt->sr_cmnd[0] != TEST_UNIT_READY)) { /* Abnormal conditions for tape */ if (driver_byte(result) & DRIVER_SENSE) { - printk(KERN_WARNING "%s:W: Command with sense data: ", name); + printk(KERN_WARNING "%s:W: Command with sense data:\n", name); print_req_sense("osst:", SRpnt); } else { @@ -281,7 +284,7 @@ static int osst_chk_result(OS_Scsi_Tape * STp, Scsi_Request * SRpnt) /* Wakeup from interrupt */ static void osst_sleep_done (Scsi_Cmnd * SCpnt) { - OS_Scsi_Tape * STp = container_of(SCpnt->request->rq_disk->private_data, OS_Scsi_Tape, driver); + struct osst_tape * STp = container_of(SCpnt->request->rq_disk->private_data, struct osst_tape, driver); if ((STp->buffer)->writing && (SCpnt->sense_buffer[0] & 0x70) == 0x70 && @@ -307,7 +310,7 @@ static void osst_sleep_done (Scsi_Cmnd * SCpnt) /* Do the scsi command. Waits until command performed if do_wait is true. Otherwise osst_write_behind_check() is used to check that the command has finished. */ -static Scsi_Request * osst_do_scsi(Scsi_Request *SRpnt, OS_Scsi_Tape *STp, +static struct scsi_request * osst_do_scsi(struct scsi_request *SRpnt, struct osst_tape *STp, unsigned char *cmd, int bytes, int direction, int timeout, int retries, int do_wait) { unsigned char *bp; @@ -366,9 +369,9 @@ static Scsi_Request * osst_do_scsi(Scsi_Request *SRpnt, OS_Scsi_Tape *STp, /* Handle the write-behind checking (downs the semaphore) */ -static void osst_write_behind_check(OS_Scsi_Tape *STp) +static void osst_write_behind_check(struct osst_tape *STp) { - OSST_buffer * STbuffer; + struct osst_buffer * STbuffer; STbuffer = STp->buffer; @@ -406,7 +409,7 @@ static void osst_write_behind_check(OS_Scsi_Tape *STp) /* * Initialize the OnStream AUX */ -static void osst_init_aux(OS_Scsi_Tape * STp, int frame_type, int frame_seq_number, +static void osst_init_aux(struct osst_tape * STp, int frame_type, int frame_seq_number, int logical_blk_num, int blk_sz, int blk_cnt) { os_aux_t *aux = STp->buffer->aux; @@ -468,13 +471,13 @@ static void osst_init_aux(OS_Scsi_Tape * STp, int frame_type, int frame_seq_numb /* * Verify that we have the correct tape frame */ -static int osst_verify_frame(OS_Scsi_Tape * STp, int frame_seq_number, int quiet) +static int osst_verify_frame(struct osst_tape * STp, int frame_seq_number, int quiet) { - char * name = tape_name(STp); - os_aux_t * aux = STp->buffer->aux; - os_partition_t * par = &(aux->partition); - struct st_partstat * STps = &(STp->ps[STp->partition]); - int blk_cnt, blk_sz, i; + char * name = tape_name(STp); + os_aux_t * aux = STp->buffer->aux; + os_partition_t * par = &(aux->partition); + struct st_partstat * STps = &(STp->ps[STp->partition]); + int blk_cnt, blk_sz, i; if (STp->raw) { if (STp->buffer->syscall_result) { @@ -602,14 +605,15 @@ err_out: /* * Wait for the unit to become Ready */ -static int osst_wait_ready(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, unsigned timeout, int initial_delay) +static int osst_wait_ready(struct osst_tape * STp, struct scsi_request ** aSRpnt, + unsigned timeout, int initial_delay) { - unsigned char cmd[MAX_COMMAND_SIZE]; - Scsi_Request * SRpnt; - unsigned long startwait = jiffies; + unsigned char cmd[MAX_COMMAND_SIZE]; + struct scsi_request * SRpnt; + unsigned long startwait = jiffies; #if DEBUG - int dbg = debugging; - char * name = tape_name(STp); + int dbg = debugging; + char * name = tape_name(STp); printk(OSST_DEB_MSG "%s:D: Reached onstream wait ready\n", name); #endif @@ -620,7 +624,7 @@ static int osst_wait_ready(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, unsigned memset(cmd, 0, MAX_COMMAND_SIZE); cmd[0] = TEST_UNIT_READY; - SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_READY_RETRIES, TRUE); + SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_RETRIES, TRUE); *aSRpnt = SRpnt; if (!SRpnt) return (-EBUSY); @@ -641,7 +645,7 @@ static int osst_wait_ready(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, unsigned memset(cmd, 0, MAX_COMMAND_SIZE); cmd[0] = TEST_UNIT_READY; - SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_READY_RETRIES, TRUE); + SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_RETRIES, TRUE); } *aSRpnt = SRpnt; #if DEBUG @@ -666,14 +670,14 @@ static int osst_wait_ready(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, unsigned /* * Wait for a tape to be inserted in the unit */ -static int osst_wait_for_medium(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, unsigned timeout) +static int osst_wait_for_medium(struct osst_tape * STp, struct scsi_request ** aSRpnt, unsigned timeout) { - unsigned char cmd[MAX_COMMAND_SIZE]; - Scsi_Request * SRpnt; - unsigned long startwait = jiffies; + unsigned char cmd[MAX_COMMAND_SIZE]; + struct scsi_request * SRpnt; + unsigned long startwait = jiffies; #if DEBUG - int dbg = debugging; - char * name = tape_name(STp); + int dbg = debugging; + char * name = tape_name(STp); printk(OSST_DEB_MSG "%s:D: Reached onstream wait for medium\n", name); #endif @@ -681,7 +685,7 @@ static int osst_wait_for_medium(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, unsi memset(cmd, 0, MAX_COMMAND_SIZE); cmd[0] = TEST_UNIT_READY; - SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_READY_RETRIES, TRUE); + SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_RETRIES, TRUE); *aSRpnt = SRpnt; if (!SRpnt) return (-EBUSY); @@ -700,7 +704,7 @@ static int osst_wait_for_medium(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, unsi memset(cmd, 0, MAX_COMMAND_SIZE); cmd[0] = TEST_UNIT_READY; - SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_READY_RETRIES, TRUE); + SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_RETRIES, TRUE); } *aSRpnt = SRpnt; #if DEBUG @@ -722,7 +726,7 @@ static int osst_wait_for_medium(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, unsi return 1; } -static int osst_position_tape_and_confirm(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int frame) +static int osst_position_tape_and_confirm(struct osst_tape * STp, struct scsi_request ** aSRpnt, int frame) { int retval; @@ -736,15 +740,14 @@ static int osst_position_tape_and_confirm(OS_Scsi_Tape * STp, Scsi_Request ** aS /* * Wait for write(s) to complete */ -static int osst_flush_drive_buffer(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt) +static int osst_flush_drive_buffer(struct osst_tape * STp, struct scsi_request ** aSRpnt) { - unsigned char cmd[MAX_COMMAND_SIZE]; - Scsi_Request * SRpnt; - - int result = 0; - int delay = OSST_WAIT_WRITE_COMPLETE; + unsigned char cmd[MAX_COMMAND_SIZE]; + struct scsi_request * SRpnt; + int result = 0; + int delay = OSST_WAIT_WRITE_COMPLETE; #if DEBUG - char * name = tape_name(STp); + char * name = tape_name(STp); printk(OSST_DEB_MSG "%s:D: Reached onstream flush drive buffer (write filemark)\n", name); #endif @@ -753,7 +756,7 @@ static int osst_flush_drive_buffer(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt) cmd[0] = WRITE_FILEMARKS; cmd[1] = 1; - SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_WRITE_RETRIES, TRUE); + SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_RETRIES, TRUE); *aSRpnt = SRpnt; if (!SRpnt) return (-EBUSY); if (STp->buffer->syscall_result) { @@ -771,12 +774,12 @@ static int osst_flush_drive_buffer(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt) } #define OSST_POLL_PER_SEC 10 -static int osst_wait_frame(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int curr, int minlast, int to) +static int osst_wait_frame(struct osst_tape * STp, struct scsi_request ** aSRpnt, int curr, int minlast, int to) { - unsigned long startwait = jiffies; - char * name = tape_name(STp); + unsigned long startwait = jiffies; + char * name = tape_name(STp); #if DEBUG - char notyetprinted = 1; + char notyetprinted = 1; #endif if (minlast >= 0 && STp->ps[STp->partition].rw != ST_READING) printk(KERN_ERR "%s:A: Waiting for frame without having initialized read!\n", name); @@ -784,7 +787,7 @@ static int osst_wait_frame(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int curr, while (time_before (jiffies, startwait + to*HZ)) { int result; - result = osst_get_frame_position (STp, aSRpnt); + result = osst_get_frame_position(STp, aSRpnt); if (result == -EIO) if ((result = osst_write_error_recovery(STp, aSRpnt, 0)) == 0) return 0; /* successful recovery leaves drive ready for frame */ @@ -826,23 +829,79 @@ static int osst_wait_frame(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int curr, return -EBUSY; } +static int osst_recover_wait_frame(struct osst_tape * STp, struct scsi_request ** aSRpnt, int writing) +{ + struct scsi_request * SRpnt; + unsigned char cmd[MAX_COMMAND_SIZE]; + unsigned long startwait = jiffies; + int retval = 1; + char * name = tape_name(STp); + + if (writing) { + char mybuf[24]; + char * olddata = STp->buffer->b_data; + int oldsize = STp->buffer->buffer_size; + + /* write zero fm then read pos - if shows write error, try to recover - if no progress, wait */ + + memset(cmd, 0, MAX_COMMAND_SIZE); + cmd[0] = WRITE_FILEMARKS; + cmd[1] = 1; + SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, + MAX_RETRIES, TRUE); + + while (retval && time_before (jiffies, startwait + 5*60*HZ)) { + + if (STp->buffer->syscall_result && (SRpnt->sr_sense_buffer[2] & 0x0f) != 2) { + + /* some failure - not just not-ready */ + retval = osst_write_error_recovery(STp, aSRpnt, 0); + break; + } + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout (HZ / OSST_POLL_PER_SEC); + + STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24; + memset(cmd, 0, MAX_COMMAND_SIZE); + cmd[0] = READ_POSITION; + + SRpnt = osst_do_scsi(SRpnt, STp, cmd, 20, SCSI_DATA_READ, STp->timeout, + MAX_RETRIES, TRUE); + + retval = ( STp->buffer->syscall_result || (STp->buffer)->b_data[15] > 25 ); + STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize; + } + if (retval) + printk(KERN_ERR "%s:E: Device did not succeed to write buffered data\n", name); + } else + /* TODO - figure out which error conditions can be handled */ + if (STp->buffer->syscall_result) + printk(KERN_WARNING + "%s:W: Recover_wait_frame(read) cannot handle %02x:%02x:%02x\n", name, + (*aSRpnt)->sr_sense_buffer[ 2] & 0x0f, + (*aSRpnt)->sr_sense_buffer[12], + (*aSRpnt)->sr_sense_buffer[13]); + + return retval; +} + /* * Read the next OnStream tape frame at the current location */ -static int osst_read_frame(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int timeout) +static int osst_read_frame(struct osst_tape * STp, struct scsi_request ** aSRpnt, int timeout) { - unsigned char cmd[MAX_COMMAND_SIZE]; - Scsi_Request * SRpnt; - int retval = 0; + unsigned char cmd[MAX_COMMAND_SIZE]; + struct scsi_request * SRpnt; + int retval = 0; #if DEBUG - os_aux_t * aux = STp->buffer->aux; - char * name = tape_name(STp); + os_aux_t * aux = STp->buffer->aux; + char * name = tape_name(STp); #endif - /* TODO: Error handling */ if (STp->poll) - retval = osst_wait_frame (STp, aSRpnt, STp->first_frame_position, 0, timeout); - + if (osst_wait_frame (STp, aSRpnt, STp->first_frame_position, 0, timeout)) + retval = osst_recover_wait_frame(STp, aSRpnt, 0); + memset(cmd, 0, MAX_COMMAND_SIZE); cmd[0] = READ_6; cmd[1] = 1; @@ -850,13 +909,13 @@ static int osst_read_frame(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int timeo #if DEBUG if (debugging) - printk(OSST_DEB_MSG "%s:D: Reading frame from OnStream tape\n", name); + printk(OSST_DEB_MSG "%s:D: Reading frame from OnStream tape\n", name); #endif SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, SCSI_DATA_READ, - STp->timeout, MAX_READ_RETRIES, TRUE); + STp->timeout, MAX_RETRIES, TRUE); *aSRpnt = SRpnt; if (!SRpnt) - return (-EBUSY); + return (-EBUSY); if ((STp->buffer)->syscall_result) { retval = 1; @@ -900,15 +959,13 @@ static int osst_read_frame(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int timeo return (retval); } -static int osst_initiate_read(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt) +static int osst_initiate_read(struct osst_tape * STp, struct scsi_request ** aSRpnt) { - struct st_partstat * STps = &(STp->ps[STp->partition]); - Scsi_Request * SRpnt ; - unsigned char cmd[MAX_COMMAND_SIZE]; - int retval = 0; -#if DEBUG - char * name = tape_name(STp); -#endif + struct st_partstat * STps = &(STp->ps[STp->partition]); + struct scsi_request * SRpnt ; + unsigned char cmd[MAX_COMMAND_SIZE]; + int retval = 0; + char * name = tape_name(STp); if (STps->rw != ST_READING) { /* Initialize read operation */ if (STps->rw == ST_WRITING || STp->dirty) { @@ -930,23 +987,25 @@ static int osst_initiate_read(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt) #if DEBUG printk(OSST_DEB_MSG "%s:D: Start Read Ahead on OnStream tape\n", name); #endif - SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_READ_RETRIES, TRUE); + SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_RETRIES, TRUE); *aSRpnt = SRpnt; - retval = STp->buffer->syscall_result; + if ((retval = STp->buffer->syscall_result)) + printk(KERN_WARNING "%s:W: Error starting read ahead\n", name); } return retval; } -static int osst_get_logical_frame(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int frame_seq_number, int quiet) +static int osst_get_logical_frame(struct osst_tape * STp, struct scsi_request ** aSRpnt, + int frame_seq_number, int quiet) { struct st_partstat * STps = &(STp->ps[STp->partition]); - char * name = tape_name(STp); - int cnt = 0, - bad = 0, - past = 0, - x, - position; + char * name = tape_name(STp); + int cnt = 0, + bad = 0, + past = 0, + x, + position; /* * If we want just any frame (-1) and there is a frame in the buffer, return it @@ -971,6 +1030,7 @@ static int osst_get_logical_frame(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, in name, STp->read_error_frame); #endif STp->read_error_frame = 0; + STp->abort_count++; } return (-EIO); } @@ -988,10 +1048,11 @@ static int osst_get_logical_frame(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, in position = 0xbb8; else if (position > STp->eod_frame_ppos || ++bad == 10) { position = STp->read_error_frame - 1; + bad = 0; } else { - position += 39; - cnt += 20; + position += 29; + cnt += 19; } #if DEBUG printk(OSST_DEB_MSG "%s:D: Bad frame detected, positioning tape to block %d\n", @@ -1064,10 +1125,10 @@ static int osst_get_logical_frame(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, in return (STps->eof); } -static int osst_seek_logical_blk(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int logical_blk_num) +static int osst_seek_logical_blk(struct osst_tape * STp, struct scsi_request ** aSRpnt, int logical_blk_num) { struct st_partstat * STps = &(STp->ps[STp->partition]); - char * name = tape_name(STp); + char * name = tape_name(STp); int retries = 0; int frame_seq_estimate, ppos_estimate, move; @@ -1173,7 +1234,7 @@ error: #define OSST_SECTOR_SHIFT 9 #define OSST_SECTOR_MASK 0x03F -static int osst_get_sector(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt) +static int osst_get_sector(struct osst_tape * STp, struct scsi_request ** aSRpnt) { int sector; #if DEBUG @@ -1203,12 +1264,12 @@ static int osst_get_sector(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt) return sector; } -static int osst_seek_sector(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int sector) +static int osst_seek_sector(struct osst_tape * STp, struct scsi_request ** aSRpnt, int sector) { - struct st_partstat * STps = &(STp->ps[STp->partition]); - int frame = sector >> OSST_FRAME_SHIFT, - offset = (sector & OSST_SECTOR_MASK) << OSST_SECTOR_SHIFT, - r; + struct st_partstat * STps = &(STp->ps[STp->partition]); + int frame = sector >> OSST_FRAME_SHIFT, + offset = (sector & OSST_SECTOR_MASK) << OSST_SECTOR_SHIFT, + r; #if DEBUG char * name = tape_name(STp); @@ -1266,23 +1327,23 @@ static int osst_seek_sector(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int sect * Precondition for this function to work: all frames in the * drive's buffer must be of one type (DATA, MARK or EOD)! */ -static int osst_read_back_buffer_and_rewrite(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, - unsigned int frame, unsigned int skip, int pending) +static int osst_read_back_buffer_and_rewrite(struct osst_tape * STp, struct scsi_request ** aSRpnt, + unsigned int frame, unsigned int skip, int pending) { - Scsi_Request * SRpnt = * aSRpnt; - unsigned char * buffer, * p; - unsigned char cmd[MAX_COMMAND_SIZE]; - int flag, new_frame, i; - int nframes = STp->cur_frames; - int blks_per_frame = ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt); - int frame_seq_number = ntohl(STp->buffer->aux->frame_seq_num) + struct scsi_request * SRpnt = * aSRpnt; + unsigned char * buffer, * p; + unsigned char cmd[MAX_COMMAND_SIZE]; + int flag, new_frame, i; + int nframes = STp->cur_frames; + int blks_per_frame = ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt); + int frame_seq_number = ntohl(STp->buffer->aux->frame_seq_num) - (nframes + pending - 1); - int logical_blk_num = ntohl(STp->buffer->aux->logical_blk_num) + int logical_blk_num = ntohl(STp->buffer->aux->logical_blk_num) - (nframes + pending - 1) * blks_per_frame; - char * name = tape_name(STp); - unsigned long startwait = jiffies; + char * name = tape_name(STp); + unsigned long startwait = jiffies; #if DEBUG - int dbg = debugging; + int dbg = debugging; #endif if ((buffer = (unsigned char *)vmalloc((nframes + 1) * OS_DATA_SIZE)) == NULL) @@ -1308,7 +1369,7 @@ static int osst_read_back_buffer_and_rewrite(OS_Scsi_Tape * STp, Scsi_Request ** cmd[8] = 32768 & 0xff; SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, SCSI_DATA_READ, - STp->timeout, MAX_READ_RETRIES, TRUE); + STp->timeout, MAX_RETRIES, TRUE); if ((STp->buffer)->syscall_result || !SRpnt) { printk(KERN_ERR "%s:E: Failed to read frame back from OnStream buffer\n", name); @@ -1357,8 +1418,8 @@ static int osst_read_back_buffer_and_rewrite(OS_Scsi_Tape * STp, Scsi_Request ** vfree((void *)buffer); return (-EIO); } - flag = 0; if ( i >= nframes + pending ) break; + flag = 0; } osst_copy_to_buffer(STp->buffer, p); /* @@ -1380,7 +1441,7 @@ static int osst_read_back_buffer_and_rewrite(OS_Scsi_Tape * STp, Scsi_Request ** p[0], p[1], p[2], p[3]); #endif SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, SCSI_DATA_WRITE, - STp->timeout, MAX_WRITE_RETRIES, TRUE); + STp->timeout, MAX_RETRIES, TRUE); if (STp->buffer->syscall_result) flag = 1; @@ -1396,7 +1457,7 @@ static int osst_read_back_buffer_and_rewrite(OS_Scsi_Tape * STp, Scsi_Request ** cmd[0] = WRITE_FILEMARKS; cmd[1] = 1; SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, SCSI_DATA_NONE, - STp->timeout, MAX_WRITE_RETRIES, TRUE); + STp->timeout, MAX_RETRIES, TRUE); #if DEBUG if (debugging) { printk(OSST_DEB_MSG "%s:D: Sleeping in re-write wait ready\n", name); @@ -1411,7 +1472,7 @@ static int osst_read_back_buffer_and_rewrite(OS_Scsi_Tape * STp, Scsi_Request ** cmd[0] = TEST_UNIT_READY; SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, - MAX_READY_RETRIES, TRUE); + MAX_RETRIES, TRUE); if (SRpnt->sr_sense_buffer[2] == 2 && SRpnt->sr_sense_buffer[12] == 4 && (SRpnt->sr_sense_buffer[13] == 1 || SRpnt->sr_sense_buffer[13] == 8)) { @@ -1448,29 +1509,34 @@ static int osst_read_back_buffer_and_rewrite(OS_Scsi_Tape * STp, Scsi_Request ** #endif osst_get_frame_position(STp, aSRpnt); #if DEBUG - printk(OSST_DEB_MSG "%s:D: reported frame positions: host = %d, tape = %d\n", - name, STp->first_frame_position, STp->last_frame_position); + printk(OSST_DEB_MSG "%s:D: reported frame positions: host = %d, tape = %d, buffer = %d\n", + name, STp->first_frame_position, STp->last_frame_position, STp->cur_frames); #endif } - } + } + if (flag) { + /* error recovery did not successfully complete */ + printk(KERN_ERR "%s:D: Write error recovery failed in %s\n", name, + STp->write_type == OS_WRITE_HEADER?"header":"body"); + } if (!pending) osst_copy_to_buffer(STp->buffer, p); /* so buffer content == at entry in all cases */ vfree((void *)buffer); return 0; } -static int osst_reposition_and_retry(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, +static int osst_reposition_and_retry(struct osst_tape * STp, struct scsi_request ** aSRpnt, unsigned int frame, unsigned int skip, int pending) { - unsigned char cmd[MAX_COMMAND_SIZE]; - Scsi_Request * SRpnt; - char * name = tape_name(STp); - int expected = 0; - int attempts = 1000 / skip; - int flag = 1; - unsigned long startwait = jiffies; + unsigned char cmd[MAX_COMMAND_SIZE]; + struct scsi_request * SRpnt; + char * name = tape_name(STp); + int expected = 0; + int attempts = 1000 / skip; + int flag = 1; + unsigned long startwait = jiffies; #if DEBUG - int dbg = debugging; + int dbg = debugging; #endif while (attempts && time_before(jiffies, startwait + 60*HZ)) { @@ -1512,7 +1578,7 @@ static int osst_reposition_and_retry(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, name, STp->frame_seq_number-1, STp->first_frame_position); #endif SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, SCSI_DATA_WRITE, - STp->timeout, MAX_WRITE_RETRIES, TRUE); + STp->timeout, MAX_RETRIES, TRUE); *aSRpnt = SRpnt; if (STp->buffer->syscall_result) { /* additional write error */ @@ -1550,6 +1616,7 @@ static int osst_reposition_and_retry(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, debugging = 0; } #endif + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(HZ / 10); } printk(KERN_ERR "%s:E: Failed to find valid tape media\n", name); @@ -1563,14 +1630,14 @@ static int osst_reposition_and_retry(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, * Error recovery algorithm for the OnStream tape. */ -static int osst_write_error_recovery(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int pending) +static int osst_write_error_recovery(struct osst_tape * STp, struct scsi_request ** aSRpnt, int pending) { - Scsi_Request * SRpnt = * aSRpnt; + struct scsi_request * SRpnt = * aSRpnt; struct st_partstat * STps = & STp->ps[STp->partition]; - char * name = tape_name(STp); - int retval = 0; - int rw_state; - unsigned int frame, skip; + char * name = tape_name(STp); + int retval = 0; + int rw_state; + unsigned int frame, skip; rw_state = STps->rw; @@ -1635,12 +1702,14 @@ static int osst_write_error_recovery(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, if (retval == 0) { STp->recover_count++; STp->recover_erreg++; - } + } else + STp->abort_count++; + STps->rw = rw_state; return retval; } -static int osst_space_over_filemarks_backward(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, +static int osst_space_over_filemarks_backward(struct osst_tape * STp, struct scsi_request ** aSRpnt, int mt_op, int mt_count) { char * name = tape_name(STp); @@ -1739,7 +1808,7 @@ found: * * Just scans for the filemark sequentially. */ -static int osst_space_over_filemarks_forward_slow(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, +static int osst_space_over_filemarks_forward_slow(struct osst_tape * STp, struct scsi_request ** aSRpnt, int mt_op, int mt_count) { int cnt = 0; @@ -1793,7 +1862,7 @@ static int osst_space_over_filemarks_forward_slow(OS_Scsi_Tape * STp, Scsi_Reque /* * Fast linux specific version of OnStream FSF */ -static int osst_space_over_filemarks_forward_fast(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, +static int osst_space_over_filemarks_forward_fast(struct osst_tape * STp, struct scsi_request ** aSRpnt, int mt_op, int mt_count) { char * name = tape_name(STp); @@ -1944,11 +2013,11 @@ static int osst_space_over_filemarks_forward_fast(OS_Scsi_Tape * STp, Scsi_Reque * to test the error recovery mechanism. */ #if DEBUG -static void osst_set_retries(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int retries) +static void osst_set_retries(struct osst_tape * STp, struct scsi_request ** aSRpnt, int retries) { - unsigned char cmd[MAX_COMMAND_SIZE]; - Scsi_Request * SRpnt = * aSRpnt; - char * name = tape_name(STp); + unsigned char cmd[MAX_COMMAND_SIZE]; + struct scsi_request * SRpnt = * aSRpnt; + char * name = tape_name(STp); memset(cmd, 0, MAX_COMMAND_SIZE); cmd[0] = MODE_SELECT; @@ -1976,7 +2045,7 @@ static void osst_set_retries(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int ret #endif -static int osst_write_filemark(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt) +static int osst_write_filemark(struct osst_tape * STp, struct scsi_request ** aSRpnt) { int result; int this_mark_ppos = STp->first_frame_position; @@ -2004,7 +2073,7 @@ static int osst_write_filemark(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt) return result; } -static int osst_write_eod(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt) +static int osst_write_eod(struct osst_tape * STp, struct scsi_request ** aSRpnt) { int result; #if DEBUG @@ -2027,7 +2096,7 @@ static int osst_write_eod(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt) return result; } -static int osst_write_filler(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int where, int count) +static int osst_write_filler(struct osst_tape * STp, struct scsi_request ** aSRpnt, int where, int count) { char * name = tape_name(STp); @@ -2052,7 +2121,7 @@ static int osst_write_filler(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int whe return osst_flush_drive_buffer(STp, aSRpnt); } -static int __osst_write_header(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int where, int count) +static int __osst_write_header(struct osst_tape * STp, struct scsi_request ** aSRpnt, int where, int count) { char * name = tape_name(STp); int result; @@ -2079,7 +2148,7 @@ static int __osst_write_header(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int w return result; } -static int osst_write_header(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int locate_eod) +static int osst_write_header(struct osst_tape * STp, struct scsi_request ** aSRpnt, int locate_eod) { os_header_t * header; int result; @@ -2153,7 +2222,7 @@ static int osst_write_header(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int loc return result; } -static int osst_reset_header(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt) +static int osst_reset_header(struct osst_tape * STp, struct scsi_request ** aSRpnt) { if (STp->header_cache != NULL) memset(STp->header_cache, 0, sizeof(os_header_t)); @@ -2166,7 +2235,7 @@ static int osst_reset_header(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt) return osst_write_header(STp, aSRpnt, 1); } -static int __osst_analyze_headers(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int ppos) +static int __osst_analyze_headers(struct osst_tape * STp, struct scsi_request ** aSRpnt, int ppos) { char * name = tape_name(STp); os_header_t * header; @@ -2343,7 +2412,7 @@ static int __osst_analyze_headers(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, in return 1; } -static int osst_analyze_headers(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt) +static int osst_analyze_headers(struct osst_tape * STp, struct scsi_request ** aSRpnt) { int position, ppos; int first, last; @@ -2398,7 +2467,7 @@ static int osst_analyze_headers(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt) return 1; } -static int osst_verify_position(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt) +static int osst_verify_position(struct osst_tape * STp, struct scsi_request ** aSRpnt) { int frame_position = STp->first_frame_position; int frame_seq_numbr = STp->frame_seq_number; @@ -2474,11 +2543,11 @@ static unsigned int osst_parse_firmware_rev (const char * str) /* * Configure the OnStream SCII tape drive for default operation */ -static int osst_configure_onstream(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt) +static int osst_configure_onstream(struct osst_tape *STp, struct scsi_request ** aSRpnt) { unsigned char cmd[MAX_COMMAND_SIZE]; char * name = tape_name(STp); - Scsi_Request * SRpnt = * aSRpnt; + struct scsi_request * SRpnt = * aSRpnt; osst_mode_parameter_header_t * header; osst_block_size_page_t * bs; osst_capabilities_page_t * cp; @@ -2645,7 +2714,7 @@ static int osst_configure_onstream(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt) /* Step over EOF if it has been inadvertently crossed (ioctl not used because it messes up the block number). */ -static int cross_eof(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt, int forward) +static int cross_eof(struct osst_tape *STp, struct scsi_request ** aSRpnt, int forward) { int result; char * name = tape_name(STp); @@ -2674,18 +2743,18 @@ static int cross_eof(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt, int forward) /* Get the tape position. */ -static int osst_get_frame_position(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt) +static int osst_get_frame_position(struct osst_tape *STp, struct scsi_request ** aSRpnt) { - unsigned char scmd[MAX_COMMAND_SIZE]; - Scsi_Request * SRpnt; - int result = 0; + unsigned char scmd[MAX_COMMAND_SIZE]; + struct scsi_request * SRpnt; + int result = 0; + char * name = tape_name(STp); /* KG: We want to be able to use it for checking Write Buffer availability * and thus don't want to risk to overwrite anything. Exchange buffers ... */ char mybuf[24]; char * olddata = STp->buffer->b_data; int oldsize = STp->buffer->buffer_size; - char * name = tape_name(STp); if (STp->ready != ST_READY) return (-EIO); @@ -2702,13 +2771,12 @@ static int osst_get_frame_position(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt) *aSRpnt = SRpnt; if (STp->buffer->syscall_result) - result = ((SRpnt->sr_sense_buffer[2] & 0x0f) == 3) ? -EIO : -EINVAL; + result = ((SRpnt->sr_sense_buffer[2] & 0x0f) == 3) ? -EIO : -EINVAL; /* 3: Write Error */ if (result == -EINVAL) printk(KERN_ERR "%s:E: Can't read tape position.\n", name); else { - - if (result == -EIO) { /* re-read position */ + if (result == -EIO) { /* re-read position - this needs to preserve media errors */ unsigned char mysense[16]; memcpy (mysense, SRpnt->sr_sense_buffer, 16); memset (scmd, 0, MAX_COMMAND_SIZE); @@ -2716,8 +2784,15 @@ static int osst_get_frame_position(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt) STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24; SRpnt = osst_do_scsi(SRpnt, STp, scmd, 20, SCSI_DATA_READ, STp->timeout, MAX_RETRIES, TRUE); +#if DEBUG + printk(OSST_DEB_MSG "%s:D: Reread position, reason=[%02x:%02x:%02x], result=[%s%02x:%02x:%02x]\n", + name, mysense[2], mysense[12], mysense[13], STp->buffer->syscall_result?"":"ok:", + SRpnt->sr_sense_buffer[2],SRpnt->sr_sense_buffer[12],SRpnt->sr_sense_buffer[13]); +#endif if (!STp->buffer->syscall_result) memcpy (SRpnt->sr_sense_buffer, mysense, 16); + else + printk(KERN_WARNING "%s:W: Double error in get position\n", name); } STp->first_frame_position = ((STp->buffer)->b_data[4] << 24) + ((STp->buffer)->b_data[5] << 16) @@ -2739,7 +2814,7 @@ static int osst_get_frame_position(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt) #endif if (STp->cur_frames == 0 && STp->first_frame_position != STp->last_frame_position) { #if DEBUG - printk(KERN_WARNING "%s:D: Correcting read position %d, %d, %d\n", name, + printk(OSST_DEB_MSG "%s:D: Correcting read position %d, %d, %d\n", name, STp->first_frame_position, STp->last_frame_position, STp->cur_frames); #endif STp->first_frame_position = STp->last_frame_position; @@ -2752,14 +2827,14 @@ static int osst_get_frame_position(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt) /* Set the tape block */ -static int osst_set_frame_position(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt, int ppos, int skip) +static int osst_set_frame_position(struct osst_tape *STp, struct scsi_request ** aSRpnt, int ppos, int skip) { - unsigned char scmd[MAX_COMMAND_SIZE]; - Scsi_Request * SRpnt; - struct st_partstat * STps; - int result = 0; - int pp = (ppos == 3000 && !skip)? 0 : ppos; - char * name = tape_name(STp); + unsigned char scmd[MAX_COMMAND_SIZE]; + struct scsi_request * SRpnt; + struct st_partstat * STps; + int result = 0; + int pp = (ppos == 3000 && !skip)? 0 : ppos; + char * name = tape_name(STp); if (STp->ready != ST_READY) return (-EIO); @@ -2810,7 +2885,7 @@ static int osst_set_frame_position(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt, in return result; } -static int osst_write_trailer(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt, int leave_at_EOT) +static int osst_write_trailer(struct osst_tape *STp, struct scsi_request ** aSRpnt, int leave_at_EOT) { struct st_partstat * STps = &(STp->ps[STp->partition]); int result = 0; @@ -2837,26 +2912,26 @@ out: /* osst versions of st functions - augmented and stripped to suit OnStream only */ /* Flush the write buffer (never need to write if variable blocksize). */ -static int osst_flush_write_buffer(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt) +static int osst_flush_write_buffer(struct osst_tape *STp, struct scsi_request ** aSRpnt) { - int offset, transfer, blks = 0; - int result = 0; - unsigned char cmd[MAX_COMMAND_SIZE]; - Scsi_Request * SRpnt = *aSRpnt; - struct st_partstat * STps; - char * name = tape_name(STp); + int offset, transfer, blks = 0; + int result = 0; + unsigned char cmd[MAX_COMMAND_SIZE]; + struct scsi_request * SRpnt = *aSRpnt; + struct st_partstat * STps; + char * name = tape_name(STp); if ((STp->buffer)->writing) { if (SRpnt == (STp->buffer)->last_SRpnt) #if DEBUG { printk(OSST_DEB_MSG - "%s:D: aSRpnt points to Scsi_Request that write_behind_check will release -- cleared\n", name); + "%s:D: aSRpnt points to scsi_request that write_behind_check will release -- cleared\n", name); #endif *aSRpnt = SRpnt = NULL; #if DEBUG } else if (SRpnt) printk(OSST_DEB_MSG - "%s:D: aSRpnt does not point to Scsi_Request that write_behind_check will release -- strange\n", name); + "%s:D: aSRpnt does not point to scsi_request that write_behind_check will release -- strange\n", name); #endif osst_write_behind_check(STp); if ((STp->buffer)->syscall_result) { @@ -2884,9 +2959,9 @@ static int osst_flush_write_buffer(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt) if (offset < OS_DATA_SIZE) osst_zero_buffer_tail(STp->buffer); - /* TODO: Error handling! */ if (STp->poll) - result = osst_wait_frame (STp, aSRpnt, STp->first_frame_position, -50, 120); + if (osst_wait_frame (STp, aSRpnt, STp->first_frame_position, -50, 120)) + result = osst_recover_wait_frame(STp, aSRpnt, 1); memset(cmd, 0, MAX_COMMAND_SIZE); cmd[0] = WRITE_6; @@ -2925,7 +3000,7 @@ static int osst_flush_write_buffer(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt) #endif SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, transfer, SCSI_DATA_WRITE, - STp->timeout, MAX_WRITE_RETRIES, TRUE); + STp->timeout, MAX_RETRIES, TRUE); *aSRpnt = SRpnt; if (!SRpnt) return (-EBUSY); @@ -2967,12 +3042,12 @@ static int osst_flush_write_buffer(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt) /* Flush the tape buffer. The tape will be positioned correctly unless seek_next is true. */ -static int osst_flush_buffer(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int seek_next) +static int osst_flush_buffer(struct osst_tape * STp, struct scsi_request ** aSRpnt, int seek_next) { struct st_partstat * STps; - int backspace = 0, result = 0; + int backspace = 0, result = 0; #if DEBUG - char * name = tape_name(STp); + char * name = tape_name(STp); #endif /* @@ -3029,13 +3104,13 @@ static int osst_flush_buffer(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int see return result; } -static int osst_write_frame(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int synchronous) +static int osst_write_frame(struct osst_tape * STp, struct scsi_request ** aSRpnt, int synchronous) { - unsigned char cmd[MAX_COMMAND_SIZE]; - Scsi_Request * SRpnt; - int blks; + unsigned char cmd[MAX_COMMAND_SIZE]; + struct scsi_request * SRpnt; + int blks; #if DEBUG - char * name = tape_name(STp); + char * name = tape_name(STp); #endif if ((!STp-> raw) && (STp->first_frame_position == 0xbae)) { /* _must_ preserve buffer! */ @@ -3055,8 +3130,9 @@ static int osst_write_frame(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int sync } if (STp->poll) - osst_wait_frame (STp, aSRpnt, STp->first_frame_position, -50, 60); - /* TODO: Check for an error ! */ + if (osst_wait_frame (STp, aSRpnt, STp->first_frame_position, -48, 120)) + if (osst_recover_wait_frame(STp, aSRpnt, 1)) + return (-EIO); // osst_build_stats(STp, &SRpnt); @@ -3081,7 +3157,7 @@ static int osst_write_frame(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int sync STp->write_pending = 1; #endif SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, SCSI_DATA_WRITE, STp->timeout, - MAX_WRITE_RETRIES, synchronous); + MAX_RETRIES, synchronous); if (!SRpnt) return (-EBUSY); *aSRpnt = SRpnt; @@ -3111,8 +3187,8 @@ static int osst_write_frame(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int sync return 0; } -/* Lock or unlock the drive door. Don't use when Scsi_Request allocated. */ -static int do_door_lock(OS_Scsi_Tape * STp, int do_lock) +/* Lock or unlock the drive door. Don't use when struct scsi_request allocated. */ +static int do_door_lock(struct osst_tape * STp, int do_lock) { int retval, cmd; @@ -3131,7 +3207,7 @@ static int do_door_lock(OS_Scsi_Tape * STp, int do_lock) } /* Set the internal state after reset */ -static void reset_state(OS_Scsi_Tape *STp) +static void reset_state(struct osst_tape *STp) { int i; struct st_partstat *STps; @@ -3154,16 +3230,16 @@ static void reset_state(OS_Scsi_Tape *STp) /* Write command */ static ssize_t osst_write(struct file * filp, const char __user * buf, size_t count, loff_t *ppos) { - ssize_t total, retval = 0; - ssize_t i, do_count, blks, transfer; - int write_threshold; - int doing_write = 0; + ssize_t total, retval = 0; + ssize_t i, do_count, blks, transfer; + int write_threshold; + int doing_write = 0; const char __user * b_point; - Scsi_Request * SRpnt = NULL; + struct scsi_request * SRpnt = NULL; struct st_modedef * STm; struct st_partstat * STps; - OS_Scsi_Tape * STp = filp->private_data; - char * name = tape_name(STp); + struct osst_tape * STp = filp->private_data; + char * name = tape_name(STp); if (down_interruptible(&STp->lock)) @@ -3477,14 +3553,14 @@ out: /* Read command */ static ssize_t osst_read(struct file * filp, char __user * buf, size_t count, loff_t *ppos) { - ssize_t total, retval = 0; - ssize_t i, transfer; - int special; - struct st_modedef * STm; + ssize_t total, retval = 0; + ssize_t i, transfer; + int special; + struct st_modedef * STm; struct st_partstat * STps; - Scsi_Request * SRpnt = NULL; - OS_Scsi_Tape * STp = filp->private_data; - char * name = tape_name(STp); + struct scsi_request * SRpnt = NULL; + struct osst_tape * STp = filp->private_data; + char * name = tape_name(STp); if (down_interruptible(&STp->lock)) @@ -3660,8 +3736,7 @@ out: /* Set the driver options */ -static void osst_log_options(OS_Scsi_Tape *STp, struct st_modedef *STm, - char *name) +static void osst_log_options(struct osst_tape *STp, struct st_modedef *STm, char *name) { printk(KERN_INFO "%s:I: Mode %d options: buffer writes: %d, async writes: %d, read ahead: %d\n", @@ -3684,12 +3759,12 @@ static void osst_log_options(OS_Scsi_Tape *STp, struct st_modedef *STm, } -static int osst_set_options(OS_Scsi_Tape *STp, long options) +static int osst_set_options(struct osst_tape *STp, long options) { - int value; - long code; + int value; + long code; struct st_modedef * STm; - char * name = tape_name(STp); + char * name = tape_name(STp); STm = &(STp->modes[STp->current_mode]); if (!STm->defined) { @@ -3840,18 +3915,19 @@ static int osst_set_options(OS_Scsi_Tape *STp, long options) /* Internal ioctl function */ -static int osst_int_ioctl(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, unsigned int cmd_in, unsigned long arg) +static int osst_int_ioctl(struct osst_tape * STp, struct scsi_request ** aSRpnt, + unsigned int cmd_in, unsigned long arg) { - int timeout; - long ltmp; - int i, ioctl_result; - int chg_eof = TRUE; - unsigned char cmd[MAX_COMMAND_SIZE]; - Scsi_Request * SRpnt = * aSRpnt; - struct st_partstat * STps; - int fileno, blkno, at_sm, frame_seq_numbr, logical_blk_num; - int datalen = 0, direction = SCSI_DATA_NONE; - char * name = tape_name(STp); + int timeout; + long ltmp; + int i, ioctl_result; + int chg_eof = TRUE; + unsigned char cmd[MAX_COMMAND_SIZE]; + struct scsi_request * SRpnt = * aSRpnt; + struct st_partstat * STps; + int fileno, blkno, at_sm, frame_seq_numbr, logical_blk_num; + int datalen = 0, direction = SCSI_DATA_NONE; + char * name = tape_name(STp); if (STp->ready != ST_READY && cmd_in != MTLOAD) { if (STp->ready == ST_NO_TAPE) @@ -4227,16 +4303,16 @@ os_bypass: /* Open the device */ static int os_scsi_tape_open(struct inode * inode, struct file * filp) { - unsigned short flags; - int i, b_size, new_session = FALSE, retval = 0; - unsigned char cmd[MAX_COMMAND_SIZE]; - Scsi_Request * SRpnt = NULL; - OS_Scsi_Tape * STp; - struct st_modedef * STm; + unsigned short flags; + int i, b_size, new_session = FALSE, retval = 0; + unsigned char cmd[MAX_COMMAND_SIZE]; + struct scsi_request * SRpnt = NULL; + struct osst_tape * STp; + struct st_modedef * STm; struct st_partstat * STps; - char * name; - int dev = TAPE_NR(inode); - int mode = TAPE_MODE(inode); + char * name; + int dev = TAPE_NR(inode); + int mode = TAPE_MODE(inode); nonseekable_open(inode, filp); write_lock(&os_scsi_tapes_lock); @@ -4327,9 +4403,9 @@ static int os_scsi_tape_open(struct inode * inode, struct file * filp) memset (cmd, 0, MAX_COMMAND_SIZE); cmd[0] = TEST_UNIT_READY; - SRpnt = osst_do_scsi(NULL, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_READY_RETRIES, TRUE); + SRpnt = osst_do_scsi(NULL, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_RETRIES, TRUE); if (!SRpnt) { - retval = (STp->buffer)->syscall_result; + retval = (STp->buffer)->syscall_result; /* FIXME - valid? */ goto err_out; } if ((SRpnt->sr_sense_buffer[0] & 0x70) == 0x70 && @@ -4348,7 +4424,7 @@ static int os_scsi_tape_open(struct inode * inode, struct file * filp) cmd[1] = 1; cmd[4] = 1; SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, SCSI_DATA_NONE, - STp->timeout, MAX_READY_RETRIES, TRUE); + STp->timeout, MAX_RETRIES, TRUE); } osst_wait_ready(STp, &SRpnt, (SRpnt->sr_sense_buffer[13]==1?15:3) * 60, 0); } @@ -4365,7 +4441,7 @@ static int os_scsi_tape_open(struct inode * inode, struct file * filp) cmd[0] = TEST_UNIT_READY; SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, SCSI_DATA_NONE, - STp->timeout, MAX_READY_RETRIES, TRUE); + STp->timeout, MAX_RETRIES, TRUE); if ((SRpnt->sr_sense_buffer[0] & 0x70) != 0x70 || (SRpnt->sr_sense_buffer[2] & 0x0f) != UNIT_ATTENTION) break; @@ -4386,6 +4462,7 @@ static int os_scsi_tape_open(struct inode * inode, struct file * filp) } new_session = TRUE; STp->recover_count = 0; + STp->abort_count = 0; } /* * if we have valid headers from before, and the drive/tape seem untouched, @@ -4473,7 +4550,7 @@ static int os_scsi_tape_open(struct inode * inode, struct file * filp) cmd[0] = TEST_UNIT_READY; SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, SCSI_DATA_NONE, - STp->timeout, MAX_READY_RETRIES, TRUE); + STp->timeout, MAX_RETRIES, TRUE); if ((SRpnt->sr_sense_buffer[0] & 0x70) != 0x70 || (SRpnt->sr_sense_buffer[2] & 0x0f) == NOT_READY) break; @@ -4588,12 +4665,12 @@ err_out: /* Flush the tape buffer before close */ static int os_scsi_tape_flush(struct file * filp) { - int result = 0, result2; - OS_Scsi_Tape * STp = filp->private_data; - struct st_modedef * STm = &(STp->modes[STp->current_mode]); - struct st_partstat * STps = &(STp->ps[STp->partition]); - Scsi_Request * SRpnt = NULL; - char * name = tape_name(STp); + int result = 0, result2; + struct osst_tape * STp = filp->private_data; + struct st_modedef * STm = &(STp->modes[STp->current_mode]); + struct st_partstat * STps = &(STp->ps[STp->partition]); + struct scsi_request * SRpnt = NULL; + char * name = tape_name(STp); if (file_count(filp) > 1) return 0; @@ -4657,14 +4734,19 @@ out: } if (SRpnt) scsi_release_request(SRpnt); - if (STp->recover_count) { - printk(KERN_INFO "%s:I: %d recovered errors in", name, STp->recover_count); + if (STp->abort_count || STp->recover_count) { + printk(KERN_INFO "%s:I:", name); + if (STp->abort_count) + printk(" %d unrecovered errors", STp->abort_count); + if (STp->recover_count) + printk(" %d recovered errors", STp->recover_count); if (STp->write_count) - printk(" %d frames written", STp->write_count); + printk(" in %d frames written", STp->write_count); if (STp->read_count) - printk(" %d frames read", STp->read_count); + printk(" in %d frames read", STp->read_count); printk("\n"); STp->recover_count = 0; + STp->abort_count = 0; } STp->write_count = 0; STp->read_count = 0; @@ -4676,9 +4758,9 @@ out: /* Close the device and release it */ static int os_scsi_tape_close(struct inode * inode, struct file * filp) { - int result = 0; - OS_Scsi_Tape * STp = filp->private_data; - Scsi_Request * SRpnt = NULL; + int result = 0; + struct osst_tape * STp = filp->private_data; + struct scsi_request * SRpnt = NULL; if (SRpnt) scsi_release_request(SRpnt); @@ -4703,14 +4785,14 @@ static int os_scsi_tape_close(struct inode * inode, struct file * filp) static int osst_ioctl(struct inode * inode,struct file * file, unsigned int cmd_in, unsigned long arg) { - int i, cmd_nr, cmd_type, retval = 0; - unsigned int blk; - struct st_modedef * STm; + int i, cmd_nr, cmd_type, retval = 0; + unsigned int blk; + struct st_modedef * STm; struct st_partstat * STps; - Scsi_Request * SRpnt = NULL; - OS_Scsi_Tape * STp = file->private_data; - char * name = tape_name(STp); - void __user *p = (void __user *)arg; + struct scsi_request * SRpnt = NULL; + struct osst_tape * STp = file->private_data; + char * name = tape_name(STp); + void __user * p = (void __user *)arg; if (down_interruptible(&STp->lock)) return -ERESTARTSYS; @@ -5039,18 +5121,18 @@ out: /* Memory handling routines */ /* Try to allocate a new tape buffer skeleton. Caller must not hold os_scsi_tapes_lock */ -static OSST_buffer * new_tape_buffer( int from_initialization, int need_dma, int max_sg ) +static struct osst_buffer * new_tape_buffer( int from_initialization, int need_dma, int max_sg ) { int i, priority; - OSST_buffer *tb; + struct osst_buffer *tb; if (from_initialization) priority = GFP_ATOMIC; else priority = GFP_KERNEL; - i = sizeof(OSST_buffer) + (osst_max_sg_segs - 1) * sizeof(struct scatterlist); - tb = (OSST_buffer *)kmalloc(i, priority); + i = sizeof(struct osst_buffer) + (osst_max_sg_segs - 1) * sizeof(struct scatterlist); + tb = (struct osst_buffer *)kmalloc(i, priority); if (!tb) { printk(KERN_NOTICE "osst :I: Can't allocate new tape buffer.\n"); return NULL; @@ -5071,7 +5153,7 @@ static OSST_buffer * new_tape_buffer( int from_initialization, int need_dma, int } /* Try to allocate a temporary (while a user has the device open) enlarged tape buffer */ -static int enlarge_buffer(OSST_buffer *STbuffer, int need_dma) +static int enlarge_buffer(struct osst_buffer *STbuffer, int need_dma) { int segs, nbr, max_segs, b_size, priority, order, got; @@ -5087,12 +5169,10 @@ static int enlarge_buffer(OSST_buffer *STbuffer, int need_dma) if (nbr <= 2) return FALSE; - priority = GFP_KERNEL; + priority = GFP_KERNEL /* | __GFP_NOWARN */; if (need_dma) priority |= GFP_DMA; - priority |= __GFP_NOWARN; - /* Try to allocate the first segment up to OS_DATA_SIZE and the others big enough to reach the goal (code assumes no segments in place) */ for (b_size = OS_DATA_SIZE, order = OSST_FIRST_ORDER; b_size >= PAGE_SIZE; order--, b_size /= 2) { @@ -5150,7 +5230,7 @@ static int enlarge_buffer(OSST_buffer *STbuffer, int need_dma) /* Release the segments */ -static void normalize_buffer(OSST_buffer *STbuffer) +static void normalize_buffer(struct osst_buffer *STbuffer) { int i, order, b_size; @@ -5174,7 +5254,7 @@ static void normalize_buffer(OSST_buffer *STbuffer) /* Move data from the user buffer to the tape buffer. Returns zero (success) or negative error code. */ -static int append_to_buffer(const char __user *ubp, OSST_buffer *st_bp, int do_count) +static int append_to_buffer(const char __user *ubp, struct osst_buffer *st_bp, int do_count) { int i, cnt, res, offset; @@ -5207,7 +5287,7 @@ static int append_to_buffer(const char __user *ubp, OSST_buffer *st_bp, int do_c /* Move data from the tape buffer to the user buffer. Returns zero (success) or negative error code. */ -static int from_buffer(OSST_buffer *st_bp, char __user *ubp, int do_count) +static int from_buffer(struct osst_buffer *st_bp, char __user *ubp, int do_count) { int i, cnt, res, offset; @@ -5239,7 +5319,7 @@ static int from_buffer(OSST_buffer *st_bp, char __user *ubp, int do_count) /* Sets the tail of the buffer after fill point to zero. Returns zero (success) or negative error code. */ -static int osst_zero_buffer_tail(OSST_buffer *st_bp) +static int osst_zero_buffer_tail(struct osst_buffer *st_bp) { int i, offset, do_count, cnt; @@ -5267,7 +5347,7 @@ static int osst_zero_buffer_tail(OSST_buffer *st_bp) /* Copy a osst 32K chunk of memory into the buffer. Returns zero (success) or negative error code. */ -static int osst_copy_to_buffer(OSST_buffer *st_bp, unsigned char *ptr) +static int osst_copy_to_buffer(struct osst_buffer *st_bp, unsigned char *ptr) { int i, cnt, do_count = OS_DATA_SIZE; @@ -5288,7 +5368,7 @@ static int osst_copy_to_buffer(OSST_buffer *st_bp, unsigned char *ptr) /* Copy a osst 32K chunk of memory from the buffer. Returns zero (success) or negative error code. */ -static int osst_copy_from_buffer(OSST_buffer *st_bp, unsigned char *ptr) +static int osst_copy_from_buffer(struct osst_buffer *st_bp, unsigned char *ptr) { int i, cnt, do_count = OS_DATA_SIZE; @@ -5406,18 +5486,163 @@ static struct osst_support_data support_list[] = { } /* + * sysfs support for osst driver parameter information + */ + +static ssize_t osst_version_show(struct device_driver *ddd, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%s\n", osst_version); +} + +static DRIVER_ATTR(version, S_IRUGO, osst_version_show, NULL); + +static void osst_create_driverfs_files(struct device_driver *driverfs) +{ + driver_create_file(driverfs, &driver_attr_version); +} + +static void osst_remove_driverfs_files(struct device_driver *driverfs) +{ + driver_remove_file(driverfs, &driver_attr_version); +} + +/* + * sysfs support for accessing ADR header information + */ + +static ssize_t osst_adr_rev_show(struct class_device *class_dev, char *buf) +{ + struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev); + ssize_t l = 0; + + if (STp && STp->header_ok && STp->linux_media) + l = snprintf(buf, PAGE_SIZE, "%d.%d\n", STp->header_cache->major_rev, STp->header_cache->minor_rev); + return l; +} + +CLASS_DEVICE_ATTR(ADR_rev, S_IRUGO, osst_adr_rev_show, NULL); + +static ssize_t osst_linux_media_version_show(struct class_device *class_dev, char *buf) +{ + struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev); + ssize_t l = 0; + + if (STp && STp->header_ok && STp->linux_media) + l = snprintf(buf, PAGE_SIZE, "LIN%d\n", STp->linux_media_version); + return l; +} + +CLASS_DEVICE_ATTR(media_version, S_IRUGO, osst_linux_media_version_show, NULL); + +static ssize_t osst_capacity_show(struct class_device *class_dev, char *buf) +{ + struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev); + ssize_t l = 0; + + if (STp && STp->header_ok && STp->linux_media) + l = snprintf(buf, PAGE_SIZE, "%d\n", STp->capacity); + return l; +} + +CLASS_DEVICE_ATTR(capacity, S_IRUGO, osst_capacity_show, NULL); + +static ssize_t osst_first_data_ppos_show(struct class_device *class_dev, char *buf) +{ + struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev); + ssize_t l = 0; + + if (STp && STp->header_ok && STp->linux_media) + l = snprintf(buf, PAGE_SIZE, "%d\n", STp->first_data_ppos); + return l; +} + +CLASS_DEVICE_ATTR(BOT_frame, S_IRUGO, osst_first_data_ppos_show, NULL); + +static ssize_t osst_eod_frame_ppos_show(struct class_device *class_dev, char *buf) +{ + struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev); + ssize_t l = 0; + + if (STp && STp->header_ok && STp->linux_media) + l = snprintf(buf, PAGE_SIZE, "%d\n", STp->eod_frame_ppos); + return l; +} + +CLASS_DEVICE_ATTR(EOD_frame, S_IRUGO, osst_eod_frame_ppos_show, NULL); + +static ssize_t osst_filemark_cnt_show(struct class_device *class_dev, char *buf) +{ + struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev); + ssize_t l = 0; + + if (STp && STp->header_ok && STp->linux_media) + l = snprintf(buf, PAGE_SIZE, "%d\n", STp->filemark_cnt); + return l; +} + +CLASS_DEVICE_ATTR(file_count, S_IRUGO, osst_filemark_cnt_show, NULL); + +static struct class_simple * osst_sysfs_class; + +static int osst_sysfs_valid = 0; + +static void osst_sysfs_init(void) +{ + osst_sysfs_class = class_simple_create(THIS_MODULE, "onstream_tape"); + if ( IS_ERR(osst_sysfs_class) ) + printk(KERN_WARNING "osst :W: Unable to register sysfs class\n"); + else + osst_sysfs_valid = TRUE; +} + +static void osst_sysfs_add(dev_t dev, struct device *device, struct osst_tape * STp, char * name) +{ + struct class_device *osst_class_member; + + if (!osst_sysfs_valid) return; + + osst_class_member = class_simple_device_add(osst_sysfs_class, dev, device, "%s", name); + if (IS_ERR(osst_class_member)) { + printk(KERN_WARNING "osst :W: Unable to add sysfs class member %s\n", name); + return; + } + class_set_devdata(osst_class_member, STp); + class_device_create_file(osst_class_member, &class_device_attr_ADR_rev); + class_device_create_file(osst_class_member, &class_device_attr_media_version); + class_device_create_file(osst_class_member, &class_device_attr_capacity); + class_device_create_file(osst_class_member, &class_device_attr_BOT_frame); + class_device_create_file(osst_class_member, &class_device_attr_EOD_frame); + class_device_create_file(osst_class_member, &class_device_attr_file_count); +} + +static void osst_sysfs_destroy(dev_t dev) +{ + if (!osst_sysfs_valid) return; + + class_simple_device_remove(dev); +} + +static void osst_sysfs_cleanup(void) +{ + if (osst_sysfs_valid) { + class_simple_destroy(osst_sysfs_class); + osst_sysfs_valid = 0; + } +} + +/* * osst startup / cleanup code */ static int osst_probe(struct device *dev) { - Scsi_Device * SDp = to_scsi_device(dev); - OS_Scsi_Tape * tpnt; - struct st_modedef * STm; - struct st_partstat * STps; - OSST_buffer * buffer; - struct gendisk * drive; - int i, mode, dev_num; + Scsi_Device * SDp = to_scsi_device(dev); + struct osst_tape * tpnt; + struct st_modedef * STm; + struct st_partstat * STps; + struct osst_buffer * buffer; + struct gendisk * drive; + int i, mode, dev_num; if (SDp->type != TYPE_TAPE || !osst_supports(SDp)) return -ENODEV; @@ -5432,7 +5657,7 @@ static int osst_probe(struct device *dev) write_lock(&os_scsi_tapes_lock); if (os_scsi_tapes == NULL) { os_scsi_tapes = - (OS_Scsi_Tape **)kmalloc(osst_max_dev * sizeof(OS_Scsi_Tape *), + (struct osst_tape **)kmalloc(osst_max_dev * sizeof(struct osst_tape *), GFP_ATOMIC); if (os_scsi_tapes == NULL) { write_unlock(&os_scsi_tapes_lock); @@ -5453,14 +5678,14 @@ static int osst_probe(struct device *dev) if(i >= osst_max_dev) panic ("Scsi_devices corrupt (osst)"); dev_num = i; - /* allocate a OS_Scsi_Tape for this device */ - tpnt = (OS_Scsi_Tape *)kmalloc(sizeof(OS_Scsi_Tape), GFP_ATOMIC); + /* allocate a struct osst_tape for this device */ + tpnt = (struct osst_tape *)kmalloc(sizeof(struct osst_tape), GFP_ATOMIC); if (tpnt == NULL) { write_unlock(&os_scsi_tapes_lock); printk(KERN_ERR "osst :E: Can't allocate device descriptor, device not attached.\n"); goto out_put_disk; } - memset(tpnt, 0, sizeof(OS_Scsi_Tape)); + memset(tpnt, 0, sizeof(struct osst_tape)); /* allocate a buffer for this device */ i = SDp->host->sg_tablesize; @@ -5545,7 +5770,14 @@ static int osst_probe(struct device *dev) init_MUTEX(&tpnt->lock); osst_nr_dev++; write_unlock(&os_scsi_tapes_lock); - + { + char name[8]; + /* Rewind entry */ + osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num), dev, tpnt, tape_name(tpnt)); + /* No-rewind entry */ + snprintf(name, 8, "%s%s", "n", tape_name(tpnt)); + osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num + 128), dev, tpnt, name); + } for (mode = 0; mode < ST_NBR_MODES; ++mode) { /* Rewind entry */ devfs_mk_cdev(MKDEV(OSST_MAJOR, dev_num + (mode << 5)), @@ -5572,8 +5804,8 @@ out_put_disk: static int osst_remove(struct device *dev) { - Scsi_Device * SDp = to_scsi_device(dev); - OS_Scsi_Tape * tpnt; + Scsi_Device * SDp = to_scsi_device(dev); + struct osst_tape * tpnt; int i, mode; if ((SDp->type != TYPE_TAPE) || (osst_nr_dev <= 0)) @@ -5582,6 +5814,8 @@ static int osst_remove(struct device *dev) write_lock(&os_scsi_tapes_lock); for(i=0; i < osst_max_dev; i++) { if((tpnt = os_scsi_tapes[i]) && (tpnt->device == SDp)) { + osst_sysfs_destroy(MKDEV(OSST_MAJOR, i)); + osst_sysfs_destroy(MKDEV(OSST_MAJOR, i+128)); tpnt->device = NULL; for (mode = 0; mode < ST_NBR_MODES; ++mode) { devfs_remove("%s/ot%s", SDp->devfs_name, osst_formats[mode]); @@ -5610,11 +5844,14 @@ static int __init init_osst(void) printk(KERN_INFO "osst :I: Tape driver with OnStream support version %s\nosst :I: %s\n", osst_version, cvsid); validate_options(); - + osst_sysfs_init(); + if ((register_chrdev(OSST_MAJOR,"osst", &osst_fops) < 0) || scsi_register_driver(&osst_template.gendrv)) { printk(KERN_ERR "osst :E: Unable to register major %d for OnStream tapes\n", OSST_MAJOR); + osst_sysfs_cleanup(); return 1; } + osst_create_driverfs_files(&osst_template.gendrv); return 0; } @@ -5622,10 +5859,12 @@ static int __init init_osst(void) static void __exit exit_osst (void) { int i; - OS_Scsi_Tape * STp; + struct osst_tape * STp; + osst_remove_driverfs_files(&osst_template.gendrv); scsi_unregister_driver(&osst_template.gendrv); unregister_chrdev(OSST_MAJOR, "osst"); + osst_sysfs_cleanup(); if (os_scsi_tapes) { for (i=0; i < osst_max_dev; ++i) { diff --git a/drivers/scsi/osst.h b/drivers/scsi/osst.h index 84bbc591a8ce3c..1561d4ded72bc9 100644 --- a/drivers/scsi/osst.h +++ b/drivers/scsi/osst.h @@ -1,5 +1,5 @@ /* - * $Header: /cvsroot/osst/Driver/osst.h,v 1.14 2003/12/14 14:34:38 wriede Exp $ + * $Header: /cvsroot/osst/Driver/osst.h,v 1.16 2005/01/01 21:13:35 wriede Exp $ */ #include <asm/byteorder.h> @@ -70,7 +70,7 @@ typedef struct { #define BLOCK_SIZE_PAGE_LENGTH 4 #define BUFFER_FILLING_PAGE 0x33 -#define BUFFER_FILLING_PAGE_LENGTH +#define BUFFER_FILLING_PAGE_LENGTH 4 #define VENDOR_IDENT_PAGE 0x36 #define VENDOR_IDENT_PAGE_LENGTH 8 @@ -508,7 +508,7 @@ typedef struct os_header_s { //#define OSST_MAX_SG 2 /* The OnStream tape buffer descriptor. */ -typedef struct { +struct osst_buffer { unsigned char in_use; unsigned char dma; /* DMA-able buffer */ int buffer_size; @@ -525,16 +525,16 @@ typedef struct { unsigned short sg_segs; /* number of segments in s/g list */ unsigned short orig_sg_segs; /* number of segments allocated at first try */ struct scatterlist sg[1]; /* MUST BE last item */ -} OSST_buffer; +} ; /* The OnStream tape drive descriptor */ -typedef struct { +struct osst_tape { struct scsi_driver *driver; unsigned capacity; Scsi_Device* device; struct semaphore lock; /* for serialization */ struct completion wait; /* for SCSI commands */ - OSST_buffer * buffer; + struct osst_buffer * buffer; /* Drive characteristics */ unsigned char omit_blklims; @@ -577,6 +577,7 @@ typedef struct { int min_block; int max_block; int recover_count; /* from tape opening */ + int abort_count; int write_count; int read_count; int recover_erreg; /* from last status call */ @@ -623,7 +624,7 @@ typedef struct { unsigned char last_sense[16]; #endif struct gendisk *drive; -} OS_Scsi_Tape; +} ; /* Values of write_type */ #define OS_WRITE_DATA 0 diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c index f1eb31b955796f..df89d2b7c30fea 100644 --- a/drivers/scsi/qla1280.c +++ b/drivers/scsi/qla1280.c @@ -3400,7 +3400,8 @@ qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp) sp->flags |= SRB_SENT; ha->actthreads++; WRT_REG_WORD(®->mailbox4, ha->req_ring_index); - (void) RD_REG_WORD(®->mailbox4); /* PCI posted write flush */ + /* Enforce mmio write ordering; see comment in qla1280_isp_cmd(). */ + mmiowb(); out: if (status) @@ -3668,7 +3669,8 @@ qla1280_32bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp) sp->flags |= SRB_SENT; ha->actthreads++; WRT_REG_WORD(®->mailbox4, ha->req_ring_index); - (void) RD_REG_WORD(®->mailbox4); /* PCI posted write flush */ + /* Enforce mmio write ordering; see comment in qla1280_isp_cmd(). */ + mmiowb(); out: if (status) @@ -3778,9 +3780,21 @@ qla1280_isp_cmd(struct scsi_qla_host *ha) } else ha->request_ring_ptr++; - /* Set chip new ring index. */ + /* + * Update request index to mailbox4 (Request Queue In). + * The mmiowb() ensures that this write is ordered with writes by other + * CPUs. Without the mmiowb(), it is possible for the following: + * CPUA posts write of index 5 to mailbox4 + * CPUA releases host lock + * CPUB acquires host lock + * CPUB posts write of index 6 to mailbox4 + * On PCI bus, order reverses and write of 6 posts, then index 5, + * causing chip to issue full queue of stale commands + * The mmiowb() prevents future writes from crossing the barrier. + * See Documentation/DocBook/deviceiobook.tmpl for more information. + */ WRT_REG_WORD(®->mailbox4, ha->req_ring_index); - (void) RD_REG_WORD(®->mailbox4); /* PCI posted write flush */ + mmiowb(); LEAVE("qla1280_isp_cmd"); } diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 82c7b0ab404739..63e5224eee0a0c 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -1083,6 +1083,28 @@ struct scsi_device *__scsi_iterate_devices(struct Scsi_Host *shost, EXPORT_SYMBOL(__scsi_iterate_devices); /** + * starget_for_each_device - helper to walk all devices of a target + * @starget: target whose devices we want to iterate over. + * + * This traverses over each devices of @shost. The devices have + * a reference that must be released by scsi_host_put when breaking + * out of the loop. + */ +void starget_for_each_device(struct scsi_target *starget, void * data, + void (*fn)(struct scsi_device *, void *)) +{ + struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); + struct scsi_device *sdev; + + shost_for_each_device(sdev, shost) { + if ((sdev->channel == starget->channel) && + (sdev->id == starget->id)) + fn(sdev, data); + } +} +EXPORT_SYMBOL(starget_for_each_device); + +/** * scsi_device_lookup - find a device given the host (UNLOCKED) * @shost: SCSI host pointer * @channel: SCSI channel (zero if only one channel) diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 73660628b520a2..38f165070c9434 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -1782,31 +1782,29 @@ scsi_device_resume(struct scsi_device *sdev) } EXPORT_SYMBOL(scsi_device_resume); -static int -device_quiesce_fn(struct device *dev, void *data) +static void +device_quiesce_fn(struct scsi_device *sdev, void *data) { - scsi_device_quiesce(to_scsi_device(dev)); - return 0; + scsi_device_quiesce(sdev); } void scsi_target_quiesce(struct scsi_target *starget) { - device_for_each_child(&starget->dev, NULL, device_quiesce_fn); + starget_for_each_device(starget, NULL, device_quiesce_fn); } EXPORT_SYMBOL(scsi_target_quiesce); -static int -device_resume_fn(struct device *dev, void *data) +static void +device_resume_fn(struct scsi_device *sdev, void *data) { - scsi_device_resume(to_scsi_device(dev)); - return 0; + scsi_device_resume(sdev); } void scsi_target_resume(struct scsi_target *starget) { - device_for_each_child(&starget->dev, NULL, device_resume_fn); + starget_for_each_device(starget, NULL, device_resume_fn); } EXPORT_SYMBOL(scsi_target_resume); diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c index 926cec15e5f2d8..1aca210eabd1a3 100644 --- a/drivers/scsi/scsi_transport_fc.c +++ b/drivers/scsi/scsi_transport_fc.c @@ -270,6 +270,16 @@ static int fc_setup_host_transport_attrs(struct Scsi_Host *shost) sizeof(fc_host_symbolic_name(shost))); fc_host_supported_speeds(shost) = FC_PORTSPEED_UNKNOWN; fc_host_maxframe_size(shost) = -1; + memset(fc_host_hardware_version(shost), 0, + sizeof(fc_host_hardware_version(shost))); + memset(fc_host_firmware_version(shost), 0, + sizeof(fc_host_firmware_version(shost))); + memset(fc_host_serial_number(shost), 0, + sizeof(fc_host_serial_number(shost))); + memset(fc_host_opt_rom_version(shost), 0, + sizeof(fc_host_opt_rom_version(shost))); + memset(fc_host_driver_version(shost), 0, + sizeof(fc_host_driver_version(shost))); fc_host_port_id(shost) = -1; fc_host_port_type(shost) = FC_PORTTYPE_UNKNOWN; @@ -536,6 +546,11 @@ fc_private_host_rd_attr_cast(node_name, "0x%llx\n", 20, unsigned long long); fc_private_host_rd_attr_cast(port_name, "0x%llx\n", 20, unsigned long long); fc_private_host_rd_attr(symbolic_name, "%s\n", (FC_SYMBOLIC_NAME_SIZE +1)); fc_private_host_rd_attr(maxframe_size, "%u bytes\n", 20); +fc_private_host_rd_attr(hardware_version, "%s\n", (FC_VERSION_STRING_SIZE +1)); +fc_private_host_rd_attr(firmware_version, "%s\n", (FC_VERSION_STRING_SIZE +1)); +fc_private_host_rd_attr(serial_number, "%s\n", (FC_SERIAL_NUMBER_SIZE +1)); +fc_private_host_rd_attr(opt_rom_version, "%s\n", (FC_VERSION_STRING_SIZE +1)); +fc_private_host_rd_attr(driver_version, "%s\n", (FC_VERSION_STRING_SIZE +1)); /* Dynamic Host Attributes */ @@ -772,6 +787,11 @@ fc_attach_transport(struct fc_function_template *ft) SETUP_HOST_ATTRIBUTE_RD(symbolic_name); SETUP_HOST_ATTRIBUTE_RD(supported_speeds); SETUP_HOST_ATTRIBUTE_RD(maxframe_size); + SETUP_HOST_ATTRIBUTE_RD(hardware_version); + SETUP_HOST_ATTRIBUTE_RD(firmware_version); + SETUP_HOST_ATTRIBUTE_RD(serial_number); + SETUP_HOST_ATTRIBUTE_RD(opt_rom_version); + SETUP_HOST_ATTRIBUTE_RD(driver_version); SETUP_HOST_ATTRIBUTE_RD(port_id); SETUP_HOST_ATTRIBUTE_RD(port_type); @@ -808,10 +828,9 @@ EXPORT_SYMBOL(fc_release_transport); * @dev: scsi device * @data: unused **/ -static int fc_device_block(struct device *dev, void *data) +static void fc_device_block(struct scsi_device *sdev, void *data) { - scsi_internal_device_block(to_scsi_device(dev)); - return 0; + scsi_internal_device_block(sdev); } /** @@ -819,10 +838,9 @@ static int fc_device_block(struct device *dev, void *data) * @dev: scsi device * @data: unused **/ -static int fc_device_unblock(struct device *dev, void *data) +static void fc_device_unblock(struct scsi_device *sdev, void *data) { - scsi_internal_device_unblock(to_scsi_device(dev)); - return 0; + scsi_internal_device_unblock(sdev); } /** @@ -842,7 +860,7 @@ static void fc_timeout_blocked_tgt(void *data) * unblock this device, then IO errors will probably * result if the host still isn't ready. */ - device_for_each_child(&starget->dev, NULL, fc_device_unblock); + starget_for_each_device(starget, NULL, fc_device_unblock); } /** @@ -870,7 +888,7 @@ fc_target_block(struct scsi_target *starget) if (timeout < 0 || timeout > SCSI_DEVICE_BLOCK_MAX_TIMEOUT) return -EINVAL; - device_for_each_child(&starget->dev, NULL, fc_device_block); + starget_for_each_device(starget, NULL, fc_device_block); /* The scsi lld blocks this target for the timeout period only. */ schedule_delayed_work(work, timeout * HZ); @@ -901,7 +919,7 @@ fc_target_unblock(struct scsi_target *starget) if (cancel_delayed_work(&fc_starget_dev_loss_work(starget))) flush_scheduled_work(); - device_for_each_child(&starget->dev, NULL, fc_device_unblock); + starget_for_each_device(starget, NULL, fc_device_unblock); } EXPORT_SYMBOL(fc_target_unblock); diff --git a/drivers/scsi/scsi_transport_spi.c b/drivers/scsi/scsi_transport_spi.c index f01133b4c580bf..d8bdde36fe448c 100644 --- a/drivers/scsi/scsi_transport_spi.c +++ b/drivers/scsi/scsi_transport_spi.c @@ -31,6 +31,7 @@ #include <scsi/scsi_device.h> #include <scsi/scsi_host.h> #include <scsi/scsi_request.h> +#include <scsi/scsi_eh.h> #include <scsi/scsi_transport.h> #include <scsi/scsi_transport_spi.h> @@ -378,10 +379,16 @@ static CLASS_DEVICE_ATTR(signalling, S_IRUGO | S_IWUSR, #define DV_RETRIES 3 /* should only need at most * two cc/ua clears */ +enum spi_compare_returns { + SPI_COMPARE_SUCCESS, + SPI_COMPARE_FAILURE, + SPI_COMPARE_SKIP_TEST, +}; + /* This is for read/write Domain Validation: If the device supports * an echo buffer, we do read/write tests to it */ -static int +static enum spi_compare_returns spi_dv_device_echo_buffer(struct scsi_request *sreq, u8 *buffer, u8 *ptr, const int retries) { @@ -438,9 +445,23 @@ spi_dv_device_echo_buffer(struct scsi_request *sreq, u8 *buffer, scsi_wait_req(sreq, spi_write_buffer, buffer, len, DV_TIMEOUT, DV_RETRIES); if(sreq->sr_result || !scsi_device_online(sdev)) { + struct scsi_sense_hdr sshdr; + scsi_device_set_state(sdev, SDEV_QUIESCE); + if (scsi_request_normalize_sense(sreq, &sshdr) + && sshdr.sense_key == ILLEGAL_REQUEST + /* INVALID FIELD IN CDB */ + && sshdr.asc == 0x24 && sshdr.ascq == 0x00) + /* This would mean that the drive lied + * to us about supporting an echo + * buffer (unfortunately some Western + * Digital drives do precisely this) + */ + return SPI_COMPARE_SKIP_TEST; + + SPI_PRINTK(sdev->sdev_target, KERN_ERR, "Write Buffer failure %x\n", sreq->sr_result); - return 0; + return SPI_COMPARE_FAILURE; } memset(ptr, 0, len); @@ -451,14 +472,14 @@ spi_dv_device_echo_buffer(struct scsi_request *sreq, u8 *buffer, scsi_device_set_state(sdev, SDEV_QUIESCE); if (memcmp(buffer, ptr, len) != 0) - return 0; + return SPI_COMPARE_FAILURE; } - return 1; + return SPI_COMPARE_SUCCESS; } /* This is for the simplest form of Domain Validation: a read test * on the inquiry data from the device */ -static int +static enum spi_compare_returns spi_dv_device_compare_inquiry(struct scsi_request *sreq, u8 *buffer, u8 *ptr, const int retries) { @@ -480,7 +501,7 @@ spi_dv_device_compare_inquiry(struct scsi_request *sreq, u8 *buffer, if(sreq->sr_result || !scsi_device_online(sdev)) { scsi_device_set_state(sdev, SDEV_QUIESCE); - return 0; + return SPI_COMPARE_FAILURE; } /* If we don't have the inquiry data already, the @@ -493,24 +514,28 @@ spi_dv_device_compare_inquiry(struct scsi_request *sreq, u8 *buffer, if (memcmp(buffer, ptr, len) != 0) /* failure */ - return 0; + return SPI_COMPARE_FAILURE; } - return 1; + return SPI_COMPARE_SUCCESS; } -static int +static enum spi_compare_returns spi_dv_retrain(struct scsi_request *sreq, u8 *buffer, u8 *ptr, - int (*compare_fn)(struct scsi_request *, u8 *, u8 *, int)) + enum spi_compare_returns + (*compare_fn)(struct scsi_request *, u8 *, u8 *, int)) { struct spi_internal *i = to_spi_internal(sreq->sr_host->transportt); struct scsi_device *sdev = sreq->sr_device; int period = 0, prevperiod = 0; + enum spi_compare_returns retval; for (;;) { int newperiod; - if (compare_fn(sreq, buffer, ptr, DV_LOOPS)) - /* Successful DV */ + retval = compare_fn(sreq, buffer, ptr, DV_LOOPS); + + if (retval == SPI_COMPARE_SUCCESS + || retval == SPI_COMPARE_SKIP_TEST) break; /* OK, retrain, fallback */ @@ -527,13 +552,13 @@ spi_dv_retrain(struct scsi_request *sreq, u8 *buffer, u8 *ptr, /* Total failure; set to async and return */ SPI_PRINTK(sdev->sdev_target, KERN_ERR, "Domain Validation Failure, dropping back to Asynchronous\n"); DV_SET(offset, 0); - return 0; + return SPI_COMPARE_FAILURE; } SPI_PRINTK(sdev->sdev_target, KERN_ERR, "Domain Validation detected failure, dropping back\n"); DV_SET(period, period); prevperiod = period; } - return 1; + return retval; } static int @@ -599,7 +624,8 @@ spi_dv_device_internal(struct scsi_request *sreq, u8 *buffer) DV_SET(offset, 0); DV_SET(width, 0); - if (!spi_dv_device_compare_inquiry(sreq, buffer, buffer, DV_LOOPS)) { + if (spi_dv_device_compare_inquiry(sreq, buffer, buffer, DV_LOOPS) + != SPI_COMPARE_SUCCESS) { SPI_PRINTK(sdev->sdev_target, KERN_ERR, "Domain Validation Initial Inquiry Failed\n"); /* FIXME: should probably offline the device here? */ return; @@ -609,9 +635,10 @@ spi_dv_device_internal(struct scsi_request *sreq, u8 *buffer) if (i->f->set_width && sdev->wdtr) { i->f->set_width(sdev->sdev_target, 1); - if (!spi_dv_device_compare_inquiry(sreq, buffer, + if (spi_dv_device_compare_inquiry(sreq, buffer, buffer + len, - DV_LOOPS)) { + DV_LOOPS) + != SPI_COMPARE_SUCCESS) { SPI_PRINTK(sdev->sdev_target, KERN_ERR, "Wide Transfers Fail\n"); i->f->set_width(sdev->sdev_target, 0); } @@ -624,31 +651,39 @@ spi_dv_device_internal(struct scsi_request *sreq, u8 *buffer) if(!sdev->ppr && !sdev->sdtr) return; - /* now set up to the maximum */ - DV_SET(offset, 255); - DV_SET(period, 1); - if (!spi_dv_retrain(sreq, buffer, buffer + len, - spi_dv_device_compare_inquiry)) - return; - - /* OK, now we have our initial speed set by the read only inquiry - * test, now try an echo buffer test (if the device allows it) */ + /* see if the device has an echo buffer. If it does we can + * do the SPI pattern write tests */ len = 0; if (sdev->ppr) len = spi_dv_device_get_echo_buffer(sreq, buffer); + retry: + + /* now set up to the maximum */ + DV_SET(offset, 255); + DV_SET(period, 1); + if (len == 0) { SPI_PRINTK(sdev->sdev_target, KERN_INFO, "Domain Validation skipping write tests\n"); + spi_dv_retrain(sreq, buffer, buffer + len, + spi_dv_device_compare_inquiry); return; } + if (len > SPI_MAX_ECHO_BUFFER_SIZE) { SPI_PRINTK(sdev->sdev_target, KERN_WARNING, "Echo buffer size %d is too big, trimming to %d\n", len, SPI_MAX_ECHO_BUFFER_SIZE); len = SPI_MAX_ECHO_BUFFER_SIZE; } - spi_dv_retrain(sreq, buffer, buffer + len, - spi_dv_device_echo_buffer); + if (spi_dv_retrain(sreq, buffer, buffer + len, + spi_dv_device_echo_buffer) + == SPI_COMPARE_SKIP_TEST) { + /* OK, the stupid drive can't do a write echo buffer + * test after all, fall back to the read tests */ + len = 0; + goto retry; + } } diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 0d10f106701d67..86ee1e14358032 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -1082,9 +1082,12 @@ repeat: " READ CAPACITY(16).\n", diskname); longrc = 1; goto repeat; - } else { - printk(KERN_ERR "%s: too big for kernel. Assuming maximum 2Tb\n", diskname); } + printk(KERN_ERR "%s: too big for this kernel. Use a " + "kernel compiled with support for large block " + "devices.\n", diskname); + sdkp->capacity = 0; + goto got_data; } sdkp->capacity = 1 + (((sector_t)buffer[0] << 24) | (buffer[1] << 16) | diff --git a/drivers/scsi/sym53c8xx_2/sym_conf.h b/drivers/scsi/sym53c8xx_2/sym_conf.h index b0f58e72570b40..30bb92c90fc614 100644 --- a/drivers/scsi/sym53c8xx_2/sym_conf.h +++ b/drivers/scsi/sym53c8xx_2/sym_conf.h @@ -79,14 +79,6 @@ /* #define SYM_CONF_IARB_SUPPORT */ /* - * Number of lists for the optimization of the IO timeout handling. - * Not used under FreeBSD and Linux. - */ -#ifndef SYM_CONF_TIMEOUT_ORDER_MAX -#define SYM_CONF_TIMEOUT_ORDER_MAX (8) -#endif - -/* * Only relevant if IARB support configured. * - Max number of successive settings of IARB hints. * - Set IARB on arbitration lost. diff --git a/drivers/scsi/sym53c8xx_2/sym_defs.h b/drivers/scsi/sym53c8xx_2/sym_defs.h index 2e1d89f5de3575..d27071dcb28bb2 100644 --- a/drivers/scsi/sym53c8xx_2/sym_defs.h +++ b/drivers/scsi/sym53c8xx_2/sym_defs.h @@ -40,30 +40,10 @@ #ifndef SYM_DEFS_H #define SYM_DEFS_H -#define SYM_VERSION "2.1.18m" +#define SYM_VERSION "2.1.18n" #define SYM_DRIVER_NAME "sym-" SYM_VERSION /* - * PCI device identifier of SYMBIOS chips. - */ -#define PCI_ID_SYM53C810 PCI_DEVICE_ID_NCR_53C810 -#define PCI_ID_SYM53C810AP PCI_DEVICE_ID_LSI_53C810AP -#define PCI_ID_SYM53C815 PCI_DEVICE_ID_NCR_53C815 -#define PCI_ID_SYM53C820 PCI_DEVICE_ID_NCR_53C820 -#define PCI_ID_SYM53C825 PCI_DEVICE_ID_NCR_53C825 -#define PCI_ID_SYM53C860 PCI_DEVICE_ID_NCR_53C860 -#define PCI_ID_SYM53C875 PCI_DEVICE_ID_NCR_53C875 -#define PCI_ID_SYM53C875_2 PCI_DEVICE_ID_NCR_53C875J -#define PCI_ID_SYM53C885 PCI_DEVICE_ID_NCR_53C885 -#define PCI_ID_SYM53C895 PCI_DEVICE_ID_NCR_53C895 -#define PCI_ID_SYM53C896 PCI_DEVICE_ID_NCR_53C896 -#define PCI_ID_SYM53C895A PCI_DEVICE_ID_LSI_53C895A -#define PCI_ID_SYM53C875A PCI_DEVICE_ID_LSI_53C875A -#define PCI_ID_LSI53C1010_33 PCI_DEVICE_ID_LSI_53C1010_33 -#define PCI_ID_LSI53C1010_66 PCI_DEVICE_ID_LSI_53C1010_66 -#define PCI_ID_LSI53C1510D PCI_DEVICE_ID_LSI_53C1510 - -/* * SYM53C8XX device features descriptor. */ struct sym_pci_chip { @@ -764,27 +744,27 @@ struct sym_tblsel { #define M_RESTORE_DP RESTORE_POINTERS #define M_DISCONNECT DISCONNECT #define M_ID_ERROR INITIATOR_ERROR -#define M_ABORT ABORT +#define M_ABORT ABORT_TASK_SET #define M_REJECT MESSAGE_REJECT #define M_NOOP NOP #define M_PARITY MSG_PARITY_ERROR #define M_LCOMPLETE LINKED_CMD_COMPLETE #define M_FCOMPLETE LINKED_FLG_CMD_COMPLETE -#define M_RESET BUS_DEVICE_RESET -#define M_ABORT_TAG (0x0d) -#define M_CLEAR_QUEUE (0x0e) +#define M_RESET TARGET_RESET +#define M_ABORT_TAG ABORT_TASK +#define M_CLEAR_QUEUE CLEAR_TASK_SET #define M_INIT_REC INITIATE_RECOVERY #define M_REL_REC RELEASE_RECOVERY #define M_TERMINATE (0x11) #define M_SIMPLE_TAG SIMPLE_QUEUE_TAG #define M_HEAD_TAG HEAD_OF_QUEUE_TAG #define M_ORDERED_TAG ORDERED_QUEUE_TAG -#define M_IGN_RESIDUE (0x23) +#define M_IGN_RESIDUE IGNORE_WIDE_RESIDUE #define M_X_MODIFY_DP EXTENDED_MODIFY_DATA_POINTER #define M_X_SYNC_REQ EXTENDED_SDTR #define M_X_WIDE_REQ EXTENDED_WDTR -#define M_X_PPR_REQ (0x04) +#define M_X_PPR_REQ EXTENDED_PPR /* * PPR protocol options diff --git a/drivers/scsi/sym53c8xx_2/sym_fw.c b/drivers/scsi/sym53c8xx_2/sym_fw.c index c30d5cd65e97e1..1c6d0d182d2c0c 100644 --- a/drivers/scsi/sym53c8xx_2/sym_fw.c +++ b/drivers/scsi/sym53c8xx_2/sym_fw.c @@ -223,13 +223,13 @@ sym_fw2_patch(struct sym_hcb *np) * Remove a couple of work-arounds specific to C1010 if * they are not desirable. See `sym_fw2.h' for more details. */ - if (!(np->device_id == PCI_ID_LSI53C1010_66 && + if (!(np->device_id == PCI_DEVICE_ID_LSI_53C1010_66 && np->revision_id < 0x1 && np->pciclk_khz < 60000)) { scripta0->datao_phase[0] = cpu_to_scr(SCR_NO_OP); scripta0->datao_phase[1] = cpu_to_scr(0); } - if (!(np->device_id == PCI_ID_LSI53C1010_33 && + if (!(np->device_id == PCI_DEVICE_ID_LSI_53C1010_33 && /* np->revision_id < 0xff */ 1)) { scripta0->sel_done[0] = cpu_to_scr(SCR_NO_OP); scripta0->sel_done[1] = cpu_to_scr(0); diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c index 4c64761be9c60c..c389e55c320454 100644 --- a/drivers/scsi/sym53c8xx_2/sym_glue.c +++ b/drivers/scsi/sym53c8xx_2/sym_glue.c @@ -55,6 +55,15 @@ #define NAME53C "sym53c" #define NAME53C8XX "sym53c8xx" +/* SPARC just has to be different ... */ +#ifdef __sparc__ +#define IRQ_FMT "%s" +#define IRQ_PRM(x) __irq_itoa(x) +#else +#define IRQ_FMT "%d" +#define IRQ_PRM(x) (x) +#endif + struct sym_driver_setup sym_driver_setup = SYM_LINUX_DRIVER_SETUP; unsigned int sym_debug_flags = 0; @@ -147,7 +156,7 @@ pci_get_base_address(struct pci_dev *pdev, int index, u_long *base) } /* This lock protects only the memory allocation/free. */ -spinlock_t sym53c8xx_lock = SPIN_LOCK_UNLOCKED; +static spinlock_t sym53c8xx_lock = SPIN_LOCK_UNLOCKED; static struct scsi_transport_template *sym2_transport_template = NULL; @@ -285,7 +294,7 @@ void sym_xpt_done(struct sym_hcb *np, struct scsi_cmnd *ccb) ccb->scsi_done(ccb); } -void sym_xpt_done2(struct sym_hcb *np, struct scsi_cmnd *ccb, int cam_status) +static void sym_xpt_done2(struct sym_hcb *np, struct scsi_cmnd *ccb, int cam_status) { sym_set_cam_status(ccb, cam_status); sym_xpt_done(np, ccb); @@ -379,7 +388,7 @@ void sym_set_cam_result_error(struct sym_hcb *np, struct sym_ccb *cp, int resid) /* * Bounce back the sense data to user. */ - bzero(&csio->sense_buffer, sizeof(csio->sense_buffer)); + memset(&csio->sense_buffer, 0, sizeof(csio->sense_buffer)); memcpy(csio->sense_buffer, cp->sns_bbuf, min(sizeof(csio->sense_buffer), (size_t)SYM_SNS_BBUF_LEN)); @@ -513,7 +522,7 @@ static int sym_queue_command(struct sym_hcb *np, struct scsi_cmnd *ccb) } /* - * Retreive the target descriptor. + * Retrieve the target descriptor. */ tp = &np->target[ccb->device->id]; @@ -1277,7 +1286,7 @@ static int sym_user_command(struct sym_hcb *np, char *buffer, int length) int arg_len; u_long target; - bzero(uc, sizeof(*uc)); + memset(uc, 0, sizeof(*uc)); if (len > 0 && ptr[len-1] == '\n') --len; @@ -1467,18 +1476,8 @@ static int sym_host_info(struct sym_hcb *np, char *ptr, off_t offset, int len) copy_info(&info, "Chip " NAME53C "%s, device id 0x%x, " "revision id 0x%x\n", np->s.chip_name, np->device_id, np->revision_id); - copy_info(&info, "At PCI address %s, " -#ifdef __sparc__ - "IRQ %s\n", -#else - "IRQ %d\n", -#endif - pci_name(np->s.device), -#ifdef __sparc__ - __irq_itoa(np->s.irq)); -#else - (int) np->s.irq); -#endif + copy_info(&info, "At PCI address %s, IRQ " IRQ_FMT "\n", + pci_name(np->s.device), IRQ_PRM(np->s.irq)); copy_info(&info, "Min. period factor %d, %s SCSI BUS%s\n", (int) (np->minsync_dt ? np->minsync_dt : np->minsync), np->maxwide ? "Wide" : "Narrow", @@ -1558,32 +1557,23 @@ static void sym_free_resources(struct sym_hcb *np) */ static int sym_setup_bus_dma_mask(struct sym_hcb *np) { -#if SYM_CONF_DMA_ADDRESSING_MODE == 0 - if (pci_set_dma_mask(np->s.device, 0xffffffffUL)) - goto out_err32; -#else +#if SYM_CONF_DMA_ADDRESSING_MODE > 0 #if SYM_CONF_DMA_ADDRESSING_MODE == 1 -#define PciDmaMask 0xffffffffffULL +#define DMA_DAC_MASK 0x000000ffffffffffULL /* 40-bit */ #elif SYM_CONF_DMA_ADDRESSING_MODE == 2 -#define PciDmaMask 0xffffffffffffffffULL +#define DMA_DAC_MASK DMA_64BIT_MASK #endif - if (np->features & FE_DAC) { - if (!pci_set_dma_mask(np->s.device, PciDmaMask)) { - np->use_dac = 1; - printf_info("%s: using 64 bit DMA addressing\n", - sym_name(np)); - } else { - if (pci_set_dma_mask(np->s.device, 0xffffffffUL)) - goto out_err32; - } + if ((np->features & FE_DAC) && + !pci_set_dma_mask(np->s.device, DMA_DAC_MASK)) { + np->use_dac = 1; + return 0; } -#undef PciDmaMask #endif - return 0; -out_err32: - printf_warning("%s: 32 BIT DMA ADDRESSING NOT SUPPORTED\n", - sym_name(np)); + if (!pci_set_dma_mask(np->s.device, DMA_32BIT_MASK)) + return 0; + + printf_warning("%s: No suitable DMA available\n", sym_name(np)); return -1; } @@ -1606,19 +1596,9 @@ static struct Scsi_Host * __devinit sym_attach(struct scsi_host_template *tpnt, struct sym_fw *fw; printk(KERN_INFO - "sym%d: <%s> rev 0x%x at pci %s " -#ifdef __sparc__ - "irq %s\n", -#else - "irq %d\n", -#endif + "sym%d: <%s> rev 0x%x at pci %s irq " IRQ_FMT "\n", unit, dev->chip.name, dev->chip.revision_id, - pci_name(dev->pdev), -#ifdef __sparc__ - __irq_itoa(dev->s.irq)); -#else - dev->s.irq); -#endif + pci_name(dev->pdev), IRQ_PRM(dev->s.irq)); /* * Get the firmware for this chip. @@ -1672,9 +1652,6 @@ static struct Scsi_Host * __devinit sym_attach(struct scsi_host_template *tpnt, strlcpy(np->s.chip_name, dev->chip.name, sizeof(np->s.chip_name)); sprintf(np->s.inst_name, "sym%d", np->s.unit); - /* - * Ask/tell the system about DMA addressing. - */ if (sym_setup_bus_dma_mask(np)) goto attach_failed; @@ -2010,7 +1987,7 @@ sym_init_device(struct pci_dev *pdev, struct sym_device *device) * the preset SCSI ID (which may be zero) must be read in from * a special configuration space register of the 875. */ -void sym_config_pqs(struct pci_dev *pdev, struct sym_device *sym_dev) +static void sym_config_pqs(struct pci_dev *pdev, struct sym_device *sym_dev) { int slot; u8 tmp; diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.h b/drivers/scsi/sym53c8xx_2/sym_glue.h index df1b9af12d877c..7cfb1b21b69ae5 100644 --- a/drivers/scsi/sym53c8xx_2/sym_glue.h +++ b/drivers/scsi/sym53c8xx_2/sym_glue.h @@ -58,13 +58,6 @@ #include <scsi/scsi_device.h> #include <scsi/scsi_host.h> -#ifndef bzero -#define bzero(d, n) memset((d), 0, (n)) -#endif - -/* - * General driver includes. - */ #include "sym_conf.h" #include "sym_defs.h" #include "sym_misc.h" @@ -123,14 +116,6 @@ typedef struct sym_tcb *tcb_p; typedef struct sym_lcb *lcb_p; typedef struct sym_ccb *ccb_p; -typedef struct sym_hcb *hcb_p; - -/* - * Define a reference to the O/S dependent IO request. - */ -typedef struct scsi_cmnd *cam_ccb_p; /* Generic */ -typedef struct scsi_cmnd *cam_scsiio_p;/* SCSI I/O */ - /* * IO functions definition for big/little endian CPU support. @@ -525,7 +510,7 @@ sym_get_cam_status(struct scsi_cmnd *ccb) /* * Async handler for negotiations. */ -void sym_xpt_async_nego_wide(hcb_p np, int target); +void sym_xpt_async_nego_wide(struct sym_hcb *np, int target); #define sym_xpt_async_nego_sync(np, target) \ sym_announce_transfer_rate(np, target) #define sym_xpt_async_nego_ppr(np, target) \ @@ -534,14 +519,14 @@ void sym_xpt_async_nego_wide(hcb_p np, int target); /* * Build CAM result for a successful IO and for a failed IO. */ -static __inline void sym_set_cam_result_ok(hcb_p np, ccb_p cp, int resid) +static __inline void sym_set_cam_result_ok(struct sym_hcb *np, ccb_p cp, int resid) { struct scsi_cmnd *cmd = cp->cam_ccb; cmd->resid = resid; cmd->result = (((DID_OK) << 16) + ((cp->ssss_status) & 0x7f)); } -void sym_set_cam_result_error(hcb_p np, ccb_p cp, int resid); +void sym_set_cam_result_error(struct sym_hcb *np, ccb_p cp, int resid); /* * Other O/S specific methods. @@ -549,13 +534,12 @@ void sym_set_cam_result_error(hcb_p np, ccb_p cp, int resid); #define sym_cam_target_id(ccb) (ccb)->target #define sym_cam_target_lun(ccb) (ccb)->lun #define sym_freeze_cam_ccb(ccb) do { ; } while (0) -void sym_xpt_done(hcb_p np, cam_ccb_p ccb); -void sym_xpt_done2(hcb_p np, cam_ccb_p ccb, int cam_status); +void sym_xpt_done(struct sym_hcb *np, struct scsi_cmnd *ccb); void sym_print_addr (ccb_p cp); -void sym_xpt_async_bus_reset(hcb_p np); -void sym_xpt_async_sent_bdr(hcb_p np, int target); -int sym_setup_data_and_start (hcb_p np, cam_scsiio_p csio, ccb_p cp); -void sym_log_bus_error(hcb_p np); -void sym_sniff_inquiry(hcb_p np, struct scsi_cmnd *cmd, int resid); +void sym_xpt_async_bus_reset(struct sym_hcb *np); +void sym_xpt_async_sent_bdr(struct sym_hcb *np, int target); +int sym_setup_data_and_start (struct sym_hcb *np, struct scsi_cmnd *csio, ccb_p cp); +void sym_log_bus_error(struct sym_hcb *np); +void sym_sniff_inquiry(struct sym_hcb *np, struct scsi_cmnd *cmd, int resid); #endif /* SYM_GLUE_H */ diff --git a/drivers/scsi/sym53c8xx_2/sym_hipd.c b/drivers/scsi/sym53c8xx_2/sym_hipd.c index 383f48b1014e84..8b7aa921e487aa 100644 --- a/drivers/scsi/sym53c8xx_2/sym_hipd.c +++ b/drivers/scsi/sym53c8xx_2/sym_hipd.c @@ -47,14 +47,14 @@ /* * Needed function prototypes. */ -static void sym_int_ma (hcb_p np); -static void sym_int_sir (hcb_p np); -static ccb_p sym_alloc_ccb(hcb_p np); -static ccb_p sym_ccb_from_dsa(hcb_p np, u32 dsa); -static void sym_alloc_lcb_tags (hcb_p np, u_char tn, u_char ln); -static void sym_complete_error (hcb_p np, ccb_p cp); -static void sym_complete_ok (hcb_p np, ccb_p cp); -static int sym_compute_residual(hcb_p np, ccb_p cp); +static void sym_int_ma (struct sym_hcb *np); +static void sym_int_sir (struct sym_hcb *np); +static ccb_p sym_alloc_ccb(struct sym_hcb *np); +static ccb_p sym_ccb_from_dsa(struct sym_hcb *np, u32 dsa); +static void sym_alloc_lcb_tags (struct sym_hcb *np, u_char tn, u_char ln); +static void sym_complete_error (struct sym_hcb *np, ccb_p cp); +static void sym_complete_ok (struct sym_hcb *np, ccb_p cp); +static int sym_compute_residual(struct sym_hcb *np, ccb_p cp); /* * Returns the name of this driver. @@ -86,12 +86,12 @@ static void sym_printl_hex (char *label, u_char *p, int n) * Print something which allows to retrieve the controler type, * unit, target, lun concerned by a kernel message. */ -static void sym_print_target (hcb_p np, int target) +static void sym_print_target (struct sym_hcb *np, int target) { printf ("%s:%d:", sym_name(np), target); } -static void sym_print_lun(hcb_p np, int target, int lun) +static void sym_print_lun(struct sym_hcb *np, int target, int lun) { printf ("%s:%d:%d:", sym_name(np), target, lun); } @@ -126,7 +126,7 @@ static void sym_print_msg (ccb_p cp, char *label, u_char *msg) printf (".\n"); } -static void sym_print_nego_msg (hcb_p np, int target, char *label, u_char *msg) +static void sym_print_nego_msg (struct sym_hcb *np, int target, char *label, u_char *msg) { PRINT_TARGET(np, target); if (label) @@ -184,7 +184,7 @@ static char *sym_scsi_bus_mode(int mode) * On the other hand, LVD devices need some delay * to settle and report actual BUS mode in STEST4. */ -static void sym_chip_reset (hcb_p np) +static void sym_chip_reset (struct sym_hcb *np) { OUTB (nc_istat, SRST); UDELAY (10); @@ -201,7 +201,7 @@ static void sym_chip_reset (hcb_p np) * So, we need to abort the current operation prior to * soft resetting the chip. */ -static void sym_soft_reset (hcb_p np) +static void sym_soft_reset (struct sym_hcb *np) { u_char istat = 0; int i; @@ -234,12 +234,12 @@ do_chip_reset: * * The interrupt handler will reinitialize the chip. */ -static void sym_start_reset(hcb_p np) +static void sym_start_reset(struct sym_hcb *np) { (void) sym_reset_scsi_bus(np, 1); } -int sym_reset_scsi_bus(hcb_p np, int enab_int) +int sym_reset_scsi_bus(struct sym_hcb *np, int enab_int) { u32 term; int retv = 0; @@ -293,7 +293,7 @@ out: /* * Select SCSI clock frequency */ -static void sym_selectclock(hcb_p np, u_char scntl3) +static void sym_selectclock(struct sym_hcb *np, u_char scntl3) { /* * If multiplier not present or not selected, leave here. @@ -348,7 +348,7 @@ static void sym_selectclock(hcb_p np, u_char scntl3) /* * calculate SCSI clock frequency (in KHz) */ -static unsigned getfreq (hcb_p np, int gen) +static unsigned getfreq (struct sym_hcb *np, int gen) { unsigned int ms = 0; unsigned int f; @@ -420,7 +420,7 @@ static unsigned getfreq (hcb_p np, int gen) return f; } -static unsigned sym_getfreq (hcb_p np) +static unsigned sym_getfreq (struct sym_hcb *np) { u_int f1, f2; int gen = 8; @@ -435,7 +435,7 @@ static unsigned sym_getfreq (hcb_p np) /* * Get/probe chip SCSI clock frequency */ -static void sym_getclock (hcb_p np, int mult) +static void sym_getclock (struct sym_hcb *np, int mult) { unsigned char scntl3 = np->sv_scntl3; unsigned char stest1 = np->sv_stest1; @@ -492,7 +492,7 @@ static void sym_getclock (hcb_p np, int mult) /* * Get/probe PCI clock frequency */ -static int sym_getpciclock (hcb_p np) +static int sym_getpciclock (struct sym_hcb *np) { int f = 0; @@ -528,7 +528,7 @@ static u32 div_10M[] = {2*_5M, 3*_5M, 4*_5M, 6*_5M, 8*_5M, 12*_5M, 16*_5M}; * synchronous factor period. */ static int -sym_getsync(hcb_p np, u_char dt, u_char sfac, u_char *divp, u_char *fakp) +sym_getsync(struct sym_hcb *np, u_char dt, u_char sfac, u_char *divp, u_char *fakp) { u32 clk = np->clock_khz; /* SCSI clock frequency in kHz */ int div = np->clock_divn; /* Number of divisors supported */ @@ -648,7 +648,7 @@ sym_getsync(hcb_p np, u_char dt, u_char sfac, u_char *divp, u_char *fakp) /* * Set initial io register bits from burst code. */ -static __inline void sym_init_burst(hcb_p np, u_char bc) +static __inline void sym_init_burst(struct sym_hcb *np, u_char bc) { np->rv_ctest4 &= ~0x80; np->rv_dmode &= ~(0x3 << 6); @@ -668,7 +668,7 @@ static __inline void sym_init_burst(hcb_p np, u_char bc) /* * Print out the list of targets that have some flag disabled by user. */ -static void sym_print_targets_flag(hcb_p np, int mask, char *msg) +static void sym_print_targets_flag(struct sym_hcb *np, int mask, char *msg) { int cnt; int i; @@ -696,7 +696,7 @@ static void sym_print_targets_flag(hcb_p np, int mask, char *msg) * is not safe on paper, but it seems to work quite * well. :) */ -static void sym_save_initial_setting (hcb_p np) +static void sym_save_initial_setting (struct sym_hcb *np) { np->sv_scntl0 = INB(nc_scntl0) & 0x0a; np->sv_scntl3 = INB(nc_scntl3) & 0x07; @@ -716,44 +716,11 @@ static void sym_save_initial_setting (hcb_p np) np->sv_ctest5 = INB(nc_ctest5) & 0x24; } -#ifdef CONFIG_PARISC -static u32 parisc_setup_hcb(hcb_p np, u32 period) -{ - unsigned long pdc_period; - char scsi_mode; - struct hardware_path hwpath; - - /* Host firmware (PDC) keeps a table for crippling SCSI capabilities. - * Many newer machines export one channel of 53c896 chip - * as SE, 50-pin HD. Also used for Multi-initiator SCSI clusters - * to set the SCSI Initiator ID. - */ - get_pci_node_path(np->s.device, &hwpath); - if (!pdc_get_initiator(&hwpath, &np->myaddr, &pdc_period, - &np->maxwide, &scsi_mode)) - return period; - - if (scsi_mode >= 0) { - /* C3000 PDC reports period/mode */ - SYM_SETUP_SCSI_DIFF = 0; - switch(scsi_mode) { - case 0: np->scsi_mode = SMODE_SE; break; - case 1: np->scsi_mode = SMODE_HVD; break; - case 2: np->scsi_mode = SMODE_LVD; break; - default: break; - } - } - - return (u32) pdc_period; -} -#else -static inline int parisc_setup_hcb(hcb_p np, u32 period) { return period; } -#endif /* * Prepare io register values used by sym_start_up() * according to selected and supported features. */ -static int sym_prepare_setting(hcb_p np, struct sym_nvram *nvram) +static int sym_prepare_setting(struct sym_hcb *np, struct sym_nvram *nvram) { u_char burst_max; u32 period; @@ -816,8 +783,6 @@ static int sym_prepare_setting(hcb_p np, struct sym_nvram *nvram) */ period = (4 * div_10M[0] + np->clock_khz - 1) / np->clock_khz; - period = parisc_setup_hcb(np, period); - if (period <= 250) np->minsync = 10; else if (period <= 303) np->minsync = 11; else if (period <= 500) np->minsync = 12; @@ -880,7 +845,7 @@ static int sym_prepare_setting(hcb_p np, struct sym_nvram *nvram) * In dual channel mode, contention occurs if internal cycles * are used. Disable internal cycles. */ - if (np->device_id == PCI_ID_LSI53C1010_33 && + if (np->device_id == PCI_DEVICE_ID_LSI_53C1010_33 && np->revision_id < 0x1) np->rv_ccntl0 |= DILS; @@ -904,9 +869,9 @@ static int sym_prepare_setting(hcb_p np, struct sym_nvram *nvram) * this driver. The generic ncr driver that does not use * LOAD/STORE instructions does not need this work-around. */ - if ((np->device_id == PCI_ID_SYM53C810 && + if ((np->device_id == PCI_DEVICE_ID_NCR_53C810 && np->revision_id >= 0x10 && np->revision_id <= 0x11) || - (np->device_id == PCI_ID_SYM53C860 && + (np->device_id == PCI_DEVICE_ID_NCR_53C860 && np->revision_id <= 0x1)) np->features &= ~(FE_WRIE|FE_ERL|FE_ERMP); @@ -1000,7 +965,7 @@ static int sym_prepare_setting(hcb_p np, struct sym_nvram *nvram) if ((SYM_SETUP_SCSI_LED || (nvram->type == SYM_SYMBIOS_NVRAM || (nvram->type == SYM_TEKRAM_NVRAM && - np->device_id == PCI_ID_SYM53C895))) && + np->device_id == PCI_DEVICE_ID_NCR_53C895))) && !(np->features & FE_LEDC) && !(np->sv_gpcntl & 0x01)) np->features |= FE_LED0; @@ -1091,7 +1056,7 @@ static int sym_prepare_setting(hcb_p np, struct sym_nvram *nvram) * Has to be called with interrupts disabled. */ #ifndef SYM_CONF_IOMAPPED -static int sym_regtest (hcb_p np) +static int sym_regtest (struct sym_hcb *np) { register volatile u32 data; /* @@ -1115,7 +1080,7 @@ static int sym_regtest (hcb_p np) } #endif -static int sym_snooptest (hcb_p np) +static int sym_snooptest (struct sym_hcb *np) { u32 sym_rd, sym_wr, sym_bk, host_rd, host_wr, pc, dstat; int i, err=0; @@ -1241,7 +1206,7 @@ restart_test: * First 24 register of the chip: * r0..rf */ -static void sym_log_hard_error(hcb_p np, u_short sist, u_char dstat) +static void sym_log_hard_error(struct sym_hcb *np, u_short sist, u_char dstat) { u32 dsp; int script_ofs; @@ -1299,85 +1264,85 @@ static void sym_log_hard_error(hcb_p np, u_short sist, u_char dstat) } static struct sym_pci_chip sym_pci_dev_table[] = { - {PCI_ID_SYM53C810, 0x0f, "810", 4, 8, 4, 64, + {PCI_DEVICE_ID_NCR_53C810, 0x0f, "810", 4, 8, 4, 64, FE_ERL} , #ifdef SYM_DEBUG_GENERIC_SUPPORT - {PCI_ID_SYM53C810, 0xff, "810a", 4, 8, 4, 1, + {PCI_DEVICE_ID_NCR_53C810, 0xff, "810a", 4, 8, 4, 1, FE_BOF} , #else - {PCI_ID_SYM53C810, 0xff, "810a", 4, 8, 4, 1, + {PCI_DEVICE_ID_NCR_53C810, 0xff, "810a", 4, 8, 4, 1, FE_CACHE_SET|FE_LDSTR|FE_PFEN|FE_BOF} , #endif - {PCI_ID_SYM53C815, 0xff, "815", 4, 8, 4, 64, + {PCI_DEVICE_ID_NCR_53C815, 0xff, "815", 4, 8, 4, 64, FE_BOF|FE_ERL} , - {PCI_ID_SYM53C825, 0x0f, "825", 6, 8, 4, 64, + {PCI_DEVICE_ID_NCR_53C825, 0x0f, "825", 6, 8, 4, 64, FE_WIDE|FE_BOF|FE_ERL|FE_DIFF} , - {PCI_ID_SYM53C825, 0xff, "825a", 6, 8, 4, 2, + {PCI_DEVICE_ID_NCR_53C825, 0xff, "825a", 6, 8, 4, 2, FE_WIDE|FE_CACHE0_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN|FE_RAM|FE_DIFF} , - {PCI_ID_SYM53C860, 0xff, "860", 4, 8, 5, 1, + {PCI_DEVICE_ID_NCR_53C860, 0xff, "860", 4, 8, 5, 1, FE_ULTRA|FE_CACHE_SET|FE_BOF|FE_LDSTR|FE_PFEN} , - {PCI_ID_SYM53C875, 0x01, "875", 6, 16, 5, 2, + {PCI_DEVICE_ID_NCR_53C875, 0x01, "875", 6, 16, 5, 2, FE_WIDE|FE_ULTRA|FE_CACHE0_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN| FE_RAM|FE_DIFF|FE_VARCLK} , - {PCI_ID_SYM53C875, 0xff, "875", 6, 16, 5, 2, + {PCI_DEVICE_ID_NCR_53C875, 0xff, "875", 6, 16, 5, 2, FE_WIDE|FE_ULTRA|FE_DBLR|FE_CACHE0_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN| FE_RAM|FE_DIFF|FE_VARCLK} , - {PCI_ID_SYM53C875_2, 0xff, "875", 6, 16, 5, 2, + {PCI_DEVICE_ID_NCR_53C875J, 0xff, "875J", 6, 16, 5, 2, FE_WIDE|FE_ULTRA|FE_DBLR|FE_CACHE0_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN| FE_RAM|FE_DIFF|FE_VARCLK} , - {PCI_ID_SYM53C885, 0xff, "885", 6, 16, 5, 2, + {PCI_DEVICE_ID_NCR_53C885, 0xff, "885", 6, 16, 5, 2, FE_WIDE|FE_ULTRA|FE_DBLR|FE_CACHE0_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN| FE_RAM|FE_DIFF|FE_VARCLK} , #ifdef SYM_DEBUG_GENERIC_SUPPORT - {PCI_ID_SYM53C895, 0xff, "895", 6, 31, 7, 2, + {PCI_DEVICE_ID_NCR_53C895, 0xff, "895", 6, 31, 7, 2, FE_WIDE|FE_ULTRA2|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFS| FE_RAM|FE_LCKFRQ} , #else - {PCI_ID_SYM53C895, 0xff, "895", 6, 31, 7, 2, + {PCI_DEVICE_ID_NCR_53C895, 0xff, "895", 6, 31, 7, 2, FE_WIDE|FE_ULTRA2|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN| FE_RAM|FE_LCKFRQ} , #endif - {PCI_ID_SYM53C896, 0xff, "896", 6, 31, 7, 4, + {PCI_DEVICE_ID_NCR_53C896, 0xff, "896", 6, 31, 7, 4, FE_WIDE|FE_ULTRA2|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN| FE_RAM|FE_RAM8K|FE_64BIT|FE_DAC|FE_IO256|FE_NOPM|FE_LEDC|FE_LCKFRQ} , - {PCI_ID_SYM53C895A, 0xff, "895a", 6, 31, 7, 4, + {PCI_DEVICE_ID_LSI_53C895A, 0xff, "895a", 6, 31, 7, 4, FE_WIDE|FE_ULTRA2|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN| FE_RAM|FE_RAM8K|FE_DAC|FE_IO256|FE_NOPM|FE_LEDC|FE_LCKFRQ} , - {PCI_ID_SYM53C875A, 0xff, "875a", 6, 31, 7, 4, + {PCI_DEVICE_ID_LSI_53C875A, 0xff, "875a", 6, 31, 7, 4, FE_WIDE|FE_ULTRA|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN| FE_RAM|FE_DAC|FE_IO256|FE_NOPM|FE_LEDC|FE_LCKFRQ} , - {PCI_ID_LSI53C1010_33, 0x00, "1010-33", 6, 31, 7, 8, + {PCI_DEVICE_ID_LSI_53C1010_33, 0x00, "1010-33", 6, 31, 7, 8, FE_WIDE|FE_ULTRA3|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFBC|FE_LDSTR|FE_PFEN| FE_RAM|FE_RAM8K|FE_64BIT|FE_DAC|FE_IO256|FE_NOPM|FE_LEDC|FE_CRC| FE_C10} , - {PCI_ID_LSI53C1010_33, 0xff, "1010-33", 6, 31, 7, 8, + {PCI_DEVICE_ID_LSI_53C1010_33, 0xff, "1010-33", 6, 31, 7, 8, FE_WIDE|FE_ULTRA3|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFBC|FE_LDSTR|FE_PFEN| FE_RAM|FE_RAM8K|FE_64BIT|FE_DAC|FE_IO256|FE_NOPM|FE_LEDC|FE_CRC| FE_C10|FE_U3EN} , - {PCI_ID_LSI53C1010_66, 0xff, "1010-66", 6, 31, 7, 8, + {PCI_DEVICE_ID_LSI_53C1010_66, 0xff, "1010-66", 6, 31, 7, 8, FE_WIDE|FE_ULTRA3|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFBC|FE_LDSTR|FE_PFEN| FE_RAM|FE_RAM8K|FE_64BIT|FE_DAC|FE_IO256|FE_NOPM|FE_LEDC|FE_66MHZ|FE_CRC| FE_C10|FE_U3EN} , - {PCI_ID_LSI53C1510D, 0xff, "1510d", 6, 31, 7, 4, + {PCI_DEVICE_ID_LSI_53C1510, 0xff, "1510d", 6, 31, 7, 4, FE_WIDE|FE_ULTRA2|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN| FE_RAM|FE_IO256|FE_LEDC} }; @@ -1415,7 +1380,7 @@ sym_lookup_pci_chip_table (u_short device_id, u_char revision) * This is only used if the direct mapping * has been unsuccessful. */ -int sym_lookup_dmap(hcb_p np, u32 h, int s) +int sym_lookup_dmap(struct sym_hcb *np, u32 h, int s) { int i; @@ -1448,7 +1413,7 @@ new: * Update IO registers scratch C..R so they will be * in sync. with queued CCB expectations. */ -static void sym_update_dmap_regs(hcb_p np) +static void sym_update_dmap_regs(struct sym_hcb *np) { int o, i; @@ -1463,13 +1428,12 @@ static void sym_update_dmap_regs(hcb_p np) } #endif +/* Enforce all the fiddly SPI rules and the chip limitations */ static void sym_check_goals(struct scsi_device *sdev) { struct sym_hcb *np = ((struct host_data *)sdev->host->hostdata)->ncb; struct sym_trans *st = &np->target[sdev->id].tinfo.goal; - /* here we enforce all the fiddly SPI rules */ - if (!scsi_device_wide(sdev)) st->width = 0; @@ -1479,7 +1443,7 @@ static void sym_check_goals(struct scsi_device *sdev) st->offset = 0; return; } - + if (scsi_device_dt(sdev)) { if (scsi_device_dt_only(sdev)) st->options |= PPR_OPT_DT; @@ -1490,7 +1454,8 @@ static void sym_check_goals(struct scsi_device *sdev) st->options &= ~PPR_OPT_DT; } - if (!(np->features & FE_ULTRA3)) + /* Some targets fail to properly negotiate DT in SE mode */ + if ((np->scsi_mode != SMODE_LVD) || !(np->features & FE_U3EN)) st->options &= ~PPR_OPT_DT; if (st->options & PPR_OPT_DT) { @@ -1520,38 +1485,31 @@ static void sym_check_goals(struct scsi_device *sdev) * negotiation and the nego_status field of the CCB. * Returns the size of the message in bytes. */ -static int sym_prepare_nego(hcb_p np, ccb_p cp, int nego, u_char *msgptr) +static int sym_prepare_nego(struct sym_hcb *np, ccb_p cp, u_char *msgptr) { tcb_p tp = &np->target[cp->target]; - int msglen = 0; struct scsi_device *sdev = tp->sdev; + struct sym_trans *goal = &tp->tinfo.goal; + struct sym_trans *curr = &tp->tinfo.curr; + int msglen = 0; + int nego; if (likely(sdev)) sym_check_goals(sdev); /* - * Early C1010 chips need a work-around for DT - * data transfer to work. + * Many devices implement PPR in a buggy way, so only use it if we + * really want to. */ - if (!(np->features & FE_U3EN)) - tp->tinfo.goal.options = 0; - /* - * negotiate using PPR ? - */ - if (scsi_device_dt(sdev)) { + if ((goal->options & PPR_OPT_MASK) || (goal->period < 0xa)) { nego = NS_PPR; + } else if (curr->width != goal->width) { + nego = NS_WIDE; + } else if (curr->period != goal->period || + curr->offset != goal->offset) { + nego = NS_SYNC; } else { - /* - * negotiate wide transfers ? - */ - if (tp->tinfo.curr.width != tp->tinfo.goal.width) - nego = NS_WIDE; - /* - * negotiate synchronous transfers? - */ - else if (tp->tinfo.curr.period != tp->tinfo.goal.period || - tp->tinfo.curr.offset != tp->tinfo.goal.offset) - nego = NS_SYNC; + nego = 0; } switch (nego) { @@ -1559,24 +1517,24 @@ static int sym_prepare_nego(hcb_p np, ccb_p cp, int nego, u_char *msgptr) msgptr[msglen++] = M_EXTENDED; msgptr[msglen++] = 3; msgptr[msglen++] = M_X_SYNC_REQ; - msgptr[msglen++] = tp->tinfo.goal.period; - msgptr[msglen++] = tp->tinfo.goal.offset; + msgptr[msglen++] = goal->period; + msgptr[msglen++] = goal->offset; break; case NS_WIDE: msgptr[msglen++] = M_EXTENDED; msgptr[msglen++] = 2; msgptr[msglen++] = M_X_WIDE_REQ; - msgptr[msglen++] = tp->tinfo.goal.width; + msgptr[msglen++] = goal->width; break; case NS_PPR: msgptr[msglen++] = M_EXTENDED; msgptr[msglen++] = 6; msgptr[msglen++] = M_X_PPR_REQ; - msgptr[msglen++] = tp->tinfo.goal.period; + msgptr[msglen++] = goal->period; msgptr[msglen++] = 0; - msgptr[msglen++] = tp->tinfo.goal.offset; - msgptr[msglen++] = tp->tinfo.goal.width; - msgptr[msglen++] = tp->tinfo.goal.options & PPR_OPT_MASK; + msgptr[msglen++] = goal->offset; + msgptr[msglen++] = goal->width; + msgptr[msglen++] = goal->options & PPR_OPT_MASK; break; }; @@ -1598,7 +1556,7 @@ static int sym_prepare_nego(hcb_p np, ccb_p cp, int nego, u_char *msgptr) /* * Insert a job into the start queue. */ -void sym_put_start_queue(hcb_p np, ccb_p cp) +void sym_put_start_queue(struct sym_hcb *np, ccb_p cp) { u_short qidx; @@ -1630,13 +1588,6 @@ void sym_put_start_queue(hcb_p np, ccb_p cp) #endif /* - * Optionnaly, set the IO timeout condition. - */ -#ifdef SYM_OPT_HANDLE_IO_TIMEOUT - sym_timeout_ccb(np, cp, sym_cam_timeout(cp->cam_ccb)); -#endif - - /* * Insert first the idle task and then our job. * The MBs should ensure proper ordering. */ @@ -1664,7 +1615,7 @@ void sym_put_start_queue(hcb_p np, ccb_p cp) /* * Start next ready-to-start CCBs. */ -void sym_start_next_ccbs(hcb_p np, lcb_p lp, int maxn) +void sym_start_next_ccbs(struct sym_hcb *np, lcb_p lp, int maxn) { SYM_QUEHEAD *qp; ccb_p cp; @@ -1718,7 +1669,7 @@ void sym_start_next_ccbs(hcb_p np, lcb_p lp, int maxn) * prevent out of order LOADs by the CPU from having * prefetched stale data prior to DMA having occurred. */ -static int sym_wakeup_done (hcb_p np) +static int sym_wakeup_done (struct sym_hcb *np) { ccb_p cp; int i, n; @@ -1752,10 +1703,64 @@ static int sym_wakeup_done (hcb_p np) } /* + * Complete all CCBs queued to the COMP queue. + * + * These CCBs are assumed: + * - Not to be referenced either by devices or + * SCRIPTS-related queues and datas. + * - To have to be completed with an error condition + * or requeued. + * + * The device queue freeze count is incremented + * for each CCB that does not prevent this. + * This function is called when all CCBs involved + * in error handling/recovery have been reaped. + */ +static void sym_flush_comp_queue(struct sym_hcb *np, int cam_status) +{ + SYM_QUEHEAD *qp; + ccb_p cp; + + while ((qp = sym_remque_head(&np->comp_ccbq)) != 0) { + struct scsi_cmnd *ccb; + cp = sym_que_entry(qp, struct sym_ccb, link_ccbq); + sym_insque_tail(&cp->link_ccbq, &np->busy_ccbq); + /* Leave quiet CCBs waiting for resources */ + if (cp->host_status == HS_WAIT) + continue; + ccb = cp->cam_ccb; + if (cam_status) + sym_set_cam_status(ccb, cam_status); +#ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING + if (sym_get_cam_status(ccb) == CAM_REQUEUE_REQ) { + tcb_p tp = &np->target[cp->target]; + lcb_p lp = sym_lp(np, tp, cp->lun); + if (lp) { + sym_remque(&cp->link2_ccbq); + sym_insque_tail(&cp->link2_ccbq, + &lp->waiting_ccbq); + if (cp->started) { + if (cp->tag != NO_TAG) + --lp->started_tags; + else + --lp->started_no_tag; + } + } + cp->started = 0; + continue; + } +#endif + sym_free_ccb(np, cp); + sym_freeze_cam_ccb(ccb); + sym_xpt_done(np, ccb); + } +} + +/* * Complete all active CCBs with error. * Used on CHIP/SCSI RESET. */ -static void sym_flush_busy_queue (hcb_p np, int cam_status) +static void sym_flush_busy_queue (struct sym_hcb *np, int cam_status) { /* * Move all active CCBs to the COMP queue @@ -1774,7 +1779,7 @@ static void sym_flush_busy_queue (hcb_p np, int cam_status) * 1: SCSI BUS RESET delivered or received. * 2: SCSI BUS MODE changed. */ -void sym_start_up (hcb_p np, int reason) +void sym_start_up (struct sym_hcb *np, int reason) { int i; u32 phys; @@ -1865,7 +1870,7 @@ void sym_start_up (hcb_p np, int reason) /* * For now, disable AIP generation on C1010-66. */ - if (np->device_id == PCI_ID_LSI53C1010_66) + if (np->device_id == PCI_DEVICE_ID_LSI_53C1010_66) OUTB (nc_aipcntl1, DISAIP); /* @@ -1875,7 +1880,7 @@ void sym_start_up (hcb_p np, int reason) * that from SCRIPTS for each selection/reselection, but * I just don't want. :) */ - if (np->device_id == PCI_ID_LSI53C1010_33 && + if (np->device_id == PCI_DEVICE_ID_LSI_53C1010_33 && np->revision_id < 1) OUTB (nc_stest1, INB(nc_stest1) | 0x30); @@ -1884,9 +1889,9 @@ void sym_start_up (hcb_p np, int reason) * Disable overlapped arbitration for some dual function devices, * regardless revision id (kind of post-chip-design feature. ;-)) */ - if (np->device_id == PCI_ID_SYM53C875) + if (np->device_id == PCI_DEVICE_ID_NCR_53C875) OUTB (nc_ctest0, (1<<5)); - else if (np->device_id == PCI_ID_SYM53C896) + else if (np->device_id == PCI_DEVICE_ID_NCR_53C896) np->rv_ccntl0 |= DPR; /* @@ -2010,7 +2015,7 @@ void sym_start_up (hcb_p np, int reason) /* * Switch trans mode for current job and it's target. */ -static void sym_settrans(hcb_p np, int target, u_char opts, u_char ofs, +static void sym_settrans(struct sym_hcb *np, int target, u_char opts, u_char ofs, u_char per, u_char wide, u_char div, u_char fak) { SYM_QUEHEAD *qp; @@ -2119,7 +2124,7 @@ static void sym_settrans(hcb_p np, int target, u_char opts, u_char ofs, * We received a WDTR. * Let everything be aware of the changes. */ -static void sym_setwide(hcb_p np, int target, u_char wide) +static void sym_setwide(struct sym_hcb *np, int target, u_char wide) { tcb_p tp = &np->target[target]; @@ -2138,7 +2143,7 @@ static void sym_setwide(hcb_p np, int target, u_char wide) * Let everything be aware of the changes. */ static void -sym_setsync(hcb_p np, int target, +sym_setsync(struct sym_hcb *np, int target, u_char ofs, u_char per, u_char div, u_char fak) { tcb_p tp = &np->target[target]; @@ -2164,7 +2169,7 @@ sym_setsync(hcb_p np, int target, * Let everything be aware of the changes. */ static void -sym_setpprot(hcb_p np, int target, u_char opts, u_char ofs, +sym_setpprot(struct sym_hcb *np, int target, u_char opts, u_char ofs, u_char per, u_char wide, u_char div, u_char fak) { tcb_p tp = &np->target[target]; @@ -2205,7 +2210,7 @@ sym_setpprot(hcb_p np, int target, u_char opts, u_char ofs, * pushes a DSA into a queue, we can trust it when it * points to a CCB. */ -static void sym_recover_scsi_int (hcb_p np, u_char hsts) +static void sym_recover_scsi_int (struct sym_hcb *np, u_char hsts) { u32 dsp = INL (nc_dsp); u32 dsa = INL (nc_dsa); @@ -2256,7 +2261,7 @@ reset_all: /* * chip exception handler for selection timeout */ -static void sym_int_sto (hcb_p np) +static void sym_int_sto (struct sym_hcb *np) { u32 dsp = INL (nc_dsp); @@ -2271,7 +2276,7 @@ static void sym_int_sto (hcb_p np) /* * chip exception handler for unexpected disconnect */ -static void sym_int_udc (hcb_p np) +static void sym_int_udc (struct sym_hcb *np) { printf ("%s: unexpected disconnect\n", sym_name(np)); sym_recover_scsi_int(np, HS_UNEXPECTED); @@ -2287,7 +2292,7 @@ static void sym_int_udc (hcb_p np) * mode to eight bit asynchronous, etc... * So, just reinitializing all except chip should be enough. */ -static void sym_int_sbmc (hcb_p np) +static void sym_int_sbmc (struct sym_hcb *np) { u_char scsi_mode = INB (nc_stest4) & SMODE; @@ -2328,7 +2333,7 @@ static void sym_int_sbmc (hcb_p np) * The chip will load the DSP with the phase mismatch * JUMP address and interrupt the host processor. */ -static void sym_int_par (hcb_p np, u_short sist) +static void sym_int_par (struct sym_hcb *np, u_short sist) { u_char hsts = INB (HS_PRT); u32 dsp = INL (nc_dsp); @@ -2416,7 +2421,7 @@ reset_all: * We have to construct a new transfer descriptor, * to transfer the rest of the current block. */ -static void sym_int_ma (hcb_p np) +static void sym_int_ma (struct sym_hcb *np) { u32 dbc; u32 rest; @@ -2826,7 +2831,7 @@ reset_all: * Use at your own decision and risk. */ -void sym_interrupt (hcb_p np) +void sym_interrupt (struct sym_hcb *np) { u_char istat, istatc; u_char dstat; @@ -2981,7 +2986,7 @@ unknown_int: * It is called with SCRIPTS not running. */ static int -sym_dequeue_from_squeue(hcb_p np, int i, int target, int lun, int task) +sym_dequeue_from_squeue(struct sym_hcb *np, int i, int target, int lun, int task) { int j; ccb_p cp; @@ -3025,60 +3030,6 @@ sym_dequeue_from_squeue(hcb_p np, int i, int target, int lun, int task) } /* - * Complete all CCBs queued to the COMP queue. - * - * These CCBs are assumed: - * - Not to be referenced either by devices or - * SCRIPTS-related queues and datas. - * - To have to be completed with an error condition - * or requeued. - * - * The device queue freeze count is incremented - * for each CCB that does not prevent this. - * This function is called when all CCBs involved - * in error handling/recovery have been reaped. - */ -void sym_flush_comp_queue(hcb_p np, int cam_status) -{ - SYM_QUEHEAD *qp; - ccb_p cp; - - while ((qp = sym_remque_head(&np->comp_ccbq)) != 0) { - cam_ccb_p ccb; - cp = sym_que_entry(qp, struct sym_ccb, link_ccbq); - sym_insque_tail(&cp->link_ccbq, &np->busy_ccbq); - /* Leave quiet CCBs waiting for resources */ - if (cp->host_status == HS_WAIT) - continue; - ccb = cp->cam_ccb; - if (cam_status) - sym_set_cam_status(ccb, cam_status); -#ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING - if (sym_get_cam_status(ccb) == CAM_REQUEUE_REQ) { - tcb_p tp = &np->target[cp->target]; - lcb_p lp = sym_lp(np, tp, cp->lun); - if (lp) { - sym_remque(&cp->link2_ccbq); - sym_insque_tail(&cp->link2_ccbq, - &lp->waiting_ccbq); - if (cp->started) { - if (cp->tag != NO_TAG) - --lp->started_tags; - else - --lp->started_no_tag; - } - } - cp->started = 0; - continue; - } -#endif - sym_free_ccb(np, cp); - sym_freeze_cam_ccb(ccb); - sym_xpt_done(np, ccb); - } -} - -/* * chip handler for bad SCSI status condition * * In case of bad SCSI status, we unqueue all the tasks @@ -3096,14 +3047,13 @@ void sym_flush_comp_queue(hcb_p np, int cam_status) * SCRATCHA is assumed to have been loaded with STARTPOS * before the SCRIPTS called the C code. */ -static void sym_sir_bad_scsi_status(hcb_p np, int num, ccb_p cp) +static void sym_sir_bad_scsi_status(struct sym_hcb *np, int num, ccb_p cp) { tcb_p tp = &np->target[cp->target]; u32 startp; u_char s_status = cp->ssss_status; u_char h_flags = cp->host_flags; int msglen; - int nego; int i; /* @@ -3178,16 +3128,7 @@ static void sym_sir_bad_scsi_status(hcb_p np, int num, ccb_p cp) * cp->nego_status is filled by sym_prepare_nego(). */ cp->nego_status = 0; - nego = 0; - if (tp->tinfo.curr.options & PPR_OPT_MASK) - nego = NS_PPR; - else if (tp->tinfo.curr.width != BUS_8_BIT) - nego = NS_WIDE; - else if (tp->tinfo.curr.offset != 0) - nego = NS_SYNC; - if (nego) - msglen += - sym_prepare_nego (np,cp, nego, &cp->scsi_smsg2[msglen]); + msglen += sym_prepare_nego(np, cp, &cp->scsi_smsg2[msglen]); /* * Message table indirect structure. */ @@ -3213,7 +3154,7 @@ static void sym_sir_bad_scsi_status(hcb_p np, int num, ccb_p cp) /* * sense data */ - bzero(cp->sns_bbuf, SYM_SNS_BBUF_LEN); + memset(cp->sns_bbuf, 0, SYM_SNS_BBUF_LEN); cp->phys.sense.addr = cpu_to_scr(vtobus(cp->sns_bbuf)); cp->phys.sense.size = cpu_to_scr(SYM_SNS_BBUF_LEN); @@ -3263,7 +3204,7 @@ static void sym_sir_bad_scsi_status(hcb_p np, int num, ccb_p cp) * - lun=-1 means any logical UNIT otherwise a given one. * - task=-1 means any task, otherwise a given one. */ -int sym_clear_tasks(hcb_p np, int cam_status, int target, int lun, int task) +int sym_clear_tasks(struct sym_hcb *np, int cam_status, int target, int lun, int task) { SYM_QUEHEAD qtmp, *qp; int i = 0; @@ -3282,7 +3223,7 @@ int sym_clear_tasks(hcb_p np, int cam_status, int target, int lun, int task) * the BUSY queue. */ while ((qp = sym_remque_head(&qtmp)) != 0) { - cam_ccb_p ccb; + struct scsi_cmnd *ccb; cp = sym_que_entry(qp, struct sym_ccb, link_ccbq); ccb = cp->cam_ccb; if (cp->host_status != HS_DISCONNECT || @@ -3346,7 +3287,7 @@ printf("XXXX TASK @%p CLEARED\n", cp); * all the CCBs that should have been aborted by the * target according to our message. */ -static void sym_sir_task_recovery(hcb_p np, int num) +static void sym_sir_task_recovery(struct sym_hcb *np, int num) { SYM_QUEHEAD *qp; ccb_p cp; @@ -3698,7 +3639,7 @@ static void sym_sir_task_recovery(hcb_p np, int num) * the corresponding values of dp_sg and dp_ofs. */ -static int sym_evaluate_dp(hcb_p np, ccb_p cp, u32 scr, int *ofs) +static int sym_evaluate_dp(struct sym_hcb *np, ccb_p cp, u32 scr, int *ofs) { u32 dp_scr; int dp_ofs, dp_sg, dp_sgmin; @@ -3816,7 +3757,7 @@ out_err: * is equivalent to a MODIFY DATA POINTER (offset=-1). */ -static void sym_modify_dp(hcb_p np, tcb_p tp, ccb_p cp, int ofs) +static void sym_modify_dp(struct sym_hcb *np, tcb_p tp, ccb_p cp, int ofs) { int dp_ofs = ofs; u32 dp_scr = sym_get_script_dp (np, cp); @@ -3915,7 +3856,7 @@ out_reject: * a relevant information. :) */ -int sym_compute_residual(hcb_p np, ccb_p cp) +int sym_compute_residual(struct sym_hcb *np, ccb_p cp) { int dp_sg, dp_sgmin, resid = 0; int dp_ofs = 0; @@ -4015,7 +3956,7 @@ int sym_compute_residual(hcb_p np, ccb_p cp) * chip handler for SYNCHRONOUS DATA TRANSFER REQUEST (SDTR) message. */ static int -sym_sync_nego_check(hcb_p np, int req, int target) +sym_sync_nego_check(struct sym_hcb *np, int req, int target) { u_char chg, ofs, per, fak, div; @@ -4096,7 +4037,7 @@ reject_it: return -1; } -static void sym_sync_nego(hcb_p np, tcb_p tp, ccb_p cp) +static void sym_sync_nego(struct sym_hcb *np, tcb_p tp, ccb_p cp) { int req = 1; int result; @@ -4133,7 +4074,7 @@ reject_it: * chip handler for PARALLEL PROTOCOL REQUEST (PPR) message. */ static int -sym_ppr_nego_check(hcb_p np, int req, int target) +sym_ppr_nego_check(struct sym_hcb *np, int req, int target) { tcb_p tp = &np->target[target]; unsigned char fak, div; @@ -4176,7 +4117,7 @@ sym_ppr_nego_check(hcb_p np, int req, int target) if (ofs) { unsigned char minsync = dt ? np->minsync_dt : np->minsync; - if (per < np->minsync_dt) { + if (per < minsync) { chg = 1; per = minsync; } @@ -4242,7 +4183,7 @@ reject_it: return -1; } -static void sym_ppr_nego(hcb_p np, tcb_p tp, ccb_p cp) +static void sym_ppr_nego(struct sym_hcb *np, tcb_p tp, ccb_p cp) { int req = 1; int result; @@ -4279,7 +4220,7 @@ reject_it: * chip handler for WIDE DATA TRANSFER REQUEST (WDTR) message. */ static int -sym_wide_nego_check(hcb_p np, int req, int target) +sym_wide_nego_check(struct sym_hcb *np, int req, int target) { u_char chg, wide; @@ -4344,7 +4285,7 @@ reject_it: return -1; } -static void sym_wide_nego(hcb_p np, tcb_p tp, ccb_p cp) +static void sym_wide_nego(struct sym_hcb *np, tcb_p tp, ccb_p cp) { int req = 1; int result; @@ -4413,7 +4354,7 @@ reject_it: * So, if a PPR makes problems, we may just want to * try a legacy negotiation later. */ -static void sym_nego_default(hcb_p np, tcb_p tp, ccb_p cp) +static void sym_nego_default(struct sym_hcb *np, tcb_p tp, ccb_p cp) { switch (cp->nego_status) { case NS_PPR: @@ -4443,7 +4384,7 @@ static void sym_nego_default(hcb_p np, tcb_p tp, ccb_p cp) * chip handler for MESSAGE REJECT received in response to * PPR, WIDE or SYNCHRONOUS negotiation. */ -static void sym_nego_rejected(hcb_p np, tcb_p tp, ccb_p cp) +static void sym_nego_rejected(struct sym_hcb *np, tcb_p tp, ccb_p cp) { sym_nego_default(np, tp, cp); OUTB (HS_PRT, HS_BUSY); @@ -4452,7 +4393,7 @@ static void sym_nego_rejected(hcb_p np, tcb_p tp, ccb_p cp) /* * chip exception handler for programmed interrupts. */ -static void sym_int_sir (hcb_p np) +static void sym_int_sir (struct sym_hcb *np) { u_char num = INB (nc_dsps); u32 dsa = INL (nc_dsa); @@ -4726,7 +4667,7 @@ out_stuck: /* * Acquire a control block */ -ccb_p sym_get_ccb (hcb_p np, u_char tn, u_char ln, u_char tag_order) +ccb_p sym_get_ccb (struct sym_hcb *np, u_char tn, u_char ln, u_char tag_order) { tcb_p tp = &np->target[tn]; lcb_p lp = sym_lp(np, tp, ln); @@ -4875,7 +4816,7 @@ out_free: /* * Release one control block */ -void sym_free_ccb (hcb_p np, ccb_p cp) +void sym_free_ccb (struct sym_hcb *np, ccb_p cp) { tcb_p tp = &np->target[cp->target]; lcb_p lp = sym_lp(np, tp, cp->lun); @@ -4960,13 +4901,6 @@ void sym_free_ccb (hcb_p np, ccb_p cp) sym_remque(&cp->link_ccbq); sym_insque_head(&cp->link_ccbq, &np->free_ccbq); -#ifdef SYM_OPT_HANDLE_IO_TIMEOUT - /* - * Cancel any pending timeout condition. - */ - sym_untimeout_ccb(np, cp); -#endif - #ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING if (lp) { sym_remque(&cp->link2_ccbq); @@ -4985,7 +4919,7 @@ void sym_free_ccb (hcb_p np, ccb_p cp) /* * Allocate a CCB from memory and initialize its fixed part. */ -static ccb_p sym_alloc_ccb(hcb_p np) +static ccb_p sym_alloc_ccb(struct sym_hcb *np) { ccb_p cp = NULL; int hcode; @@ -5053,9 +4987,6 @@ static ccb_p sym_alloc_ccb(hcb_p np) /* * Chain into optionnal lists. */ -#ifdef SYM_OPT_HANDLE_IO_TIMEOUT - sym_insque_head(&cp->tmo_linkq, &np->tmo0_ccbq); -#endif #ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING sym_insque_head(&cp->link2_ccbq, &np->dummy_ccbq); #endif @@ -5072,7 +5003,7 @@ out_free: /* * Look up a CCB from a DSA value. */ -static ccb_p sym_ccb_from_dsa(hcb_p np, u32 dsa) +static ccb_p sym_ccb_from_dsa(struct sym_hcb *np, u32 dsa) { int hcode; ccb_p cp; @@ -5092,7 +5023,7 @@ static ccb_p sym_ccb_from_dsa(hcb_p np, u32 dsa) * Target control block initialisation. * Nothing important to do at the moment. */ -static void sym_init_tcb (hcb_p np, u_char tn) +static void sym_init_tcb (struct sym_hcb *np, u_char tn) { #if 0 /* Hmmm... this checking looks paranoid. */ /* @@ -5108,7 +5039,7 @@ static void sym_init_tcb (hcb_p np, u_char tn) /* * Lun control block allocation and initialization. */ -lcb_p sym_alloc_lcb (hcb_p np, u_char tn, u_char ln) +lcb_p sym_alloc_lcb (struct sym_hcb *np, u_char tn, u_char ln) { tcb_p tp = &np->target[tn]; lcb_p lp = sym_lp(np, tp, ln); @@ -5210,7 +5141,7 @@ fail: /* * Allocate LCB resources for tagged command queuing. */ -static void sym_alloc_lcb_tags (hcb_p np, u_char tn, u_char ln) +static void sym_alloc_lcb_tags (struct sym_hcb *np, u_char tn, u_char ln) { tcb_p tp = &np->target[tn]; lcb_p lp = sym_lp(np, tp, ln); @@ -5262,7 +5193,7 @@ fail: /* * Queue a SCSI IO to the controller. */ -int sym_queue_scsiio(hcb_p np, cam_scsiio_p csio, ccb_p cp) +int sym_queue_scsiio(struct sym_hcb *np, struct scsi_cmnd *csio, ccb_p cp) { tcb_p tp; lcb_p lp; @@ -5273,7 +5204,7 @@ int sym_queue_scsiio(hcb_p np, cam_scsiio_p csio, ccb_p cp) /* * Keep track of the IO in our CCB. */ - cp->cam_ccb = (cam_ccb_p) csio; + cp->cam_ccb = csio; /* * Retrieve the target descriptor. @@ -5351,7 +5282,7 @@ int sym_queue_scsiio(hcb_p np, cam_scsiio_p csio, ccb_p cp) tp->tinfo.curr.offset != tp->tinfo.goal.offset || tp->tinfo.curr.options != tp->tinfo.goal.options) { if (!tp->nego_cp && lp) - msglen += sym_prepare_nego(np, cp, 0, msgptr + msglen); + msglen += sym_prepare_nego(np, cp, msgptr + msglen); } /* @@ -5401,7 +5332,7 @@ int sym_queue_scsiio(hcb_p np, cam_scsiio_p csio, ccb_p cp) /* * Reset a SCSI target (all LUNs of this target). */ -int sym_reset_scsi_target(hcb_p np, int target) +int sym_reset_scsi_target(struct sym_hcb *np, int target) { tcb_p tp; @@ -5420,7 +5351,7 @@ int sym_reset_scsi_target(hcb_p np, int target) /* * Abort a SCSI IO. */ -int sym_abort_ccb(hcb_p np, ccb_p cp, int timed_out) +int sym_abort_ccb(struct sym_hcb *np, ccb_p cp, int timed_out) { /* * Check that the IO is active. @@ -5450,7 +5381,7 @@ int sym_abort_ccb(hcb_p np, ccb_p cp, int timed_out) return 0; } -int sym_abort_scsiio(hcb_p np, cam_ccb_p ccb, int timed_out) +int sym_abort_scsiio(struct sym_hcb *np, struct scsi_cmnd *ccb, int timed_out) { ccb_p cp; SYM_QUEHEAD *qp; @@ -5480,7 +5411,7 @@ int sym_abort_scsiio(hcb_p np, cam_ccb_p ccb, int timed_out) * SCRATCHA is assumed to have been loaded with STARTPOS * before the SCRIPTS called the C code. */ -void sym_complete_error (hcb_p np, ccb_p cp) +void sym_complete_error (struct sym_hcb *np, ccb_p cp) { tcb_p tp; lcb_p lp; @@ -5614,11 +5545,11 @@ finish: * The SCRIPTS processor is running while we are * completing successful commands. */ -void sym_complete_ok (hcb_p np, ccb_p cp) +void sym_complete_ok (struct sym_hcb *np, ccb_p cp) { tcb_p tp; lcb_p lp; - cam_ccb_p ccb; + struct scsi_cmnd *ccb; int resid; /* @@ -5724,7 +5655,7 @@ if (resid) /* * Soft-attach the controller. */ -int sym_hcb_attach(hcb_p np, struct sym_fw *fw, struct sym_nvram *nvram) +int sym_hcb_attach(struct sym_hcb *np, struct sym_fw *fw, struct sym_nvram *nvram) { int i; @@ -5815,17 +5746,9 @@ int sym_hcb_attach(hcb_p np, struct sym_fw *fw, struct sym_nvram *nvram) sym_que_init(&np->comp_ccbq); /* - * Initializations for optional handling - * of IO timeouts and device queueing. + * Initialization for optional handling + * of device queueing. */ -#ifdef SYM_OPT_HANDLE_IO_TIMEOUT - sym_que_init(&np->tmo0_ccbq); - np->tmo_ccbq = - sym_calloc(2*SYM_CONF_TIMEOUT_ORDER_MAX*sizeof(SYM_QUEHEAD), - "TMO_CCBQ"); - for (i = 0 ; i < 2*SYM_CONF_TIMEOUT_ORDER_MAX ; i++) - sym_que_init(&np->tmo_ccbq[i]); -#endif #ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING sym_que_init(&np->dummy_ccbq); #endif @@ -5957,7 +5880,7 @@ attach_failed: /* * Free everything that has been allocated for this device. */ -void sym_hcb_free(hcb_p np) +void sym_hcb_free(struct sym_hcb *np) { SYM_QUEHEAD *qp; ccb_p cp; @@ -5971,12 +5894,6 @@ void sym_hcb_free(hcb_p np) sym_mfree_dma(np->scriptb0, np->scriptb_sz, "SCRIPTB0"); if (np->scripta0) sym_mfree_dma(np->scripta0, np->scripta_sz, "SCRIPTA0"); -#ifdef SYM_OPT_HANDLE_IO_TIMEOUT - if (np->tmo_ccbq) - sym_mfree(np->tmo_ccbq, - 2*SYM_CONF_TIMEOUT_ORDER_MAX*sizeof(SYM_QUEHEAD), - "TMO_CCBQ"); -#endif if (np->squeue) sym_mfree_dma(np->squeue, sizeof(u32)*(MAX_QUEUE*2), "SQUEUE"); if (np->dqueue) diff --git a/drivers/scsi/sym53c8xx_2/sym_hipd.h b/drivers/scsi/sym53c8xx_2/sym_hipd.h index 4d3b989539521e..e3509d4c879cbd 100644 --- a/drivers/scsi/sym53c8xx_2/sym_hipd.h +++ b/drivers/scsi/sym53c8xx_2/sym_hipd.h @@ -749,7 +749,7 @@ struct sym_ccb { /* * Pointer to CAM ccb and related stuff. */ - cam_ccb_p cam_ccb; /* CAM scsiio ccb */ + struct scsi_cmnd *cam_ccb; /* CAM scsiio ccb */ u8 cdb_buf[16]; /* Copy of CDB */ u8 *sns_bbuf; /* Bounce buffer for sense data */ #ifndef SYM_SNS_BBUF_LEN @@ -796,10 +796,6 @@ struct sym_ccb { /* * Other fields. */ -#ifdef SYM_OPT_HANDLE_IO_TIMEOUT - SYM_QUEHEAD tmo_linkq; /* Optional timeout handling */ - u_int tmo_clock; /* (link and dealine value) */ -#endif u32 ccb_ba; /* BUS address of this CCB */ u_short tag; /* Tag for this transfer */ /* NO_TAG means no tag */ @@ -946,8 +942,8 @@ struct sym_hcb { struct sym_fwa_ba fwa_bas; /* Useful SCRIPTA bus addresses */ struct sym_fwb_ba fwb_bas; /* Useful SCRIPTB bus addresses */ struct sym_fwz_ba fwz_bas; /* Useful SCRIPTZ bus addresses */ - void (*fw_setup)(hcb_p np, struct sym_fw *fw); - void (*fw_patch)(hcb_p np); + void (*fw_setup)(struct sym_hcb *np, struct sym_fw *fw); + void (*fw_patch)(struct sym_hcb *np); char *fw_name; /* @@ -1025,15 +1021,6 @@ struct sym_hcb { #ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING SYM_QUEHEAD dummy_ccbq; #endif - /* - * Optional handling of IO timeouts. - */ -#ifdef SYM_OPT_HANDLE_IO_TIMEOUT - SYM_QUEHEAD tmo0_ccbq; - SYM_QUEHEAD *tmo_ccbq; /* [2*SYM_TIMEOUT_ORDER_MAX] */ - u_int tmo_clock; - u_int tmo_actq; -#endif /* * IMMEDIATE ARBITRATION (IARB) control. @@ -1082,54 +1069,39 @@ struct sym_hcb { * FIRMWARES (sym_fw.c) */ struct sym_fw * sym_find_firmware(struct sym_pci_chip *chip); -void sym_fw_bind_script (hcb_p np, u32 *start, int len); +void sym_fw_bind_script (struct sym_hcb *np, u32 *start, int len); /* * Driver methods called from O/S specific code. */ char *sym_driver_name(void); void sym_print_xerr(ccb_p cp, int x_status); -int sym_reset_scsi_bus(hcb_p np, int enab_int); +int sym_reset_scsi_bus(struct sym_hcb *np, int enab_int); struct sym_pci_chip * sym_lookup_pci_chip_table (u_short device_id, u_char revision); -void sym_put_start_queue(hcb_p np, ccb_p cp); +void sym_put_start_queue(struct sym_hcb *np, ccb_p cp); #ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING -void sym_start_next_ccbs(hcb_p np, lcb_p lp, int maxn); +void sym_start_next_ccbs(struct sym_hcb *np, lcb_p lp, int maxn); #endif -void sym_start_up (hcb_p np, int reason); -void sym_interrupt (hcb_p np); -void sym_flush_comp_queue(hcb_p np, int cam_status); -int sym_clear_tasks(hcb_p np, int cam_status, int target, int lun, int task); -ccb_p sym_get_ccb (hcb_p np, u_char tn, u_char ln, u_char tag_order); -void sym_free_ccb (hcb_p np, ccb_p cp); -lcb_p sym_alloc_lcb (hcb_p np, u_char tn, u_char ln); -int sym_queue_scsiio(hcb_p np, cam_scsiio_p csio, ccb_p cp); -int sym_abort_scsiio(hcb_p np, cam_ccb_p ccb, int timed_out); -int sym_abort_ccb(hcb_p np, ccb_p cp, int timed_out); -int sym_reset_scsi_target(hcb_p np, int target); -void sym_hcb_free(hcb_p np); -int sym_hcb_attach(hcb_p np, struct sym_fw *fw, struct sym_nvram *nvram); - -/* - * Optionnaly, the driver may handle IO timeouts. - */ -#ifdef SYM_OPT_HANDLE_IO_TIMEOUT -int sym_abort_ccb(hcb_p np, ccb_p cp, int timed_out); -void sym_timeout_ccb(hcb_p np, ccb_p cp, u_int ticks); -static void __inline sym_untimeout_ccb(hcb_p np, ccb_p cp) -{ - sym_remque(&cp->tmo_linkq); - sym_insque_head(&cp->tmo_linkq, &np->tmo0_ccbq); -} -void sym_clock(hcb_p np); -#endif /* SYM_OPT_HANDLE_IO_TIMEOUT */ +void sym_start_up (struct sym_hcb *np, int reason); +void sym_interrupt (struct sym_hcb *np); +int sym_clear_tasks(struct sym_hcb *np, int cam_status, int target, int lun, int task); +ccb_p sym_get_ccb (struct sym_hcb *np, u_char tn, u_char ln, u_char tag_order); +void sym_free_ccb (struct sym_hcb *np, ccb_p cp); +lcb_p sym_alloc_lcb (struct sym_hcb *np, u_char tn, u_char ln); +int sym_queue_scsiio(struct sym_hcb *np, struct scsi_cmnd *csio, ccb_p cp); +int sym_abort_scsiio(struct sym_hcb *np, struct scsi_cmnd *ccb, int timed_out); +int sym_abort_ccb(struct sym_hcb *np, ccb_p cp, int timed_out); +int sym_reset_scsi_target(struct sym_hcb *np, int target); +void sym_hcb_free(struct sym_hcb *np); +int sym_hcb_attach(struct sym_hcb *np, struct sym_fw *fw, struct sym_nvram *nvram); /* * Optionnaly, the driver may provide a function * to announce transfer rate changes. */ #ifdef SYM_OPT_ANNOUNCE_TRANSFER_RATE -void sym_announce_transfer_rate(hcb_p np, int target); +void sym_announce_transfer_rate(struct sym_hcb *np, int target); #endif /* @@ -1153,9 +1125,9 @@ do { \ (data)->size = cpu_to_scr((((badd) >> 8) & 0xff000000) + len); \ } while (0) #elif SYM_CONF_DMA_ADDRESSING_MODE == 2 -int sym_lookup_dmap(hcb_p np, u32 h, int s); +int sym_lookup_dmap(struct sym_hcb *np, u32 h, int s); static __inline void -sym_build_sge(hcb_p np, struct sym_tblmove *data, u64 badd, int len) +sym_build_sge(struct sym_hcb *np, struct sym_tblmove *data, u64 badd, int len) { u32 h = (badd>>32); int s = (h&SYM_DMAP_MASK); diff --git a/drivers/scsi/sym53c8xx_2/sym_malloc.c b/drivers/scsi/sym53c8xx_2/sym_malloc.c index 567a6dd31a27b4..01f380a2d28f8b 100644 --- a/drivers/scsi/sym53c8xx_2/sym_malloc.c +++ b/drivers/scsi/sym53c8xx_2/sym_malloc.c @@ -170,7 +170,7 @@ static void *__sym_calloc2(m_pool_p mp, int size, char *name, int uflags) } if (p) - bzero(p, size); + memset(p, 0, size); else if (uflags & SYM_MEM_WARN) printf ("__sym_calloc2: failed to allocate %s[%d]\n", name, size); return p; diff --git a/drivers/scsi/sym53c8xx_2/sym_misc.c b/drivers/scsi/sym53c8xx_2/sym_misc.c index f27f52e651dccf..0b678ae73acca2 100644 --- a/drivers/scsi/sym53c8xx_2/sym_misc.c +++ b/drivers/scsi/sym53c8xx_2/sym_misc.c @@ -37,109 +37,13 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifdef __FreeBSD__ -#include <dev/sym/sym_glue.h> -#else #include "sym_glue.h" -#endif - -#ifdef SYM_OPT_HANDLE_IO_TIMEOUT -/* - * Optional CCB timeout handling. - * - * This code is useful for O/Ses that allow or expect - * SIMs (low-level drivers) to handle SCSI IO timeouts. - * It uses a power-of-two based algorithm of my own:) - * that avoids scanning of lists, provided that: - * - * - The IO does complete in less than half the associated - * timeout value. - * - The greatest delay between the queuing of the IO and - * its completion is less than - * (1<<(SYM_CONF_TIMEOUT_ORDER_MAX-1))/2 ticks. - * - * For example, if tick is 1 second and the max order is 8, - * any IO that is completed within less than 64 seconds will - * just be put into some list at queuing and be removed - * at completion without any additionnal overhead. - */ - -/* - * Set a timeout condition on a CCB. - */ -void sym_timeout_ccb(hcb_p np, ccb_p cp, u_int ticks) -{ - sym_remque(&cp->tmo_linkq); - cp->tmo_clock = np->tmo_clock + ticks; - if (!ticks) { - sym_insque_head(&cp->tmo_linkq, &np->tmo0_ccbq); - } - else { - int i = SYM_CONF_TIMEOUT_ORDER_MAX - 1; - while (i > 0) { - if (ticks >= (1<<(i+1))) - break; - --i; - } - if (!(np->tmo_actq & (1<<i))) - i += SYM_CONF_TIMEOUT_ORDER_MAX; - sym_insque_head(&cp->tmo_linkq, &np->tmo_ccbq[i]); - } -} - -/* - * Walk a list of CCB and handle timeout conditions. - * Should never be called in normal situations. - */ -static void sym_walk_ccb_tmo_list(hcb_p np, SYM_QUEHEAD *tmoq) -{ - SYM_QUEHEAD qtmp, *qp; - ccb_p cp; - - sym_que_move(tmoq, &qtmp); - while ((qp = sym_remque_head(&qtmp)) != 0) { - sym_insque_head(qp, &np->tmo0_ccbq); - cp = sym_que_entry(qp, struct sym_ccb, tmo_linkq); - if (cp->tmo_clock != np->tmo_clock && - cp->tmo_clock + 1 != np->tmo_clock) - sym_timeout_ccb(np, cp, cp->tmo_clock - np->tmo_clock); - else - sym_abort_ccb(np, cp, 1); - } -} - -/* - * Our clock handler called from the O/S specific side. - */ -void sym_clock(hcb_p np) -{ - int i, j; - u_int tmp; - - tmp = np->tmo_clock; - tmp ^= (++np->tmo_clock); - - for (i = 0; i < SYM_CONF_TIMEOUT_ORDER_MAX; i++, tmp >>= 1) { - if (!(tmp & 1)) - continue; - j = i; - if (np->tmo_actq & (1<<i)) - j += SYM_CONF_TIMEOUT_ORDER_MAX; - - if (!sym_que_empty(&np->tmo_ccbq[j])) { - sym_walk_ccb_tmo_list(np, &np->tmo_ccbq[j]); - } - np->tmo_actq ^= (1<<i); - } -} -#endif /* SYM_OPT_HANDLE_IO_TIMEOUT */ - #ifdef SYM_OPT_ANNOUNCE_TRANSFER_RATE /* * Announce transfer rate if anything changed since last announcement. */ -void sym_announce_transfer_rate(hcb_p np, int target) +void sym_announce_transfer_rate(struct sym_hcb *np, int target) { tcb_p tp = &np->target[target]; diff --git a/drivers/scsi/sym53c8xx_2/sym_nvram.c b/drivers/scsi/sym53c8xx_2/sym_nvram.c index f3621324a73b78..0809437706e83b 100644 --- a/drivers/scsi/sym53c8xx_2/sym_nvram.c +++ b/drivers/scsi/sym53c8xx_2/sym_nvram.c @@ -68,6 +68,21 @@ void sym_nvram_setup_host(struct sym_hcb *np, struct sym_nvram *nvram) case SYM_TEKRAM_NVRAM: np->myaddr = nvram->data.Tekram.host_id & 0x0f; break; +#ifdef CONFIG_PARISC + case SYM_PARISC_PDC: + if (nvram->data.parisc.host_id != -1) + np->myaddr = nvram->data.parisc.host_id; + if (nvram->data.parisc.factor != -1) + np->minsync = nvram->data.parisc.factor; + if (nvram->data.parisc.width != -1) + np->maxwide = nvram->data.parisc.width; + switch (nvram->data.parisc.mode) { + case 0: np->scsi_mode = SMODE_SE; break; + case 1: np->scsi_mode = SMODE_HVD; break; + case 2: np->scsi_mode = SMODE_LVD; break; + default: break; + } +#endif default: break; } @@ -702,6 +717,28 @@ static int sym_read_Tekram_nvram (struct sym_device *np, Tekram_nvram *nvram) return 0; } +#ifdef CONFIG_PARISC +/* + * Host firmware (PDC) keeps a table for altering SCSI capabilities. + * Many newer machines export one channel of 53c896 chip as SE, 50-pin HD. + * Also used for Multi-initiator SCSI clusters to set the SCSI Initiator ID. + */ +static int sym_read_parisc_pdc(struct sym_device *np, struct pdc_initiator *pdc) +{ + struct hardware_path hwpath; + get_pci_node_path(np->pdev, &hwpath); + if (!pdc_get_initiator(&hwpath, pdc)) + return 0; + + return SYM_PARISC_PDC; +} +#else +static int sym_read_parisc_pdc(struct sym_device *np, struct pdc_initiator *x) +{ + return 0; +} +#endif + /* * Try reading Symbios or Tekram NVRAM */ @@ -714,7 +751,7 @@ int sym_read_nvram(struct sym_device *np, struct sym_nvram *nvp) nvp->type = SYM_TEKRAM_NVRAM; sym_display_Tekram_nvram(np, &nvp->data.Tekram); } else { - nvp->type = 0; + nvp->type = sym_read_parisc_pdc(np, &nvp->data.parisc); } return nvp->type; } diff --git a/drivers/scsi/sym53c8xx_2/sym_nvram.h b/drivers/scsi/sym53c8xx_2/sym_nvram.h index a6bd02afba4022..9572f87b599afb 100644 --- a/drivers/scsi/sym53c8xx_2/sym_nvram.h +++ b/drivers/scsi/sym53c8xx_2/sym_nvram.h @@ -171,6 +171,10 @@ struct Tekram_nvram { typedef struct Tekram_nvram Tekram_nvram; typedef struct Tekram_target Tekram_target; +#ifndef CONFIG_PARISC +struct pdc_initiator { int dummy; }; +#endif + /* * Union of supported NVRAM formats. */ @@ -178,10 +182,12 @@ struct sym_nvram { int type; #define SYM_SYMBIOS_NVRAM (1) #define SYM_TEKRAM_NVRAM (2) +#define SYM_PARISC_PDC (3) #if SYM_CONF_NVRAM_SUPPORT union { Symbios_nvram Symbios; Tekram_nvram Tekram; + struct pdc_initiator parisc; } data; #endif }; diff --git a/drivers/scsi/sym53c8xx_comm.h b/drivers/scsi/sym53c8xx_comm.h index 7ca14db3475481..04ebe5486d5bf8 100644 --- a/drivers/scsi/sym53c8xx_comm.h +++ b/drivers/scsi/sym53c8xx_comm.h @@ -505,8 +505,6 @@ static int __map_scsi_sg_data(struct device *dev, struct scsi_cmnd *cmd) #define unmap_scsi_data(np, cmd) __unmap_scsi_data(np->dev, cmd) #define map_scsi_single_data(np, cmd) __map_scsi_single_data(np->dev, cmd) #define map_scsi_sg_data(np, cmd) __map_scsi_sg_data(np->dev, cmd) -#define sync_scsi_data_for_cpu(np, cmd) __sync_scsi_data_for_cpu(np->dev, cmd) -#define sync_scsi_data_for_device(np, cmd) __sync_scsi_data_for_device(np->dev, cmd) /*========================================================== ** diff --git a/drivers/scsi/zalon.c b/drivers/scsi/zalon.c index c2afeb7775633e..31ba6a9168c771 100644 --- a/drivers/scsi/zalon.c +++ b/drivers/scsi/zalon.c @@ -87,7 +87,7 @@ zalon_probe(struct parisc_device *dev) { struct gsc_irq gsc_irq; u32 zalon_vers; - int irq, error = -ENODEV; + int error = -ENODEV; unsigned long zalon = dev->hpa; unsigned long io_port = zalon + GSC_SCSI_ZALON_OFFSET; static int unit = 0; @@ -107,10 +107,10 @@ zalon_probe(struct parisc_device *dev) /* Setup the interrupts first. ** Later on request_irq() will register the handler. */ - irq = gsc_alloc_irq(&gsc_irq); + dev->irq = gsc_alloc_irq(&gsc_irq); printk("%s: Zalon vers field is 0x%x, IRQ %d\n", __FUNCTION__, - zalon_vers, irq); + zalon_vers, dev->irq); __raw_writel(gsc_irq.txn_addr | gsc_irq.txn_data, dev->hpa + IO_MODULE_EIM); @@ -130,16 +130,16 @@ zalon_probe(struct parisc_device *dev) device.dev = &dev->dev; device.slot.base = (u_long)io_port; device.slot.base_c = (u_long)io_port; - device.slot.irq = irq; + device.slot.irq = dev->irq; device.differential = 2; host = ncr_attach(&zalon7xx_template, unit, &device); if (!host) goto fail; - if (request_irq(irq, ncr53c8xx_intr, SA_SHIRQ, dev->dev.bus_id, host)) { + if (request_irq(dev->irq, ncr53c8xx_intr, SA_SHIRQ, "zalon", host)) { printk(KERN_ERR "%s: irq problem with %d, detaching\n ", - dev->dev.bus_id, irq); + dev->dev.bus_id, dev->irq); goto fail; } @@ -155,7 +155,7 @@ zalon_probe(struct parisc_device *dev) return 0; fail_free_irq: - free_irq(irq, host); + free_irq(dev->irq, host); fail: ncr53c8xx_release(host); return error; @@ -171,18 +171,16 @@ MODULE_DEVICE_TABLE(parisc, zalon_tbl); static int __exit zalon_remove(struct parisc_device *dev) { struct Scsi_Host *host = dev_get_drvdata(&dev->dev); - int irq = host->irq; scsi_remove_host(host); ncr53c8xx_release(host); - free_irq(irq, host); + free_irq(dev->irq, host); return 0; } - static struct parisc_driver zalon_driver = { - .name = "GSC SCSI (Zalon)", + .name = "zalon", .id_table = zalon_tbl, .probe = zalon_probe, .remove = __devexit_p(zalon_remove), @@ -201,6 +199,7 @@ static int __init zalon7xx_init(void) static void __exit zalon7xx_exit(void) { unregister_parisc_driver(&zalon_driver); + ncr53c8xx_exit(); } module_init(zalon7xx_init); |