diff options
Diffstat (limited to 'drivers/scsi/qla2xxx')
-rw-r--r-- | drivers/scsi/qla2xxx/Kconfig | 3 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_dbg.c | 6 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_def.h | 16 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_init.c | 79 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_isr.c | 17 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_mbx.c | 31 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_mid.c | 24 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_nx.c | 2 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_os.c | 11 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_sup.c | 11 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_target.c | 2 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_tmpl.c | 15 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_version.h | 2 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/tcm_qla2xxx.c | 174 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/tcm_qla2xxx.h | 1 |
15 files changed, 249 insertions, 145 deletions
diff --git a/drivers/scsi/qla2xxx/Kconfig b/drivers/scsi/qla2xxx/Kconfig index 113e6c9826a1..33f60c92e20e 100644 --- a/drivers/scsi/qla2xxx/Kconfig +++ b/drivers/scsi/qla2xxx/Kconfig @@ -18,6 +18,9 @@ config SCSI_QLA_FC 2322, 6322 ql2322_fw.bin 24xx, 54xx ql2400_fw.bin 25xx ql2500_fw.bin + 2031 ql2600_fw.bin + 8031 ql8300_fw.bin + 27xx ql2700_fw.bin Upon request, the driver caches the firmware image until the driver is unloaded. diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c index d77fe43793b6..0e6ee3ca30e6 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.c +++ b/drivers/scsi/qla2xxx/qla_dbg.c @@ -11,9 +11,9 @@ * ---------------------------------------------------------------------- * | Level | Last Value Used | Holes | * ---------------------------------------------------------------------- - * | Module Init and Probe | 0x017d | 0x0144,0x0146 | + * | Module Init and Probe | 0x017f | 0x0146 | * | | | 0x015b-0x0160 | - * | | | 0x016e-0x0170 | + * | | | 0x016e-0x0170 | * | Mailbox commands | 0x118d | 0x1115-0x1116 | * | | | 0x111a-0x111b | * | Device Discovery | 0x2016 | 0x2020-0x2022, | @@ -60,7 +60,7 @@ * | | | 0xb13c-0xb140 | * | | | 0xb149 | * | MultiQ | 0xc00c | | - * | Misc | 0xd213 | 0xd011-0xd017 | + * | Misc | 0xd300 | 0xd016-0xd017 | * | | | 0xd021,0xd024 | * | | | 0xd025,0xd029 | * | | | 0xd02a,0xd02e | diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 5f6b2960cccb..e86201d3b8c6 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -2163,7 +2163,7 @@ struct ct_fdmi_hba_attr { uint8_t node_name[WWN_SIZE]; uint8_t manufacturer[64]; uint8_t serial_num[32]; - uint8_t model[16]; + uint8_t model[16+1]; uint8_t model_desc[80]; uint8_t hw_version[32]; uint8_t driver_version[32]; @@ -2184,9 +2184,9 @@ struct ct_fdmiv2_hba_attr { uint16_t len; union { uint8_t node_name[WWN_SIZE]; - uint8_t manufacturer[32]; + uint8_t manufacturer[64]; uint8_t serial_num[32]; - uint8_t model[16]; + uint8_t model[16+1]; uint8_t model_desc[80]; uint8_t hw_version[16]; uint8_t driver_version[32]; @@ -2252,7 +2252,7 @@ struct ct_fdmiv2_port_attr { uint32_t cur_speed; uint32_t max_frame_size; uint8_t os_dev_name[32]; - uint8_t host_name[32]; + uint8_t host_name[256]; uint8_t node_name[WWN_SIZE]; uint8_t port_name[WWN_SIZE]; uint8_t port_sym_name[128]; @@ -2283,7 +2283,7 @@ struct ct_fdmi_port_attr { uint32_t cur_speed; uint32_t max_frame_size; uint8_t os_dev_name[32]; - uint8_t host_name[32]; + uint8_t host_name[256]; } a; }; @@ -3132,7 +3132,8 @@ struct qla_hw_data { IS_QLA25XX(ha) || IS_QLA81XX(ha) || \ IS_QLA82XX(ha) || IS_QLA83XX(ha) || \ IS_QLA8044(ha) || IS_QLA27XX(ha)) -#define IS_MSIX_NACK_CAPABLE(ha) (IS_QLA81XX(ha) || IS_QLA83XX(ha)) +#define IS_MSIX_NACK_CAPABLE(ha) (IS_QLA81XX(ha) || IS_QLA83XX(ha) || \ + IS_QLA27XX(ha)) #define IS_NOPOLLING_TYPE(ha) (IS_QLA81XX(ha) && (ha)->flags.msix_enabled) #define IS_FAC_REQUIRED(ha) (IS_QLA81XX(ha) || IS_QLA83XX(ha) || \ IS_QLA27XX(ha)) @@ -3300,6 +3301,8 @@ struct qla_hw_data { #define RISC_RDY_AFT_RESET 3 #define RISC_SRAM_DUMP_CMPL 4 #define RISC_EXT_MEM_DUMP_CMPL 5 +#define ISP_MBX_RDY 6 +#define ISP_SOFT_RESET_CMPL 7 int fw_dump_reading; int prev_minidump_failed; dma_addr_t eft_dma; @@ -3587,6 +3590,7 @@ typedef struct scsi_qla_host { #define VP_BIND_NEEDED 2 #define VP_DELETE_NEEDED 3 #define VP_SCR_NEEDED 4 /* State Change Request registration */ +#define VP_CONFIG_OK 5 /* Flag to cfg VP, if FW is ready */ atomic_t vp_state; #define VP_OFFLINE 0 #define VP_ACTIVE 1 diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index e59f25bff7ab..285cb204f300 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -1121,7 +1121,7 @@ qla81xx_reset_mpi(scsi_qla_host_t *vha) * * Returns 0 on success. */ -static inline void +static inline int qla24xx_reset_risc(scsi_qla_host_t *vha) { unsigned long flags = 0; @@ -1130,6 +1130,7 @@ qla24xx_reset_risc(scsi_qla_host_t *vha) uint32_t cnt, d2; uint16_t wd; static int abts_cnt; /* ISP abort retry counts */ + int rval = QLA_SUCCESS; spin_lock_irqsave(&ha->hardware_lock, flags); @@ -1142,26 +1143,57 @@ qla24xx_reset_risc(scsi_qla_host_t *vha) udelay(10); } + if (!(RD_REG_DWORD(®->ctrl_status) & CSRX_DMA_ACTIVE)) + set_bit(DMA_SHUTDOWN_CMPL, &ha->fw_dump_cap_flags); + + ql_dbg(ql_dbg_init + ql_dbg_verbose, vha, 0x017e, + "HCCR: 0x%x, Control Status %x, DMA active status:0x%x\n", + RD_REG_DWORD(®->hccr), + RD_REG_DWORD(®->ctrl_status), + (RD_REG_DWORD(®->ctrl_status) & CSRX_DMA_ACTIVE)); + WRT_REG_DWORD(®->ctrl_status, CSRX_ISP_SOFT_RESET|CSRX_DMA_SHUTDOWN|MWB_4096_BYTES); pci_read_config_word(ha->pdev, PCI_COMMAND, &wd); udelay(100); + /* Wait for firmware to complete NVRAM accesses. */ d2 = (uint32_t) RD_REG_WORD(®->mailbox0); - for (cnt = 10000 ; cnt && d2; cnt--) { - udelay(5); - d2 = (uint32_t) RD_REG_WORD(®->mailbox0); + for (cnt = 10000; RD_REG_WORD(®->mailbox0) != 0 && + rval == QLA_SUCCESS; cnt--) { barrier(); + if (cnt) + udelay(5); + else + rval = QLA_FUNCTION_TIMEOUT; } + if (rval == QLA_SUCCESS) + set_bit(ISP_MBX_RDY, &ha->fw_dump_cap_flags); + + ql_dbg(ql_dbg_init + ql_dbg_verbose, vha, 0x017f, + "HCCR: 0x%x, MailBox0 Status 0x%x\n", + RD_REG_DWORD(®->hccr), + RD_REG_DWORD(®->mailbox0)); + /* Wait for soft-reset to complete. */ d2 = RD_REG_DWORD(®->ctrl_status); - for (cnt = 6000000 ; cnt && (d2 & CSRX_ISP_SOFT_RESET); cnt--) { - udelay(5); - d2 = RD_REG_DWORD(®->ctrl_status); + for (cnt = 0; cnt < 6000000; cnt++) { barrier(); + if ((RD_REG_DWORD(®->ctrl_status) & + CSRX_ISP_SOFT_RESET) == 0) + break; + + udelay(5); } + if (!(RD_REG_DWORD(®->ctrl_status) & CSRX_ISP_SOFT_RESET)) + set_bit(ISP_SOFT_RESET_CMPL, &ha->fw_dump_cap_flags); + + ql_dbg(ql_dbg_init + ql_dbg_verbose, vha, 0x015d, + "HCCR: 0x%x, Soft Reset status: 0x%x\n", + RD_REG_DWORD(®->hccr), + RD_REG_DWORD(®->ctrl_status)); /* If required, do an MPI FW reset now */ if (test_and_clear_bit(MPI_RESET_NEEDED, &vha->dpc_flags)) { @@ -1190,16 +1222,32 @@ qla24xx_reset_risc(scsi_qla_host_t *vha) RD_REG_DWORD(®->hccr); d2 = (uint32_t) RD_REG_WORD(®->mailbox0); - for (cnt = 6000000 ; cnt && d2; cnt--) { - udelay(5); - d2 = (uint32_t) RD_REG_WORD(®->mailbox0); + for (cnt = 6000000; RD_REG_WORD(®->mailbox0) != 0 && + rval == QLA_SUCCESS; cnt--) { barrier(); + if (cnt) + udelay(5); + else + rval = QLA_FUNCTION_TIMEOUT; } + if (rval == QLA_SUCCESS) + set_bit(RISC_RDY_AFT_RESET, &ha->fw_dump_cap_flags); + + ql_dbg(ql_dbg_init + ql_dbg_verbose, vha, 0x015e, + "Host Risc 0x%x, mailbox0 0x%x\n", + RD_REG_DWORD(®->hccr), + RD_REG_WORD(®->mailbox0)); spin_unlock_irqrestore(&ha->hardware_lock, flags); + ql_dbg(ql_dbg_init + ql_dbg_verbose, vha, 0x015f, + "Driver in %s mode\n", + IS_NOPOLLING_TYPE(ha) ? "Interrupt" : "Polling"); + if (IS_NOPOLLING_TYPE(ha)) ha->isp_ops->enable_intrs(ha); + + return rval; } static void @@ -2243,8 +2291,11 @@ qla2x00_fw_ready(scsi_qla_host_t *vha) rval = QLA_SUCCESS; - /* 20 seconds for loop down. */ - min_wait = 20; + /* Time to wait for loop down */ + if (IS_P3P_TYPE(ha)) + min_wait = 30; + else + min_wait = 20; /* * Firmware should take at most one RATOV to login, plus 5 seconds for @@ -5364,7 +5415,7 @@ qla2x00_load_risc(scsi_qla_host_t *vha, uint32_t *srisc_addr) blob = qla2x00_request_firmware(vha); if (!blob) { ql_log(ql_log_info, vha, 0x0083, - "Fimware image unavailable.\n"); + "Firmware image unavailable.\n"); ql_log(ql_log_info, vha, 0x0084, "Firmware images can be retrieved from: "QLA_FW_URL ".\n"); return QLA_FUNCTION_FAILED; @@ -5467,7 +5518,7 @@ qla24xx_load_risc_blob(scsi_qla_host_t *vha, uint32_t *srisc_addr) blob = qla2x00_request_firmware(vha); if (!blob) { ql_log(ql_log_warn, vha, 0x0090, - "Fimware image unavailable.\n"); + "Firmware image unavailable.\n"); ql_log(ql_log_warn, vha, 0x0091, "Firmware images can be retrieved from: " QLA_FW_URL ".\n"); diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index a04a1b1f7f32..6dc14cd782b2 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -756,11 +756,21 @@ skip_rio: /* * In case of loop down, restore WWPN from * NVRAM in case of FA-WWPN capable ISP + * Restore for Physical Port only */ - if (ha->flags.fawwpn_enabled) { - void *wwpn = ha->init_cb->port_name; + if (!vha->vp_idx) { + if (ha->flags.fawwpn_enabled) { + void *wwpn = ha->init_cb->port_name; + memcpy(vha->port_name, wwpn, WWN_SIZE); + fc_host_port_name(vha->host) = + wwn_to_u64(vha->port_name); + ql_dbg(ql_dbg_init + ql_dbg_verbose, + vha, 0x0144, "LOOP DOWN detected," + "restore WWPN %016llx\n", + wwn_to_u64(vha->port_name)); + } - memcpy(vha->port_name, wwpn, WWN_SIZE); + clear_bit(VP_CONFIG_OK, &vha->vp_flags); } vha->device_flags |= DFLG_NO_CABLE; @@ -947,6 +957,7 @@ skip_rio: set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags); + set_bit(VP_CONFIG_OK, &vha->vp_flags); qlt_async_event(mb[0], vha, mb); break; diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index 72971daa2552..02b1c1c5355b 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c @@ -33,7 +33,7 @@ static int qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) { - int rval; + int rval, i; unsigned long flags = 0; device_reg_t *reg; uint8_t abort_active; @@ -43,10 +43,12 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) uint16_t __iomem *optr; uint32_t cnt; uint32_t mboxes; + uint16_t __iomem *mbx_reg; unsigned long wait_time; struct qla_hw_data *ha = vha->hw; scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev); + ql_dbg(ql_dbg_mbx, vha, 0x1000, "Entered %s.\n", __func__); if (ha->pdev->error_state > pci_channel_io_frozen) { @@ -376,6 +378,18 @@ mbx_done: ql_dbg(ql_dbg_disc, base_vha, 0x1020, "**** Failed mbx[0]=%x, mb[1]=%x, mb[2]=%x, mb[3]=%x, cmd=%x ****.\n", mcp->mb[0], mcp->mb[1], mcp->mb[2], mcp->mb[3], command); + + ql_dbg(ql_dbg_disc, vha, 0x1115, + "host status: 0x%x, flags:0x%lx, intr ctrl reg:0x%x, intr status:0x%x\n", + RD_REG_DWORD(®->isp24.host_status), + ha->fw_dump_cap_flags, + RD_REG_DWORD(®->isp24.ictrl), + RD_REG_DWORD(®->isp24.istatus)); + + mbx_reg = ®->isp24.mailbox0; + for (i = 0; i < 6; i++) + ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0x1116, + "mbox[%d] 0x%04x\n", i, RD_REG_WORD(mbx_reg++)); } else { ql_dbg(ql_dbg_mbx, base_vha, 0x1021, "Done %s.\n", __func__); } @@ -2838,7 +2852,7 @@ qla2x00_write_serdes_word(scsi_qla_host_t *vha, uint16_t addr, uint16_t data) mbx_cmd_t mc; mbx_cmd_t *mcp = &mc; - if (!IS_QLA2031(vha->hw)) + if (!IS_QLA2031(vha->hw) && !IS_QLA27XX(vha->hw)) return QLA_FUNCTION_FAILED; ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1182, @@ -2846,7 +2860,11 @@ qla2x00_write_serdes_word(scsi_qla_host_t *vha, uint16_t addr, uint16_t data) mcp->mb[0] = MBC_WRITE_SERDES; mcp->mb[1] = addr; - mcp->mb[2] = data & 0xff; + if (IS_QLA2031(vha->hw)) + mcp->mb[2] = data & 0xff; + else + mcp->mb[2] = data; + mcp->mb[3] = 0; mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; mcp->in_mb = MBX_0; @@ -2872,7 +2890,7 @@ qla2x00_read_serdes_word(scsi_qla_host_t *vha, uint16_t addr, uint16_t *data) mbx_cmd_t mc; mbx_cmd_t *mcp = &mc; - if (!IS_QLA2031(vha->hw)) + if (!IS_QLA2031(vha->hw) && !IS_QLA27XX(vha->hw)) return QLA_FUNCTION_FAILED; ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1185, @@ -2887,7 +2905,10 @@ qla2x00_read_serdes_word(scsi_qla_host_t *vha, uint16_t addr, uint16_t *data) mcp->flags = 0; rval = qla2x00_mailbox_command(vha, mcp); - *data = mcp->mb[1] & 0xff; + if (IS_QLA2031(vha->hw)) + *data = mcp->mb[1] & 0xff; + else + *data = mcp->mb[1]; if (rval != QLA_SUCCESS) { ql_dbg(ql_dbg_mbx, vha, 0x1186, diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c index 5c2e0317f1c0..cc94192511cf 100644 --- a/drivers/scsi/qla2xxx/qla_mid.c +++ b/drivers/scsi/qla2xxx/qla_mid.c @@ -306,19 +306,25 @@ qla2x00_vp_abort_isp(scsi_qla_host_t *vha) static int qla2x00_do_dpc_vp(scsi_qla_host_t *vha) { + struct qla_hw_data *ha = vha->hw; + scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev); + ql_dbg(ql_dbg_dpc + ql_dbg_verbose, vha, 0x4012, "Entering %s vp_flags: 0x%lx.\n", __func__, vha->vp_flags); qla2x00_do_work(vha); - if (test_and_clear_bit(VP_IDX_ACQUIRED, &vha->vp_flags)) { - /* VP acquired. complete port configuration */ - ql_dbg(ql_dbg_dpc, vha, 0x4014, - "Configure VP scheduled.\n"); - qla24xx_configure_vp(vha); - ql_dbg(ql_dbg_dpc, vha, 0x4015, - "Configure VP end.\n"); - return 0; + /* Check if Fw is ready to configure VP first */ + if (test_bit(VP_CONFIG_OK, &base_vha->vp_flags)) { + if (test_and_clear_bit(VP_IDX_ACQUIRED, &vha->vp_flags)) { + /* VP acquired. complete port configuration */ + ql_dbg(ql_dbg_dpc, vha, 0x4014, + "Configure VP scheduled.\n"); + qla24xx_configure_vp(vha); + ql_dbg(ql_dbg_dpc, vha, 0x4015, + "Configure VP end.\n"); + return 0; + } } if (test_bit(FCPORT_UPDATE_NEEDED, &vha->dpc_flags)) { @@ -788,7 +794,7 @@ qla25xx_create_rsp_que(struct qla_hw_data *ha, uint16_t options, rsp->msix = &ha->msix_entries[que_id + 1]; else ql_log(ql_log_warn, base_vha, 0x00e3, - "MSIX not enalbled.\n"); + "MSIX not enabled.\n"); ha->rsp_q_map[que_id] = rsp; rsp->rid = rid; diff --git a/drivers/scsi/qla2xxx/qla_nx.c b/drivers/scsi/qla2xxx/qla_nx.c index 54cb2ac9339b..7d2b18f2675c 100644 --- a/drivers/scsi/qla2xxx/qla_nx.c +++ b/drivers/scsi/qla2xxx/qla_nx.c @@ -1274,7 +1274,7 @@ qla82xx_pinit_from_rom(scsi_qla_host_t *vha) if (off == ADDR_ERROR) { ql_log(ql_log_fatal, vha, 0x0116, - "Unknow addr: 0x%08lx.\n", buf[i].addr); + "Unknown addr: 0x%08lx.\n", buf[i].addr); continue; } diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index cce1cbc1a927..7462dd70b150 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -446,11 +446,11 @@ static int qla25xx_setup_mode(struct scsi_qla_host *vha) } ha->flags.cpu_affinity_enabled = 1; ql_dbg(ql_dbg_multiq, vha, 0xc007, - "CPU affinity mode enalbed, " + "CPU affinity mode enabled, " "no. of response queues:%d no. of request queues:%d.\n", ha->max_rsp_queues, ha->max_req_queues); ql_dbg(ql_dbg_init, vha, 0x00e9, - "CPU affinity mode enalbed, " + "CPU affinity mode enabled, " "no. of response queues:%d no. of request queues:%d.\n", ha->max_rsp_queues, ha->max_req_queues); } @@ -4102,7 +4102,7 @@ qla83xx_schedule_work(scsi_qla_host_t *base_vha, int work_code) break; default: ql_log(ql_log_warn, base_vha, 0xb05f, - "Unknow work-code=0x%x.\n", work_code); + "Unknown work-code=0x%x.\n", work_code); } return; @@ -4702,7 +4702,7 @@ qla83xx_idc_state_handler(scsi_qla_host_t *base_vha) break; default: ql_log(ql_log_warn, base_vha, 0xb071, - "Unknow Device State: %x.\n", dev_state); + "Unknown Device State: %x.\n", dev_state); qla83xx_idc_unlock(base_vha, 0); qla8xxx_dev_failed_handler(base_vha); rval = QLA_FUNCTION_FAILED; @@ -5834,3 +5834,6 @@ MODULE_FIRMWARE(FW_FILE_ISP2300); MODULE_FIRMWARE(FW_FILE_ISP2322); MODULE_FIRMWARE(FW_FILE_ISP24XX); MODULE_FIRMWARE(FW_FILE_ISP25XX); +MODULE_FIRMWARE(FW_FILE_ISP2031); +MODULE_FIRMWARE(FW_FILE_ISP8031); +MODULE_FIRMWARE(FW_FILE_ISP27XX); diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c index b656a05613e8..028e8c8a7de9 100644 --- a/drivers/scsi/qla2xxx/qla_sup.c +++ b/drivers/scsi/qla2xxx/qla_sup.c @@ -1718,13 +1718,16 @@ qla83xx_beacon_blink(struct scsi_qla_host *vha) uint16_t orig_led_cfg[6]; uint32_t led_10_value, led_43_value; - if (!IS_QLA83XX(ha) && !IS_QLA81XX(ha)) + if (!IS_QLA83XX(ha) && !IS_QLA81XX(ha) && !IS_QLA27XX(ha)) return; if (!ha->beacon_blink_led) return; - if (IS_QLA2031(ha)) { + if (IS_QLA27XX(ha)) { + qla2x00_write_ram_word(vha, 0x1003, 0x40000230); + qla2x00_write_ram_word(vha, 0x1004, 0x40000230); + } else if (IS_QLA2031(ha)) { led_select_value = qla83xx_select_led_port(ha); qla83xx_wr_reg(vha, led_select_value, 0x40000230); @@ -1811,7 +1814,7 @@ qla24xx_beacon_on(struct scsi_qla_host *vha) return QLA_FUNCTION_FAILED; } - if (IS_QLA2031(ha)) + if (IS_QLA2031(ha) || IS_QLA27XX(ha)) goto skip_gpio; spin_lock_irqsave(&ha->hardware_lock, flags); @@ -1848,7 +1851,7 @@ qla24xx_beacon_off(struct scsi_qla_host *vha) ha->beacon_blink_led = 0; - if (IS_QLA2031(ha)) + if (IS_QLA2031(ha) || IS_QLA27XX(ha)) goto set_fw_options; if (IS_QLA8031(ha) || IS_QLA81XX(ha)) diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index 57418258c101..fe8a8d157e22 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c @@ -3065,7 +3065,7 @@ static void qlt_do_ctio_completion(struct scsi_qla_host *vha, uint32_t handle, { struct qla_hw_data *ha = vha->hw; struct se_cmd *se_cmd; - struct target_core_fabric_ops *tfo; + const struct target_core_fabric_ops *tfo; struct qla_tgt_cmd *cmd; if (handle & CTIO_INTERMEDIATE_HANDLE_MARK) { diff --git a/drivers/scsi/qla2xxx/qla_tmpl.c b/drivers/scsi/qla2xxx/qla_tmpl.c index a8c0c7362e48..962cb89fe0ae 100644 --- a/drivers/scsi/qla2xxx/qla_tmpl.c +++ b/drivers/scsi/qla2xxx/qla_tmpl.c @@ -190,7 +190,7 @@ static inline void qla27xx_write_reg(__iomem struct device_reg_24xx *reg, uint offset, uint32_t data, void *buf) { - __iomem void *window = reg + offset; + __iomem void *window = (void __iomem *)reg + offset; if (buf) { WRT_REG_DWORD(window, data); @@ -219,6 +219,8 @@ qla27xx_skip_entry(struct qla27xx_fwdt_entry *ent, void *buf) { if (buf) ent->hdr.driver_flags |= DRIVER_FLAG_SKIP_ENTRY; + ql_dbg(ql_dbg_misc + ql_dbg_verbose, NULL, 0xd011, + "Skipping entry %d\n", ent->hdr.entry_type); } static int @@ -784,6 +786,13 @@ qla27xx_walk_template(struct scsi_qla_host *vha, ql_dbg(ql_dbg_misc, vha, 0xd01b, "%s: len=%lx\n", __func__, *len); + + if (buf) { + ql_log(ql_log_warn, vha, 0xd015, + "Firmware dump saved to temp buffer (%ld/%p)\n", + vha->host_no, vha->hw->fw_dump); + qla2x00_post_uevent_work(vha, QLA_UEVENT_CODE_FW_DUMP); + } } static void @@ -938,6 +947,10 @@ qla27xx_fwdump(scsi_qla_host_t *vha, int hardware_locked) ql_log(ql_log_warn, vha, 0xd01e, "fwdump buffer missing.\n"); else if (!vha->hw->fw_dump_template) ql_log(ql_log_warn, vha, 0xd01f, "fwdump template missing.\n"); + else if (vha->hw->fw_dumped) + ql_log(ql_log_warn, vha, 0xd300, + "Firmware has been previously dumped (%p)," + " -- ignoring request\n", vha->hw->fw_dump); else qla27xx_execute_fwdt_template(vha); diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h index d88b86214ec5..2ed9ab90a455 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.07.00.16-k" +#define QLA2XXX_VERSION "8.07.00.18-k" #define QLA_DRIVER_MAJOR_VER 8 #define QLA_DRIVER_MINOR_VER 7 diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c index ab4879e12ea7..68c2002e78bf 100644 --- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c +++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c @@ -53,9 +53,8 @@ static struct workqueue_struct *tcm_qla2xxx_free_wq; static struct workqueue_struct *tcm_qla2xxx_cmd_wq; -/* Local pointer to allocated TCM configfs fabric module */ -static struct target_fabric_configfs *tcm_qla2xxx_fabric_configfs; -static struct target_fabric_configfs *tcm_qla2xxx_npiv_fabric_configfs; +static const struct target_core_fabric_ops tcm_qla2xxx_ops; +static const struct target_core_fabric_ops tcm_qla2xxx_npiv_ops; /* * Parse WWN. @@ -336,6 +335,14 @@ static int tcm_qla2xxx_check_demo_mode_login_only(struct se_portal_group *se_tpg return tpg->tpg_attrib.demo_mode_login_only; } +static int tcm_qla2xxx_check_prot_fabric_only(struct se_portal_group *se_tpg) +{ + struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg, + struct tcm_qla2xxx_tpg, se_tpg); + + return tpg->tpg_attrib.fabric_prot_type; +} + static struct se_node_acl *tcm_qla2xxx_alloc_fabric_acl( struct se_portal_group *se_tpg) { @@ -1082,8 +1089,53 @@ static ssize_t tcm_qla2xxx_tpg_store_enable( TF_TPG_BASE_ATTR(tcm_qla2xxx, enable, S_IRUGO | S_IWUSR); +static ssize_t tcm_qla2xxx_tpg_show_dynamic_sessions( + struct se_portal_group *se_tpg, + char *page) +{ + return target_show_dynamic_sessions(se_tpg, page); +} + +TF_TPG_BASE_ATTR_RO(tcm_qla2xxx, dynamic_sessions); + +static ssize_t tcm_qla2xxx_tpg_store_fabric_prot_type( + struct se_portal_group *se_tpg, + const char *page, + size_t count) +{ + struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg, + struct tcm_qla2xxx_tpg, se_tpg); + unsigned long val; + int ret = kstrtoul(page, 0, &val); + + if (ret) { + pr_err("kstrtoul() returned %d for fabric_prot_type\n", ret); + return ret; + } + if (val != 0 && val != 1 && val != 3) { + pr_err("Invalid qla2xxx fabric_prot_type: %lu\n", val); + return -EINVAL; + } + tpg->tpg_attrib.fabric_prot_type = val; + + return count; +} + +static ssize_t tcm_qla2xxx_tpg_show_fabric_prot_type( + struct se_portal_group *se_tpg, + char *page) +{ + struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg, + struct tcm_qla2xxx_tpg, se_tpg); + + return sprintf(page, "%d\n", tpg->tpg_attrib.fabric_prot_type); +} +TF_TPG_BASE_ATTR(tcm_qla2xxx, fabric_prot_type, S_IRUGO | S_IWUSR); + static struct configfs_attribute *tcm_qla2xxx_tpg_attrs[] = { &tcm_qla2xxx_tpg_enable.attr, + &tcm_qla2xxx_tpg_dynamic_sessions.attr, + &tcm_qla2xxx_tpg_fabric_prot_type.attr, NULL, }; @@ -1124,7 +1176,7 @@ static struct se_portal_group *tcm_qla2xxx_make_tpg( tpg->tpg_attrib.cache_dynamic_acls = 1; tpg->tpg_attrib.demo_mode_login_only = 1; - ret = core_tpg_register(&tcm_qla2xxx_fabric_configfs->tf_ops, wwn, + ret = core_tpg_register(&tcm_qla2xxx_ops, wwn, &tpg->se_tpg, tpg, TRANSPORT_TPG_TYPE_NORMAL); if (ret < 0) { kfree(tpg); @@ -1244,7 +1296,7 @@ static struct se_portal_group *tcm_qla2xxx_npiv_make_tpg( tpg->tpg_attrib.cache_dynamic_acls = 1; tpg->tpg_attrib.demo_mode_login_only = 1; - ret = core_tpg_register(&tcm_qla2xxx_npiv_fabric_configfs->tf_ops, wwn, + ret = core_tpg_register(&tcm_qla2xxx_npiv_ops, wwn, &tpg->se_tpg, tpg, TRANSPORT_TPG_TYPE_NORMAL); if (ret < 0) { kfree(tpg); @@ -1560,7 +1612,7 @@ static int tcm_qla2xxx_check_initiator_node_acl( se_sess = transport_init_session_tags(num_tags, sizeof(struct qla_tgt_cmd), - TARGET_PROT_NORMAL); + TARGET_PROT_ALL); if (IS_ERR(se_sess)) { pr_err("Unable to initialize struct se_session\n"); return PTR_ERR(se_sess); @@ -1934,7 +1986,9 @@ static struct configfs_attribute *tcm_qla2xxx_wwn_attrs[] = { NULL, }; -static struct target_core_fabric_ops tcm_qla2xxx_ops = { +static const struct target_core_fabric_ops tcm_qla2xxx_ops = { + .module = THIS_MODULE, + .name = "qla2xxx", .get_fabric_name = tcm_qla2xxx_get_fabric_name, .get_fabric_proto_ident = tcm_qla2xxx_get_fabric_proto_ident, .tpg_get_wwn = tcm_qla2xxx_get_fabric_wwn, @@ -1949,6 +2003,7 @@ static struct target_core_fabric_ops tcm_qla2xxx_ops = { tcm_qla2xxx_check_demo_write_protect, .tpg_check_prod_mode_write_protect = tcm_qla2xxx_check_prod_write_protect, + .tpg_check_prot_fabric_only = tcm_qla2xxx_check_prot_fabric_only, .tpg_check_demo_mode_login_only = tcm_qla2xxx_check_demo_mode_login_only, .tpg_alloc_fabric_acl = tcm_qla2xxx_alloc_fabric_acl, .tpg_release_fabric_acl = tcm_qla2xxx_release_fabric_acl, @@ -1983,9 +2038,15 @@ static struct target_core_fabric_ops tcm_qla2xxx_ops = { .fabric_drop_np = NULL, .fabric_make_nodeacl = tcm_qla2xxx_make_nodeacl, .fabric_drop_nodeacl = tcm_qla2xxx_drop_nodeacl, + + .tfc_wwn_attrs = tcm_qla2xxx_wwn_attrs, + .tfc_tpg_base_attrs = tcm_qla2xxx_tpg_attrs, + .tfc_tpg_attrib_attrs = tcm_qla2xxx_tpg_attrib_attrs, }; -static struct target_core_fabric_ops tcm_qla2xxx_npiv_ops = { +static const struct target_core_fabric_ops tcm_qla2xxx_npiv_ops = { + .module = THIS_MODULE, + .name = "qla2xxx_npiv", .get_fabric_name = tcm_qla2xxx_npiv_get_fabric_name, .get_fabric_proto_ident = tcm_qla2xxx_get_fabric_proto_ident, .tpg_get_wwn = tcm_qla2xxx_get_fabric_wwn, @@ -2033,94 +2094,26 @@ static struct target_core_fabric_ops tcm_qla2xxx_npiv_ops = { .fabric_drop_np = NULL, .fabric_make_nodeacl = tcm_qla2xxx_make_nodeacl, .fabric_drop_nodeacl = tcm_qla2xxx_drop_nodeacl, + + .tfc_wwn_attrs = tcm_qla2xxx_wwn_attrs, + .tfc_tpg_base_attrs = tcm_qla2xxx_npiv_tpg_attrs, }; static int tcm_qla2xxx_register_configfs(void) { - struct target_fabric_configfs *fabric, *npiv_fabric; int ret; pr_debug("TCM QLOGIC QLA2XXX fabric module %s on %s/%s on " UTS_RELEASE"\n", TCM_QLA2XXX_VERSION, utsname()->sysname, utsname()->machine); - /* - * Register the top level struct config_item_type with TCM core - */ - fabric = target_fabric_configfs_init(THIS_MODULE, "qla2xxx"); - if (IS_ERR(fabric)) { - pr_err("target_fabric_configfs_init() failed\n"); - return PTR_ERR(fabric); - } - /* - * Setup fabric->tf_ops from our local tcm_qla2xxx_ops - */ - fabric->tf_ops = tcm_qla2xxx_ops; - /* - * Setup default attribute lists for various fabric->tf_cit_tmpl - */ - fabric->tf_cit_tmpl.tfc_wwn_cit.ct_attrs = tcm_qla2xxx_wwn_attrs; - fabric->tf_cit_tmpl.tfc_tpg_base_cit.ct_attrs = tcm_qla2xxx_tpg_attrs; - fabric->tf_cit_tmpl.tfc_tpg_attrib_cit.ct_attrs = - tcm_qla2xxx_tpg_attrib_attrs; - fabric->tf_cit_tmpl.tfc_tpg_param_cit.ct_attrs = NULL; - fabric->tf_cit_tmpl.tfc_tpg_np_base_cit.ct_attrs = NULL; - fabric->tf_cit_tmpl.tfc_tpg_nacl_base_cit.ct_attrs = NULL; - fabric->tf_cit_tmpl.tfc_tpg_nacl_attrib_cit.ct_attrs = NULL; - fabric->tf_cit_tmpl.tfc_tpg_nacl_auth_cit.ct_attrs = NULL; - fabric->tf_cit_tmpl.tfc_tpg_nacl_param_cit.ct_attrs = NULL; - /* - * Register the fabric for use within TCM - */ - ret = target_fabric_configfs_register(fabric); - if (ret < 0) { - pr_err("target_fabric_configfs_register() failed for TCM_QLA2XXX\n"); + + ret = target_register_template(&tcm_qla2xxx_ops); + if (ret) return ret; - } - /* - * Setup our local pointer to *fabric - */ - tcm_qla2xxx_fabric_configfs = fabric; - pr_debug("TCM_QLA2XXX[0] - Set fabric -> tcm_qla2xxx_fabric_configfs\n"); - /* - * Register the top level struct config_item_type for NPIV with TCM core - */ - npiv_fabric = target_fabric_configfs_init(THIS_MODULE, "qla2xxx_npiv"); - if (IS_ERR(npiv_fabric)) { - pr_err("target_fabric_configfs_init() failed\n"); - ret = PTR_ERR(npiv_fabric); - goto out_fabric; - } - /* - * Setup fabric->tf_ops from our local tcm_qla2xxx_npiv_ops - */ - npiv_fabric->tf_ops = tcm_qla2xxx_npiv_ops; - /* - * Setup default attribute lists for various npiv_fabric->tf_cit_tmpl - */ - npiv_fabric->tf_cit_tmpl.tfc_wwn_cit.ct_attrs = tcm_qla2xxx_wwn_attrs; - npiv_fabric->tf_cit_tmpl.tfc_tpg_base_cit.ct_attrs = - tcm_qla2xxx_npiv_tpg_attrs; - npiv_fabric->tf_cit_tmpl.tfc_tpg_attrib_cit.ct_attrs = NULL; - npiv_fabric->tf_cit_tmpl.tfc_tpg_param_cit.ct_attrs = NULL; - npiv_fabric->tf_cit_tmpl.tfc_tpg_np_base_cit.ct_attrs = NULL; - npiv_fabric->tf_cit_tmpl.tfc_tpg_nacl_base_cit.ct_attrs = NULL; - npiv_fabric->tf_cit_tmpl.tfc_tpg_nacl_attrib_cit.ct_attrs = NULL; - npiv_fabric->tf_cit_tmpl.tfc_tpg_nacl_auth_cit.ct_attrs = NULL; - npiv_fabric->tf_cit_tmpl.tfc_tpg_nacl_param_cit.ct_attrs = NULL; - /* - * Register the npiv_fabric for use within TCM - */ - ret = target_fabric_configfs_register(npiv_fabric); - if (ret < 0) { - pr_err("target_fabric_configfs_register() failed for TCM_QLA2XXX\n"); + ret = target_register_template(&tcm_qla2xxx_npiv_ops); + if (ret) goto out_fabric; - } - /* - * Setup our local pointer to *npiv_fabric - */ - tcm_qla2xxx_npiv_fabric_configfs = npiv_fabric; - pr_debug("TCM_QLA2XXX[0] - Set fabric -> tcm_qla2xxx_npiv_fabric_configfs\n"); tcm_qla2xxx_free_wq = alloc_workqueue("tcm_qla2xxx_free", WQ_MEM_RECLAIM, 0); @@ -2140,9 +2133,9 @@ static int tcm_qla2xxx_register_configfs(void) out_free_wq: destroy_workqueue(tcm_qla2xxx_free_wq); out_fabric_npiv: - target_fabric_configfs_deregister(tcm_qla2xxx_npiv_fabric_configfs); + target_unregister_template(&tcm_qla2xxx_npiv_ops); out_fabric: - target_fabric_configfs_deregister(tcm_qla2xxx_fabric_configfs); + target_unregister_template(&tcm_qla2xxx_ops); return ret; } @@ -2151,13 +2144,8 @@ static void tcm_qla2xxx_deregister_configfs(void) destroy_workqueue(tcm_qla2xxx_cmd_wq); destroy_workqueue(tcm_qla2xxx_free_wq); - target_fabric_configfs_deregister(tcm_qla2xxx_fabric_configfs); - tcm_qla2xxx_fabric_configfs = NULL; - pr_debug("TCM_QLA2XXX[0] - Cleared tcm_qla2xxx_fabric_configfs\n"); - - target_fabric_configfs_deregister(tcm_qla2xxx_npiv_fabric_configfs); - tcm_qla2xxx_npiv_fabric_configfs = NULL; - pr_debug("TCM_QLA2XXX[0] - Cleared tcm_qla2xxx_npiv_fabric_configfs\n"); + target_unregister_template(&tcm_qla2xxx_ops); + target_unregister_template(&tcm_qla2xxx_npiv_ops); } static int __init tcm_qla2xxx_init(void) diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.h b/drivers/scsi/qla2xxx/tcm_qla2xxx.h index 10c002145648..23295115c9fc 100644 --- a/drivers/scsi/qla2xxx/tcm_qla2xxx.h +++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.h @@ -33,6 +33,7 @@ struct tcm_qla2xxx_tpg_attrib { int demo_mode_write_protect; int prod_mode_write_protect; int demo_mode_login_only; + int fabric_prot_type; }; struct tcm_qla2xxx_tpg { |