diff options
Diffstat (limited to 'drivers/scsi/qla2xxx')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_attr.c | 9 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_def.h | 1 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_devtbl.h | 7 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_iocb.c | 2 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_isr.c | 8 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_mbx.c | 2 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_os.c | 50 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_sup.c | 30 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_version.h | 2 |
9 files changed, 75 insertions, 36 deletions
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index 05fa7796a559..fb388b8c07cf 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c @@ -114,7 +114,6 @@ qla2x00_sysfs_write_nvram(struct kobject *kobj, { struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj, struct device, kobj))); - unsigned long flags; uint16_t cnt; if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->nvram_size) @@ -144,11 +143,9 @@ qla2x00_sysfs_write_nvram(struct kobject *kobj, } /* Write NVRAM. */ - spin_lock_irqsave(&ha->hardware_lock, flags); ha->isp_ops->write_nvram(ha, (uint8_t *)buf, ha->nvram_base, count); ha->isp_ops->read_nvram(ha, (uint8_t *)ha->nvram, ha->nvram_base, count); - spin_unlock_irqrestore(&ha->hardware_lock, flags); set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); @@ -397,16 +394,13 @@ qla2x00_sysfs_write_vpd(struct kobject *kobj, { struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj, struct device, kobj))); - unsigned long flags; if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->vpd_size) return 0; /* Write NVRAM. */ - spin_lock_irqsave(&ha->hardware_lock, flags); ha->isp_ops->write_nvram(ha, (uint8_t *)buf, ha->vpd_base, count); ha->isp_ops->read_nvram(ha, (uint8_t *)ha->vpd, ha->vpd_base, count); - spin_unlock_irqrestore(&ha->hardware_lock, flags); return count; } @@ -544,6 +538,9 @@ qla2x00_serial_num_show(struct class_device *cdev, char *buf) scsi_qla_host_t *ha = shost_priv(class_to_shost(cdev)); uint32_t sn; + if (IS_FWI2_CAPABLE(ha)) + return snprintf(buf, PAGE_SIZE, "\n"); + sn = ((ha->serial0 & 0x1f) << 16) | (ha->serial2 << 8) | ha->serial1; return snprintf(buf, PAGE_SIZE, "%c%05d\n", 'A' + sn / 100000, sn % 100000); diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 1900fbf6cd74..04e8cbca4c0d 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -2271,6 +2271,7 @@ typedef struct scsi_qla_host { spinlock_t hardware_lock ____cacheline_aligned; + int bars; device_reg_t __iomem *iobase; /* Base I/O address */ unsigned long pio_address; unsigned long pio_length; diff --git a/drivers/scsi/qla2xxx/qla_devtbl.h b/drivers/scsi/qla2xxx/qla_devtbl.h index dd435410dfa2..d78d35e681ab 100644 --- a/drivers/scsi/qla2xxx/qla_devtbl.h +++ b/drivers/scsi/qla2xxx/qla_devtbl.h @@ -1,4 +1,4 @@ -#define QLA_MODEL_NAMES 0x57 +#define QLA_MODEL_NAMES 0x5C /* * Adapter model names and descriptions. @@ -91,4 +91,9 @@ static char *qla2x00_model_name[QLA_MODEL_NAMES*2] = { " ", " ", /* 0x154 */ "QLE220", "PCI-Express to 4Gb FC, Single Channel", /* 0x155 */ "QLE220", "PCI-Express to 4Gb FC, Single Channel", /* 0x156 */ + " ", " ", /* 0x157 */ + " ", " ", /* 0x158 */ + " ", " ", /* 0x159 */ + " ", " ", /* 0x15a */ + "QME2472", "Dell BS PCI-Express to 4Gb FC, Dual Channel", /* 0x15b */ }; diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index 7f6a89bd94f3..024c662ec34d 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c @@ -525,7 +525,7 @@ qla2x00_req_pkt(scsi_qla_host_t *ha) /* Check for pending interrupts. */ /* During init we issue marker directly */ - if (!ha->marker_needed) + if (!ha->marker_needed && !ha->flags.init_done) qla2x00_poll(ha); spin_lock_irq(&ha->hardware_lock); diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index c4768c4f3990..1104bd2eed40 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -1012,8 +1012,14 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt) case CS_DATA_UNDERRUN: resid = resid_len; /* Use F/W calculated residual length. */ - if (IS_FWI2_CAPABLE(ha)) + if (IS_FWI2_CAPABLE(ha)) { + if (scsi_status & SS_RESIDUAL_UNDER && + resid != fw_resid_len) { + scsi_status &= ~SS_RESIDUAL_UNDER; + lscsi_status = 0; + } resid = fw_resid_len; + } if (scsi_status & SS_RESIDUAL_UNDER) { scsi_set_resid(cp, resid); diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index c53ec67c47f4..ccd662a6f5dc 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c @@ -252,7 +252,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *pvha, mbx_cmd_t *mcp) /* Clean up */ ha->mcp = NULL; - if (!abort_active) { + if (abort_active || !io_lock_on) { DEBUG11(printk("%s(%ld): checking for additional resp " "interrupt.\n", __func__, ha->host_no)); diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 0351d380c2d7..a5bcf1f390b3 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -1482,6 +1482,17 @@ qla2x00_iospace_config(scsi_qla_host_t *ha) unsigned long pio, pio_len, pio_flags; unsigned long mmio, mmio_len, mmio_flags; + if (pci_request_selected_regions(ha->pdev, ha->bars, + QLA2XXX_DRIVER_NAME)) { + qla_printk(KERN_WARNING, ha, + "Failed to reserve PIO/MMIO regions (%s)\n", + pci_name(ha->pdev)); + + goto iospace_error_exit; + } + if (!(ha->bars & 1)) + goto skip_pio; + /* We only need PIO for Flash operations on ISP2312 v2 chips. */ pio = pci_resource_start(ha->pdev, 0); pio_len = pci_resource_len(ha->pdev, 0); @@ -1499,7 +1510,10 @@ qla2x00_iospace_config(scsi_qla_host_t *ha) pci_name(ha->pdev)); pio = 0; } + ha->pio_address = pio; + ha->pio_length = pio_len; +skip_pio: /* Use MMIO operations for all accesses. */ mmio = pci_resource_start(ha->pdev, 1); mmio_len = pci_resource_len(ha->pdev, 1); @@ -1518,16 +1532,6 @@ qla2x00_iospace_config(scsi_qla_host_t *ha) goto iospace_error_exit; } - if (pci_request_regions(ha->pdev, QLA2XXX_DRIVER_NAME)) { - qla_printk(KERN_WARNING, ha, - "Failed to reserve PIO/MMIO regions (%s)\n", - pci_name(ha->pdev)); - - goto iospace_error_exit; - } - - ha->pio_address = pio; - ha->pio_length = pio_len; ha->iobase = ioremap(mmio, MIN_IOBASE_LEN); if (!ha->iobase) { qla_printk(KERN_ERR, ha, @@ -1579,21 +1583,26 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) char pci_info[30]; char fw_str[30]; struct scsi_host_template *sht; + int bars; - if (pci_enable_device(pdev)) - goto probe_out; - - if (pci_find_aer_capability(pdev)) - if (pci_enable_pcie_error_reporting(pdev)) - goto probe_out; - + bars = pci_select_bars(pdev, IORESOURCE_MEM | IORESOURCE_IO); sht = &qla2x00_driver_template; if (pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2422 || pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2432 || pdev->device == PCI_DEVICE_ID_QLOGIC_ISP5422 || pdev->device == PCI_DEVICE_ID_QLOGIC_ISP5432 || - pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2532) + pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2532) { + bars = pci_select_bars(pdev, IORESOURCE_MEM); sht = &qla24xx_driver_template; + } + + if (pci_enable_device_bars(pdev, bars)) + goto probe_out; + + if (pci_find_aer_capability(pdev)) + if (pci_enable_pcie_error_reporting(pdev)) + goto probe_out; + host = scsi_host_alloc(sht, sizeof(scsi_qla_host_t)); if (host == NULL) { printk(KERN_WARNING @@ -1610,6 +1619,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) ha->host_no = host->host_no; sprintf(ha->host_str, "%s_%ld", QLA2XXX_DRIVER_NAME, ha->host_no); ha->parent = NULL; + ha->bars = bars; /* Set ISP-type information. */ qla2x00_set_isp_flags(ha); @@ -1880,7 +1890,7 @@ qla2x00_free_device(scsi_qla_host_t *ha) /* release io space registers */ if (ha->iobase) iounmap(ha->iobase); - pci_release_regions(ha->pdev); + pci_release_selected_regions(ha->pdev, ha->bars); } static inline void @@ -2890,7 +2900,7 @@ qla2xxx_pci_slot_reset(struct pci_dev *pdev) pci_ers_result_t ret = PCI_ERS_RESULT_DISCONNECT; scsi_qla_host_t *ha = pci_get_drvdata(pdev); - if (pci_enable_device(pdev)) { + if (pci_enable_device_bars(pdev, ha->bars)) { qla_printk(KERN_WARNING, ha, "Can't re-enable PCI device after reset.\n"); diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c index 40b059fc1981..ad2fa01bd233 100644 --- a/drivers/scsi/qla2xxx/qla_sup.c +++ b/drivers/scsi/qla2xxx/qla_sup.c @@ -7,6 +7,7 @@ #include "qla_def.h" #include <linux/delay.h> +#include <linux/vmalloc.h> #include <asm/uaccess.h> static uint16_t qla2x00_nvram_request(scsi_qla_host_t *, uint32_t); @@ -642,7 +643,7 @@ qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr, } /* Go with burst-write. */ - if (optrom && (liter + OPTROM_BURST_DWORDS) < dwords) { + if (optrom && (liter + OPTROM_BURST_DWORDS) <= dwords) { /* Copy data to DMA'ble buffer. */ for (miter = 0, s = optrom, d = dwptr; miter < OPTROM_BURST_DWORDS; miter++, s++, d++) @@ -656,7 +657,7 @@ qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr, "Unable to burst-write optrom segment " "(%x/%x/%llx).\n", ret, flash_data_to_access_addr(faddr), - optrom_dma); + (unsigned long long)optrom_dma); qla_printk(KERN_WARNING, ha, "Reverting to slow-write.\n"); @@ -745,9 +746,11 @@ qla2x00_write_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr, int ret, stat; uint32_t i; uint16_t *wptr; + unsigned long flags; ret = QLA_SUCCESS; + spin_lock_irqsave(&ha->hardware_lock, flags); qla2x00_lock_nvram_access(ha); /* Disable NVRAM write-protection. */ @@ -764,6 +767,7 @@ qla2x00_write_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr, qla2x00_set_nvram_protection(ha, stat); qla2x00_unlock_nvram_access(ha); + spin_unlock_irqrestore(&ha->hardware_lock, flags); return ret; } @@ -776,9 +780,11 @@ qla24xx_write_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr, uint32_t i; uint32_t *dwptr; struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; + unsigned long flags; ret = QLA_SUCCESS; + spin_lock_irqsave(&ha->hardware_lock, flags); /* Enable flash write. */ WRT_REG_DWORD(®->ctrl_status, RD_REG_DWORD(®->ctrl_status) | CSRX_FLASH_ENABLE); @@ -812,6 +818,7 @@ qla24xx_write_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr, WRT_REG_DWORD(®->ctrl_status, RD_REG_DWORD(®->ctrl_status) & ~CSRX_FLASH_ENABLE); RD_REG_DWORD(®->ctrl_status); /* PCI Posting. */ + spin_unlock_irqrestore(&ha->hardware_lock, flags); return ret; } @@ -836,8 +843,20 @@ int qla25xx_write_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr, uint32_t bytes) { - return qla24xx_write_flash_data(ha, (uint32_t *)buf, - FA_VPD_NVRAM_ADDR | naddr, bytes >> 2); +#define RMW_BUFFER_SIZE (64 * 1024) + uint8_t *dbuf; + + dbuf = vmalloc(RMW_BUFFER_SIZE); + if (!dbuf) + return QLA_MEMORY_ALLOC_FAILED; + ha->isp_ops->read_optrom(ha, dbuf, FA_VPD_NVRAM_ADDR << 2, + RMW_BUFFER_SIZE); + memcpy(dbuf + (naddr << 2), buf, bytes); + ha->isp_ops->write_optrom(ha, dbuf, FA_VPD_NVRAM_ADDR << 2, + RMW_BUFFER_SIZE); + vfree(dbuf); + + return QLA_SUCCESS; } static inline void @@ -1853,7 +1872,8 @@ qla25xx_read_optrom_data(struct scsi_qla_host *ha, uint8_t *buf, qla_printk(KERN_WARNING, ha, "Unable to burst-read optrom segment " "(%x/%x/%llx).\n", rval, - flash_data_to_access_addr(faddr), optrom_dma); + flash_data_to_access_addr(faddr), + (unsigned long long)optrom_dma); qla_printk(KERN_WARNING, ha, "Reverting to slow-read.\n"); diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h index 2d551a3006f6..ae6f7a2fb19f 100644 --- a/drivers/scsi/qla2xxx/qla_version.h +++ b/drivers/scsi/qla2xxx/qla_version.h @@ -7,7 +7,7 @@ /* * Driver version */ -#define QLA2XXX_VERSION "8.02.00-k4" +#define QLA2XXX_VERSION "8.02.00-k5" #define QLA_DRIVER_MAJOR_VER 8 #define QLA_DRIVER_MINOR_VER 2 |