diff options
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_init.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_init.c | 206 |
1 files changed, 102 insertions, 104 deletions
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index cc6ebb609e9..1a058ec9bd0 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -79,20 +79,20 @@ qla2x00_initialize_adapter(scsi_qla_host_t *ha) set_bit(REGISTER_FDMI_NEEDED, &ha->dpc_flags); qla_printk(KERN_INFO, ha, "Configuring PCI space...\n"); - rval = ha->isp_ops.pci_config(ha); + rval = ha->isp_ops->pci_config(ha); if (rval) { DEBUG2(printk("scsi(%ld): Unable to configure PCI space.\n", ha->host_no)); return (rval); } - ha->isp_ops.reset_chip(ha); + ha->isp_ops->reset_chip(ha); - ha->isp_ops.get_flash_version(ha, ha->request_ring); + ha->isp_ops->get_flash_version(ha, ha->request_ring); qla_printk(KERN_INFO, ha, "Configure NVRAM parameters...\n"); - ha->isp_ops.nvram_config(ha); + ha->isp_ops->nvram_config(ha); if (ha->flags.disable_serdes) { /* Mask HBA via NVRAM settings? */ @@ -108,7 +108,7 @@ qla2x00_initialize_adapter(scsi_qla_host_t *ha) qla_printk(KERN_INFO, ha, "Verifying loaded RISC code...\n"); if (qla2x00_isp_firmware(ha) != QLA_SUCCESS) { - rval = ha->isp_ops.chip_diag(ha); + rval = ha->isp_ops->chip_diag(ha); if (rval) return (rval); rval = qla2x00_setup_chip(ha); @@ -129,14 +129,13 @@ qla2x00_initialize_adapter(scsi_qla_host_t *ha) int qla2100_pci_config(scsi_qla_host_t *ha) { - int ret; uint16_t w; uint32_t d; unsigned long flags; struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; pci_set_master(ha->pdev); - ret = pci_set_mwi(ha->pdev); + pci_try_set_mwi(ha->pdev); pci_read_config_word(ha->pdev, PCI_COMMAND, &w); w |= (PCI_COMMAND_PARITY | PCI_COMMAND_SERR); @@ -164,7 +163,6 @@ qla2100_pci_config(scsi_qla_host_t *ha) int qla2300_pci_config(scsi_qla_host_t *ha) { - int ret; uint16_t w; uint32_t d; unsigned long flags = 0; @@ -172,7 +170,7 @@ qla2300_pci_config(scsi_qla_host_t *ha) struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; pci_set_master(ha->pdev); - ret = pci_set_mwi(ha->pdev); + pci_try_set_mwi(ha->pdev); pci_read_config_word(ha->pdev, PCI_COMMAND, &w); w |= (PCI_COMMAND_PARITY | PCI_COMMAND_SERR); @@ -250,15 +248,13 @@ qla2300_pci_config(scsi_qla_host_t *ha) int qla24xx_pci_config(scsi_qla_host_t *ha) { - int ret; uint16_t w; uint32_t d; unsigned long flags = 0; struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; - int pcix_cmd_reg, pcie_dctl_reg; pci_set_master(ha->pdev); - ret = pci_set_mwi(ha->pdev); + pci_try_set_mwi(ha->pdev); pci_read_config_word(ha->pdev, PCI_COMMAND, &w); w |= (PCI_COMMAND_PARITY | PCI_COMMAND_SERR); @@ -268,28 +264,12 @@ qla24xx_pci_config(scsi_qla_host_t *ha) pci_write_config_byte(ha->pdev, PCI_LATENCY_TIMER, 0x80); /* PCI-X -- adjust Maximum Memory Read Byte Count (2048). */ - pcix_cmd_reg = pci_find_capability(ha->pdev, PCI_CAP_ID_PCIX); - if (pcix_cmd_reg) { - uint16_t pcix_cmd; - - pcix_cmd_reg += PCI_X_CMD; - pci_read_config_word(ha->pdev, pcix_cmd_reg, &pcix_cmd); - pcix_cmd &= ~PCI_X_CMD_MAX_READ; - pcix_cmd |= 0x0008; - pci_write_config_word(ha->pdev, pcix_cmd_reg, pcix_cmd); - } + if (pci_find_capability(ha->pdev, PCI_CAP_ID_PCIX)) + pcix_set_mmrbc(ha->pdev, 2048); /* PCIe -- adjust Maximum Read Request Size (2048). */ - pcie_dctl_reg = pci_find_capability(ha->pdev, PCI_CAP_ID_EXP); - if (pcie_dctl_reg) { - uint16_t pcie_dctl; - - pcie_dctl_reg += PCI_EXP_DEVCTL; - pci_read_config_word(ha->pdev, pcie_dctl_reg, &pcie_dctl); - pcie_dctl &= ~PCI_EXP_DEVCTL_READRQ; - pcie_dctl |= 0x4000; - pci_write_config_word(ha->pdev, pcie_dctl_reg, pcie_dctl); - } + if (pci_find_capability(ha->pdev, PCI_CAP_ID_EXP)) + pcie_set_readrq(ha->pdev, 2048); /* Reset expansion ROM address decode enable */ pci_read_config_dword(ha->pdev, PCI_ROM_ADDRESS, &d); @@ -307,6 +287,40 @@ qla24xx_pci_config(scsi_qla_host_t *ha) } /** + * qla25xx_pci_config() - Setup ISP25xx PCI configuration registers. + * @ha: HA context + * + * Returns 0 on success. + */ +int +qla25xx_pci_config(scsi_qla_host_t *ha) +{ + uint16_t w; + uint32_t d; + + pci_set_master(ha->pdev); + pci_try_set_mwi(ha->pdev); + + pci_read_config_word(ha->pdev, PCI_COMMAND, &w); + w |= (PCI_COMMAND_PARITY | PCI_COMMAND_SERR); + w &= ~PCI_COMMAND_INTX_DISABLE; + pci_write_config_word(ha->pdev, PCI_COMMAND, w); + + /* PCIe -- adjust Maximum Read Request Size (2048). */ + if (pci_find_capability(ha->pdev, PCI_CAP_ID_EXP)) + pcie_set_readrq(ha->pdev, 2048); + + /* Reset expansion ROM address decode enable */ + pci_read_config_dword(ha->pdev, PCI_ROM_ADDRESS, &d); + d &= ~PCI_ROM_ADDRESS_ENABLE; + pci_write_config_dword(ha->pdev, PCI_ROM_ADDRESS, d); + + ha->chip_revision = ha->pdev->revision; + + return QLA_SUCCESS; +} + +/** * qla2x00_isp_firmware() - Choose firmware image. * @ha: HA context * @@ -351,7 +365,7 @@ qla2x00_reset_chip(scsi_qla_host_t *ha) uint32_t cnt; uint16_t cmd; - ha->isp_ops.disable_intrs(ha); + ha->isp_ops->disable_intrs(ha); spin_lock_irqsave(&ha->hardware_lock, flags); @@ -551,7 +565,7 @@ qla24xx_reset_risc(scsi_qla_host_t *ha) void qla24xx_reset_chip(scsi_qla_host_t *ha) { - ha->isp_ops.disable_intrs(ha); + ha->isp_ops->disable_intrs(ha); /* Perform RISC reset. */ qla24xx_reset_risc(ha); @@ -736,8 +750,10 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *ha) fixed_size = offsetof(struct qla2300_fw_dump, data_ram); mem_size = (ha->fw_memory_size - 0x11000 + 1) * sizeof(uint16_t); - } else if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { - fixed_size = offsetof(struct qla24xx_fw_dump, ext_mem); + } else if (IS_FWI2_CAPABLE(ha)) { + fixed_size = IS_QLA25XX(ha) ? + offsetof(struct qla25xx_fw_dump, ext_mem): + offsetof(struct qla24xx_fw_dump, ext_mem); mem_size = (ha->fw_memory_size - 0x100000 + 1) * sizeof(uint32_t); @@ -879,7 +895,7 @@ qla2x00_setup_chip(scsi_qla_host_t *ha) uint32_t srisc_address = 0; /* Load firmware sequences */ - rval = ha->isp_ops.load_risc(ha, &srisc_address); + rval = ha->isp_ops->load_risc(ha, &srisc_address); if (rval == QLA_SUCCESS) { DEBUG(printk("scsi(%ld): Verifying Checksum of loaded RISC " "code.\n", ha->host_no)); @@ -1130,12 +1146,12 @@ qla2x00_init_rings(scsi_qla_host_t *ha) /* Initialize response queue entries */ qla2x00_init_response_q_entries(ha); - ha->isp_ops.config_rings(ha); + ha->isp_ops->config_rings(ha); spin_unlock_irqrestore(&ha->hardware_lock, flags); /* Update any ISP specific firmware options before initialization. */ - ha->isp_ops.update_fw_options(ha); + ha->isp_ops->update_fw_options(ha); DEBUG(printk("scsi(%ld): Issue init firmware.\n", ha->host_no)); @@ -1445,8 +1461,8 @@ qla2x00_nvram_config(scsi_qla_host_t *ha) uint16_t cnt; uint8_t *dptr1, *dptr2; init_cb_t *icb = ha->init_cb; - nvram_t *nv = (nvram_t *)ha->request_ring; - uint8_t *ptr = (uint8_t *)ha->request_ring; + nvram_t *nv = ha->nvram; + uint8_t *ptr = ha->nvram; struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; rval = QLA_SUCCESS; @@ -1459,13 +1475,12 @@ qla2x00_nvram_config(scsi_qla_host_t *ha) ha->nvram_base = 0x80; /* Get NVRAM data and calculate checksum. */ - ha->isp_ops.read_nvram(ha, ptr, ha->nvram_base, ha->nvram_size); + ha->isp_ops->read_nvram(ha, ptr, ha->nvram_base, ha->nvram_size); for (cnt = 0, chksum = 0; cnt < ha->nvram_size; cnt++) chksum += *ptr++; DEBUG5(printk("scsi(%ld): Contents of NVRAM\n", ha->host_no)); - DEBUG5(qla2x00_dump_buffer((uint8_t *)ha->request_ring, - ha->nvram_size)); + DEBUG5(qla2x00_dump_buffer((uint8_t *)nv, ha->nvram_size)); /* Bad NVRAM data, set defaults parameters. */ if (chksum || nv->id[0] != 'I' || nv->id[1] != 'S' || @@ -2064,17 +2079,7 @@ qla2x00_configure_local_loop(scsi_qla_host_t *ha) } /* Base iIDMA settings on HBA port speed. */ - switch (ha->link_data_rate) { - case PORT_SPEED_1GB: - fcport->fp_speed = cpu_to_be16(BIT_15); - break; - case PORT_SPEED_2GB: - fcport->fp_speed = cpu_to_be16(BIT_14); - break; - case PORT_SPEED_4GB: - fcport->fp_speed = cpu_to_be16(BIT_13); - break; - } + fcport->fp_speed = ha->link_data_rate; qla2x00_update_fcport(ha, fcport); @@ -2115,38 +2120,25 @@ static void qla2x00_iidma_fcport(scsi_qla_host_t *ha, fc_port_t *fcport) { #define LS_UNKNOWN 2 - static char *link_speeds[5] = { "1", "2", "?", "4" }; + static char *link_speeds[5] = { "1", "2", "?", "4", "8" }; int rval; - uint16_t port_speed, mb[6]; + uint16_t mb[6]; - if (!IS_QLA24XX(ha)) + if (!IS_IIDMA_CAPABLE(ha)) return; - switch (be16_to_cpu(fcport->fp_speed)) { - case BIT_15: - port_speed = PORT_SPEED_1GB; - break; - case BIT_14: - port_speed = PORT_SPEED_2GB; - break; - case BIT_13: - port_speed = PORT_SPEED_4GB; - break; - default: + if (fcport->fp_speed == PORT_SPEED_UNKNOWN) { DEBUG2(printk("scsi(%ld): %02x%02x%02x%02x%02x%02x%02x%02x -- " - "unsupported FM port operating speed (%04x).\n", + "unsupported FM port operating speed.\n", ha->host_no, fcport->port_name[0], fcport->port_name[1], fcport->port_name[2], fcport->port_name[3], fcport->port_name[4], fcport->port_name[5], - fcport->port_name[6], fcport->port_name[7], - be16_to_cpu(fcport->fp_speed))); - port_speed = PORT_SPEED_UNKNOWN; - break; - } - if (port_speed == PORT_SPEED_UNKNOWN) + fcport->port_name[6], fcport->port_name[7])); return; + } - rval = qla2x00_set_idma_speed(ha, fcport->loop_id, port_speed, mb); + rval = qla2x00_set_idma_speed(ha, fcport->loop_id, fcport->fp_speed, + mb); if (rval != QLA_SUCCESS) { DEBUG2(printk("scsi(%ld): Unable to adjust iIDMA " "%02x%02x%02x%02x%02x%02x%02x%02x -- %04x %x %04x %04x.\n", @@ -2154,12 +2146,12 @@ qla2x00_iidma_fcport(scsi_qla_host_t *ha, fc_port_t *fcport) fcport->port_name[2], fcport->port_name[3], fcport->port_name[4], fcport->port_name[5], fcport->port_name[6], fcport->port_name[7], rval, - port_speed, mb[0], mb[1])); + fcport->fp_speed, mb[0], mb[1])); } else { DEBUG2(qla_printk(KERN_INFO, ha, "iIDMA adjusted to %s GB/s on " "%02x%02x%02x%02x%02x%02x%02x%02x.\n", - link_speeds[port_speed], fcport->port_name[0], + link_speeds[fcport->fp_speed], fcport->port_name[0], fcport->port_name[1], fcport->port_name[2], fcport->port_name[3], fcport->port_name[4], fcport->port_name[5], fcport->port_name[6], @@ -2267,7 +2259,7 @@ qla2x00_configure_fabric(scsi_qla_host_t *ha) scsi_qla_host_t *pha = to_qla_parent(ha); /* If FL port exists, then SNS is present */ - if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) + if (IS_FWI2_CAPABLE(ha)) loop_id = NPH_F_PORT; else loop_id = SNS_FL_PORT; @@ -2294,11 +2286,11 @@ qla2x00_configure_fabric(scsi_qla_host_t *ha) qla2x00_fdmi_register(ha); /* Ensure we are logged into the SNS. */ - if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) + if (IS_FWI2_CAPABLE(ha)) loop_id = NPH_SNS; else loop_id = SIMPLE_NAME_SERVER; - ha->isp_ops.fabric_login(ha, loop_id, 0xff, 0xff, + ha->isp_ops->fabric_login(ha, loop_id, 0xff, 0xff, 0xfc, mb, BIT_1 | BIT_0); if (mb[0] != MBS_COMMAND_COMPLETE) { DEBUG2(qla_printk(KERN_INFO, ha, @@ -2355,7 +2347,7 @@ qla2x00_configure_fabric(scsi_qla_host_t *ha) (fcport->flags & FCF_TAPE_PRESENT) == 0 && fcport->port_type != FCT_INITIATOR && fcport->port_type != FCT_BROADCAST) { - ha->isp_ops.fabric_logout(ha, + ha->isp_ops->fabric_logout(ha, fcport->loop_id, fcport->d_id.b.domain, fcport->d_id.b.area, @@ -2664,7 +2656,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *ha, struct list_head *new_fcports) (fcport->flags & FCF_TAPE_PRESENT) == 0 && fcport->port_type != FCT_INITIATOR && fcport->port_type != FCT_BROADCAST) { - ha->isp_ops.fabric_logout(ha, fcport->loop_id, + ha->isp_ops->fabric_logout(ha, fcport->loop_id, fcport->d_id.b.domain, fcport->d_id.b.area, fcport->d_id.b.al_pa); fcport->loop_id = FC_NO_LOOP_ID; @@ -2919,7 +2911,7 @@ qla2x00_fabric_dev_login(scsi_qla_host_t *ha, fc_port_t *fcport, opts |= BIT_1; rval = qla2x00_get_port_database(ha, fcport, opts); if (rval != QLA_SUCCESS) { - ha->isp_ops.fabric_logout(ha, fcport->loop_id, + ha->isp_ops->fabric_logout(ha, fcport->loop_id, fcport->d_id.b.domain, fcport->d_id.b.area, fcport->d_id.b.al_pa); qla2x00_mark_device_lost(ha, fcport, 1, 0); @@ -2964,7 +2956,7 @@ qla2x00_fabric_login(scsi_qla_host_t *ha, fc_port_t *fcport, fcport->d_id.b.area, fcport->d_id.b.al_pa)); /* Login fcport on switch. */ - ha->isp_ops.fabric_login(ha, fcport->loop_id, + ha->isp_ops->fabric_login(ha, fcport->loop_id, fcport->d_id.b.domain, fcport->d_id.b.area, fcport->d_id.b.al_pa, mb, BIT_0); if (mb[0] == MBS_PORT_ID_USED) { @@ -3032,7 +3024,7 @@ qla2x00_fabric_login(scsi_qla_host_t *ha, fc_port_t *fcport, * dead. */ *next_loopid = fcport->loop_id; - ha->isp_ops.fabric_logout(ha, fcport->loop_id, + ha->isp_ops->fabric_logout(ha, fcport->loop_id, fcport->d_id.b.domain, fcport->d_id.b.area, fcport->d_id.b.al_pa); qla2x00_mark_device_lost(ha, fcport, 1, 0); @@ -3050,7 +3042,7 @@ qla2x00_fabric_login(scsi_qla_host_t *ha, fc_port_t *fcport, fcport->d_id.b.al_pa, fcport->loop_id, jiffies)); *next_loopid = fcport->loop_id; - ha->isp_ops.fabric_logout(ha, fcport->loop_id, + ha->isp_ops->fabric_logout(ha, fcport->loop_id, fcport->d_id.b.domain, fcport->d_id.b.area, fcport->d_id.b.al_pa); fcport->loop_id = FC_NO_LOOP_ID; @@ -3206,7 +3198,7 @@ qla2x00_abort_isp(scsi_qla_host_t *ha) qla_printk(KERN_INFO, ha, "Performing ISP error recovery - ha= %p.\n", ha); - ha->isp_ops.reset_chip(ha); + ha->isp_ops->reset_chip(ha); atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME); if (atomic_read(&ha->loop_state) != LOOP_DOWN) { @@ -3232,9 +3224,9 @@ qla2x00_abort_isp(scsi_qla_host_t *ha) } spin_unlock_irqrestore(&ha->hardware_lock, flags); - ha->isp_ops.get_flash_version(ha, ha->request_ring); + ha->isp_ops->get_flash_version(ha, ha->request_ring); - ha->isp_ops.nvram_config(ha); + ha->isp_ops->nvram_config(ha); if (!qla2x00_restart_isp(ha)) { clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags); @@ -3249,7 +3241,7 @@ qla2x00_abort_isp(scsi_qla_host_t *ha) ha->flags.online = 1; - ha->isp_ops.enable_intrs(ha); + ha->isp_ops->enable_intrs(ha); ha->isp_abort_cnt = 0; clear_bit(ISP_ABORT_RETRY, &ha->dpc_flags); @@ -3274,7 +3266,7 @@ qla2x00_abort_isp(scsi_qla_host_t *ha) * The next call disables the board * completely. */ - ha->isp_ops.reset_adapter(ha); + ha->isp_ops->reset_adapter(ha); ha->flags.online = 0; clear_bit(ISP_ABORT_RETRY, &ha->dpc_flags); @@ -3331,7 +3323,7 @@ qla2x00_restart_isp(scsi_qla_host_t *ha) /* If firmware needs to be loaded */ if (qla2x00_isp_firmware(ha)) { ha->flags.online = 0; - if (!(status = ha->isp_ops.chip_diag(ha))) { + if (!(status = ha->isp_ops->chip_diag(ha))) { if (IS_QLA2100(ha) || IS_QLA2200(ha)) { status = qla2x00_setup_chip(ha); goto done; @@ -3339,7 +3331,8 @@ qla2x00_restart_isp(scsi_qla_host_t *ha) spin_lock_irqsave(&ha->hardware_lock, flags); - if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha)) { + if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha) && + !IS_QLA25XX(ha)) { /* * Disable SRAM, Instruction RAM and GP RAM * parity. @@ -3355,7 +3348,8 @@ qla2x00_restart_isp(scsi_qla_host_t *ha) spin_lock_irqsave(&ha->hardware_lock, flags); - if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha)) { + if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha) && + !IS_QLA25XX(ha)) { /* Enable proper parity */ if (IS_QLA2300(ha)) /* SRAM parity */ @@ -3423,7 +3417,7 @@ qla2x00_reset_adapter(scsi_qla_host_t *ha) struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; ha->flags.online = 0; - ha->isp_ops.disable_intrs(ha); + ha->isp_ops->disable_intrs(ha); spin_lock_irqsave(&ha->hardware_lock, flags); WRT_REG_WORD(®->hccr, HCCR_RESET_RISC); @@ -3440,7 +3434,7 @@ qla24xx_reset_adapter(scsi_qla_host_t *ha) struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; ha->flags.online = 0; - ha->isp_ops.disable_intrs(ha); + ha->isp_ops->disable_intrs(ha); spin_lock_irqsave(&ha->hardware_lock, flags); WRT_REG_DWORD(®->hccr, HCCRX_SET_RISC_RESET); @@ -3484,7 +3478,7 @@ qla24xx_nvram_config(scsi_qla_host_t *ha) rval = QLA_SUCCESS; icb = (struct init_cb_24xx *)ha->init_cb; - nv = (struct nvram_24xx *)ha->request_ring; + nv = ha->nvram; /* Determine NVRAM starting address. */ ha->nvram_size = sizeof(struct nvram_24xx); @@ -3496,16 +3490,20 @@ qla24xx_nvram_config(scsi_qla_host_t *ha) ha->vpd_base = FA_NVRAM_VPD1_ADDR; } - /* Get NVRAM data and calculate checksum. */ + /* Get VPD data into cache */ + ha->vpd = ha->nvram + VPD_OFFSET; + ha->isp_ops->read_nvram(ha, (uint8_t *)ha->vpd, + ha->nvram_base - FA_NVRAM_FUNC0_ADDR, FA_NVRAM_VPD_SIZE * 4); + + /* Get NVRAM data into cache and calculate checksum. */ dptr = (uint32_t *)nv; - ha->isp_ops.read_nvram(ha, (uint8_t *)dptr, ha->nvram_base, + ha->isp_ops->read_nvram(ha, (uint8_t *)dptr, ha->nvram_base, ha->nvram_size); for (cnt = 0, chksum = 0; cnt < ha->nvram_size >> 2; cnt++) chksum += le32_to_cpu(*dptr++); DEBUG5(printk("scsi(%ld): Contents of NVRAM\n", ha->host_no)); - DEBUG5(qla2x00_dump_buffer((uint8_t *)ha->request_ring, - ha->nvram_size)); + DEBUG5(qla2x00_dump_buffer((uint8_t *)nv, ha->nvram_size)); /* Bad NVRAM data, set defaults parameters. */ if (chksum || nv->id[0] != 'I' || nv->id[1] != 'S' || nv->id[2] != 'P' @@ -4012,7 +4010,7 @@ qla2x00_try_to_stop_firmware(scsi_qla_host_t *ha) { int ret, retries; - if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha)) + if (!IS_FWI2_CAPABLE(ha)) return; if (!ha->fw_major_version) return; |