diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-08-16 08:06:26 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-08-16 08:06:26 +0300 |
commit | 72f02ba66bd83b54054da20eae550123de84da6f (patch) | |
tree | 96a8360400e040aa2e38e7352594dbbc485461db /drivers/scsi/qla2xxx/qla_mbx.c | |
parent | db06f826ec12bf0701ea7fc0a3c0aa00b84417c8 (diff) | |
parent | 51372570ac3c919b036e760f4ca449e81cf8e995 (diff) | |
download | linux-72f02ba66bd83b54054da20eae550123de84da6f.tar.xz |
Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
Pull SCSI updates from James Bottomley:
"This is mostly updates to the usual drivers: mpt3sas, lpfc, qla2xxx,
hisi_sas, smartpqi, megaraid_sas, arcmsr.
In addition, with the continuing absence of Nic we have target updates
for tcmu and target core (all with reviews and acks).
The biggest observable change is going to be that we're (again) trying
to switch to mulitqueue as the default (a user can still override the
setting on the kernel command line).
Other major core stuff is the removal of the remaining Microchannel
drivers, an update of the internal timers and some reworks of
completion and result handling"
* tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (203 commits)
scsi: core: use blk_mq_run_hw_queues in scsi_kick_queue
scsi: ufs: remove unnecessary query(DM) UPIU trace
scsi: qla2xxx: Fix issue reported by static checker for qla2x00_els_dcmd2_sp_done()
scsi: aacraid: Spelling fix in comment
scsi: mpt3sas: Fix calltrace observed while running IO & reset
scsi: aic94xx: fix an error code in aic94xx_init()
scsi: st: remove redundant pointer STbuffer
scsi: qla2xxx: Update driver version to 10.00.00.08-k
scsi: qla2xxx: Migrate NVME N2N handling into state machine
scsi: qla2xxx: Save frame payload size from ICB
scsi: qla2xxx: Fix stalled relogin
scsi: qla2xxx: Fix race between switch cmd completion and timeout
scsi: qla2xxx: Fix Management Server NPort handle reservation logic
scsi: qla2xxx: Flush mailbox commands on chip reset
scsi: qla2xxx: Fix unintended Logout
scsi: qla2xxx: Fix session state stuck in Get Port DB
scsi: qla2xxx: Fix redundant fc_rport registration
scsi: qla2xxx: Silent erroneous message
scsi: qla2xxx: Prevent sysfs access when chip is down
scsi: qla2xxx: Add longer window for chip reset
...
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_mbx.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_mbx.c | 155 |
1 files changed, 109 insertions, 46 deletions
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index f0ec13d48bf3..2c6c2cd5a0d0 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c @@ -59,6 +59,7 @@ static struct rom_cmd { { MBC_IOCB_COMMAND_A64 }, { MBC_GET_ADAPTER_LOOP_ID }, { MBC_READ_SFP }, + { MBC_GET_RNID_PARAMS }, }; static int is_rom_cmd(uint16_t cmd) @@ -110,6 +111,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) unsigned long wait_time; struct qla_hw_data *ha = vha->hw; scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev); + u32 chip_reset; ql_dbg(ql_dbg_mbx, vha, 0x1000, "Entered %s.\n", __func__); @@ -140,7 +142,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) rval = QLA_SUCCESS; abort_active = test_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags); - + chip_reset = ha->chip_reset; if (ha->flags.pci_channel_io_perm_failure) { ql_log(ql_log_warn, vha, 0x1003, @@ -167,6 +169,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) return QLA_FUNCTION_TIMEOUT; } + atomic_inc(&ha->num_pend_mbx_stage1); /* * Wait for active mailbox commands to finish by waiting at most tov * seconds. This is to serialize actual issuing of mailbox cmds during @@ -177,8 +180,14 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) ql_log(ql_log_warn, vha, 0xd035, "Cmd access timeout, cmd=0x%x, Exiting.\n", mcp->mb[0]); + atomic_dec(&ha->num_pend_mbx_stage1); return QLA_FUNCTION_TIMEOUT; } + atomic_dec(&ha->num_pend_mbx_stage1); + if (ha->flags.purge_mbox || chip_reset != ha->chip_reset) { + rval = QLA_ABORTED; + goto premature_exit; + } ha->flags.mbox_busy = 1; /* Save mailbox command for debug */ @@ -189,6 +198,13 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) spin_lock_irqsave(&ha->hardware_lock, flags); + if (ha->flags.purge_mbox || chip_reset != ha->chip_reset) { + rval = QLA_ABORTED; + ha->flags.mbox_busy = 0; + spin_unlock_irqrestore(&ha->hardware_lock, flags); + goto premature_exit; + } + /* Load mailbox registers. */ if (IS_P3P_TYPE(ha)) optr = (uint16_t __iomem *)®->isp82.mailbox_in[0]; @@ -231,7 +247,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) "jiffies=%lx.\n", jiffies); /* Wait for mbx cmd completion until timeout */ - + atomic_inc(&ha->num_pend_mbx_stage2); if ((!abort_active && io_lock_on) || IS_NOPOLLING_TYPE(ha)) { set_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags); @@ -241,6 +257,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) spin_unlock_irqrestore(&ha->hardware_lock, flags); ha->flags.mbox_busy = 0; + atomic_dec(&ha->num_pend_mbx_stage2); ql_dbg(ql_dbg_mbx, vha, 0x1010, "Pending mailbox timeout, exiting.\n"); rval = QLA_FUNCTION_TIMEOUT; @@ -254,6 +271,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) spin_unlock_irqrestore(&ha->hardware_lock, flags); wait_time = jiffies; + atomic_inc(&ha->num_pend_mbx_stage3); if (!wait_for_completion_timeout(&ha->mbx_intr_comp, mcp->tov * HZ)) { ql_dbg(ql_dbg_mbx, vha, 0x117a, @@ -261,7 +279,17 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) spin_lock_irqsave(&ha->hardware_lock, flags); clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags); spin_unlock_irqrestore(&ha->hardware_lock, flags); + + } else if (ha->flags.purge_mbox || + chip_reset != ha->chip_reset) { + ha->flags.mbox_busy = 0; + atomic_dec(&ha->num_pend_mbx_stage2); + atomic_dec(&ha->num_pend_mbx_stage3); + rval = QLA_ABORTED; + goto premature_exit; } + atomic_dec(&ha->num_pend_mbx_stage3); + if (time_after(jiffies, wait_time + 5 * HZ)) ql_log(ql_log_warn, vha, 0x1015, "cmd=0x%x, waited %d msecs\n", command, jiffies_to_msecs(jiffies - wait_time)); @@ -275,6 +303,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) spin_unlock_irqrestore(&ha->hardware_lock, flags); ha->flags.mbox_busy = 0; + atomic_dec(&ha->num_pend_mbx_stage2); ql_dbg(ql_dbg_mbx, vha, 0x1012, "Pending mailbox timeout, exiting.\n"); rval = QLA_FUNCTION_TIMEOUT; @@ -289,6 +318,14 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) wait_time = jiffies + mcp->tov * HZ; /* wait at most tov secs */ while (!ha->flags.mbox_int) { + if (ha->flags.purge_mbox || + chip_reset != ha->chip_reset) { + ha->flags.mbox_busy = 0; + atomic_dec(&ha->num_pend_mbx_stage2); + rval = QLA_ABORTED; + goto premature_exit; + } + if (time_after(jiffies, wait_time)) break; @@ -312,6 +349,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) "Waited %d sec.\n", (uint)((jiffies - (wait_time - (mcp->tov * HZ)))/HZ)); } + atomic_dec(&ha->num_pend_mbx_stage2); /* Check whether we timed out */ if (ha->flags.mbox_int) { @@ -390,7 +428,8 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) /* Capture FW dump only, if PCI device active */ if (!pci_channel_offline(vha->hw->pdev)) { pci_read_config_word(ha->pdev, PCI_VENDOR_ID, &w); - if (w == 0xffff || ictrl == 0xffffffff) { + if (w == 0xffff || ictrl == 0xffffffff || + (chip_reset != ha->chip_reset)) { /* This is special case if there is unload * of driver happening and if PCI device go * into bad state due to PCI error condition @@ -497,7 +536,11 @@ premature_exit: complete(&ha->mbx_cmd_comp); mbx_done: - if (rval) { + if (rval == QLA_ABORTED) { + ql_log(ql_log_info, vha, 0xd035, + "Chip Reset in progress. Purging Mbox cmd=0x%x.\n", + mcp->mb[0]); + } else if (rval) { if (ql2xextended_error_logging & (ql_dbg_disc|ql_dbg_mbx)) { pr_warn("%s [%s]-%04x:%ld: **** Failed", QL_MSGHDR, dev_name(&ha->pdev->dev), 0x1020+0x800, @@ -2177,7 +2220,10 @@ qla2x00_lip_reset(scsi_qla_host_t *vha) mcp->out_mb = MBX_2|MBX_1|MBX_0; } else if (IS_FWI2_CAPABLE(vha->hw)) { mcp->mb[0] = MBC_LIP_FULL_LOGIN; - mcp->mb[1] = BIT_6; + if (N2N_TOPO(vha->hw)) + mcp->mb[1] = BIT_4; /* re-init */ + else + mcp->mb[1] = BIT_6; /* LIP */ mcp->mb[2] = 0; mcp->mb[3] = vha->hw->loop_reset_delay; mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; @@ -3797,30 +3843,68 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha, "Format 1: WWPN %8phC.\n", vha->port_name); - /* N2N. direct connect */ - if (IS_QLA27XX(ha) && - ((rptid_entry->u.f1.flags>>1) & 0x7) == 2) { - /* if our portname is higher then initiate N2N login */ - if (wwn_to_u64(vha->port_name) > - wwn_to_u64(rptid_entry->u.f1.port_name)) { - // ??? qlt_update_host_map(vha, id); - vha->n2n_id = 0x1; - ql_dbg(ql_dbg_async, vha, 0x5075, - "Format 1: Setting n2n_update_needed for id %d\n", - vha->n2n_id); + switch (rptid_entry->u.f1.flags & TOPO_MASK) { + case TOPO_N2N: + ha->current_topology = ISP_CFG_N; + spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags); + fcport = qla2x00_find_fcport_by_wwpn(vha, + rptid_entry->u.f1.port_name, 1); + spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags); + + if (fcport) { + fcport->plogi_nack_done_deadline = jiffies + HZ; + fcport->dm_login_expire = jiffies + 3*HZ; + fcport->scan_state = QLA_FCPORT_FOUND; + switch (fcport->disc_state) { + case DSC_DELETED: + set_bit(RELOGIN_NEEDED, + &vha->dpc_flags); + break; + case DSC_DELETE_PEND: + break; + default: + qlt_schedule_sess_for_deletion(fcport); + break; + } } else { - ql_dbg(ql_dbg_async, vha, 0x5075, - "Format 1: Remote login - Waiting for WWPN %8phC.\n", - rptid_entry->u.f1.port_name); + id.b24 = 0; + if (wwn_to_u64(vha->port_name) > + wwn_to_u64(rptid_entry->u.f1.port_name)) { + vha->d_id.b24 = 0; + vha->d_id.b.al_pa = 1; + ha->flags.n2n_bigger = 1; + + id.b.al_pa = 2; + ql_dbg(ql_dbg_async, vha, 0x5075, + "Format 1: assign local id %x remote id %x\n", + vha->d_id.b24, id.b24); + } else { + ql_dbg(ql_dbg_async, vha, 0x5075, + "Format 1: Remote login - Waiting for WWPN %8phC.\n", + rptid_entry->u.f1.port_name); + ha->flags.n2n_bigger = 0; + } + qla24xx_post_newsess_work(vha, &id, + rptid_entry->u.f1.port_name, + rptid_entry->u.f1.node_name, + NULL, + FC4_TYPE_UNKNOWN); } - memcpy(vha->n2n_port_name, rptid_entry->u.f1.port_name, - WWN_SIZE); + /* if our portname is higher then initiate N2N login */ + set_bit(N2N_LOGIN_NEEDED, &vha->dpc_flags); - set_bit(REGISTER_FC4_NEEDED, &vha->dpc_flags); - set_bit(REGISTER_FDMI_NEEDED, &vha->dpc_flags); ha->flags.n2n_ae = 1; return; + break; + case TOPO_FL: + ha->current_topology = ISP_CFG_FL; + break; + case TOPO_F: + ha->current_topology = ISP_CFG_F; + break; + default: + break; } ha->flags.gpsc_supported = 1; @@ -3909,30 +3993,9 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha, rptid_entry->u.f2.port_name, 1); if (fcport) { + fcport->login_retry = vha->hw->login_retry_count; fcport->plogi_nack_done_deadline = jiffies + HZ; fcport->scan_state = QLA_FCPORT_FOUND; - switch (fcport->disc_state) { - case DSC_DELETED: - ql_dbg(ql_dbg_disc, vha, 0x210d, - "%s %d %8phC login\n", - __func__, __LINE__, fcport->port_name); - qla24xx_fcport_handle_login(vha, fcport); - break; - case DSC_DELETE_PEND: - break; - default: - qlt_schedule_sess_for_deletion(fcport); - break; - } - } else { - id.b.al_pa = rptid_entry->u.f2.remote_nport_id[0]; - id.b.area = rptid_entry->u.f2.remote_nport_id[1]; - id.b.domain = rptid_entry->u.f2.remote_nport_id[2]; - qla24xx_post_newsess_work(vha, &id, - rptid_entry->u.f2.port_name, - rptid_entry->u.f2.node_name, - NULL, - FC4_TYPE_UNKNOWN); } } } @@ -4663,7 +4726,7 @@ qla24xx_get_port_login_templ(scsi_qla_host_t *vha, dma_addr_t buf_dma, "Done %s.\n", __func__); bp = (uint32_t *) buf; for (i = 0; i < (bufsiz-4)/4; i++, bp++) - *bp = cpu_to_be32(*bp); + *bp = le32_to_cpu(*bp); } return rval; |