diff options
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_isr.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_isr.c | 129 |
1 files changed, 97 insertions, 32 deletions
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 9d9668aac6f6..14109d86c3f6 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -809,6 +809,7 @@ skip_rio: break; case MBA_LOOP_DOWN: /* Loop Down Event */ + SAVE_TOPO(ha); ha->flags.n2n_ae = 0; ha->flags.lip_ae = 0; ha->current_topology = 0; @@ -922,7 +923,6 @@ skip_rio: set_bit(REGISTER_FC4_NEEDED, &vha->dpc_flags); set_bit(REGISTER_FDMI_NEEDED, &vha->dpc_flags); - ha->flags.gpsc_supported = 1; vha->flags.management_server_logged_in = 0; break; @@ -1009,7 +1009,7 @@ skip_rio: if (qla_ini_mode_enabled(vha)) { qla2x00_mark_device_lost(fcport->vha, fcport, 1, 1); fcport->logout_on_delete = 0; - qlt_schedule_sess_for_deletion_lock(fcport); + qlt_schedule_sess_for_deletion(fcport); } break; @@ -1041,6 +1041,7 @@ global_port_update: */ atomic_set(&vha->loop_down_timer, 0); if (atomic_read(&vha->loop_state) != LOOP_DOWN && + !ha->flags.n2n_ae && atomic_read(&vha->loop_state) != LOOP_DEAD) { ql_dbg(ql_dbg_async, vha, 0x5011, "Asynchronous PORT UPDATE ignored %04x/%04x/%04x.\n", @@ -1058,8 +1059,7 @@ global_port_update: * Mark all devices as missing so we will login again. */ atomic_set(&vha->loop_state, LOOP_UP); - - qla2x00_mark_all_devices_lost(vha, 1); + vha->scan.scan_retry = 0; set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags); @@ -1201,6 +1201,7 @@ global_port_update: qla2xxx_wake_dpc(vha); } } + /* fall through */ case MBA_IDC_COMPLETE: if (ha->notify_lb_portup_comp && !vha->vp_idx) complete(&ha->lb_portup_comp); @@ -1543,8 +1544,8 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req, struct fc_bsg_reply *bsg_reply; uint16_t comp_status; uint32_t fw_status[3]; - uint8_t* fw_sts_ptr; int res; + struct srb_iocb *els; sp = qla2x00_get_sp_from_handle(vha, func, req, pkt); if (!sp) @@ -1561,15 +1562,19 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req, break; case SRB_ELS_DCMD: type = "Driver ELS logo"; - ql_dbg(ql_dbg_user, vha, 0x5047, - "Completing %s: (%p) type=%d.\n", type, sp, sp->type); - sp->done(sp, 0); - return; + if (iocb_type != ELS_IOCB_TYPE) { + ql_dbg(ql_dbg_user, vha, 0x5047, + "Completing %s: (%p) type=%d.\n", + type, sp, sp->type); + sp->done(sp, 0); + return; + } + break; case SRB_CT_PTHRU_CMD: /* borrowing sts_entry_24xx.comp_status. same location as ct_entry_24xx.comp_status */ - res = qla2x00_chk_ms_status(vha, (ms_iocb_entry_t *)pkt, + res = qla2x00_chk_ms_status(sp->vha, (ms_iocb_entry_t *)pkt, (struct ct_sns_rsp *)sp->u.iocb_cmd.u.ctarg.rsp, sp->name); sp->done(sp, res); @@ -1584,6 +1589,33 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req, fw_status[1] = le16_to_cpu(((struct els_sts_entry_24xx*)pkt)->error_subcode_1); fw_status[2] = le16_to_cpu(((struct els_sts_entry_24xx*)pkt)->error_subcode_2); + if (iocb_type == ELS_IOCB_TYPE) { + els = &sp->u.iocb_cmd; + els->u.els_plogi.fw_status[0] = fw_status[0]; + els->u.els_plogi.fw_status[1] = fw_status[1]; + els->u.els_plogi.fw_status[2] = fw_status[2]; + els->u.els_plogi.comp_status = fw_status[0]; + if (comp_status == CS_COMPLETE) { + res = DID_OK << 16; + } else { + if (comp_status == CS_DATA_UNDERRUN) { + res = DID_OK << 16; + els->u.els_plogi.len = + le16_to_cpu(((struct els_sts_entry_24xx *) + pkt)->total_byte_count); + } else { + els->u.els_plogi.len = 0; + res = DID_ERROR << 16; + } + } + ql_log(ql_log_info, vha, 0x503f, + "ELS IOCB Done -%s error hdl=%x comp_status=0x%x error subcode 1=0x%x error subcode 2=0x%x total_byte=0x%x\n", + type, sp->handle, comp_status, fw_status[1], fw_status[2], + le16_to_cpu(((struct els_sts_entry_24xx *) + pkt)->total_byte_count)); + goto els_ct_done; + } + /* return FC_CTELS_STATUS_OK and leave the decoding of the ELS/CT * fc payload to the caller */ @@ -1604,11 +1636,7 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req, type, sp->handle, comp_status, fw_status[1], fw_status[2], le16_to_cpu(((struct els_sts_entry_24xx *) pkt)->total_byte_count)); - fw_sts_ptr = ((uint8_t*)scsi_req(bsg_job->req)->sense) + - sizeof(struct fc_bsg_reply); - memcpy( fw_sts_ptr, fw_status, sizeof(fw_status)); - } - else { + } else { ql_dbg(ql_dbg_user, vha, 0x5040, "ELS-CT pass-through-%s error hdl=%x comp_status-status=0x%x " "error subcode 1=0x%x error subcode 2=0x%x.\n", @@ -1619,10 +1647,9 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req, pkt)->error_subcode_2)); res = DID_ERROR << 16; bsg_reply->reply_payload_rcv_len = 0; - fw_sts_ptr = ((uint8_t*)scsi_req(bsg_job->req)->sense) + - sizeof(struct fc_bsg_reply); - memcpy( fw_sts_ptr, fw_status, sizeof(fw_status)); } + memcpy(bsg_job->reply + sizeof(struct fc_bsg_reply), + fw_status, sizeof(fw_status)); ql_dump_buffer(ql_dbg_user + ql_dbg_buffer, vha, 0x5056, (uint8_t *)pkt, sizeof(*pkt)); } @@ -1631,6 +1658,7 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req, bsg_reply->reply_payload_rcv_len = bsg_job->reply_payload.payload_len; bsg_job->reply_len = 0; } +els_ct_done: sp->done(sp, res); } @@ -1741,7 +1769,7 @@ qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req, set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); qla2xxx_wake_dpc(vha); } - /* drop through */ + /* fall through */ default: data[0] = MBS_COMMAND_ERROR; break; @@ -1908,6 +1936,37 @@ qla24xx_nvme_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, void *tsk) sp->done(sp, ret); } +static void qla_ctrlvp_completed(scsi_qla_host_t *vha, struct req_que *req, + struct vp_ctrl_entry_24xx *vce) +{ + const char func[] = "CTRLVP-IOCB"; + srb_t *sp; + int rval = QLA_SUCCESS; + + sp = qla2x00_get_sp_from_handle(vha, func, req, vce); + if (!sp) + return; + + if (vce->entry_status != 0) { + ql_dbg(ql_dbg_vport, vha, 0x10c4, + "%s: Failed to complete IOCB -- error status (%x)\n", + sp->name, vce->entry_status); + rval = QLA_FUNCTION_FAILED; + } else if (vce->comp_status != cpu_to_le16(CS_COMPLETE)) { + ql_dbg(ql_dbg_vport, vha, 0x10c5, + "%s: Failed to complete IOCB -- completion status (%x) vpidx %x\n", + sp->name, le16_to_cpu(vce->comp_status), + le16_to_cpu(vce->vp_idx_failed)); + rval = QLA_FUNCTION_FAILED; + } else { + ql_dbg(ql_dbg_vport, vha, 0x10c6, + "Done %s.\n", __func__); + } + + sp->rc = rval; + sp->done(sp, rval); +} + /** * qla2x00_process_response_queue() - Process response queue entries. * @ha: SCSI driver HA context @@ -2341,7 +2400,6 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) int res = 0; uint16_t state_flags = 0; uint16_t retry_delay = 0; - uint8_t no_logout = 0; sts = (sts_entry_t *) pkt; sts24 = (struct sts_entry_24xx *) pkt; @@ -2612,7 +2670,6 @@ check_scsi_status: break; case CS_PORT_LOGGED_OUT: - no_logout = 1; case CS_PORT_CONFIG_CHG: case CS_PORT_BUSY: case CS_INCOMPLETE: @@ -2643,11 +2700,8 @@ check_scsi_status: port_state_str[atomic_read(&fcport->state)], comp_status); - if (no_logout) - fcport->logout_on_delete = 0; - qla2x00_mark_device_lost(fcport->vha, fcport, 1, 1); - qlt_schedule_sess_for_deletion_lock(fcport); + qlt_schedule_sess_for_deletion(fcport); } break; @@ -2944,9 +2998,9 @@ process_err: (response_t *)pkt); break; } else { - /* drop through */ qlt_24xx_process_atio_queue(vha, 1); } + /* fall through */ case ABTS_RESP_24XX: case CTIO_TYPE7: case CTIO_CRC2: @@ -2977,6 +3031,10 @@ process_err: qla24xx_mbx_iocb_entry(vha, rsp->req, (struct mbx_24xx_entry *)pkt); break; + case VP_CTRL_IOCB_TYPE: + qla_ctrlvp_completed(vha, rsp->req, + (struct vp_ctrl_entry_24xx *)pkt); + break; default: /* Type Not Supported. */ ql_dbg(ql_dbg_async, vha, 0x5042, @@ -3129,6 +3187,7 @@ qla24xx_intr_handler(int irq, void *dev_id) case INTR_RSP_QUE_UPDATE_83XX: qla24xx_process_response_queue(vha, rsp); break; + case INTR_ATIO_QUE_UPDATE_27XX: case INTR_ATIO_QUE_UPDATE:{ unsigned long flags2; spin_lock_irqsave(&ha->tgt.atio_lock, flags2); @@ -3259,6 +3318,7 @@ qla24xx_msix_default(int irq, void *dev_id) case INTR_RSP_QUE_UPDATE_83XX: qla24xx_process_response_queue(vha, rsp); break; + case INTR_ATIO_QUE_UPDATE_27XX: case INTR_ATIO_QUE_UPDATE:{ unsigned long flags2; spin_lock_irqsave(&ha->tgt.atio_lock, flags2); @@ -3347,7 +3407,8 @@ qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp) .pre_vectors = QLA_BASE_VECTORS, }; - if (QLA_TGT_MODE_ENABLED() && IS_ATIO_MSIX_CAPABLE(ha)) { + if (QLA_TGT_MODE_ENABLED() && (ql2xenablemsix != 0) && + IS_ATIO_MSIX_CAPABLE(ha)) { desc.pre_vectors++; min_vecs++; } @@ -3374,7 +3435,7 @@ qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp) ha->msix_count, ret); ha->msix_count = ret; /* Recalculate queue values */ - if (ha->mqiobase && ql2xmqsupport) { + if (ha->mqiobase && (ql2xmqsupport || ql2xnvmeenable)) { ha->max_req_queues = ha->msix_count - 1; /* ATIOQ needs 1 vector. That's 1 less QPair */ @@ -3432,7 +3493,8 @@ qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp) * If target mode is enable, also request the vector for the ATIO * queue. */ - if (QLA_TGT_MODE_ENABLED() && IS_ATIO_MSIX_CAPABLE(ha)) { + if (QLA_TGT_MODE_ENABLED() && (ql2xenablemsix != 0) && + IS_ATIO_MSIX_CAPABLE(ha)) { qentry = &ha->msix_entries[QLA_ATIO_VECTOR]; rsp->msix = qentry; qentry->handle = rsp; @@ -3486,11 +3548,14 @@ qla2x00_request_irqs(struct qla_hw_data *ha, struct rsp_que *rsp) scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev); /* If possible, enable MSI-X. */ - if (!IS_QLA2432(ha) && !IS_QLA2532(ha) && !IS_QLA8432(ha) && - !IS_CNA_CAPABLE(ha) && !IS_QLA2031(ha) && !IS_QLAFX00(ha) && - !IS_QLA27XX(ha)) + if (ql2xenablemsix == 0 || (!IS_QLA2432(ha) && !IS_QLA2532(ha) && + !IS_QLA8432(ha) && !IS_CNA_CAPABLE(ha) && !IS_QLA2031(ha) && + !IS_QLAFX00(ha) && !IS_QLA27XX(ha))) goto skip_msi; + if (ql2xenablemsix == 2) + goto skip_msix; + if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_HP && (ha->pdev->subsystem_device == 0x7040 || ha->pdev->subsystem_device == 0x7041 || |