diff options
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_os.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_os.c | 171 |
1 files changed, 125 insertions, 46 deletions
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 89a53002b58..19e99cc3372 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -120,15 +120,17 @@ MODULE_PARM_DESC(ql2xmaxqdepth, int ql2xenabledif = 2; module_param(ql2xenabledif, int, S_IRUGO); MODULE_PARM_DESC(ql2xenabledif, - " Enable T10-CRC-DIF " - " Default is 0 - No DIF Support. 1 - Enable it" - ", 2 - Enable DIF for all types, except Type 0."); + " Enable T10-CRC-DIF:\n" + " Default is 2.\n" + " 0 -- No DIF Support\n" + " 1 -- Enable DIF for all types\n" + " 2 -- Enable DIF for all types, except Type 0.\n"); int ql2xenablehba_err_chk = 2; module_param(ql2xenablehba_err_chk, int, S_IRUGO|S_IWUSR); MODULE_PARM_DESC(ql2xenablehba_err_chk, " Enable T10-CRC-DIF Error isolation by HBA:\n" - " Default is 1.\n" + " Default is 2.\n" " 0 -- Error isolation disabled\n" " 1 -- Error isolation enabled only for DIX Type 0\n" " 2 -- Error isolation enabled for all Types\n"); @@ -1975,7 +1977,7 @@ static struct isp_operations qla82xx_isp_ops = { .prep_ms_fdmi_iocb = qla24xx_prep_ms_fdmi_iocb, .read_nvram = qla24xx_read_nvram_data, .write_nvram = qla24xx_write_nvram_data, - .fw_dump = qla24xx_fw_dump, + .fw_dump = qla82xx_fw_dump, .beacon_on = qla82xx_beacon_on, .beacon_off = qla82xx_beacon_off, .beacon_blink = NULL, @@ -2013,11 +2015,11 @@ static struct isp_operations qla8044_isp_ops = { .prep_ms_fdmi_iocb = qla24xx_prep_ms_fdmi_iocb, .read_nvram = NULL, .write_nvram = NULL, - .fw_dump = qla24xx_fw_dump, + .fw_dump = qla8044_fw_dump, .beacon_on = qla82xx_beacon_on, .beacon_off = qla82xx_beacon_off, .beacon_blink = NULL, - .read_optrom = qla82xx_read_optrom_data, + .read_optrom = qla8044_read_optrom_data, .write_optrom = qla8044_write_optrom_data, .get_flash_version = qla82xx_get_flash_version, .start_scsi = qla82xx_start_scsi, @@ -2078,7 +2080,7 @@ static struct isp_operations qlafx00_isp_ops = { .intr_handler = qlafx00_intr_handler, .enable_intrs = qlafx00_enable_intrs, .disable_intrs = qlafx00_disable_intrs, - .abort_command = qlafx00_abort_command, + .abort_command = qla24xx_async_abort_command, .target_reset = qlafx00_abort_target, .lun_reset = qlafx00_lun_reset, .fabric_login = NULL, @@ -2102,6 +2104,44 @@ static struct isp_operations qlafx00_isp_ops = { .initialize_adapter = qlafx00_initialize_adapter, }; +static struct isp_operations qla27xx_isp_ops = { + .pci_config = qla25xx_pci_config, + .reset_chip = qla24xx_reset_chip, + .chip_diag = qla24xx_chip_diag, + .config_rings = qla24xx_config_rings, + .reset_adapter = qla24xx_reset_adapter, + .nvram_config = qla81xx_nvram_config, + .update_fw_options = qla81xx_update_fw_options, + .load_risc = qla81xx_load_risc, + .pci_info_str = qla24xx_pci_info_str, + .fw_version_str = qla24xx_fw_version_str, + .intr_handler = qla24xx_intr_handler, + .enable_intrs = qla24xx_enable_intrs, + .disable_intrs = qla24xx_disable_intrs, + .abort_command = qla24xx_abort_command, + .target_reset = qla24xx_abort_target, + .lun_reset = qla24xx_lun_reset, + .fabric_login = qla24xx_login_fabric, + .fabric_logout = qla24xx_fabric_logout, + .calc_req_entries = NULL, + .build_iocbs = NULL, + .prep_ms_iocb = qla24xx_prep_ms_iocb, + .prep_ms_fdmi_iocb = qla24xx_prep_ms_fdmi_iocb, + .read_nvram = NULL, + .write_nvram = NULL, + .fw_dump = qla27xx_fwdump, + .beacon_on = qla24xx_beacon_on, + .beacon_off = qla24xx_beacon_off, + .beacon_blink = qla83xx_beacon_blink, + .read_optrom = qla25xx_read_optrom_data, + .write_optrom = qla24xx_write_optrom_data, + .get_flash_version = qla24xx_get_flash_version, + .start_scsi = qla24xx_dif_start_scsi, + .abort_isp = qla2x00_abort_isp, + .iospace_config = qla83xx_iospace_config, + .initialize_adapter = qla2x00_initialize_adapter, +}; + static inline void qla2x00_set_isp_flags(struct qla_hw_data *ha) { @@ -2223,21 +2263,29 @@ qla2x00_set_isp_flags(struct qla_hw_data *ha) case PCI_DEVICE_ID_QLOGIC_ISPF001: ha->device_type |= DT_ISPFX00; break; + case PCI_DEVICE_ID_QLOGIC_ISP2071: + ha->device_type |= DT_ISP2071; + ha->device_type |= DT_ZIO_SUPPORTED; + ha->device_type |= DT_FWI2; + ha->device_type |= DT_IIDMA; + ha->fw_srisc_address = RISC_START_ADDRESS_2400; + break; } if (IS_QLA82XX(ha)) - ha->port_no = !(ha->portnum & 1); - else + ha->port_no = ha->portnum & 1; + else { /* Get adapter physical port no from interrupt pin register. */ pci_read_config_byte(ha->pdev, PCI_INTERRUPT_PIN, &ha->port_no); + if (IS_QLA27XX(ha)) + ha->port_no--; + else + ha->port_no = !(ha->port_no & 1); + } - if (ha->port_no & 1) - ha->flags.port0 = 1; - else - ha->flags.port0 = 0; ql_dbg_pci(ql_dbg_init, ha->pdev, 0x000b, "device_type=0x%x port=%d fw_srisc_address=0x%x.\n", - ha->device_type, ha->flags.port0, ha->fw_srisc_address); + ha->device_type, ha->port_no, ha->fw_srisc_address); } static void @@ -2297,7 +2345,8 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2031 || pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8031 || pdev->device == PCI_DEVICE_ID_QLOGIC_ISPF001 || - pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8044) { + pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8044 || + pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2071) { bars = pci_select_bars(pdev, IORESOURCE_MEM); mem_only = 1; ql_dbg_pci(ql_dbg_init, pdev, 0x0007, @@ -2334,13 +2383,14 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) spin_lock_init(&ha->hardware_lock); spin_lock_init(&ha->vport_slock); mutex_init(&ha->selflogin_lock); + mutex_init(&ha->optrom_mutex); /* Set ISP-type information. */ qla2x00_set_isp_flags(ha); /* Set EEH reset type to fundamental if required by hba */ if (IS_QLA24XX(ha) || IS_QLA25XX(ha) || IS_QLA81XX(ha) || - IS_QLA83XX(ha)) + IS_QLA83XX(ha) || IS_QLA27XX(ha)) pdev->needs_freset = 1; ha->prev_topology = 0; @@ -2488,7 +2538,6 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) ha->aen_mbx_count = AEN_MAILBOX_REGISTER_COUNT_FX00; req_length = REQUEST_ENTRY_CNT_FX00; rsp_length = RESPONSE_ENTRY_CNT_FX00; - ha->init_cb_size = sizeof(struct init_cb_fx); ha->isp_ops = &qlafx00_isp_ops; ha->port_down_retry_count = 30; /* default value */ ha->mr.fw_hbt_cnt = QLAFX00_HEARTBEAT_INTERVAL; @@ -2497,6 +2546,22 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) ha->mr.fw_hbt_en = 1; ha->mr.host_info_resend = false; ha->mr.hinfo_resend_timer_tick = QLAFX00_HINFO_RESEND_INTERVAL; + } else if (IS_QLA27XX(ha)) { + ha->portnum = PCI_FUNC(ha->pdev->devfn); + ha->max_fibre_devices = MAX_FIBRE_DEVICES_2400; + ha->mbx_count = MAILBOX_REGISTER_COUNT; + req_length = REQUEST_ENTRY_CNT_24XX; + rsp_length = RESPONSE_ENTRY_CNT_2300; + ha->max_loop_id = SNS_LAST_LOOP_ID_2300; + ha->init_cb_size = sizeof(struct mid_init_cb_81xx); + ha->gid_list_info_size = 8; + ha->optrom_size = OPTROM_SIZE_83XX; + ha->nvram_npiv_size = QLA_MAX_VPORTS_QLA25XX; + ha->isp_ops = &qla27xx_isp_ops; + ha->flash_conf_off = FARX_ACCESS_FLASH_CONF_81XX; + ha->flash_data_off = FARX_ACCESS_FLASH_DATA_81XX; + ha->nvram_conf_off = ~0; + ha->nvram_data_off = ~0; } ql_dbg_pci(ql_dbg_init, pdev, 0x001e, @@ -2536,7 +2601,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) ha->flags.enable_64bit_addressing ? "enable" : "disable"); ret = qla2x00_mem_alloc(ha, req_length, rsp_length, &req, &rsp); - if (!ret) { + if (ret) { ql_log_pci(ql_log_fatal, pdev, 0x0031, "Failed to allocate memory for adapter, aborting.\n"); @@ -2561,10 +2626,6 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) host = base_vha->host; base_vha->req = req; - if (IS_QLAFX00(ha)) - host->can_queue = QLAFX00_MAX_CANQUEUE; - else - host->can_queue = req->length + 128; if (IS_QLA2XXX_MIDTYPE(ha)) base_vha->mgmt_svr_loop_id = 10 + base_vha->vp_idx; else @@ -2587,11 +2648,6 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) if (!IS_QLA82XX(ha)) host->sg_tablesize = QLA_SG_ALL; } - ql_dbg(ql_dbg_init, base_vha, 0x0032, - "can_queue=%d, req=%p, " - "mgmt_svr_loop_id=%d, sg_tablesize=%d.\n", - host->can_queue, base_vha->req, - base_vha->mgmt_svr_loop_id, host->sg_tablesize); host->max_id = ha->max_fibre_devices; host->cmd_per_lun = 3; host->unique_id = host->host_no; @@ -2646,7 +2702,7 @@ que_init: req->req_q_out = &ha->iobase->isp24.req_q_out; rsp->rsp_q_in = &ha->iobase->isp24.rsp_q_in; rsp->rsp_q_out = &ha->iobase->isp24.rsp_q_out; - if (ha->mqenable || IS_QLA83XX(ha)) { + if (ha->mqenable || IS_QLA83XX(ha) || IS_QLA27XX(ha)) { req->req_q_in = &ha->mqiobase->isp25mq.req_q_in; req->req_q_out = &ha->mqiobase->isp25mq.req_q_out; rsp->rsp_q_in = &ha->mqiobase->isp25mq.rsp_q_in; @@ -2707,6 +2763,16 @@ que_init: goto probe_failed; } + if (IS_QLAFX00(ha)) + host->can_queue = QLAFX00_MAX_CANQUEUE; + else + host->can_queue = req->num_outstanding_cmds - 10; + + ql_dbg(ql_dbg_init, base_vha, 0x0032, + "can_queue=%d, req=%p, mgmt_svr_loop_id=%d, sg_tablesize=%d.\n", + host->can_queue, base_vha->req, + base_vha->mgmt_svr_loop_id, host->sg_tablesize); + if (ha->mqenable) { if (qla25xx_setup_mode(base_vha)) { ql_log(ql_log_warn, base_vha, 0x00ec, @@ -2887,9 +2953,9 @@ probe_hw_failed: iospace_config_failed: if (IS_P3P_TYPE(ha)) { if (!ha->nx_pcibase) - iounmap((device_reg_t __iomem *)ha->nx_pcibase); + iounmap((device_reg_t *)ha->nx_pcibase); if (!ql2xdbwr) - iounmap((device_reg_t __iomem *)ha->nxdb_wr_ptr); + iounmap((device_reg_t *)ha->nxdb_wr_ptr); } else { if (ha->iobase) iounmap(ha->iobase); @@ -3020,9 +3086,9 @@ qla2x00_unmap_iobases(struct qla_hw_data *ha) { if (IS_QLA82XX(ha)) { - iounmap((device_reg_t __iomem *)ha->nx_pcibase); + iounmap((device_reg_t *)ha->nx_pcibase); if (!ql2xdbwr) - iounmap((device_reg_t __iomem *)ha->nxdb_wr_ptr); + iounmap((device_reg_t *)ha->nxdb_wr_ptr); } else { if (ha->iobase) iounmap(ha->iobase); @@ -3033,7 +3099,7 @@ qla2x00_unmap_iobases(struct qla_hw_data *ha) if (ha->mqiobase) iounmap(ha->mqiobase); - if (IS_QLA83XX(ha) && ha->msixbase) + if ((IS_QLA83XX(ha) || IS_QLA27XX(ha)) && ha->msixbase) iounmap(ha->msixbase); } } @@ -3447,7 +3513,7 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len, ha->npiv_info = NULL; /* Get consistent memory allocated for EX-INIT-CB. */ - if (IS_CNA_CAPABLE(ha) || IS_QLA2031(ha)) { + if (IS_CNA_CAPABLE(ha) || IS_QLA2031(ha) || IS_QLA27XX(ha)) { ha->ex_init_cb = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &ha->ex_init_cb_dma); if (!ha->ex_init_cb) @@ -3478,10 +3544,10 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len, else { qla2x00_set_reserved_loop_ids(ha); ql_dbg_pci(ql_dbg_init, ha->pdev, 0x0123, - "loop_id_map=%p. \n", ha->loop_id_map); + "loop_id_map=%p.\n", ha->loop_id_map); } - return 1; + return 0; fail_async_pd: dma_pool_free(ha->s_dma_pool, ha->ex_init_cb, ha->ex_init_cb_dma); @@ -3562,22 +3628,28 @@ static void qla2x00_free_fw_dump(struct qla_hw_data *ha) { if (ha->fce) - dma_free_coherent(&ha->pdev->dev, FCE_SIZE, ha->fce, - ha->fce_dma); + dma_free_coherent(&ha->pdev->dev, + FCE_SIZE, ha->fce, ha->fce_dma); - if (ha->fw_dump) { - if (ha->eft) - dma_free_coherent(&ha->pdev->dev, - ntohl(ha->fw_dump->eft_size), ha->eft, ha->eft_dma); + if (ha->eft) + dma_free_coherent(&ha->pdev->dev, + EFT_SIZE, ha->eft, ha->eft_dma); + + if (ha->fw_dump) vfree(ha->fw_dump); - } + if (ha->fw_dump_template) + vfree(ha->fw_dump_template); + ha->fce = NULL; ha->fce_dma = 0; ha->eft = NULL; ha->eft_dma = 0; - ha->fw_dump = NULL; ha->fw_dumped = 0; ha->fw_dump_reading = 0; + ha->fw_dump = NULL; + ha->fw_dump_len = 0; + ha->fw_dump_template = NULL; + ha->fw_dump_template_len = 0; } /* @@ -5242,7 +5314,7 @@ qla2x00_timer(scsi_qla_host_t *vha) /* Firmware interface routines. */ -#define FW_BLOBS 10 +#define FW_BLOBS 11 #define FW_ISP21XX 0 #define FW_ISP22XX 1 #define FW_ISP2300 2 @@ -5253,6 +5325,7 @@ qla2x00_timer(scsi_qla_host_t *vha) #define FW_ISP82XX 7 #define FW_ISP2031 8 #define FW_ISP8031 9 +#define FW_ISP2071 10 #define FW_FILE_ISP21XX "ql2100_fw.bin" #define FW_FILE_ISP22XX "ql2200_fw.bin" @@ -5264,6 +5337,8 @@ qla2x00_timer(scsi_qla_host_t *vha) #define FW_FILE_ISP82XX "ql8200_fw.bin" #define FW_FILE_ISP2031 "ql2600_fw.bin" #define FW_FILE_ISP8031 "ql8300_fw.bin" +#define FW_FILE_ISP2071 "ql2700_fw.bin" + static DEFINE_MUTEX(qla_fw_lock); @@ -5278,6 +5353,7 @@ static struct fw_blob qla_fw_blobs[FW_BLOBS] = { { .name = FW_FILE_ISP82XX, }, { .name = FW_FILE_ISP2031, }, { .name = FW_FILE_ISP8031, }, + { .name = FW_FILE_ISP2071, }, }; struct fw_blob * @@ -5306,6 +5382,8 @@ qla2x00_request_firmware(scsi_qla_host_t *vha) blob = &qla_fw_blobs[FW_ISP2031]; } else if (IS_QLA8031(ha)) { blob = &qla_fw_blobs[FW_ISP8031]; + } else if (IS_QLA2071(ha)) { + blob = &qla_fw_blobs[FW_ISP2071]; } else { return NULL; } @@ -5635,6 +5713,7 @@ static struct pci_device_id qla2xxx_pci_tbl[] = { { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP8031) }, { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISPF001) }, { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP8044) }, + { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2071) }, { 0 }, }; MODULE_DEVICE_TABLE(pci, qla2xxx_pci_tbl); |