diff options
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_init.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_init.c | 198 |
1 files changed, 61 insertions, 137 deletions
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 8d1acc802a67..420045155ba0 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -366,14 +366,16 @@ qla2x00_async_prlo(struct scsi_qla_host *vha, fc_port_t *fcport) qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2); sp->done = qla2x00_async_prlo_sp_done; - rval = qla2x00_start_sp(sp); - if (rval != QLA_SUCCESS) - goto done_free_sp; ql_dbg(ql_dbg_disc, vha, 0x2070, "Async-prlo - hdl=%x loop-id=%x portid=%02x%02x%02x.\n", sp->handle, fcport->loop_id, fcport->d_id.b.domain, fcport->d_id.b.area, fcport->d_id.b.al_pa); + + rval = qla2x00_start_sp(sp); + if (rval != QLA_SUCCESS) + goto done_free_sp; + return rval; done_free_sp: @@ -471,9 +473,11 @@ qla2x00_async_adisc(struct scsi_qla_host *vha, fc_port_t *fcport, { srb_t *sp; struct srb_iocb *lio; - int rval; + int rval = QLA_FUNCTION_FAILED; + + if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT)) + return rval; - rval = QLA_FUNCTION_FAILED; fcport->flags |= FCF_ASYNC_SENT; sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL); if (!sp) @@ -644,11 +648,14 @@ static void qla24xx_handle_gnl_done_event(scsi_qla_host_t *vha, break; case DSC_LS_PORT_UNAVAIL: default: - if (fcport->loop_id != FC_NO_LOOP_ID) - qla2x00_clear_loop_id(fcport); - - fcport->loop_id = loop_id; - fcport->fw_login_state = DSC_LS_PORT_UNAVAIL; + if (fcport->loop_id == FC_NO_LOOP_ID) { + qla2x00_find_new_loop_id(vha, fcport); + fcport->fw_login_state = + DSC_LS_PORT_UNAVAIL; + } + ql_dbg(ql_dbg_disc, vha, 0x20e5, + "%s %d %8phC\n", __func__, __LINE__, + fcport->port_name); qla24xx_fcport_handle_login(vha, fcport); break; } @@ -931,14 +938,14 @@ int qla24xx_async_gnl(struct scsi_qla_host *vha, fc_port_t *fcport) sp->done = qla24xx_async_gnl_sp_done; - rval = qla2x00_start_sp(sp); - if (rval != QLA_SUCCESS) - goto done_free_sp; - ql_dbg(ql_dbg_disc, vha, 0x20da, "Async-%s - OUT WWPN %8phC hndl %x\n", sp->name, fcport->port_name, sp->handle); + rval = qla2x00_start_sp(sp); + if (rval != QLA_SUCCESS) + goto done_free_sp; + return rval; done_free_sp: @@ -1072,6 +1079,11 @@ qla24xx_async_prli(struct scsi_qla_host *vha, fc_port_t *fcport) if (fcport->fc4f_nvme) 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"); + rval = qla2x00_start_sp(sp); if (rval != QLA_SUCCESS) { fcport->flags |= FCF_LOGIN_NEEDED; @@ -1079,11 +1091,6 @@ qla24xx_async_prli(struct scsi_qla_host *vha, fc_port_t *fcport) goto done_free_sp; } - 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"); - return rval; done_free_sp: @@ -1471,29 +1478,6 @@ int qla24xx_fcport_handle_login(struct scsi_qla_host *vha, fc_port_t *fcport) return 0; } -static -void qla24xx_handle_rscn_event(fc_port_t *fcport, struct event_arg *ea) -{ - fcport->rscn_gen++; - - ql_dbg(ql_dbg_disc, fcport->vha, 0x210c, - "%s %8phC DS %d LS %d\n", - __func__, fcport->port_name, fcport->disc_state, - fcport->fw_login_state); - - if (fcport->flags & FCF_ASYNC_SENT) - return; - - switch (fcport->disc_state) { - case DSC_DELETED: - case DSC_LOGIN_COMPLETE: - qla24xx_post_gpnid_work(fcport->vha, &ea->id); - break; - default: - break; - } -} - int qla24xx_post_newsess_work(struct scsi_qla_host *vha, port_id_t *id, u8 *port_name, u8 *node_name, void *pla, u8 fc4_type) { @@ -1560,8 +1544,6 @@ static void qla_handle_els_plogi_done(scsi_qla_host_t *vha, void qla2x00_fcport_event_handler(scsi_qla_host_t *vha, struct event_arg *ea) { - fc_port_t *f, *tf; - uint32_t id = 0, mask, rid; fc_port_t *fcport; switch (ea->event) { @@ -1574,10 +1556,6 @@ void qla2x00_fcport_event_handler(scsi_qla_host_t *vha, struct event_arg *ea) case FCME_RSCN: if (test_bit(UNLOADING, &vha->dpc_flags)) return; - switch (ea->id.b.rsvd_1) { - case RSCN_PORT_ADDR: -#define BIGSCAN 1 -#if defined BIGSCAN & BIGSCAN > 0 { unsigned long flags; fcport = qla2x00_find_fcport_by_nportid @@ -1596,59 +1574,6 @@ void qla2x00_fcport_event_handler(scsi_qla_host_t *vha, struct event_arg *ea) } spin_unlock_irqrestore(&vha->work_lock, flags); } -#else - { - int rc; - fcport = qla2x00_find_fcport_by_nportid(vha, &ea->id, 1); - if (!fcport) { - /* cable moved */ - rc = qla24xx_post_gpnid_work(vha, &ea->id); - if (rc) { - ql_log(ql_log_warn, vha, 0xd044, - "RSCN GPNID work failed %06x\n", - ea->id.b24); - } - } else { - ea->fcport = fcport; - fcport->scan_needed = 1; - qla24xx_handle_rscn_event(fcport, ea); - } - } -#endif - break; - case RSCN_AREA_ADDR: - case RSCN_DOM_ADDR: - if (ea->id.b.rsvd_1 == RSCN_AREA_ADDR) { - mask = 0xffff00; - ql_dbg(ql_dbg_async, vha, 0x5044, - "RSCN: Area 0x%06x was affected\n", - ea->id.b24); - } else { - mask = 0xff0000; - ql_dbg(ql_dbg_async, vha, 0x507a, - "RSCN: Domain 0x%06x was affected\n", - ea->id.b24); - } - - rid = ea->id.b24 & mask; - list_for_each_entry_safe(f, tf, &vha->vp_fcports, - list) { - id = f->d_id.b24 & mask; - if (rid == id) { - ea->fcport = f; - qla24xx_handle_rscn_event(f, ea); - } - } - break; - case RSCN_FAB_ADDR: - default: - ql_log(ql_log_warn, vha, 0xd045, - "RSCN: Fabric was affected. Addr format %d\n", - ea->id.b.rsvd_1); - qla2x00_mark_all_devices_lost(vha, 1); - set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); - set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags); - } break; case FCME_GNL_DONE: qla24xx_handle_gnl_done_event(vha, ea); @@ -1709,11 +1634,7 @@ void qla_rscn_replay(fc_port_t *fcport) ea.event = FCME_RSCN; ea.id = fcport->d_id; ea.id.b.rsvd_1 = RSCN_PORT_ADDR; -#if defined BIGSCAN & BIGSCAN > 0 qla2x00_fcport_event_handler(fcport->vha, &ea); -#else - qla24xx_post_gpnid_work(fcport->vha, &ea.id); -#endif } } @@ -1784,8 +1705,8 @@ qla2x00_async_tm_cmd(fc_port_t *fcport, uint32_t flags, uint32_t lun, lun = (uint16_t)tm_iocb->u.tmf.lun; /* Issue Marker IOCB */ - qla2x00_marker(vha, vha->hw->req_q_map[0], - vha->hw->rsp_q_map[0], fcport->loop_id, lun, + qla2x00_marker(vha, vha->hw->base_qpair, + fcport->loop_id, lun, flags == TCF_LUN_RESET ? MK_SYNC_ID_LUN : MK_SYNC_ID); } @@ -1829,7 +1750,7 @@ qla24xx_async_abort_cmd(srb_t *cmd_sp, bool wait) int rval = QLA_FUNCTION_FAILED; sp = qla2xxx_get_qpair_sp(cmd_sp->vha, cmd_sp->qpair, cmd_sp->fcport, - GFP_KERNEL); + GFP_ATOMIC); if (!sp) goto done; @@ -1912,6 +1833,12 @@ qla24xx_handle_prli_done_event(struct scsi_qla_host *vha, struct event_arg *ea) ea->fcport->chip_reset = vha->hw->base_qpair->chip_reset; ea->fcport->logout_on_delete = 1; + ea->fcport->nvme_prli_service_param = ea->iop[0]; + if (ea->iop[0] & NVME_PRLI_SP_FIRST_BURST) + ea->fcport->nvme_first_burst_size = + (ea->iop[1] & 0xffff) * 512; + else + ea->fcport->nvme_first_burst_size = 0; qla24xx_post_gpdb_work(vha, ea->fcport, 0); break; default: @@ -3955,8 +3882,17 @@ qla24xx_config_rings(struct scsi_qla_host *vha) WRT_REG_DWORD(®->isp24.rsp_q_in, 0); WRT_REG_DWORD(®->isp24.rsp_q_out, 0); } + qlt_24xx_config_rings(vha); + /* If the user has configured the speed, set it here */ + if (ha->set_data_rate) { + ql_dbg(ql_dbg_init, vha, 0x00fd, + "Speed set by user : %s Gbps \n", + qla2x00_get_link_speed_str(ha, ha->set_data_rate)); + icb->firmware_options_3 = (ha->set_data_rate << 13); + } + /* PCI posting */ RD_REG_DWORD(&ioreg->hccr); } @@ -4755,6 +4691,16 @@ qla2x00_alloc_fcport(scsi_qla_host_t *vha, gfp_t flags) if (!fcport) return NULL; + fcport->ct_desc.ct_sns = dma_alloc_coherent(&vha->hw->pdev->dev, + sizeof(struct ct_sns_pkt), &fcport->ct_desc.ct_sns_dma, + flags); + if (!fcport->ct_desc.ct_sns) { + ql_log(ql_log_warn, vha, 0xd049, + "Failed to allocate ct_sns request.\n"); + kfree(fcport); + return NULL; + } + /* Setup fcport template structure. */ fcport->vha = vha; fcport->port_type = FCT_UNKNOWN; @@ -4763,13 +4709,11 @@ qla2x00_alloc_fcport(scsi_qla_host_t *vha, gfp_t flags) fcport->supported_classes = FC_COS_UNSPECIFIED; fcport->fp_speed = PORT_SPEED_UNKNOWN; - fcport->ct_desc.ct_sns = dma_alloc_coherent(&vha->hw->pdev->dev, - sizeof(struct ct_sns_pkt), &fcport->ct_desc.ct_sns_dma, - flags); fcport->disc_state = DSC_DELETED; fcport->fw_login_state = DSC_LS_PORT_UNAVAIL; fcport->deleted = QLA_SESS_DELETED; fcport->login_retry = vha->hw->login_retry_count; + fcport->chip_reset = vha->hw->base_qpair->chip_reset; fcport->logout_on_delete = 1; if (!fcport->ct_desc.ct_sns) { @@ -4778,6 +4722,7 @@ qla2x00_alloc_fcport(scsi_qla_host_t *vha, gfp_t flags) kfree(fcport); fcport = NULL; } + INIT_WORK(&fcport->del_work, qla24xx_delete_sess_fn); INIT_WORK(&fcport->reg_work, qla_register_fcport_fn); INIT_LIST_HEAD(&fcport->gnl_entry); @@ -5046,11 +4991,6 @@ qla2x00_configure_local_loop(scsi_qla_host_t *vha) if ((domain & 0xf0) == 0xf0) continue; - /* Bypass if not same domain and area of adapter. */ - if (area && domain && - (area != vha->d_id.b.area || domain != vha->d_id.b.domain)) - continue; - /* Bypass invalid local loop ID. */ if (loop_id > LAST_LOCAL_LOOP_ID) continue; @@ -6101,11 +6041,6 @@ qla2x00_loop_resync(scsi_qla_host_t *vha) { int rval = QLA_SUCCESS; uint32_t wait_time; - struct req_que *req; - struct rsp_que *rsp; - - req = vha->req; - rsp = req->rsp; clear_bit(ISP_ABORT_RETRY, &vha->dpc_flags); if (vha->flags.online) { @@ -6118,8 +6053,8 @@ qla2x00_loop_resync(scsi_qla_host_t *vha) * Issue a marker after FW becomes * ready. */ - qla2x00_marker(vha, req, rsp, 0, 0, - MK_SYNC_ALL); + qla2x00_marker(vha, vha->hw->base_qpair, + 0, 0, MK_SYNC_ALL); vha->marker_needed = 0; } @@ -6857,8 +6792,6 @@ qla2x00_restart_isp(scsi_qla_host_t *vha) { int status = 0; struct qla_hw_data *ha = vha->hw; - struct req_que *req = ha->req_q_map[0]; - struct rsp_que *rsp = ha->rsp_q_map[0]; /* If firmware needs to be loaded */ if (qla2x00_isp_firmware(vha)) { @@ -6878,7 +6811,7 @@ qla2x00_restart_isp(scsi_qla_host_t *vha) status = qla2x00_fw_ready(vha); if (!status) { /* Issue a marker after FW becomes ready. */ - qla2x00_marker(vha, req, rsp, 0, 0, MK_SYNC_ALL); + qla2x00_marker(vha, ha->base_qpair, 0, 0, MK_SYNC_ALL); set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); } @@ -7933,22 +7866,15 @@ qla24xx_configure_vhba(scsi_qla_host_t *vha) uint16_t mb[MAILBOX_REGISTER_COUNT]; struct qla_hw_data *ha = vha->hw; struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev); - struct req_que *req; - struct rsp_que *rsp; if (!vha->vp_idx) return -EINVAL; rval = qla2x00_fw_ready(base_vha); - if (vha->qpair) - req = vha->qpair->req; - else - req = ha->req_q_map[0]; - rsp = req->rsp; if (rval == QLA_SUCCESS) { clear_bit(RESET_MARKER_NEEDED, &vha->dpc_flags); - qla2x00_marker(vha, req, rsp, 0, 0, MK_SYNC_ALL); + qla2x00_marker(vha, ha->base_qpair, 0, 0, MK_SYNC_ALL); } vha->flags.management_server_logged_in = 0; @@ -8340,8 +8266,6 @@ qla82xx_restart_isp(scsi_qla_host_t *vha) { int status, rval; struct qla_hw_data *ha = vha->hw; - struct req_que *req = ha->req_q_map[0]; - struct rsp_que *rsp = ha->rsp_q_map[0]; struct scsi_qla_host *vp; unsigned long flags; @@ -8353,7 +8277,7 @@ qla82xx_restart_isp(scsi_qla_host_t *vha) status = qla2x00_fw_ready(vha); if (!status) { /* Issue a marker after FW becomes ready. */ - qla2x00_marker(vha, req, rsp, 0, 0, MK_SYNC_ALL); + qla2x00_marker(vha, ha->base_qpair, 0, 0, MK_SYNC_ALL); vha->flags.online = 1; set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); } |