vserver 1.9.5.x5
[linux-2.6.git] / drivers / scsi / qla1280.c
index c4820cf..df89d2b 100644 (file)
 * General Public License for more details.
 *
 ******************************************************************************/
-#define QLA1280_VERSION      "3.24.4"
+#define QLA1280_VERSION      "3.25"
 /*****************************************************************************
     Revision History:
+    Rev  3.25, September 28, 2004, Christoph Hellwig
+       - add support for ISP1020/1040
+       - don't include "scsi.h" anymore for 2.6.x
     Rev  3.24.4 June 7, 2004 Christoph Hellwig
        - restructure firmware loading, cleanup initialization code
        - prepare support for ISP1020/1040 chips
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_tcq.h>
-#include "scsi.h"
 #else
 #include <linux/blk.h>
 #include "scsi.h"
 #include "sd.h"
 #endif
 
+#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2)
+#include <asm/sn/io.h>
+#endif
+
 #if LINUX_VERSION_CODE < 0x020407
 #error "Kernels older than 2.4.7 are no longer supported"
 #endif
 #include "qla1280.h"
 #include "ql12160_fw.h"                /* ISP RISC codes */
 #include "ql1280_fw.h"
+#include "ql1040_fw.h"
 
 
 /*
 #define QLA_64BIT_PTR  1
 #endif
 
-#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2)
-#include <asm/sn/pci/pciio.h>
-/* Ugly hack needed for the virtual channel fix on SN2 */
-extern int snia_pcibr_rrb_alloc(struct pci_dev *pci_dev,
-                               int *count_vchan0, int *count_vchan1);
-#endif
-
 #ifdef QLA_64BIT_PTR
 #define pci_dma_hi32(a)                        ((a >> 16) >> 16)
 #else
@@ -540,7 +540,7 @@ static void qla1280_error_entry(struct scsi_qla_host *, struct response *,
                                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 uint16_t qla1280_debounce_register(volatile uint16_t __iomem *);
 static request_t *qla1280_req_pkt(struct scsi_qla_host *);
 static int qla1280_check_for_dead_scsi_bus(struct scsi_qla_host *,
                                           unsigned int);
@@ -549,7 +549,7 @@ static void qla1280_get_target_parameters(struct scsi_qla_host *,
 static int qla1280_set_target_parameters(struct scsi_qla_host *, int, int);
 
 
-static struct qla_driver_setup driver_setup __initdata;
+static struct qla_driver_setup driver_setup;
 
 /*
  * convert scsi data direction to request_t control flags
@@ -588,7 +588,7 @@ static void __qla1280_dump_buffer(char *, int);
 static char *qla1280;
 
 /* insmod qla1280 options=verbose" */
-MODULE_PARM(qla1280, "s");
+module_param(qla1280, charp, 0);
 #else
 __setup("qla1280=", qla1280_setup);
 #endif
@@ -632,18 +632,22 @@ struct qla_boards {
        unsigned char *fwver;   /* Ptr to F/W version array    */
 };
 
-/* NOTE: qla1280_pci_tbl and ql1280_board_tbl must be in the same order */
+/* NOTE: the last argument in each entry is used to index ql1280_board_tbl */
 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,
+#ifdef CONFIG_SCSI_QLOGIC_1280_1040
+       {PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP1020,
                PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
-       {PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP1240,
+#endif
+       {PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP1080,
                PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2},
-       {PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP1280,
+       {PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP1240,
                PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3},
-       {PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP10160,
+       {PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP1280,
                PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4},
+       {PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP10160,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5},
        {0,}
 };
 MODULE_DEVICE_TABLE(pci, qla1280_pci_tbl);
@@ -652,6 +656,8 @@ 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]},
+       {"QLA1040", 1, &risc_code01[0], &risc_code_length01,
+        &risc_code_addr01, &firmware_version[0]},
        {"QLA1080", 1, &fw1280ei_code01[0], &fw1280ei_length01,
         &fw1280ei_addr01, &fw1280ei_version_str[0]},
        {"QLA1240", 2, &fw1280ei_code01[0], &fw1280ei_length01,
@@ -943,7 +949,7 @@ static void qla1280_error_wait_timeout(unsigned long __data)
 static void qla1280_mailbox_timeout(unsigned long __data)
 {
        struct scsi_qla_host *ha = (struct scsi_qla_host *)__data;
-       struct device_reg *reg;
+       struct device_reg __iomem *reg;
        reg = ha->iobase;
 
        ha->mailbox_out[0] = RD_REG_WORD(&reg->mailbox0);
@@ -1354,7 +1360,7 @@ static irqreturn_t
 qla1280_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
 {
        struct scsi_qla_host *ha;
-       struct device_reg *reg;
+       struct device_reg __iomem *reg;
        u16 data;
        int handled = 0;
 
@@ -1710,7 +1716,7 @@ qla1280_return_status(struct response * sts, struct scsi_cmnd *cp)
 static inline void
 qla1280_enable_intrs(struct scsi_qla_host *ha)
 {
-       struct device_reg *reg;
+       struct device_reg __iomem *reg;
 
        reg = ha->iobase;
        /* enable risc and host interrupts */
@@ -1722,7 +1728,7 @@ qla1280_enable_intrs(struct scsi_qla_host *ha)
 static inline void
 qla1280_disable_intrs(struct scsi_qla_host *ha)
 {
-       struct device_reg *reg;
+       struct device_reg __iomem *reg;
 
        reg = ha->iobase;
        /* disable risc and host interrupts */
@@ -1744,7 +1750,7 @@ qla1280_disable_intrs(struct scsi_qla_host *ha)
 static int __devinit
 qla1280_initialize_adapter(struct scsi_qla_host *ha)
 {
-       struct device_reg *reg;
+       struct device_reg __iomem *reg;
        int status;
        int bus;
 #if LINUX_VERSION_CODE > 0x020500
@@ -1762,23 +1768,17 @@ qla1280_initialize_adapter(struct scsi_qla_host *ha)
        ha->flags.ints_enabled = 0;
 #if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2)
        if (ia64_platform_is("sn2")) {
-               int count1, count2;
-               int c;
-
-               count1 = 3;
-               count2 = 3;
                printk(KERN_INFO "scsi(%li): Enabling SN2 PCI DMA "
                       "dual channel lockup workaround\n", ha->host_no);
-               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);
-               else
-                       ha->flags.use_pci_vchannel = 1;
-
+               ha->flags.use_pci_vchannel = 1;
                driver_setup.no_nvram = 1;
        }
 #endif
 
+       /* TODO: implement support for the 1040 nvram format */
+       if (IS_ISP1040(ha))
+               driver_setup.no_nvram = 1;
+
        dprintk(1, "Configure PCI space for adapter...\n");
 
        reg = ha->iobase;
@@ -1921,7 +1921,7 @@ static int
 qla1280_chip_diag(struct scsi_qla_host *ha)
 {
        uint16_t mb[MAILBOX_REGISTER_COUNT];
-       struct device_reg *reg = ha->iobase;
+       struct device_reg __iomem *reg = ha->iobase;
        int status = 0;
        int cnt;
        uint16_t data;
@@ -2339,9 +2339,7 @@ qla1280_set_target_defaults(struct scsi_qla_host *ha, int bus, int target)
 #if 1  /* Some SCSI Processors do not seem to like this */
        nv->bus[bus].target[target].parameter.f.enable_wide = 1;
 #endif
-       if (!IS_ISP1040(ha))
-               nv->bus[bus].target[target].parameter.f.parity_checking = 1;
-
+       nv->bus[bus].target[target].parameter.f.parity_checking = 1;
        nv->bus[bus].target[target].parameter.f.disconnect_allowed = 1;
        nv->bus[bus].target[target].execution_throttle =
                nv->bus[bus].max_queue_depth - 1;
@@ -2515,7 +2513,7 @@ qla1280_config_bus(struct scsi_qla_host *ha, int bus)
 static int
 qla1280_nvram_config(struct scsi_qla_host *ha)
 {
-       struct device_reg *reg = ha->iobase;
+       struct device_reg __iomem *reg = ha->iobase;
        struct nvram *nv = &ha->nvram;
        int bus, target, status = 0;
        uint16_t mb[MAILBOX_REGISTER_COUNT];
@@ -2701,7 +2699,7 @@ qla1280_get_nvram_word(struct scsi_qla_host *ha, uint32_t address)
 static uint16_t
 qla1280_nvram_request(struct scsi_qla_host *ha, uint32_t nv_cmd)
 {
-       struct device_reg *reg = ha->iobase;
+       struct device_reg __iomem *reg = ha->iobase;
        int cnt;
        uint16_t data = 0;
        uint16_t reg_data;
@@ -2744,7 +2742,7 @@ qla1280_nvram_request(struct scsi_qla_host *ha, uint32_t nv_cmd)
 static void
 qla1280_nv_write(struct scsi_qla_host *ha, uint16_t data)
 {
-       struct device_reg *reg = ha->iobase;
+       struct device_reg __iomem *reg = ha->iobase;
 
        WRT_REG_WORD(&reg->nvram, data | NV_SELECT);
        RD_REG_WORD(&reg->id_l);        /* Flush PCI write */
@@ -2775,13 +2773,14 @@ qla1280_nv_write(struct scsi_qla_host *ha, uint16_t data)
 static int
 qla1280_mailbox_command(struct scsi_qla_host *ha, uint8_t mr, uint16_t *mb)
 {
-       struct device_reg *reg = ha->iobase;
+       struct device_reg __iomem *reg = ha->iobase;
 #if 0
        LIST_HEAD(done_q);
 #endif
        int status = 0;
        int cnt;
        uint16_t *optr, *iptr;
+       uint16_t __iomem *mptr;
        uint16_t data;
        DECLARE_COMPLETION(wait);
        struct timer_list timer;
@@ -2798,15 +2797,15 @@ qla1280_mailbox_command(struct scsi_qla_host *ha, uint8_t mr, uint16_t *mb)
         * available before starting sending the command data
         */
        /* Load mailbox registers. */
-       optr = (uint16_t *) &reg->mailbox0;
+       mptr = (uint16_t __iomem *) &reg->mailbox0;
        iptr = mb;
        for (cnt = 0; cnt < MAILBOX_REGISTER_COUNT; cnt++) {
                if (mr & BIT_0) {
-                       WRT_REG_WORD(optr, (*iptr));
+                       WRT_REG_WORD(mptr, (*iptr));
                }
 
                mr >>= 1;
-               optr++;
+               mptr++;
                iptr++;
        }
 
@@ -2882,7 +2881,7 @@ qla1280_mailbox_command(struct scsi_qla_host *ha, uint8_t mr, uint16_t *mb)
 static void
 qla1280_poll(struct scsi_qla_host *ha)
 {
-       struct device_reg *reg = ha->iobase;
+       struct device_reg __iomem *reg = ha->iobase;
        uint16_t data;
        LIST_HEAD(done_q);
 
@@ -3085,7 +3084,7 @@ qla1280_abort_command(struct scsi_qla_host *ha, struct srb * sp, int handle)
 static void
 qla1280_reset_adapter(struct scsi_qla_host *ha)
 {
-       struct device_reg *reg = ha->iobase;
+       struct device_reg __iomem *reg = ha->iobase;
 
        ENTER("qla1280_reset_adapter");
 
@@ -3149,7 +3148,7 @@ qla1280_marker(struct scsi_qla_host *ha, int bus, int id, int lun, u8 type)
 static int
 qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
 {
-       struct device_reg *reg = ha->iobase;
+       struct device_reg __iomem *reg = ha->iobase;
        struct scsi_cmnd *cmd = sp->cmd;
        cmd_a64_entry_t *pkt;
        struct scatterlist *sg = NULL;
@@ -3272,7 +3271,8 @@ qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
                                dma_handle = sg_dma_address(sg);
 #if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2)
                                if (ha->flags.use_pci_vchannel)
-                                       sn_pci_set_vchan(ha->pdev, &dma_handle,
+                                       sn_pci_set_vchan(ha->pdev,
+                                                       (unsigned long *)&dma_handle,
                                                         SCSI_BUS_32(cmd));
 #endif
                                *dword_ptr++ =
@@ -3330,7 +3330,8 @@ qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
                                        dma_handle = sg_dma_address(sg);
 #if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2)
                                if (ha->flags.use_pci_vchannel)
-                                       sn_pci_set_vchan(ha->pdev, &dma_handle,
+                                       sn_pci_set_vchan(ha->pdev, 
+                                                       (unsigned long *)&dma_handle,
                                                         SCSI_BUS_32(cmd));
 #endif
                                        *dword_ptr++ =
@@ -3364,7 +3365,8 @@ qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
                        sp->saved_dma_handle = dma_handle;
 #if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2)
                        if (ha->flags.use_pci_vchannel)
-                               sn_pci_set_vchan(ha->pdev, &dma_handle,
+                               sn_pci_set_vchan(ha->pdev, 
+                                               (unsigned long *)&dma_handle,
                                                 SCSI_BUS_32(cmd));
 #endif
                        *dword_ptr++ = cpu_to_le32(pci_dma_lo32(dma_handle));
@@ -3398,7 +3400,8 @@ qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
        sp->flags |= SRB_SENT;
        ha->actthreads++;
        WRT_REG_WORD(&reg->mailbox4, ha->req_ring_index);
-       (void) RD_REG_WORD(&reg->mailbox4); /* PCI posted write flush */
+       /* Enforce mmio write ordering; see comment in qla1280_isp_cmd(). */
+       mmiowb();
 
  out:
        if (status)
@@ -3432,7 +3435,7 @@ qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
 static int
 qla1280_32bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
 {
-       struct device_reg *reg = ha->iobase;
+       struct device_reg __iomem *reg = ha->iobase;
        struct scsi_cmnd *cmd = sp->cmd;
        struct cmd_entry *pkt;
        struct scatterlist *sg = NULL;
@@ -3666,7 +3669,8 @@ qla1280_32bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
        sp->flags |= SRB_SENT;
        ha->actthreads++;
        WRT_REG_WORD(&reg->mailbox4, ha->req_ring_index);
-       (void) RD_REG_WORD(&reg->mailbox4); /* PCI posted write flush */
+       /* Enforce mmio write ordering; see comment in qla1280_isp_cmd(). */
+       mmiowb();
 
 out:
        if (status)
@@ -3692,7 +3696,7 @@ out:
 static request_t *
 qla1280_req_pkt(struct scsi_qla_host *ha)
 {
-       struct device_reg *reg = ha->iobase;
+       struct device_reg __iomem *reg = ha->iobase;
        request_t *pkt = NULL;
        int cnt;
        uint32_t timer;
@@ -3760,7 +3764,7 @@ qla1280_req_pkt(struct scsi_qla_host *ha)
 static void
 qla1280_isp_cmd(struct scsi_qla_host *ha)
 {
-       struct device_reg *reg = ha->iobase;
+       struct device_reg __iomem *reg = ha->iobase;
 
        ENTER("qla1280_isp_cmd");
 
@@ -3776,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(&reg->mailbox4, ha->req_ring_index);
-       (void) RD_REG_WORD(&reg->mailbox4); /* PCI posted write flush */
+       mmiowb();
 
        LEAVE("qla1280_isp_cmd");
 }
@@ -3798,7 +3814,7 @@ qla1280_isp_cmd(struct scsi_qla_host *ha)
 static void
 qla1280_isr(struct scsi_qla_host *ha, struct list_head *done_q)
 {
-       struct device_reg *reg = ha->iobase;
+       struct device_reg __iomem *reg = ha->iobase;
        struct response *pkt;
        struct srb *sp = NULL;
        uint16_t mailbox[MAILBOX_REGISTER_COUNT];
@@ -4257,7 +4273,7 @@ qla1280_error_entry(struct scsi_qla_host *ha, struct response *pkt,
 static int
 qla1280_abort_isp(struct scsi_qla_host *ha)
 {
-       struct device_reg *reg = ha->iobase;
+       struct device_reg __iomem *reg = ha->iobase;
        struct srb *sp;
        int status = 0;
        int cnt;
@@ -4335,7 +4351,7 @@ qla1280_abort_isp(struct scsi_qla_host *ha)
  *      register value.
  */
 static u16
-qla1280_debounce_register(volatile u16 * addr)
+qla1280_debounce_register(volatile u16 __iomem * addr)
 {
        volatile u16 ret;
        volatile u16 ret2;
@@ -4367,7 +4383,7 @@ static int
 qla1280_check_for_dead_scsi_bus(struct scsi_qla_host *ha, unsigned int bus)
 {
        uint16_t config_reg, scsi_control;
-       struct device_reg *reg = ha->iobase;
+       struct device_reg __iomem *reg = ha->iobase;
 
        if (ha->bus_settings[bus].scsi_bus_dead) {
                WRT_REG_WORD(&reg->host_cmd, HC_PAUSE_RISC);
@@ -4641,6 +4657,7 @@ qla1280_get_token(char *str)
 
 #if LINUX_VERSION_CODE >= 0x020600
 static struct scsi_host_template qla1280_driver_template = {
+       .module                 = THIS_MODULE,
        .proc_name              = "qla1280",
        .name                   = "Qlogic ISP 1280/12160",
        .info                   = qla1280_info,
@@ -4785,7 +4802,7 @@ qla1280_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
        }
 
        host->base = (unsigned long)ha->mmpbase;
-       ha->iobase = (struct device_reg *)ha->mmpbase;
+       ha->iobase = (struct device_reg __iomem *)ha->mmpbase;
 #else
        host->io_port = pci_resource_start(ha->pdev, 0);
        if (!request_region(host->io_port, 0xff, "qla1280")) {