From: Jes Sorensen I am attaching the latest version of the qla1280 driver for inclusion in the next 2.6.x release. drivers/scsi/qla1280.c | 1495 ++++++++++++++++++++----------------------------- drivers/scsi/qla1280.h | 104 --- 2 files changed, 634 insertions(+), 965 deletions(-) diff -puN drivers/scsi/qla1280.c~qla1280-update-2 drivers/scsi/qla1280.c --- 25/drivers/scsi/qla1280.c~qla1280-update-2 2004-01-06 08:02:26.000000000 -0800 +++ 25-akpm/drivers/scsi/qla1280.c 2004-01-06 08:02:26.000000000 -0800 @@ -3,7 +3,8 @@ * * QLogic QLA1280 (Ultra2) and QLA12160 (Ultra3) SCSI driver * Copyright (C) 2000 Qlogic Corporation (www.qlogic.com) -* Copyright (C) 2001-2003 Jes Sorensen, Wild Open Source Inc. +* Copyright (C) 2001-2004 Jes Sorensen, Wild Open Source Inc. +* Copyright (C) 2003 Christoph Hellwig * * 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 @@ -16,13 +17,30 @@ * General Public License for more details. * ******************************************************************************/ -#define QLA1280_VERSION "3.23.37.1" +#define QLA1280_VERSION "3.24.1" /***************************************************************************** Revision History: - Rev 3.23.37.1 December 17, 2003, Jes Sorensen + Rev 3.24.1 January 5, 2004, Jes Sorensen + - Initialize completion queue to avoid OOPS on probe + - Handle interrupts during mailbox testing + Rev 3.24 November 17, 2003, Christoph Hellwig + - use struct list_head for completion queue + - avoid old Scsi_FOO typedefs + - cleanup 2.4 compat glue a bit + - use headers on 2.6 instead of "scsi.h" + - make initialization for memory mapped vs port I/O more similar + - remove broken pci config space manipulation + - kill more cruft + - this is an almost perfect 2.6 scsi driver now! ;) + Rev 3.23.39 December 17, 2003, Jes Sorensen - Delete completion queue from srb if mailbox command failed to to avoid qla1280_done completeting qla1280_error_action's obsolete context + - Reduce arguments for qla1280_done + Rev 3.23.38 October 18, 2003, Christoph Hellwig + - Convert to new-style hotplugable driver for 2.6 + - Fix missing scsi_unregister/scsi_host_put on HBA removal + - Kill some more cruft Rev 3.23.37 October 1, 2003, Jes Sorensen - Make MMIO depend on CONFIG_X86_VISWS instead of yet another random CONFIG option @@ -323,7 +341,12 @@ #include #if LINUX_VERSION_CODE >= 0x020545 +#include /* for flush_cache_all() */ +#include +#include +#include #include +#include #include "scsi.h" #else #include @@ -341,9 +364,6 @@ * Compile time Options: * 0 - Disable and 1 - Enable */ -#define QL1280_LUN_SUPPORT 0 -#define WATCHDOGTIMER 0 - #define DEBUG_QLA1280_INTR 0 #define DEBUG_PRINT_NVRAM 0 #define DEBUG_QLA1280 0 @@ -414,8 +434,18 @@ extern int snia_pcibr_rrb_alloc(struct p #define irqreturn_t void #define IRQ_RETVAL(foo) #define MSG_ORDERED_TAG 1 + +#define DMA_BIDIRECTIONAL SCSI_DATA_UNKNOWN +#define DMA_TO_DEVICE SCSI_DATA_WRITE +#define DMA_FROM_DEVICE SCSI_DATA_READ +#define DMA_NONE SCSI_DATA_NONE + +#ifndef HAVE_SECTOR_T +typedef unsigned int sector_t; +#endif + static inline void -scsi_adjust_queue_depth(Scsi_Device *device, int tag, int depth) +scsi_adjust_queue_depth(struct scsi_device *device, int tag, int depth) { if (tag) { device->tagged_queue = tag; @@ -423,11 +453,25 @@ scsi_adjust_queue_depth(Scsi_Device *dev } device->queue_depth = depth; } +static inline struct Scsi_Host *scsi_host_alloc(Scsi_Host_Template *t, size_t s) +{ + return scsi_register(t, s); +} +static inline void scsi_host_put(struct Scsi_Host *h) +{ + scsi_unregister(h); +} #else #define HOST_LOCK ha->host->host_lock #endif #if LINUX_VERSION_CODE < 0x020600 #define DEV_SIMPLE_TAGS(device) device->tagged_queue +/* + * Hack around that qla1280_remove_one is called from + * qla1280_release in 2.4 + */ +#undef __devexit +#define __devexit #else #define DEV_SIMPLE_TAGS(device) device->simple_tags #endif @@ -435,30 +479,25 @@ scsi_adjust_queue_depth(Scsi_Device *dev #define ia64_platform_is(foo) (!strcmp(x, platform_name)) #endif +static int qla1280_probe_one(struct pci_dev *, const struct pci_device_id *); +#if defined(CONFIG_SCSI_QLOGIC_1280_MODULE) || (LINUX_VERSION_CODE < 0x020600) +static void qla1280_remove_one(struct pci_dev *); +#endif + /* * QLogic Driver Support Function Prototypes. */ -static void qla1280_done(struct scsi_qla_host *, struct srb **, struct srb **); -static void qla1280_done_q_put(struct srb *, struct srb **, struct srb **); -static int qla1280_slave_configure(Scsi_Device *); +static void qla1280_done(struct scsi_qla_host *); #if LINUX_VERSION_CODE < 0x020545 -static void qla1280_select_queue_depth(struct Scsi_Host *, Scsi_Device *); static void qla1280_get_target_options(struct scsi_cmnd *, struct scsi_qla_host *); #endif - -static int qla1280_return_status(struct response * sts, Scsi_Cmnd * cp); -static void qla1280_mem_free(struct scsi_qla_host *ha); static int qla1280_get_token(char *); static int qla1280_setup(char *s) __init; -static inline void qla1280_enable_intrs(struct scsi_qla_host *); -static inline void qla1280_disable_intrs(struct scsi_qla_host *); /* * QLogic ISP1280 Hardware Support Function Prototypes. */ -static int qla1280_initialize_adapter(struct scsi_qla_host *ha); static int qla1280_isp_firmware(struct scsi_qla_host *); -static int qla1280_pci_config(struct scsi_qla_host *); static int qla1280_chip_diag(struct scsi_qla_host *); static int qla1280_setup_chip(struct scsi_qla_host *); static int qla1280_init_rings(struct scsi_qla_host *); @@ -477,24 +516,21 @@ static void qla1280_poll(struct scsi_qla static void qla1280_reset_adapter(struct scsi_qla_host *); static void qla1280_marker(struct scsi_qla_host *, int, int, int, u8); static void qla1280_isp_cmd(struct scsi_qla_host *); -irqreturn_t qla1280_intr_handler(int, void *, struct pt_regs *); -static void qla1280_isr(struct scsi_qla_host *, struct srb **, struct srb **); +static void qla1280_isr(struct scsi_qla_host *, struct list_head *); static void qla1280_rst_aen(struct scsi_qla_host *); static void qla1280_status_entry(struct scsi_qla_host *, struct response *, - struct srb **, struct srb **); + struct list_head *); static void qla1280_error_entry(struct scsi_qla_host *, struct response *, - struct srb **, struct srb **); + struct list_head *); static uint16_t qla1280_get_nvram_word(struct scsi_qla_host *, uint32_t); static uint16_t qla1280_nvram_request(struct scsi_qla_host *, uint32_t); static uint16_t qla1280_debounce_register(volatile uint16_t *); static request_t *qla1280_req_pkt(struct scsi_qla_host *); static int qla1280_check_for_dead_scsi_bus(struct scsi_qla_host *, unsigned int); -static int qla1280_mem_alloc(struct scsi_qla_host *ha); - -static void qla12160_get_target_parameters(struct scsi_qla_host *, - Scsi_Device *); -static int qla12160_set_target_parameters(struct scsi_qla_host *, int, int); +static void qla1280_get_target_parameters(struct scsi_qla_host *, + struct scsi_device *); +static int qla1280_set_target_parameters(struct scsi_qla_host *, int, int); static struct qla_driver_setup driver_setup __initdata; @@ -505,36 +541,26 @@ static struct qla_driver_setup driver_se static inline uint16_t qla1280_data_direction(struct scsi_cmnd *cmnd) { - uint16_t flags = 0; - switch(cmnd->sc_data_direction) { - - case SCSI_DATA_NONE: - flags = 0; - break; - - case SCSI_DATA_READ: - flags = BIT_5; - break; - - case SCSI_DATA_WRITE: - flags = BIT_6; - break; - - case SCSI_DATA_UNKNOWN: + case DMA_FROM_DEVICE: + return BIT_5; + case DMA_TO_DEVICE: + return BIT_6; + case DMA_BIDIRECTIONAL: + return BIT_5 | BIT_6; + /* + * We could BUG() on default here if one of the four cases aren't + * met, but then again if we receive something like that from the + * SCSI layer we have more serious problems. This shuts up GCC. + */ + case DMA_NONE: default: - flags = BIT_5 | BIT_6; - break; + return 0; } - return flags; } -#if QL1280_LUN_SUPPORT -static void qla1280_enable_lun(struct scsi_qla_host *, int, int); -#endif - #if DEBUG_QLA1280 -static void __qla1280_print_scsi_cmd(Scsi_Cmnd * cmd); +static void __qla1280_print_scsi_cmd(struct scsi_cmnd * cmd); static void __qla1280_dump_buffer(char *, int); #endif @@ -551,21 +577,11 @@ MODULE_PARM(qla1280, "s"); __setup("qla1280=", qla1280_setup); #endif -MODULE_LICENSE("GPL"); - -/* We use the Scsi_Pointer structure that's included with each command - * SCSI_Cmnd as a scratchpad for our SRB. - * - * SCp will always point to the SRB structure (defined in qla1280.h). - * It is define as follows: - * - SCp.ptr -- > pointer back to the cmd - * - SCp.this_residual --> used as forward pointer to next srb - * - SCp.buffer --> used as backward pointer to next srb - * - SCp.buffers_residual --> used as flags field - * - SCp.have_data_in --> not used - * - SCp.sent_command --> not used - * - SCp.phase --> not used +/* + * We use the scsi_pointer structure that's included with each scsi_command + * to overlay our struct srb over it. qla1280_init() checks that a srb is not + * bigger than a scsi_pointer. */ #define CMD_SP(Cmnd) &Cmnd->SCp @@ -576,28 +592,23 @@ MODULE_LICENSE("GPL"); #define CMD_RESULT(Cmnd) Cmnd->result #define CMD_HANDLE(Cmnd) Cmnd->host_scribble #if LINUX_VERSION_CODE < 0x020545 -#define CMD_HOST(Cmnd) Cmnd->host #define CMD_REQUEST(Cmnd) Cmnd->request.cmd -#define SCSI_BUS_32(Cmnd) Cmnd->channel -#define SCSI_TCN_32(Cmnd) Cmnd->target -#define SCSI_LUN_32(Cmnd) Cmnd->lun #else -#define CMD_HOST(Cmnd) Cmnd->device->host #define CMD_REQUEST(Cmnd) Cmnd->request->cmd +#endif + +#define CMD_HOST(Cmnd) Cmnd->device->host #define SCSI_BUS_32(Cmnd) Cmnd->device->channel #define SCSI_TCN_32(Cmnd) Cmnd->device->id #define SCSI_LUN_32(Cmnd) Cmnd->device->lun -#endif + /*****************************************/ /* ISP Boards supported by this driver */ /*****************************************/ -#define NUM_OF_ISP_DEVICES 6 - struct qla_boards { unsigned char name[9]; /* Board ID String */ - unsigned long device_id; /* Device PCI ID */ int numPorts; /* Number of SCSI ports */ unsigned short *fwcode; /* pointer to FW array */ unsigned short *fwlen; /* number of words in array */ @@ -605,28 +616,38 @@ struct qla_boards { unsigned char *fwver; /* Ptr to F/W version array */ }; -struct qla_boards ql1280_board_tbl[NUM_OF_ISP_DEVICES] = { - /* Name , Board PCI Device ID, Number of ports */ - {"QLA12160", PCI_DEVICE_ID_QLOGIC_ISP12160, 2, - &fw12160i_code01[0], &fw12160i_length01, +/* NOTE: qla1280_pci_tbl and ql1280_board_tbl must be in the same order */ +static struct pci_device_id qla1280_pci_tbl[] = { + {PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP12160, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + {PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP1080, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, + {PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP1240, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2}, + {PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP1280, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3}, + {PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP10160, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4}, + {0,} +}; +MODULE_DEVICE_TABLE(pci, qla1280_pci_tbl); + +static struct qla_boards ql1280_board_tbl[] = { + /* Name , Number of ports, FW details */ + {"QLA12160", 2, &fw12160i_code01[0], &fw12160i_length01, &fw12160i_addr01, &fw12160i_version_str[0]}, - {"QLA1080", PCI_DEVICE_ID_QLOGIC_ISP1080, 1, - &fw1280ei_code01[0], &fw1280ei_length01, + {"QLA1080", 1, &fw1280ei_code01[0], &fw1280ei_length01, &fw1280ei_addr01, &fw1280ei_version_str[0]}, - {"QLA1240", PCI_DEVICE_ID_QLOGIC_ISP1240, 2, - &fw1280ei_code01[0], &fw1280ei_length01, + {"QLA1240", 2, &fw1280ei_code01[0], &fw1280ei_length01, &fw1280ei_addr01, &fw1280ei_version_str[0]}, - {"QLA1280", PCI_DEVICE_ID_QLOGIC_ISP1280, 2, - &fw1280ei_code01[0], &fw1280ei_length01, + {"QLA1280", 2, &fw1280ei_code01[0], &fw1280ei_length01, &fw1280ei_addr01, &fw1280ei_version_str[0]}, - {"QLA10160", PCI_DEVICE_ID_QLOGIC_ISP10160, 1, - &fw12160i_code01[0], &fw12160i_length01, + {"QLA10160", 1, &fw12160i_code01[0], &fw12160i_length01, &fw12160i_addr01, &fw12160i_version_str[0]}, - {" ", 0, 0} + {" ", 0} }; static int qla1280_verbose = 1; -static struct scsi_qla_host *qla1280_hostlist; static int qla1280_buffer_size; static char *qla1280_buffer; @@ -663,43 +684,13 @@ static int ql_debug_level = 1; *************************************************************************/ #define PROC_BUF &qla1280_buffer[len] -#if LINUX_VERSION_CODE < 0x020600 -static int qla1280_proc_info(char *buffer, char **start, off_t offset, - int length, int hostno, int inout) -#else static int qla1280_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, int length, int inout) -#endif { - struct scsi_qla_host *ha; + struct scsi_qla_host *ha = (struct scsi_qla_host *)host->hostdata; + struct qla_boards *bdp = &ql1280_board_tbl[ha->devnum]; int size = 0; int len = 0; - struct qla_boards *bdp; -#ifdef BOGUS_QUEUE - struct scsi_lu *up; - uint32_t b, t, l; -#endif -#if LINUX_VERSION_CODE >= 0x020600 - ha = (struct scsi_qla_host *)host->hostdata; -#else - struct Scsi_Host *host; - /* Find the host that was specified */ - for (ha = qla1280_hostlist; (ha != NULL) - && ha->host->host_no != hostno; ha = ha->next) ; - - /* if host wasn't found then exit */ - if (!ha) { - size = sprintf(buffer, "Can't find adapter for host " - "number %d\n", hostno); - if (size > length) { - return size; - } else { - return 0; - } - } - - host = ha->host; -#endif if (inout) return -ENOSYS; @@ -728,7 +719,6 @@ static int qla1280_proc_info(struct Scsi memset(qla1280_buffer, 0, PAGE_SIZE); /* start building the print buffer */ - bdp = &ql1280_board_tbl[ha->devnum]; size = sprintf(PROC_BUF, "QLogic PCI to SCSI Adapter for ISP 1280/12160:\n" " Firmware version: %2d.%02d.%02d, Driver version %s\n", @@ -753,51 +743,6 @@ static int qla1280_proc_info(struct Scsi size = sprintf(PROC_BUF, "\n"); /* 1 */ len += size; - size = sprintf(PROC_BUF, "SCSI device Information:\n"); - len += size; -#ifdef BOGUS_QUEUE - /* scan for all equipment stats */ - for (b = 0; b < MAX_BUSES; b++) - for (t = 0; t < MAX_TARGETS; t++) { - for (l = 0; l < MAX_LUNS; l++) { - up = LU_Q(ha, b, t, l); - if (up == NULL) - continue; - /* unused device/lun */ - if (up->io_cnt == 0 || up->io_cnt < 2) - continue; - /* total reads since boot */ - /* total writes since boot */ - /* total requests since boot */ - size = sprintf (PROC_BUF, - "(%2d:%2d:%2d): Total reqs %ld,", - b, t, l, up->io_cnt); - len += size; - /* current number of pending requests */ - size = sprintf(PROC_BUF, " Pend reqs %d,", - up->q_outcnt); - len += size; -#if 0 - /* avg response time */ - size = sprintf(PROC_BUF, " Avg resp time %ld%%,", - (up->resp_time / up->io_cnt) * - 100); - len += size; - - /* avg active time */ - size = sprintf(PROC_BUF, - " Avg active time %ld%%\n", - (up->act_time / up->io_cnt) * 100); -#else - size = sprintf(PROC_BUF, "\n"); -#endif - len += size; - } - if (len >= qla1280_buffer_size) - break; - } -#endif - if (len >= qla1280_buffer_size) { printk(KERN_WARNING "qla1280: Overflow buffer in qla1280_proc.c\n"); @@ -875,312 +820,6 @@ static int qla1280_read_nvram(struct scs return chksum; } - -/************************************************************************** - * qla1280_do_device_init - * This routine will register the device with the SCSI subsystem, - * initialize the host adapter structure and call the device init - * routines. - * - * Input: - * pdev - pointer to struct pci_dev for adapter - * template - pointer to SCSI template - * devnum - the device number - * bdp - pointer to struct _qlaboards - * num_hosts - the host number - * - * Returns: - * host - pointer to SCSI host structure - **************************************************************************/ -struct Scsi_Host * -qla1280_do_device_init(struct pci_dev *pdev, Scsi_Host_Template * template, - int devnum, struct qla_boards *bdp, int num_hosts) -{ - struct Scsi_Host *host; - struct scsi_qla_host *ha; - - printk(KERN_INFO "qla1280: %s found on PCI bus %i, dev %i\n", - bdp->name, pdev->bus->number, PCI_SLOT(pdev->devfn)); - - host = scsi_register(template, sizeof(struct scsi_qla_host)); - if (!host) { - printk(KERN_WARNING - "qla1280: Failed to register host, aborting.\n"); - goto error; - } - -#if LINUX_VERSION_CODE < 0x020545 - scsi_set_pci_device(host, pdev); -#else - scsi_set_device(host, &pdev->dev); -#endif - ha = (struct scsi_qla_host *)host->hostdata; - /* Clear our data area */ - memset(ha, 0, sizeof(struct scsi_qla_host)); - /* Sanitize the information from PCI BIOS. */ - host->irq = pdev->irq; - ha->pci_bus = pdev->bus->number; - ha->pci_device_fn = pdev->devfn; - ha->pdev = pdev; - ha->device_id = bdp->device_id; - ha->devnum = devnum; /* specifies microcode load address */ - - if (qla1280_mem_alloc(ha)) { - printk(KERN_INFO "qla1x160: Failed to get memory\n"); - goto error_scsi_unregister; - } - - ha->ports = bdp->numPorts; - /* following needed for all cases of OS versions */ - ha->host = host; - ha->host_no = host->host_no; - - host->can_queue = 0xfffff; /* unlimited */ - host->cmd_per_lun = 1; - host->base = (unsigned long)ha->mmpbase; - host->max_channel = bdp->numPorts - 1; - host->max_lun = MAX_LUNS - 1; - host->max_id = MAX_TARGETS; - host->max_sectors = 1024; -#if LINUX_VERSION_CODE < 0x020545 - host->select_queue_depths = qla1280_select_queue_depth; -#endif - - ha->instance = num_hosts; - host->unique_id = ha->instance; - - if (qla1280_pci_config(ha)) { - printk(KERN_INFO "qla1x160: Unable to configure PCI\n"); - goto error_mem_alloced; - } - - /* Disable ISP interrupts. */ - qla1280_disable_intrs(ha); - - /* Register the IRQ with Linux (sharable) */ - if (request_irq(host->irq, qla1280_intr_handler, SA_SHIRQ, - "qla1280", ha)) { - printk("qla1280 : Failed to reserve interrupt %d already " - "in use\n", host->irq); - goto error_iounmap; - } -#if !MEMORY_MAPPED_IO - /* Register the I/O space with Linux */ - if (!request_region(host->io_port, 0xff, "qla1280")) { - printk("qla1280: Failed to reserve i/o region 0x%04lx-0x%04lx" - " already in use\n", - host->io_port, host->io_port + 0xff); - goto error_free_irq; - } -#endif - - /* load the F/W, read paramaters, and init the H/W */ - if (qla1280_initialize_adapter(ha)) { - printk(KERN_INFO "qla1x160: Failed to initialize adapter\n"); - goto error_release_region; - } - - /* set our host ID (need to do something about our two IDs) */ - host->this_id = ha->bus_settings[0].id; - - return host; - - error_release_region: -#if !MEMORY_MAPPED_IO - release_region(host->io_port, 0xff); - error_free_irq: -#endif - free_irq(host->irq, ha); - error_iounmap: -#if MEMORY_MAPPED_IO - if (ha->mmpbase) - iounmap((void *)(((unsigned long) ha->mmpbase) & PAGE_MASK)); -#endif - error_mem_alloced: - qla1280_mem_free(ha); - error_scsi_unregister: - scsi_unregister(host); - error: - return NULL; -} - -/************************************************************************** - * qla1280_detect - * This routine will probe for Qlogic 1280 SCSI host adapters. - * It returns the number of host adapters of a particular - * type that were found. It also initialize all data necessary for - * the driver. It is passed-in the host number, so that it - * knows where its first entry is in the scsi_hosts[] array. - * - * Input: - * template - pointer to SCSI template - * - * Returns: - * num - number of host adapters found. - **************************************************************************/ -static int -qla1280_detect(Scsi_Host_Template * template) -{ - struct pci_dev *pdev = NULL; - struct Scsi_Host *host; - struct scsi_qla_host *ha, *cur_ha; - struct qla_boards *bdp; - uint16_t subsys_vendor, subsys_device; - int num_hosts = 0; - int devnum = 0; - - ENTER("qla1280_detect"); - - if (sizeof(struct srb) > sizeof(Scsi_Pointer)) { - printk(KERN_WARNING - "qla1280_detect: [WARNING] struct srb too big\n"); - return 0; - } -#ifdef MODULE - /* - * If we are called as a module, the qla1280 pointer may not be null - * and it would point to our bootup string, just like on the lilo - * command line. IF not NULL, then process this config string with - * qla1280_setup - * - * Boot time Options - * To add options at boot time add a line to your lilo.conf file like: - * append="qla1280=verbose,max_tags:{{255,255,255,255},{255,255,255,255}}" - * which will result in the first four devices on the first two - * controllers being set to a tagged queue depth of 32. - */ - if (qla1280) - qla1280_setup(qla1280); -#endif - - bdp = &ql1280_board_tbl[0]; - qla1280_hostlist = NULL; - template->proc_name = "qla1280"; - - /* First Initialize QLA12160 on PCI Bus 1 Dev 2 */ - while ((pdev = pci_find_subsys(PCI_VENDOR_ID_QLOGIC, bdp->device_id, - PCI_ANY_ID, PCI_ANY_ID, pdev))) { - - /* find QLA12160 device on PCI bus=1 slot=2 */ - if ((pdev->bus->number != 1) || (PCI_SLOT(pdev->devfn) != 2)) - continue; - - /* Bypass all AMI SUBSYS VENDOR IDs */ - if (pdev->subsystem_vendor == PCI_VENDOR_ID_AMI) { - printk(KERN_INFO - "qla1x160: Skip AMI SubSys Vendor ID Chip\n"); - continue; - } - - if (pci_enable_device(pdev)) - goto find_devices; - - host = qla1280_do_device_init(pdev, template, devnum, - bdp, num_hosts); - if (!host) - continue; - ha = (struct scsi_qla_host *)host->hostdata; - - /* this preferred device will always be the first one found */ - cur_ha = qla1280_hostlist = ha; - num_hosts++; - } - - find_devices: - - pdev = NULL; - /* Try and find each different type of adapter we support */ - for (devnum = 0; bdp->device_id != 0 && devnum < NUM_OF_ISP_DEVICES; - devnum++, bdp++) { - /* PCI_SUBSYSTEM_IDS supported */ - while ((pdev = pci_find_subsys(PCI_VENDOR_ID_QLOGIC, - bdp->device_id, PCI_ANY_ID, - PCI_ANY_ID, pdev))) { - if (pci_enable_device(pdev)) - continue; - /* found an adapter */ - subsys_vendor = pdev->subsystem_vendor; - subsys_device = pdev->subsystem_device; - - /* - * skip QLA12160 already initialized on - * PCI Bus 1 Dev 2 since we already initialized - * and presented it - */ - if ((bdp->device_id == PCI_DEVICE_ID_QLOGIC_ISP12160)&& - (pdev->bus->number == 1) && - (PCI_SLOT(pdev->devfn) == 2)) - continue; - - /* Bypass all AMI SUBSYS VENDOR IDs */ - if (subsys_vendor == PCI_VENDOR_ID_AMI) { - printk(KERN_INFO - "qla1x160: Skip AMI SubSys Vendor ID Chip\n"); - continue; - } - dprintk(1, "qla1x160: Supported Device Found VID=%x " - "DID=%x SSVID=%x SSDID=%x\n", pdev->vendor, - pdev->device, subsys_vendor, subsys_device); - - host = qla1280_do_device_init(pdev, template, - devnum, bdp, num_hosts); - if (!host) - continue; - ha = (struct scsi_qla_host *)host->hostdata; - - if (qla1280_hostlist == NULL) { - cur_ha = qla1280_hostlist = ha; - } else { - cur_ha = qla1280_hostlist; - while (cur_ha->next != NULL) - cur_ha = cur_ha->next; - cur_ha->next = ha; - } - num_hosts++; - } /* end of WHILE */ - } /* end of FOR */ - - LEAVE("qla1280_detect"); - return num_hosts; -} - -/************************************************************************** - * qla1280_release - * Free the passed in Scsi_Host memory structures prior to unloading the - * module. - **************************************************************************/ -static int -qla1280_release(struct Scsi_Host *host) -{ - struct scsi_qla_host *ha = (struct scsi_qla_host *)host->hostdata; - - ENTER("qla1280_release"); - - if (!ha->flags.online) - return 0; - - /* turn-off interrupts on the card */ - WRT_REG_WORD(&ha->iobase->ictrl, 0); - - /* Detach interrupts */ - if (host->irq) - free_irq(host->irq, ha); - -#if MEMORY_MAPPED_IO - if (ha->mmpbase) - iounmap(ha->mmpbase); -#else - /* release io space registers */ - if (host->io_port) - release_region(host->io_port, 0xff); -#endif /* MEMORY_MAPPED_IO */ - - qla1280_mem_free(ha); - - ENTER("qla1280_release"); - return 0; -} - /************************************************************************** * qla1280_info * Return a string describing the driver. @@ -1197,11 +836,11 @@ qla1280_info(struct Scsi_Host *host) ha = (struct scsi_qla_host *)host->hostdata; bdp = &ql1280_board_tbl[ha->devnum]; memset(bp, 0, sizeof(qla1280_scsi_name_buffer)); + sprintf (bp, - "QLogic %s PCI to SCSI Host Adapter: bus %d device %d irq %d\n" + "QLogic %s PCI to SCSI Host Adapter\n" " Firmware version: %2d.%02d.%02d, Driver version %s", - &bdp->name[0], ha->pci_bus, (ha->pci_device_fn & 0xf8) >> 3, - host->irq, bdp->fwver[0], bdp->fwver[1], bdp->fwver[2], + &bdp->name[0], bdp->fwver[0], bdp->fwver[1], bdp->fwver[2], QLA1280_VERSION); return bp; } @@ -1218,40 +857,21 @@ qla1280_info(struct Scsi_Host *host) * context which is a big NO! NO!. **************************************************************************/ static int -qla1280_queuecommand(Scsi_Cmnd * cmd, void (*fn) (Scsi_Cmnd *)) +qla1280_queuecommand(struct scsi_cmnd *cmd, void (*fn)(struct scsi_cmnd *)) { - struct scsi_qla_host *ha; - struct srb *sp; - struct Scsi_Host *host; - int bus, target, lun; - int status; - - /*ENTER("qla1280_queuecommand"); - */ - dprintk(2, "qla1280_queuecommand(): jiffies %li\n", jiffies); - - host = CMD_HOST(cmd); - ha = (struct scsi_qla_host *)host->hostdata; + struct Scsi_Host *host = cmd->device->host; + struct scsi_qla_host *ha = (struct scsi_qla_host *)host->hostdata; + struct srb *sp = (struct srb *)&cmd->SCp; - /* send command to adapter */ - sp = (struct srb *)CMD_SP(cmd); - sp->cmd = cmd; cmd->scsi_done = fn; + sp->cmd = cmd; sp->flags = 0; qla1280_print_scsi_cmd(5, cmd); - /* Generate LU queue on bus, target, LUN */ - bus = SCSI_BUS_32(cmd); - target = SCSI_TCN_32(cmd); - lun = SCSI_LUN_32(cmd); if (ha->flags.enable_64bit_addressing) - status = qla1280_64bit_start_scsi(ha, sp); - else - status = qla1280_32bit_start_scsi(ha, sp); - - /*LEAVE("qla1280_queuecommand"); */ - return status; + return qla1280_64bit_start_scsi(ha, sp); + return qla1280_32bit_start_scsi(ha, sp); } enum action { @@ -1305,7 +925,7 @@ static void qla1280_mailbox_timeout(unsi * the SCSI bus reset line. **************************************************************************/ static int -qla1280_error_action(Scsi_Cmnd * cmd, enum action action) +qla1280_error_action(struct scsi_cmnd *cmd, enum action action) { struct scsi_qla_host *ha; int bus, target, lun; @@ -1350,7 +970,7 @@ qla1280_error_action(Scsi_Cmnd * cmd, en * grabs the lock. /Jes */ if (data & RISC_INT) - qla1280_isr(ha, &ha->done_q_first, &ha->done_q_last); + qla1280_isr(ha, &ha->done_q); /* * Determine the suggested action that the mid-level driver wants @@ -1461,8 +1081,8 @@ qla1280_error_action(Scsi_Cmnd * cmd, en ha->flags.reset_active = 0; } - if (ha->done_q_first) - qla1280_done(ha, &ha->done_q_first, &ha->done_q_last); + if (!list_empty(&ha->done_q)) + qla1280_done(ha); ha->flags.in_reset = 0; /* If we didn't manage to issue the action, or we have no @@ -1547,22 +1167,11 @@ qla1280_eh_adapter_reset(struct scsi_cmn return qla1280_error_action(cmd, ADAPTER_RESET); } -/************************************************************************** - * qla1280_biosparam - * Return the disk geometry for the given SCSI device. - **************************************************************************/ static int -#if LINUX_VERSION_CODE < 0x020545 -qla1280_biosparam(Disk * disk, kdev_t dev, int geom[]) -#else qla1280_biosparam(struct scsi_device *sdev, struct block_device *bdev, sector_t capacity, int geom[]) -#endif { int heads, sectors, cylinders; -#if LINUX_VERSION_CODE < 0x020545 - unsigned long capacity = disk->capacity; -#endif heads = 64; sectors = 32; @@ -1582,11 +1191,118 @@ qla1280_biosparam(struct scsi_device *sd return 0; } +#if LINUX_VERSION_CODE < 0x020600 +static int +qla1280_detect(Scsi_Host_Template *template) +{ + struct pci_device_id *id = &qla1280_pci_tbl[0]; + struct pci_dev *pdev = NULL; + int num_hosts = 0; + + if (sizeof(struct srb) > sizeof(Scsi_Pointer)) { + printk(KERN_WARNING + "qla1280: struct srb too big, aborting\n"); + return 0; + } + + if ((DMA_BIDIRECTIONAL != PCI_DMA_BIDIRECTIONAL) || + (DMA_TO_DEVICE != PCI_DMA_TODEVICE) || + (DMA_FROM_DEVICE != PCI_DMA_FROMDEVICE) || + (DMA_NONE != PCI_DMA_NONE)) { + printk(KERN_WARNING + "qla1280: dma direction bits don't match\n"); + return 0; + } + +#ifdef MODULE + /* + * If we are called as a module, the qla1280 pointer may not be null + * and it would point to our bootup string, just like on the lilo + * command line. IF not NULL, then process this config string with + * qla1280_setup + * + * Boot time Options + * To add options at boot time add a line to your lilo.conf file like: + * append="qla1280=verbose,max_tags:{{255,255,255,255},{255,255,255,255}}" + * which will result in the first four devices on the first two + * controllers being set to a tagged queue depth of 32. + */ + if (qla1280) + qla1280_setup(qla1280); +#endif + + /* First Initialize QLA12160 on PCI Bus 1 Dev 2 */ + while ((pdev = pci_find_device(id->vendor, id->device, pdev))) { + if (pdev->bus->number == 1 && PCI_SLOT(pdev->devfn) == 2) { + if (!qla1280_probe_one(pdev, id)) + num_hosts++; + } + } + + pdev = NULL; + /* Try and find each different type of adapter we support */ + for (id = &qla1280_pci_tbl[0]; id->device; id++) { + while ((pdev = pci_find_device(id->vendor, id->device, pdev))) { + /* + * skip QLA12160 already initialized on + * PCI Bus 1 Dev 2 since we already initialized + * and presented it + */ + if (id->device == PCI_DEVICE_ID_QLOGIC_ISP12160 && + pdev->bus->number == 1 && + PCI_SLOT(pdev->devfn) == 2) + continue; + + if (!qla1280_probe_one(pdev, id)) + num_hosts++; + } + } + + return num_hosts; +} + +/* + * This looks a bit ugly as we could just pass down host to + * qla1280_remove_one, but I want to keep qla1280_release purely a wrapper + * around pci_driver::remove as used from 2.6 onwards. + */ +static int +qla1280_release(struct Scsi_Host *host) +{ + struct scsi_qla_host *ha = (struct scsi_qla_host *)host->hostdata; + + qla1280_remove_one(ha->pdev); + return 0; +} + +static int +qla1280_biosparam_old(Disk * disk, kdev_t dev, int geom[]) +{ + return qla1280_biosparam(disk->device, NULL, disk->capacity, geom); +} + +static int +qla1280_proc_info_old(char *buffer, char **start, off_t offset, int length, + int hostno, int inout) +{ + struct Scsi_Host *host; + + for (host = scsi_hostlist; host; host = host->next) { + if (host->host_no == hostno) { + return qla1280_proc_info(host, buffer, start, + offset, length, inout); + } + } + + return -ESRCH; +} +#endif + /************************************************************************** * qla1280_intr_handler * Handles the H/W interrupt **************************************************************************/ -irqreturn_t +static irqreturn_t qla1280_intr_handler(int irq, void *dev_id, struct pt_regs *regs) { struct scsi_qla_host *ha; @@ -1607,11 +1323,11 @@ qla1280_intr_handler(int irq, void *dev_ data = qla1280_debounce_register(®->istatus); /* Check for pending interrupts. */ if (data & RISC_INT) { - qla1280_isr(ha, &ha->done_q_first, &ha->done_q_last); + qla1280_isr(ha, &ha->done_q); handled = 1; } - if (ha->done_q_first) - qla1280_done(ha, &ha->done_q_first, &ha->done_q_last); + if (!list_empty(&ha->done_q)) + qla1280_done(ha); spin_unlock(HOST_LOCK); @@ -1624,7 +1340,7 @@ qla1280_intr_handler(int irq, void *dev_ static int -qla12160_set_target_parameters(struct scsi_qla_host *ha, int bus, int target) +qla1280_set_target_parameters(struct scsi_qla_host *ha, int bus, int target) { uint8_t mr; uint16_t mb[MAILBOX_REGISTER_COUNT]; @@ -1633,8 +1349,8 @@ qla12160_set_target_parameters(struct sc nv = &ha->nvram; - if (ha->device_id == PCI_DEVICE_ID_QLOGIC_ISP12160 || - ha->device_id == PCI_DEVICE_ID_QLOGIC_ISP10160) + if (ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP12160 || + ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP10160) is1x160 = 1; else is1x160 = 0; @@ -1683,7 +1399,7 @@ qla12160_set_target_parameters(struct sc * default queue depth (dependent on the number of hardware SCBs). **************************************************************************/ static int -qla1280_slave_configure(Scsi_Device *device) +qla1280_slave_configure(struct scsi_device *device) { struct scsi_qla_host *ha; int default_depth = 3; @@ -1721,8 +1437,8 @@ qla1280_slave_configure(Scsi_Device *dev (driver_setup.wide_mask && (~driver_setup.wide_mask & (1 << target)))) nv->bus[bus].target[target].parameter.f.enable_wide = 0; - if (ha->device_id == PCI_DEVICE_ID_QLOGIC_ISP12160 || - ha->device_id == PCI_DEVICE_ID_QLOGIC_ISP10160) { + if (ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP12160 || + ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP10160) { if (driver_setup.no_ppr || (driver_setup.ppr_mask && (~driver_setup.ppr_mask & (1 << target)))) @@ -1730,11 +1446,9 @@ qla1280_slave_configure(Scsi_Device *dev } spin_lock_irqsave(HOST_LOCK, flags); - if (nv->bus[bus].target[target].parameter.f.enable_sync) { - status = qla12160_set_target_parameters(ha, bus, target); - } - - qla12160_get_target_parameters(ha, device); + if (nv->bus[bus].target[target].parameter.f.enable_sync) + status = qla1280_set_target_parameters(ha, bus, target); + qla1280_get_target_parameters(ha, device); spin_unlock_irqrestore(HOST_LOCK, flags); return status; } @@ -1748,54 +1462,46 @@ qla1280_slave_configure(Scsi_Device *dev * support tagged queueing. **************************************************************************/ static void -qla1280_select_queue_depth(struct Scsi_Host *host, Scsi_Device *scsi_devs) +qla1280_select_queue_depth(struct Scsi_Host *host, struct scsi_device *sdev_q) { - Scsi_Device *device; struct scsi_qla_host *ha = (struct scsi_qla_host *)host->hostdata; + struct scsi_device *sdev; ENTER("qla1280_select_queue_depth"); - for (device = scsi_devs; device != NULL; device = device->next) { - if (device->host == host) - qla1280_slave_configure(device); - } - - if (scsi_devs) - qla1280_check_for_dead_scsi_bus(ha, scsi_devs->channel); + for (sdev = sdev_q; sdev; sdev = sdev->next) + if (sdev->host == host) + qla1280_slave_configure(sdev); + if (sdev_q) + qla1280_check_for_dead_scsi_bus(ha, sdev_q->channel); LEAVE("qla1280_select_queue_depth"); } #endif /* - * Driver Support Routines - */ - -/* * qla1280_done * Process completed commands. * * Input: * ha = adapter block pointer. - * done_q_first = done queue first pointer. - * done_q_last = done queue last pointer. + * done_q = done queue. */ static void -qla1280_done(struct scsi_qla_host *ha, struct srb ** done_q_first, - struct srb ** done_q_last) +qla1280_done(struct scsi_qla_host *ha) { struct srb *sp; + struct list_head *done_q; int bus, target, lun; - Scsi_Cmnd *cmd; + struct scsi_cmnd *cmd; ENTER("qla1280_done"); - while (*done_q_first != NULL) { - /* remove command from done list */ - sp = *done_q_first; - if (!(*done_q_first = sp->s_next)) - *done_q_last = NULL; - else - (*done_q_first)->s_prev = NULL; + done_q = &ha->done_q; + + while (!list_empty(done_q)) { + sp = list_entry(done_q->next, struct srb, list); + + list_del(&sp->list); cmd = sp->cmd; bus = SCSI_BUS_32(cmd); @@ -1822,15 +1528,13 @@ qla1280_done(struct scsi_qla_host *ha, s dprintk(3, "S/G unmap_sg cmd=%p\n", cmd); pci_unmap_sg(ha->pdev, cmd->request_buffer, - cmd->use_sg, - scsi_to_pci_dma_dir(cmd->sc_data_direction)); + cmd->use_sg, cmd->sc_data_direction); } else if (cmd->request_bufflen) { /*dprintk(1, "No S/G unmap_single cmd=%x saved_dma_handle=%lx\n", cmd, sp->saved_dma_handle); */ pci_unmap_page(ha->pdev, sp->saved_dma_handle, - cmd->request_bufflen, - scsi_to_pci_dma_dir(cmd->sc_data_direction)); + cmd->request_bufflen, cmd->sc_data_direction); } /* Call the mid-level driver interrupt handler */ @@ -1845,7 +1549,6 @@ qla1280_done(struct scsi_qla_host *ha, s if(sp->wait != NULL) complete(sp->wait); - } LEAVE("qla1280_done"); } @@ -1854,7 +1557,7 @@ qla1280_done(struct scsi_qla_host *ha, s * Translates a ISP error to a Linux SCSI error */ static int -qla1280_return_status(struct response * sts, Scsi_Cmnd * cp) +qla1280_return_status(struct response * sts, struct scsi_cmnd *cp) { int host_status = DID_ERROR; #if DEBUG_QLA1280_INTR @@ -1925,132 +1628,24 @@ qla1280_return_status(struct response * printk(KERN_WARNING "scsi: Underflow detected - retrying " "command.\n"); - host_status = DID_ERROR; - } else - host_status = DID_OK; - break; - - default: - host_status = DID_ERROR; - break; - } - -#if DEBUG_QLA1280_INTR - dprintk(1, "qla1280 ISP status: host status (%s) scsi status %x\n", - reason[host_status], sts->scsi_status); -#endif - - LEAVE("qla1280_return_status"); - - return (sts->scsi_status & 0xff) | (host_status << 16); -} - -/* - * qla1280_done_q_put - * Place SRB command on done queue. - * - * Input: - * sp = srb pointer. - * done_q_first = done queue first pointer. - * done_q_last = done queue last pointer. - */ -static void -qla1280_done_q_put(struct srb * sp, struct srb ** done_q_first, - struct srb ** done_q_last) -{ - ENTER("qla1280_put_done_q"); - - /* Place block on done queue */ - sp->s_next = NULL; - sp->s_prev = *done_q_last; - if (!*done_q_first) - *done_q_first = sp; - else - (*done_q_last)->s_next = sp; - *done_q_last = sp; - - LEAVE("qla1280_put_done_q"); -} - - -/* -* qla1280_mem_alloc -* Allocates adapter memory. -* -* Returns: -* 0 = success. -* 1 = failure. -*/ -static int -qla1280_mem_alloc(struct scsi_qla_host *ha) -{ - int status = 1; - dma_addr_t dma_handle; - - ENTER("qla1280_mem_alloc"); - - /* get consistent memory allocated for request and response rings */ - ha->request_ring = pci_alloc_consistent(ha->pdev, - ((REQUEST_ENTRY_CNT + 1) * - (sizeof(request_t))), - &dma_handle); - if (!ha->request_ring) - goto error; - ha->request_dma = dma_handle; - ha->response_ring = pci_alloc_consistent(ha->pdev, - ((RESPONSE_ENTRY_CNT + 1) * - (sizeof(struct response))), - &dma_handle); - if (!ha->response_ring) - goto error; - ha->response_dma = dma_handle; - status = 0; - goto finish; - - error: - if (status) - dprintk(2, "qla1280_mem_alloc: **** FAILED ****\n"); + host_status = DID_ERROR; + } else + host_status = DID_OK; + break; - if (ha->request_ring) - pci_free_consistent(ha->pdev, - ((REQUEST_ENTRY_CNT + 1) * - (sizeof(request_t))), - ha->request_ring, ha->request_dma); - finish: - LEAVE("qla1280_mem_alloc"); - return status; -} + default: + host_status = DID_ERROR; + break; + } -/* - * qla1280_mem_free - * Frees adapter allocated memory. - * - * Input: - * ha = adapter block pointer. - */ -static void -qla1280_mem_free(struct scsi_qla_host *ha) -{ - ENTER("qlc1280_mem_free"); - /* free consistent memory allocated for request and response rings */ - if (ha->request_ring) - pci_free_consistent(ha->pdev, - ((REQUEST_ENTRY_CNT + 1) * - (sizeof(request_t))), - ha->request_ring, ha->request_dma); - - if (ha->response_ring) - pci_free_consistent(ha->pdev, - ((RESPONSE_ENTRY_CNT + 1) * - (sizeof(struct response))), - ha->response_ring, ha->response_dma); +#if DEBUG_QLA1280_INTR + dprintk(1, "qla1280 ISP status: host status (%s) scsi status %x\n", + reason[host_status], sts->scsi_status); +#endif - if (qla1280_buffer) { - free_page((unsigned long) qla1280_buffer); - qla1280_buffer = NULL; - } + LEAVE("qla1280_return_status"); - LEAVE("qlc1280_mem_free"); + return (sts->scsi_status & 0xff) | (host_status << 16); } /****************************************************************************/ @@ -2058,14 +1653,14 @@ qla1280_mem_free(struct scsi_qla_host *h /****************************************************************************/ /* - * qla2100_enable_intrs - * qla2100_disable_intrs - * - * Input: - * ha = adapter block pointer. - * - * Returns: - * None + * qla2100_enable_intrs + * qla2100_disable_intrs + * + * Input: + * ha = adapter block pointer. + * + * Returns: + * None */ static inline void qla1280_enable_intrs(struct scsi_qla_host *ha) @@ -2101,7 +1696,7 @@ qla1280_disable_intrs(struct scsi_qla_ho * Returns: * 0 = success */ -static int +static int __devinit qla1280_initialize_adapter(struct scsi_qla_host *ha) { struct device_reg *reg; @@ -2132,7 +1727,8 @@ qla1280_initialize_adapter(struct scsi_q if ((c = snia_pcibr_rrb_alloc(ha->pdev, &count1, &count2)) < 0) printk(KERN_ERR "scsi(%li): Unable to allocate SN2 " "virtual DMA channels\n", ha->host_no); - ha->flags.use_pci_vchannel = 1; + else + ha->flags.use_pci_vchannel = 1; driver_setup.no_nvram = 1; } @@ -2164,7 +1760,7 @@ qla1280_initialize_adapter(struct scsi_q #endif /* If firmware needs to be loaded */ if (qla1280_isp_firmware(ha)) { - if (!(status = qla1280_chip_diag (ha))) { + if (!(status = qla1280_chip_diag(ha))) { status = qla1280_setup_chip(ha); } } else { @@ -2288,72 +1884,6 @@ qla1280_isp_firmware(struct scsi_qla_hos } /* - * PCI configuration - * Setup device PCI configuration registers. - * - * Input: - * ha = adapter block pointer. - * - * Returns: - * 0 = success. - */ -static int -qla1280_pci_config(struct scsi_qla_host *ha) -{ -#if MEMORY_MAPPED_IO - unsigned long base; - int size; -#endif - uint16_t buf_wd; - int status = 1; - - ENTER("qla1280_pci_config"); - - pci_set_master(ha->pdev); - /* - * Set Bus Master Enable, Memory Address Space Enable and - * reset any error bits, in the command register. - */ - pci_read_config_word (ha->pdev, PCI_COMMAND, &buf_wd); -#if MEMORY_MAPPED_IO - buf_wd |= PCI_COMMAND_MEMORY; -#endif - buf_wd |= PCI_COMMAND_IO; - pci_write_config_word (ha->pdev, PCI_COMMAND, buf_wd); - /* - * Reset expansion ROM address decode enable. - */ - pci_read_config_word(ha->pdev, PCI_ROM_ADDRESS, &buf_wd); - buf_wd &= ~PCI_ROM_ADDRESS_ENABLE; - pci_write_config_word (ha->pdev, PCI_ROM_ADDRESS, buf_wd); - - ha->host->io_port = pci_resource_start(ha->pdev, 0); - ha->host->io_port &= PCI_BASE_ADDRESS_IO_MASK; - ha->iobase = (struct device_reg *) ha->host->io_port; - -#if MEMORY_MAPPED_IO - /* - * Find proper memory chunk for memory map I/O reg. - */ - base = pci_resource_start(ha->pdev, 1); - size = pci_resource_len(ha->pdev, 1); - /* - * Get virtual address for I/O registers. - */ - ha->mmpbase = ioremap(base, size); - if (ha->mmpbase) { - ha->iobase = (struct device_reg *)ha->mmpbase; - status = 0; - } -#else /* MEMORY_MAPPED_IO */ - status = 0; -#endif /* MEMORY_MAPPED_IO */ - - LEAVE("qla1280_pci_config"); - return status; -} - -/* * Chip diagnostics * Test chip for proper operation. * @@ -2724,8 +2254,8 @@ qla1280_nvram_config(struct scsi_qla_hos ENTER("qla1280_nvram_config"); - if (ha->device_id == PCI_DEVICE_ID_QLOGIC_ISP12160 || - ha->device_id == PCI_DEVICE_ID_QLOGIC_ISP10160) + if (ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP12160 || + ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP10160) is1x160 = 1; else is1x160 = 0; @@ -3196,8 +2726,7 @@ qla1280_mailbox_command(struct scsi_qla_ { struct device_reg *reg = ha->iobase; #if 0 - struct srb *done_q_first = 0; - struct srb *done_q_last = 0; + LIST_HEAD(done_q); #endif int status = 0; int cnt; @@ -3208,8 +2737,6 @@ qla1280_mailbox_command(struct scsi_qla_ ENTER("qla1280_mailbox_command"); - ha->flags.mbox_busy = 1; - if (ha->mailbox_wait) { printk(KERN_ERR "Warning mailbox wait already in use!\n"); } @@ -3233,7 +2760,6 @@ qla1280_mailbox_command(struct scsi_qla_ } /* Issue set host interrupt command. */ - ha->flags.mbox_busy = 0; /* set up a timer just in case we're really jammed */ init_timer(&timer); @@ -3276,15 +2802,15 @@ qla1280_mailbox_command(struct scsi_qla_ #if 0 /* Go check for any response interrupts pending. */ - qla1280_isr(ha, &done_q_first, &done_q_last); + qla1280_isr(ha, &done_q); #endif if (ha->flags.reset_marker) qla1280_rst_aen(ha); #if 0 - if (done_q_first) - qla1280_done (ha, &done_q_first, &done_q_last); + if (!list_empty(&done_q)) + qla1280_done(ha, &done_q); #endif if (status) @@ -3307,23 +2833,22 @@ qla1280_poll(struct scsi_qla_host *ha) { struct device_reg *reg = ha->iobase; uint16_t data; - struct srb *done_q_first = 0; - struct srb *done_q_last = 0; + LIST_HEAD(done_q); /* ENTER("qla1280_poll"); */ /* Check for pending interrupts. */ data = RD_REG_WORD(®->istatus); if (data & RISC_INT) - qla1280_isr(ha, &done_q_first, &done_q_last); + qla1280_isr(ha, &done_q); - if (!ha->flags.mbox_busy) { + if (!ha->mailbox_wait) { if (ha->flags.reset_marker) qla1280_rst_aen(ha); } - if (done_q_first) - qla1280_done(ha, &done_q_first, &done_q_last); + if (!list_empty(&done_q)) + qla1280_done(ha); /* LEAVE("qla1280_poll"); */ } @@ -3573,7 +3098,7 @@ static int qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp) { struct device_reg *reg = ha->iobase; - Scsi_Cmnd *cmd = sp->cmd; + struct scsi_cmnd *cmd = sp->cmd; cmd_a64_entry_t *pkt; struct scatterlist *sg = NULL; u32 *dword_ptr; @@ -3582,6 +3107,7 @@ qla1280_64bit_start_scsi(struct scsi_qla int cnt; int req_cnt; u16 seg_cnt; + u8 dir; ENTER("qla1280_64bit_start_scsi:"); @@ -3590,7 +3116,7 @@ qla1280_64bit_start_scsi(struct scsi_qla if (cmd->use_sg) { sg = (struct scatterlist *) cmd->request_buffer; seg_cnt = pci_map_sg(ha->pdev, sg, cmd->use_sg, - scsi_to_pci_dma_dir(cmd->sc_data_direction)); + cmd->sc_data_direction); if (seg_cnt > 2) { req_cnt += (seg_cnt - 2) / 5; @@ -3675,8 +3201,8 @@ qla1280_64bit_start_scsi(struct scsi_qla /* dprintk(1, "Build packet for command[0]=0x%x\n",pkt->scsi_cdb[0]); */ /* Set transfer direction. */ - sp->dir = qla1280_data_direction(cmd); - pkt->control_flags |= cpu_to_le16(sp->dir); + dir = qla1280_data_direction(cmd); + pkt->control_flags |= cpu_to_le16(dir); /* Set total data segment count. */ pkt->dseg_count = cpu_to_le16(seg_cnt); @@ -3780,7 +3306,7 @@ qla1280_64bit_start_scsi(struct scsi_qla dma_handle = pci_map_page(ha->pdev, page, off, cmd->request_bufflen, - scsi_to_pci_dma_dir(cmd->sc_data_direction)); + cmd->sc_data_direction); /* save dma_handle for pci_unmap_page */ sp->saved_dma_handle = dma_handle; @@ -3858,7 +3384,7 @@ static int qla1280_32bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp) { struct device_reg *reg = ha->iobase; - Scsi_Cmnd *cmd = sp->cmd; + struct scsi_cmnd *cmd = sp->cmd; struct cmd_entry *pkt; struct scatterlist *sg = NULL; uint32_t *dword_ptr; @@ -3867,6 +3393,7 @@ qla1280_32bit_start_scsi(struct scsi_qla int req_cnt; uint16_t seg_cnt; dma_addr_t dma_handle; + u8 dir; ENTER("qla1280_32bit_start_scsi"); @@ -3884,7 +3411,7 @@ qla1280_32bit_start_scsi(struct scsi_qla */ sg = (struct scatterlist *) cmd->request_buffer; seg_cnt = pci_map_sg(ha->pdev, sg, cmd->use_sg, - scsi_to_pci_dma_dir(cmd->sc_data_direction)); + cmd->sc_data_direction); /* * if greater than four sg entries then we need to allocate @@ -3975,8 +3502,8 @@ qla1280_32bit_start_scsi(struct scsi_qla /*dprintk(1, "Build packet for command[0]=0x%x\n",pkt->scsi_cdb[0]); */ /* Set transfer direction. */ - sp->dir = qla1280_data_direction(cmd); - pkt->control_flags |= cpu_to_le16(sp->dir); + dir = qla1280_data_direction(cmd); + pkt->control_flags |= cpu_to_le16(dir); /* Set total data segment count. */ pkt->dseg_count = cpu_to_le16(seg_cnt); @@ -4061,7 +3588,7 @@ qla1280_32bit_start_scsi(struct scsi_qla unsigned long off = (unsigned long)cmd->request_buffer & ~PAGE_MASK; dma_handle = pci_map_page(ha->pdev, page, off, cmd->request_bufflen, - scsi_to_pci_dma_dir(cmd->sc_data_direction)); + cmd->sc_data_direction); sp->saved_dma_handle = dma_handle; *dword_ptr++ = cpu_to_le32(pci_dma_lo32(dma_handle)); @@ -4207,48 +3734,6 @@ qla1280_isp_cmd(struct scsi_qla_host *ha LEAVE("qla1280_isp_cmd"); } -#if QL1280_LUN_SUPPORT -/* - * qla1280_enable_lun - * Issue enable LUN entry IOCB. - * - * Input: - * ha = adapter block pointer. - * bus = SCSI BUS number. - * lun = LUN number. - */ -static void -qla1280_enable_lun(struct scsi_qla_host *ha, int bus, int lun) -{ - struct elun_entry *pkt; - - ENTER("qla1280_enable_lun"); - - /* Get request packet. */ - /* - if (pkt = (struct elun_entry *)qla1280_req_pkt(ha)) - { - pkt->entry_type = ENABLE_LUN_TYPE; - pkt->lun = cpu_to_le16(bus ? lun | BIT_15 : lun); - pkt->command_count = 32; - pkt->immed_notify_count = 1; - pkt->group_6_length = MAX_CMDSZ; - pkt->group_7_length = MAX_CMDSZ; - pkt->timeout = cpu_to_le16(0x30); - - qla1280_isp_cmd(ha); - } - */ - pkt = (struct elun_entry *) 1; - - if (!pkt) - dprintk(2, "qla1280_enable_lun: **** FAILED ****\n"); - else - dprintk(3, "qla1280_enable_lun: exiting normally\n"); -} -#endif - - /****************************************************************************/ /* Interrupt Service Routine. */ /****************************************************************************/ @@ -4259,12 +3744,10 @@ qla1280_enable_lun(struct scsi_qla_host * * Input: * ha = adapter block pointer. - * done_q_first = done queue first pointer. - * done_q_last = done queue last pointer. + * done_q = done queue. ****************************************************************************/ static void -qla1280_isr(struct scsi_qla_host *ha, struct srb ** done_q_first, - struct srb ** done_q_last) +qla1280_isr(struct scsi_qla_host *ha, struct list_head *done_q) { struct device_reg *reg = ha->iobase; struct response *pkt; @@ -4336,13 +3819,7 @@ qla1280_isr(struct scsi_qla_host *ha, st CMD_RESULT(sp->cmd) = 0; /* Place block on done queue */ - sp->s_next = NULL; - sp->s_prev = *done_q_last; - if (!*done_q_first) - *done_q_first = sp; - else - (*done_q_last)->s_next = sp; - *done_q_last = sp; + list_add_tail(&sp->list, done_q); } else { /* * If we get here we have a real problem! @@ -4420,15 +3897,10 @@ qla1280_isr(struct scsi_qla_host *ha, st } /* - * Response ring - waiting for the mbox_busy flag here seems - * unnecessary as the mailbox data has been copied to ha->mailbox_out - * by the time we actually get here! + * We will receive interrupts during mailbox testing prior to + * the card being marked online, hence the double check. */ - if (!(ha->flags.online -#if 0 - && !ha->flags.mbox_busy -#endif - )) { + if (!(ha->flags.online && !ha->mailbox_wait)) { dprintk(2, "qla1280_isr: Response pointer Error\n"); goto out; } @@ -4468,12 +3940,9 @@ qla1280_isr(struct scsi_qla_host *ha, st ha->outstanding_cmds[pkt->handle]->cmd, pkt->handle); if (pkt->entry_type == STATUS_TYPE) - qla1280_status_entry(ha, pkt, done_q_first, - done_q_last); + qla1280_status_entry(ha, pkt, done_q); else - qla1280_error_entry(ha, pkt, done_q_first, - done_q_last); - + qla1280_error_entry(ha, pkt, done_q); /* Adjust ring index. */ ha->rsp_ring_index++; if (ha->rsp_ring_index == RESPONSE_ENTRY_CNT) { @@ -4575,17 +4044,16 @@ qla1280_get_target_options(struct scsi_c * Input: * ha = adapter block pointer. * pkt = entry pointer. - * done_q_first = done queue first pointer. - * done_q_last = done queue last pointer. + * done_q = done queue. */ static void qla1280_status_entry(struct scsi_qla_host *ha, struct response *pkt, - struct srb **done_q_first, struct srb **done_q_last) + struct list_head *done_q) { unsigned int bus, target, lun; int sense_sz; struct srb *sp; - Scsi_Cmnd *cmd; + struct scsi_cmnd *cmd; uint32_t handle = le32_to_cpu(pkt->handle); uint16_t scsi_status = le16_to_cpu(pkt->scsi_status); uint16_t comp_status = le16_to_cpu(pkt->comp_status); @@ -4637,7 +4105,7 @@ qla1280_status_entry(struct scsi_qla_hos sense_sz = req_sense_length; else /* - * Scsi_Cmnd->sense_buffer is + * scsi_cmnd->sense_buffer is * 64 bytes, why only copy 63? * This looks wrong! /Jes */ @@ -4659,9 +4127,9 @@ qla1280_status_entry(struct scsi_qla_hos sense_sz); } } - /* Place command on done queue. */ - qla1280_done_q_put(sp, done_q_first, done_q_last); + /* Place command on done queue. */ + list_add_tail(&sp->list, done_q); out: LEAVE("qla1280_status_entry"); } @@ -4673,12 +4141,11 @@ qla1280_status_entry(struct scsi_qla_hos * Input: * ha = adapter block pointer. * pkt = entry pointer. - * done_q_first = done queue first pointer. - * done_q_last = done queue last pointer. + * done_q = done queue. */ static void -qla1280_error_entry(struct scsi_qla_host *ha, struct response * pkt, - struct srb ** done_q_first, struct srb ** done_q_last) +qla1280_error_entry(struct scsi_qla_host *ha, struct response *pkt, + struct list_head *done_q) { struct srb *sp; uint32_t handle = le32_to_cpu(pkt->handle); @@ -4715,8 +4182,9 @@ qla1280_error_entry(struct scsi_qla_host /* Set error status. */ CMD_RESULT(sp->cmd) = DID_ERROR << 16; } + /* Place command on done queue. */ - qla1280_done_q_put(sp, done_q_first, done_q_last); + list_add_tail(&sp->list, done_q); } #ifdef QLA_64BIT_PTR else if (pkt->entry_type == COMMAND_A64_TYPE) { @@ -4760,7 +4228,7 @@ qla1280_abort_isp(struct scsi_qla_host * ha->host_no); /* Dequeue all commands in outstanding command list. */ for (cnt = 0; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) { - Scsi_Cmnd *cmd; + struct scsi_cmnd *cmd; sp = ha->outstanding_cmds[cnt]; if (sp) { @@ -4894,7 +4362,8 @@ qla1280_check_for_dead_scsi_bus(struct s } static void -qla12160_get_target_parameters(struct scsi_qla_host *ha, Scsi_Device *device) +qla1280_get_target_parameters(struct scsi_qla_host *ha, + struct scsi_device *device) { uint16_t mb[MAILBOX_REGISTER_COUNT]; int bus, target, lun; @@ -4959,7 +4428,7 @@ __qla1280_dump_buffer(char *b, int size) * **************************************************************************/ static void -__qla1280_print_scsi_cmd(Scsi_Cmnd * cmd) +__qla1280_print_scsi_cmd(struct scsi_cmnd *cmd) { struct scsi_qla_host *ha; struct Scsi_Host *host = CMD_HOST(cmd); @@ -4987,11 +4456,11 @@ __qla1280_print_scsi_cmd(Scsi_Cmnd * cmd printk(" SG buffer: \n"); qla1280_dump_buffer(1, (char *)sg, (cmd->use_sg*sizeof(struct scatterlist))); } */ - printk(" tag=%d, flags=0x%x, transfersize=0x%x \n", - cmd->tag, cmd->flags, cmd->transfersize); + printk(" tag=%d, transfersize=0x%x \n", + cmd->tag, cmd->transfersize); printk(" Pid=%li, SP=0x%p\n", cmd->pid, CMD_SP(cmd)); printk(" underflow size = 0x%x, direction=0x%x\n", - cmd->underflow, sp->dir); + cmd->underflow, cmd->sc_data_direction); } /************************************************************************** @@ -5002,7 +4471,7 @@ static void ql1280_dump_device(struct scsi_qla_host *ha) { - Scsi_Cmnd *cp; + struct scsi_cmnd *cp; struct srb *sp; int i; @@ -5136,34 +4605,296 @@ qla1280_get_token(char *str) return ret; } - -static Scsi_Host_Template driver_template = { +#if LINUX_VERSION_CODE >= 0x020600 +static struct scsi_host_template qla1280_driver_template = { + .proc_name = "qla1280", + .name = "Qlogic ISP 1280/12160", + .info = qla1280_info, + .slave_configure = qla1280_slave_configure, + .queuecommand = qla1280_queuecommand, + .eh_abort_handler = qla1280_eh_abort, + .eh_device_reset_handler= qla1280_eh_device_reset, + .eh_bus_reset_handler = qla1280_eh_bus_reset, + .eh_host_reset_handler = qla1280_eh_adapter_reset, + .bios_param = qla1280_biosparam, .proc_info = qla1280_proc_info, + .can_queue = 0xfffff, + .this_id = -1, + .sg_tablesize = SG_ALL, + .cmd_per_lun = 1, + .use_clustering = ENABLE_CLUSTERING, +}; +#else +static Scsi_Host_Template qla1280_driver_template = { + .proc_name = "qla1280", .name = "Qlogic ISP 1280/12160", .detect = qla1280_detect, .release = qla1280_release, .info = qla1280_info, .queuecommand = qla1280_queuecommand, -#if LINUX_VERSION_CODE >= 0x020545 - .slave_configure = qla1280_slave_configure, -#endif .eh_abort_handler = qla1280_eh_abort, .eh_device_reset_handler= qla1280_eh_device_reset, .eh_bus_reset_handler = qla1280_eh_bus_reset, .eh_host_reset_handler = qla1280_eh_adapter_reset, - .bios_param = qla1280_biosparam, - .can_queue = 255, + .bios_param = qla1280_biosparam_old, + .proc_info = qla1280_proc_info_old, + .can_queue = 0xfffff, .this_id = -1, .sg_tablesize = SG_ALL, - .cmd_per_lun = 3, + .cmd_per_lun = 1, .use_clustering = ENABLE_CLUSTERING, -#if LINUX_VERSION_CODE < 0x020545 .use_new_eh_code = 1, +}; +#endif + +static int __devinit +qla1280_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) +{ + int devnum = id->driver_data; + struct qla_boards *bdp = &ql1280_board_tbl[devnum]; + struct Scsi_Host *host; + struct scsi_qla_host *ha; + int error = -ENODEV; + + /* Bypass all AMI SUBSYS VENDOR IDs */ + if (pdev->subsystem_vendor == PCI_VENDOR_ID_AMI) { + printk(KERN_INFO + "qla1280: Skipping AMI SubSys Vendor ID Chip\n"); + goto error; + } + + printk(KERN_INFO "qla1280: %s found on PCI bus %i, dev %i\n", + bdp->name, pdev->bus->number, PCI_SLOT(pdev->devfn)); + + if (pci_enable_device(pdev)) { + printk(KERN_WARNING + "qla1280: Failed to enabled pci device, aborting.\n"); + goto error; + } + + pci_set_master(pdev); + + error = -ENOMEM; + host = scsi_host_alloc(&qla1280_driver_template, sizeof(*ha)); + if (!host) { + printk(KERN_WARNING + "qla1280: Failed to register host, aborting.\n"); + goto error_disable_device; + } + + ha = (struct scsi_qla_host *)host->hostdata; + memset(ha, 0, sizeof(struct scsi_qla_host)); + + ha->pdev = pdev; + ha->devnum = devnum; /* specifies microcode load address */ + + ha->request_ring = pci_alloc_consistent(ha->pdev, + ((REQUEST_ENTRY_CNT + 1) * (sizeof(request_t))), + &ha->request_dma); + if (!ha->request_ring) { + printk(KERN_INFO "qla1280: Failed to get request memory\n"); + goto error_put_host; + } + + ha->response_ring = pci_alloc_consistent(ha->pdev, + ((RESPONSE_ENTRY_CNT + 1) * (sizeof(struct response))), + &ha->response_dma); + if (!ha->response_ring) { + printk(KERN_INFO "qla1280: Failed to get response memory\n"); + goto error_free_request_ring; + } + + ha->ports = bdp->numPorts; + + ha->host = host; + ha->host_no = host->host_no; + + host->irq = pdev->irq; + host->max_channel = bdp->numPorts - 1; + host->max_lun = MAX_LUNS - 1; + host->max_id = MAX_TARGETS; + host->max_sectors = 1024; + host->unique_id = host->host_no; + +#if LINUX_VERSION_CODE < 0x020545 + host->select_queue_depths = qla1280_select_queue_depth; +#endif + + error = -ENODEV; + +#if MEMORY_MAPPED_IO + ha->mmpbase = ioremap(pci_resource_start(ha->pdev, 1), + pci_resource_len(ha->pdev, 1)); + if (!ha->mmpbase) { + printk(KERN_INFO "qla1280: Unable to map I/O memory\n"); + goto error_free_response_ring; + } + + host->base = (unsigned long)ha->mmpbase; + ha->iobase = (struct device_reg *)ha->mmpbase; +#else + host->io_port = pci_resource_start(ha->pdev, 0); + if (!request_region(host->io_port, 0xff, "qla1280")) { + printk(KERN_INFO "qla1280: Failed to reserve i/o region " + "0x%04lx-0x%04lx - already in use\n", + host->io_port, host->io_port + 0xff); + goto error_free_response_ring; + } + + ha->iobase = (struct device_reg *)host->io_port; +#endif + + INIT_LIST_HEAD(&ha->done_q); + + /* Disable ISP interrupts. */ + qla1280_disable_intrs(ha); + + if (request_irq(pdev->irq, qla1280_intr_handler, SA_SHIRQ, + "qla1280", ha)) { + printk("qla1280 : Failed to reserve interrupt %d already " + "in use\n", pdev->irq); + goto error_release_region; + } + + /* load the F/W, read paramaters, and init the H/W */ + if (qla1280_initialize_adapter(ha)) { + printk(KERN_INFO "qla1x160: Failed to initialize adapter\n"); + goto error_free_irq; + } + + /* set our host ID (need to do something about our two IDs) */ + host->this_id = ha->bus_settings[0].id; + + pci_set_drvdata(pdev, host); + +#if LINUX_VERSION_CODE >= 0x020600 + error = scsi_add_host(host, &pdev->dev); + if (error) + goto error_disable_adapter; + scsi_scan_host(host); +#else + scsi_set_pci_device(host, pdev); +#endif + + return 0; + +#if LINUX_VERSION_CODE >= 0x020600 + error_disable_adapter: + WRT_REG_WORD(&ha->iobase->ictrl, 0); +#endif + error_release_region: +#if MEMORY_MAPPED_IO + iounmap(ha->mmpbase); +#else + release_region(host->io_port, 0xff); +#endif + error_free_irq: + free_irq(pdev->irq, ha); + error_free_response_ring: + pci_free_consistent(ha->pdev, + ((RESPONSE_ENTRY_CNT + 1) * (sizeof(struct response))), + ha->response_ring, ha->response_dma); + error_free_request_ring: + pci_free_consistent(ha->pdev, + ((REQUEST_ENTRY_CNT + 1) * (sizeof(request_t))), + ha->request_ring, ha->request_dma); + error_put_host: + scsi_host_put(host); + error_disable_device: + pci_disable_device(pdev); + error: + return error; +} + + +#if defined(CONFIG_SCSI_QLOGIC_1280_MODULE) || (LINUX_VERSION_CODE < 0x020600) +static void __devexit +qla1280_remove_one(struct pci_dev *pdev) +{ + struct Scsi_Host *host = pci_get_drvdata(pdev); + struct scsi_qla_host *ha = (struct scsi_qla_host *)host->hostdata; + +#if LINUX_VERSION_CODE >= 0x020600 + scsi_remove_host(host); +#endif + + WRT_REG_WORD(&ha->iobase->ictrl, 0); + + free_irq(pdev->irq, ha); + +#if MEMORY_MAPPED_IO + iounmap(ha->mmpbase); +#else + release_region(host->io_port, 0xff); +#endif + + pci_free_consistent(ha->pdev, + ((REQUEST_ENTRY_CNT + 1) * (sizeof(request_t))), + ha->request_ring, ha->request_dma); + pci_free_consistent(ha->pdev, + ((RESPONSE_ENTRY_CNT + 1) * (sizeof(struct response))), + ha->response_ring, ha->response_dma); + + pci_disable_device(pdev); + + scsi_host_put(host); +} #endif + +#if LINUX_VERSION_CODE >= 0x020600 +static struct pci_driver qla1280_pci_driver = { + .name = "qla1280", + .id_table = qla1280_pci_tbl, + .probe = qla1280_probe_one, + .remove = __devexit_p(qla1280_remove_one), }; -#include "scsi_module.c" +static int __init +qla1280_init(void) +{ + if (sizeof(struct srb) > sizeof(struct scsi_pointer)) { + printk(KERN_WARNING + "qla1280: struct srb too big, aborting\n"); + return -EINVAL; + } + +#ifdef MODULE + /* + * If we are called as a module, the qla1280 pointer may not be null + * and it would point to our bootup string, just like on the lilo + * command line. IF not NULL, then process this config string with + * qla1280_setup + * + * Boot time Options + * To add options at boot time add a line to your lilo.conf file like: + * append="qla1280=verbose,max_tags:{{255,255,255,255},{255,255,255,255}}" + * which will result in the first four devices on the first two + * controllers being set to a tagged queue depth of 32. + */ + if (qla1280) + qla1280_setup(qla1280); +#endif + + return pci_module_init(&qla1280_pci_driver); +} + +static void __exit +qla1280_exit(void) +{ + pci_unregister_driver(&qla1280_pci_driver); +} + +module_init(qla1280_init); +module_exit(qla1280_exit); +#else +# define driver_template qla1280_driver_template +# include "scsi_module.c" +#endif + +MODULE_AUTHOR("Qlogic & Jes Sorensen"); +MODULE_DESCRIPTION("Qlogic ISP SCSI (qla1x80/qla1x160) driver"); +MODULE_LICENSE("GPL"); /* * Overrides for Emacs so that we almost follow Linus's tabbing style. diff -puN drivers/scsi/qla1280.h~qla1280-update-2 drivers/scsi/qla1280.h --- 25/drivers/scsi/qla1280.h~qla1280-update-2 2004-01-06 08:02:26.000000000 -0800 +++ 25-akpm/drivers/scsi/qla1280.h 2004-01-06 08:02:26.000000000 -0800 @@ -17,8 +17,8 @@ * ******************************************************************************/ -#ifndef _IO_HBA_QLA1280_H /* wrapper symbol for kernel use */ -#define _IO_HBA_QLA1280_H /* subject to change without notice */ +#ifndef _QLA1280_H +#define _QLA1280_H /* * Data bit definitions. @@ -100,55 +100,23 @@ * on cmd->SCp location of every I/O */ struct srb { - Scsi_Cmnd *cmd; /* (4/8) SCSI command block */ - struct srb *s_next; /* (4/8) Next block on LU queue */ - struct srb *s_prev; /* (4/8) Previous block on LU queue */ - uint8_t flags; /* (1) Status flags. */ - uint8_t dir; /* direction of transfer */ - /* - * This should be moved around to save space. - */ - dma_addr_t saved_dma_handle; /* for unmap of single transfers */ + struct list_head list; /* (8/16) LU queue */ + struct scsi_cmnd *cmd; /* (4/8) SCSI command block */ /* NOTE: the sp->cmd will be NULL when this completion is * called, so you should know the scsi_cmnd when using this */ struct completion *wait; + dma_addr_t saved_dma_handle; /* for unmap of single transfers */ + uint8_t flags; /* (1) Status flags. */ + uint8_t dir; /* direction of transfer */ }; /* * SRB flag definitions */ -#define SRB_TIMEOUT BIT_0 /* Command timed out */ -#define SRB_SENT BIT_1 /* Command sent to ISP */ -#define SRB_ABORT_PENDING BIT_2 /* Command abort sent to device */ -#define SRB_ABORTED BIT_3 /* Command aborted command already */ - -/* - * Logical Unit Queue structure - */ -struct scsi_lu { - struct srb *q_first; /* First block on LU queue */ - struct srb *q_last; /* Last block on LU queue */ - uint8_t q_flag; /* LU queue state flags */ - uint8_t q_sense[16]; /* sense data */ - unsigned long io_cnt; /* total xfer count */ - unsigned long resp_time;/* total response time (start - finish) */ - unsigned long act_time; /* total actived time (minus queuing time) */ - unsigned long w_cnt; /* total writes */ - unsigned long r_cnt; /* total reads */ - uint16_t q_outcnt; /* Pending jobs for this LU */ -}; - -/* - * Logical Unit flags - */ -#define QLA1280_QBUSY BIT_0 -#define QLA1280_QWAIT BIT_1 -#define QLA1280_QSUSP BIT_2 -#define QLA1280_QSENSE BIT_3 /* Sense data cache valid */ -#define QLA1280_QRESET BIT_4 -#define QLA1280_QHBA BIT_5 -#define QLA1280_BSUSP BIT_6 /* controller is suspended */ -#define QLA1280_BREM BIT_7 /* controller is removed */ +#define SRB_TIMEOUT (1 << 0) /* Command timed out */ +#define SRB_SENT (1 << 1) /* Command sent to ISP */ +#define SRB_ABORT_PENDING (1 << 2) /* Command abort sent to device */ +#define SRB_ABORTED (1 << 3) /* Command aborted command already */ /* * ISP I/O Register Set structure definitions. @@ -1021,11 +989,7 @@ struct scsi_qla_host { unsigned char *mmpbase; /* memory mapped address */ unsigned long host_no; - unsigned long instance; struct pci_dev *pdev; - uint32_t device_id; - uint8_t pci_bus; - uint8_t pci_device_fn; uint8_t devnum; uint8_t revision; uint8_t ports; @@ -1040,18 +1004,9 @@ struct scsi_qla_host { /* BUS configuration data */ struct bus_param bus_settings[MAX_BUSES]; -#if 0 - /* bottom half run queue */ - struct tq_struct run_qla_bh; -#endif - /* Received ISP mailbox data. */ volatile uint16_t mailbox_out[MAILBOX_REGISTER_COUNT]; -#ifdef UNUSED - struct timer_list dev_timer[MAX_TARGETS]; -#endif - dma_addr_t request_dma; /* Physical Address */ request_t *request_ring; /* Base virtual address */ request_t *request_ring_ptr; /* Current address. */ @@ -1063,30 +1018,19 @@ struct scsi_qla_host { struct response *response_ring_ptr; /* Current address. */ uint16_t rsp_ring_index; /* Current index. */ -#if WATCHDOGTIMER - /* Watchdog queue, lock and total timer */ - uint8_t watchdog_q_lock; /* Lock for watchdog queue */ - struct srb *wdg_q_first; /* First job on watchdog queue */ - struct srb *wdg_q_last; /* Last job on watchdog queue */ - uint32_t total_timeout; /* Total timeout (quantum count) */ - uint32_t watchdogactive; -#endif - - struct srb *done_q_first; /* First job on done queue */ - struct srb *done_q_last; /* Last job on done queue */ + struct list_head done_q; /* Done queue */ struct completion *mailbox_wait; volatile struct { - uint32_t mbox_busy:1; /* 0 */ - uint32_t online:1; /* 1 */ - uint32_t reset_marker:1; /* 2 */ - uint32_t disable_host_adapter:1; /* 4 */ - uint32_t reset_active:1; /* 5 */ - uint32_t abort_isp_active:1; /* 6 */ - uint32_t disable_risc_code_load:1; /* 7 */ - uint32_t enable_64bit_addressing:1; /* 8 */ - uint32_t in_reset:1; /* 9 */ + uint32_t online:1; /* 0 */ + uint32_t reset_marker:1; /* 1 */ + uint32_t disable_host_adapter:1; /* 2 */ + uint32_t reset_active:1; /* 3 */ + uint32_t abort_isp_active:1; /* 4 */ + uint32_t disable_risc_code_load:1; /* 5 */ + uint32_t enable_64bit_addressing:1; /* 6 */ + uint32_t in_reset:1; /* 7 */ uint32_t ints_enabled:1; uint32_t ignore_nvram:1; #ifdef __ia64__ @@ -1098,10 +1042,4 @@ struct scsi_qla_host { int nvram_valid; }; -/* - * Macros to help code, maintain, etc. - */ -#define SUBDEV(b, t, l) ((b << (MAX_T_BITS + MAX_L_BITS)) | (t << MAX_L_BITS) | l) -#define LU_Q(ha, b, t, l) (ha->dev[SUBDEV(b, t, l)]) - -#endif /* _IO_HBA_QLA1280_H */ +#endif /* _QLA1280_H */ _