X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fscsi%2Fqla1280.c;h=df89d2b7c30feae3d13e951e7f7c19a9bd77b157;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=c4820cfde08ac9da4cb216c3c0ccc1d79e82b02b;hpb=87fc8d1bb10cd459024a742c6a10961fefcef18f;p=linux-2.6.git diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c index c4820cfde..df89d2b7c 100644 --- a/drivers/scsi/qla1280.c +++ b/drivers/scsi/qla1280.c @@ -17,9 +17,12 @@ * 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 @@ -356,7 +359,6 @@ #include #include #include -#include "scsi.h" #else #include #include "scsi.h" @@ -364,6 +366,10 @@ #include "sd.h" #endif +#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2) +#include +#endif + #if LINUX_VERSION_CODE < 0x020407 #error "Kernels older than 2.4.7 are no longer supported" #endif @@ -390,6 +396,7 @@ #include "qla1280.h" #include "ql12160_fw.h" /* ISP RISC codes */ #include "ql1280_fw.h" +#include "ql1040_fw.h" /* @@ -422,13 +429,6 @@ #define QLA_64BIT_PTR 1 #endif -#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2) -#include -/* 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(®->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(®->nvram, data | NV_SELECT); RD_REG_WORD(®->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 *) ®->mailbox0; + mptr = (uint16_t __iomem *) ®->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(®->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) @@ -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(®->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) @@ -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(®->mailbox4, ha->req_ring_index); - (void) RD_REG_WORD(®->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(®->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")) {