diff options
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_init.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_init.c | 167 |
1 files changed, 93 insertions, 74 deletions
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 1d041313ec52..aa5204163bec 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -17,7 +17,6 @@ #include <asm/prom.h> #endif -#include <target/target_core_base.h> #include "qla_target.h" /* @@ -101,8 +100,22 @@ static void qla24xx_abort_iocb_timeout(void *data) u32 handle; unsigned long flags; + if (sp->cmd_sp) + ql_dbg(ql_dbg_async, sp->vha, 0x507c, + "Abort timeout - cmd hdl=%x, cmd type=%x hdl=%x, type=%x\n", + sp->cmd_sp->handle, sp->cmd_sp->type, + sp->handle, sp->type); + else + ql_dbg(ql_dbg_async, sp->vha, 0x507c, + "Abort timeout 2 - hdl=%x, type=%x\n", + sp->handle, sp->type); + spin_lock_irqsave(qpair->qp_lock_ptr, flags); for (handle = 1; handle < qpair->req->num_outstanding_cmds; handle++) { + if (sp->cmd_sp && (qpair->req->outstanding_cmds[handle] == + sp->cmd_sp)) + qpair->req->outstanding_cmds[handle] = NULL; + /* removing the abort */ if (qpair->req->outstanding_cmds[handle] == sp) { qpair->req->outstanding_cmds[handle] = NULL; @@ -111,6 +124,9 @@ static void qla24xx_abort_iocb_timeout(void *data) } spin_unlock_irqrestore(qpair->qp_lock_ptr, flags); + if (sp->cmd_sp) + sp->cmd_sp->done(sp->cmd_sp, QLA_OS_TIMER_EXPIRED); + abt->u.abt.comp_status = CS_TIMEOUT; sp->done(sp, QLA_OS_TIMER_EXPIRED); } @@ -142,6 +158,7 @@ static int qla24xx_async_abort_cmd(srb_t *cmd_sp, bool wait) sp->type = SRB_ABT_CMD; sp->name = "abort"; sp->qpair = cmd_sp->qpair; + sp->cmd_sp = cmd_sp; if (wait) sp->flags = SRB_WAKEUP_ON_COMP; @@ -328,7 +345,7 @@ qla2x00_async_login(struct scsi_qla_host *vha, fc_port_t *fcport, else lio->u.logio.flags |= SRB_LOGIN_COND_PLOGI; - if (fcport->fc4f_nvme) + if (NVME_TARGET(vha->hw, fcport)) lio->u.logio.flags |= SRB_LOGIN_SKIP_PRLI; ql_dbg(ql_dbg_disc, vha, 0x2072, @@ -516,6 +533,7 @@ static int qla_post_els_plogi_work(struct scsi_qla_host *vha, fc_port_t *fcport) e->u.fcport.fcport = fcport; fcport->flags |= FCF_ASYNC_ACTIVE; + fcport->disc_state = DSC_LOGIN_PEND; return qla2x00_post_work(vha, e); } @@ -726,19 +744,17 @@ static void qla24xx_handle_gnl_done_event(scsi_qla_host_t *vha, loop_id = le16_to_cpu(e->nport_handle); loop_id = (loop_id & 0x7fff); - if (fcport->fc4f_nvme) + if (NVME_TARGET(vha->hw, fcport)) current_login_state = e->current_login_state >> 4; else current_login_state = e->current_login_state & 0xf; - ql_dbg(ql_dbg_disc, vha, 0x20e2, - "%s found %8phC CLS [%x|%x] nvme %d ID[%02x%02x%02x|%02x%02x%02x] lid[%d|%d]\n", + "%s found %8phC CLS [%x|%x] fc4_type %d ID[%06x|%06x] lid[%d|%d]\n", __func__, fcport->port_name, e->current_login_state, fcport->fw_login_state, - fcport->fc4f_nvme, id.b.domain, id.b.area, id.b.al_pa, - fcport->d_id.b.domain, fcport->d_id.b.area, - fcport->d_id.b.al_pa, loop_id, fcport->loop_id); + fcport->fc4_type, id.b24, fcport->d_id.b24, + loop_id, fcport->loop_id); switch (fcport->disc_state) { case DSC_DELETE_PEND: @@ -1135,19 +1151,18 @@ static void qla24xx_async_gpdb_sp_done(srb_t *sp, int res) "Async done-%s res %x, WWPN %8phC mb[1]=%x mb[2]=%x \n", sp->name, res, fcport->port_name, mb[1], mb[2]); - if (res == QLA_FUNCTION_TIMEOUT) { - dma_pool_free(sp->vha->hw->s_dma_pool, sp->u.iocb_cmd.u.mbx.in, - sp->u.iocb_cmd.u.mbx.in_dma); - return; - } - fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE); + + if (res == QLA_FUNCTION_TIMEOUT) + goto done; + memset(&ea, 0, sizeof(ea)); ea.fcport = fcport; ea.sp = sp; qla24xx_handle_gpdb_event(vha, &ea); +done: dma_pool_free(ha->s_dma_pool, sp->u.iocb_cmd.u.mbx.in, sp->u.iocb_cmd.u.mbx.in_dma); @@ -1225,13 +1240,13 @@ qla24xx_async_prli(struct scsi_qla_host *vha, fc_port_t *fcport) sp->done = qla2x00_async_prli_sp_done; lio->u.logio.flags = 0; - if (fcport->fc4f_nvme) + if (NVME_TARGET(vha->hw, fcport)) lio->u.logio.flags |= SRB_LOGIN_NVME_PRLI; ql_dbg(ql_dbg_disc, vha, 0x211b, "Async-prli - %8phC hdl=%x, loopid=%x portid=%06x retries=%d %s.\n", fcport->port_name, sp->handle, fcport->loop_id, fcport->d_id.b24, - fcport->login_retry, fcport->fc4f_nvme ? "nvme" : "fc"); + fcport->login_retry, NVME_TARGET(vha->hw, fcport) ? "nvme" : "fc"); rval = qla2x00_start_sp(sp); if (rval != QLA_SUCCESS) { @@ -1382,14 +1397,14 @@ void qla24xx_handle_gpdb_event(scsi_qla_host_t *vha, struct event_arg *ea) fcport->flags &= ~FCF_ASYNC_SENT; ql_dbg(ql_dbg_disc, vha, 0x20d2, - "%s %8phC DS %d LS %d nvme %x rc %d\n", __func__, fcport->port_name, - fcport->disc_state, pd->current_login_state, fcport->fc4f_nvme, - ea->rc); + "%s %8phC DS %d LS %d fc4_type %x rc %d\n", __func__, + fcport->port_name, fcport->disc_state, pd->current_login_state, + fcport->fc4_type, ea->rc); if (fcport->disc_state == DSC_DELETE_PEND) return; - if (fcport->fc4f_nvme) + if (NVME_TARGET(vha->hw, fcport)) ls = pd->current_login_state >> 4; else ls = pd->current_login_state & 0xf; @@ -1512,8 +1527,8 @@ int qla24xx_fcport_handle_login(struct scsi_qla_host *vha, fc_port_t *fcport) } } - /* for pure Target Mode. Login will not be initiated */ - if (vha->host->active_mode == MODE_TARGET) + /* Target won't initiate port login if fabric is present */ + if (vha->host->active_mode == MODE_TARGET && !N2N_TOPO(vha->hw)) return 0; if (fcport->flags & FCF_ASYNC_SENT) { @@ -1578,7 +1593,8 @@ int qla24xx_fcport_handle_login(struct scsi_qla_host *vha, fc_port_t *fcport) ql_dbg(ql_dbg_disc, vha, 0x2118, "%s %d %8phC post %s PRLI\n", __func__, __LINE__, fcport->port_name, - fcport->fc4f_nvme ? "NVME" : "FC"); + NVME_TARGET(vha->hw, fcport) ? "NVME" : + "FC"); qla24xx_post_prli_work(vha, fcport); } break; @@ -1701,6 +1717,19 @@ void qla24xx_handle_relogin_event(scsi_qla_host_t *vha, qla24xx_fcport_handle_login(vha, fcport); } +void qla_handle_els_plogi_done(scsi_qla_host_t *vha, + struct event_arg *ea) +{ + /* for pure Target Mode, PRLI will not be initiated */ + if (vha->host->active_mode == MODE_TARGET) + return; + + ql_dbg(ql_dbg_disc, vha, 0x2118, + "%s %d %8phC post PRLI\n", + __func__, __LINE__, ea->fcport->port_name); + qla24xx_post_prli_work(vha, ea->fcport); +} + /* * RSCN(s) came in for this fcport, but the RSCN(s) was not able * to be consumed by the fcport @@ -1860,38 +1889,26 @@ qla24xx_handle_prli_done_event(struct scsi_qla_host *vha, struct event_arg *ea) break; } - if (ea->fcport->fc4f_nvme) { + /* + * Retry PRLI with other FC-4 type if failure occurred on dual + * FCP/NVMe port + */ + if (NVME_FCP_TARGET(ea->fcport)) { ql_dbg(ql_dbg_disc, vha, 0x2118, - "%s %d %8phC post fc4 prli\n", - __func__, __LINE__, ea->fcport->port_name); - ea->fcport->fc4f_nvme = 0; - qla24xx_post_prli_work(vha, ea->fcport); - return; + "%s %d %8phC post %s prli\n", + __func__, __LINE__, ea->fcport->port_name, + (ea->fcport->fc4_type & FS_FC4TYPE_NVME) ? + "NVMe" : "FCP"); + if (vha->hw->fc4_type_priority == FC4_PRIORITY_NVME) + ea->fcport->fc4_type &= ~FS_FC4TYPE_NVME; + else + ea->fcport->fc4_type &= ~FS_FC4TYPE_FCP; } - /* at this point both PRLI NVME & PRLI FCP failed */ - if (N2N_TOPO(vha->hw)) { - if (ea->fcport->n2n_link_reset_cnt < 3) { - ea->fcport->n2n_link_reset_cnt++; - /* - * remote port is not sending Plogi. Reset - * link to kick start his state machine - */ - set_bit(N2N_LINK_RESET, &vha->dpc_flags); - } else { - ql_log(ql_log_warn, vha, 0x2119, - "%s %d %8phC Unable to reconnect\n", - __func__, __LINE__, ea->fcport->port_name); - } - } else { - /* - * switch connect. login failed. Take connection - * down and allow relogin to retrigger - */ - ea->fcport->flags &= ~FCF_ASYNC_SENT; - ea->fcport->keep_nport_handle = 0; - qlt_schedule_sess_for_deletion(ea->fcport); - } + ea->fcport->flags &= ~FCF_ASYNC_SENT; + ea->fcport->keep_nport_handle = 0; + ea->fcport->logout_on_delete = 1; + qlt_schedule_sess_for_deletion(ea->fcport); break; } } @@ -1952,7 +1969,7 @@ qla24xx_handle_plogi_done_event(struct scsi_qla_host *vha, struct event_arg *ea) * force a relogin attempt via implicit LOGO, PLOGI, and PRLI * requests. */ - if (ea->fcport->fc4f_nvme) { + if (NVME_TARGET(vha->hw, ea->fcport)) { ql_dbg(ql_dbg_disc, vha, 0x2117, "%s %d %8phC post prli\n", __func__, __LINE__, ea->fcport->port_name); @@ -2206,8 +2223,18 @@ qla2x00_initialize_adapter(scsi_qla_host_t *vha) ql_dbg(ql_dbg_init, vha, 0x0061, "Configure NVRAM parameters...\n"); + /* Let priority default to FCP, can be overridden by nvram_config */ + ha->fc4_type_priority = FC4_PRIORITY_FCP; + ha->isp_ops->nvram_config(vha); + if (ha->fc4_type_priority != FC4_PRIORITY_FCP && + ha->fc4_type_priority != FC4_PRIORITY_NVME) + ha->fc4_type_priority = FC4_PRIORITY_FCP; + + ql_log(ql_log_info, vha, 0xffff, "FC4 priority set to %s\n", + ha->fc4_type_priority == FC4_PRIORITY_FCP ? "FCP" : "NVMe"); + if (ha->flags.disable_serdes) { /* Mask HBA via NVRAM settings? */ ql_log(ql_log_info, vha, 0x0077, @@ -4830,6 +4857,7 @@ qla2x00_alloc_fcport(scsi_qla_host_t *vha, gfp_t flags) } INIT_WORK(&fcport->del_work, qla24xx_delete_sess_fn); + INIT_WORK(&fcport->free_work, qlt_free_session_done); INIT_WORK(&fcport->reg_work, qla_register_fcport_fn); INIT_LIST_HEAD(&fcport->gnl_entry); INIT_LIST_HEAD(&fcport->list); @@ -4908,14 +4936,8 @@ qla2x00_configure_loop(scsi_qla_host_t *vha) set_bit(RSCN_UPDATE, &flags); clear_bit(LOCAL_LOOP_UPDATE, &flags); - } else if (ha->current_topology == ISP_CFG_N) { - clear_bit(RSCN_UPDATE, &flags); - if (qla_tgt_mode_enabled(vha)) { - /* allow the other side to start the login */ - clear_bit(LOCAL_LOOP_UPDATE, &flags); - set_bit(RELOGIN_NEEDED, &vha->dpc_flags); - } - } else if (ha->current_topology == ISP_CFG_NL) { + } else if (ha->current_topology == ISP_CFG_NL || + ha->current_topology == ISP_CFG_N) { clear_bit(RSCN_UPDATE, &flags); set_bit(LOCAL_LOOP_UPDATE, &flags); } else if (!vha->flags.online || @@ -5032,7 +5054,6 @@ qla2x00_configure_local_loop(scsi_qla_host_t *vha) memcpy(&ha->plogi_els_payld.data, (void *)ha->init_cb, sizeof(ha->plogi_els_payld.data)); - set_bit(RELOGIN_NEEDED, &vha->dpc_flags); } else { ql_dbg(ql_dbg_init, vha, 0x00d1, "PLOGI ELS param read fail.\n"); @@ -5382,7 +5403,7 @@ qla2x00_update_fcport(scsi_qla_host_t *vha, fc_port_t *fcport) qla2x00_iidma_fcport(vha, fcport); - if (fcport->fc4f_nvme) { + if (NVME_TARGET(vha->hw, fcport)) { qla_nvme_register_remote(vha, fcport); fcport->disc_state = DSC_LOGIN_COMPLETE; qla2x00_set_fcport_state(fcport, FCS_ONLINE); @@ -5710,11 +5731,8 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha) new_fcport->fc4_type = swl[swl_idx].fc4_type; new_fcport->nvme_flag = 0; - new_fcport->fc4f_nvme = 0; if (vha->flags.nvme_enabled && - swl[swl_idx].fc4f_nvme) { - new_fcport->fc4f_nvme = - swl[swl_idx].fc4f_nvme; + swl[swl_idx].fc4_type & FS_FC4TYPE_NVME) { ql_log(ql_log_info, vha, 0x2131, "FOUND: NVME port %8phC as FC Type 28h\n", new_fcport->port_name); @@ -5770,7 +5788,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha) /* Bypass ports whose FCP-4 type is not FCP_SCSI */ if (ql2xgffidenable && - (new_fcport->fc4_type != FC4_TYPE_FCP_SCSI && + (!(new_fcport->fc4_type & FS_FC4TYPE_FCP) && new_fcport->fc4_type != FC4_TYPE_UNKNOWN)) continue; @@ -5839,7 +5857,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha) break; } - if (fcport->fc4f_nvme) { + if (NVME_TARGET(vha->hw, fcport)) { if (fcport->disc_state == DSC_DELETE_PEND) { fcport->disc_state = DSC_GNL; vha->fcport_count--; @@ -5879,8 +5897,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha) if (test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags)) break; - if ((fcport->flags & FCF_FABRIC_DEVICE) == 0 || - (fcport->flags & FCF_LOGIN_NEEDED) == 0) + if ((fcport->flags & FCF_FABRIC_DEVICE) == 0) continue; if (fcport->scan_state == QLA_FCPORT_SCAN) { @@ -5903,7 +5920,8 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha) } } - if (fcport->scan_state == QLA_FCPORT_FOUND) + if (fcport->scan_state == QLA_FCPORT_FOUND && + (fcport->flags & FCF_LOGIN_NEEDED) != 0) qla24xx_fcport_handle_login(vha, fcport); } return (rval); @@ -8514,6 +8532,9 @@ qla81xx_nvram_config(scsi_qla_host_t *vha) /* N2N: driver will initiate Login instead of FW */ icb->firmware_options_3 |= BIT_8; + /* Determine NVMe/FCP priority for target ports */ + ha->fc4_type_priority = qla2xxx_get_fc4_priority(vha); + if (rval) { ql_log(ql_log_warn, vha, 0x0076, "NVRAM configuration failed.\n"); @@ -9003,8 +9024,6 @@ int qla2xxx_delete_qpair(struct scsi_qla_host *vha, struct qla_qpair *qpair) struct qla_hw_data *ha = qpair->hw; qpair->delete_in_progress = 1; - while (atomic_read(&qpair->ref_count)) - msleep(500); ret = qla25xx_delete_req_que(vha, qpair->req); if (ret != QLA_SUCCESS) |