diff options
author | Maxime Ripard <maxime@cerno.tech> | 2020-02-17 12:34:34 +0300 |
---|---|---|
committer | Maxime Ripard <maxime@cerno.tech> | 2020-02-17 12:34:34 +0300 |
commit | 28f2aff1caa4997f58ca31179cad1b4a84a62827 (patch) | |
tree | 69fb4b0a752f3660ce022a4313f8c7b276bbcceb /drivers/scsi/qla2xxx | |
parent | 3e8a3844fefbaad911c596f02dd48c39188ffa81 (diff) | |
parent | 11a48a5a18c63fd7621bb050228cebf13566e4d8 (diff) | |
download | linux-28f2aff1caa4997f58ca31179cad1b4a84a62827.tar.xz |
Merge v5.6-rc2 into drm-misc-next
Lyude needs some patches in 5.6-rc2 and we didn't bring drm-misc-next
forward yet, so it looks like a good occasion.
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
Diffstat (limited to 'drivers/scsi/qla2xxx')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_bsg.c | 11 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_dbg.c | 8 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_dbg.h | 6 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_def.h | 22 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_fw.h | 50 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_gbl.h | 11 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_gs.c | 6 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_init.c | 175 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_inline.h | 24 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_iocb.c | 51 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_isr.c | 72 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_mbx.c | 3 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_mid.c | 6 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_mr.c | 20 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_nx.c | 15 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_os.c | 66 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_sup.c | 11 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_target.c | 47 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_target.h | 3 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_version.h | 2 |
20 files changed, 355 insertions, 254 deletions
diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c index cbaf178fc979..d7169e43f5e1 100644 --- a/drivers/scsi/qla2xxx/qla_bsg.c +++ b/drivers/scsi/qla2xxx/qla_bsg.c @@ -54,7 +54,8 @@ void qla2x00_bsg_sp_free(srb_t *sp) if (sp->type == SRB_CT_CMD || sp->type == SRB_FXIOCB_BCMD || sp->type == SRB_ELS_CMD_HST) - kfree(sp->fcport); + qla2x00_free_fcport(sp->fcport); + qla2x00_rel_sp(sp); } @@ -405,7 +406,7 @@ done_unmap_sg: done_free_fcport: if (bsg_request->msgcode == FC_BSG_RPT_ELS) - kfree(fcport); + qla2x00_free_fcport(fcport); done: return rval; } @@ -545,7 +546,7 @@ qla2x00_process_ct(struct bsg_job *bsg_job) return rval; done_free_fcport: - kfree(fcport); + qla2x00_free_fcport(fcport); done_unmap_sg: dma_unmap_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list, bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE); @@ -796,7 +797,7 @@ qla2x00_process_loopback(struct bsg_job *bsg_job) if (atomic_read(&vha->loop_state) == LOOP_READY && (ha->current_topology == ISP_CFG_F || - (le32_to_cpu(*(uint32_t *)req_data) == ELS_OPCODE_BYTE && + (get_unaligned_le32(req_data) == ELS_OPCODE_BYTE && req_data_len == MAX_ELS_FRAME_PAYLOAD)) && elreq.options == EXTERNAL_LOOPBACK) { type = "FC_BSG_HST_VENDOR_ECHO_DIAG"; @@ -2049,7 +2050,7 @@ qlafx00_mgmt_cmd(struct bsg_job *bsg_job) return rval; done_free_fcport: - kfree(fcport); + qla2x00_free_fcport(fcport); done_unmap_rsp_sg: if (piocb_rqst->flags & SRB_FXDISC_RESP_DMA_VALID) diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c index 30afc59c1870..88a56e8480f7 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.c +++ b/drivers/scsi/qla2xxx/qla_dbg.c @@ -18,7 +18,7 @@ * | Device Discovery | 0x2134 | 0x210e-0x2116 | * | | | 0x211a | * | | | 0x211c-0x2128 | - * | | | 0x212a-0x2130 | + * | | | 0x212a-0x2134 | * | Queue Command and IO tracing | 0x3074 | 0x300b | * | | | 0x3027-0x3028 | * | | | 0x303d-0x3041 | @@ -2519,12 +2519,6 @@ qla83xx_fw_dump_failed: /* Driver Debug Functions. */ /****************************************************************************/ -static inline int -ql_mask_match(uint level) -{ - return (level & ql2xextended_error_logging) == level; -} - /* * This function is for formatting and logging debug information. * It is to be used when vha is available. It formats the message diff --git a/drivers/scsi/qla2xxx/qla_dbg.h b/drivers/scsi/qla2xxx/qla_dbg.h index bb01b680ce9f..433e95502808 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.h +++ b/drivers/scsi/qla2xxx/qla_dbg.h @@ -374,3 +374,9 @@ extern int qla24xx_dump_ram(struct qla_hw_data *, uint32_t, uint32_t *, extern void qla24xx_pause_risc(struct device_reg_24xx __iomem *, struct qla_hw_data *); extern int qla24xx_soft_reset(struct qla_hw_data *); + +static inline int +ql_mask_match(uint level) +{ + return (level & ql2xextended_error_logging) == level; +} diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 2edd9f7b3074..ed32e9715794 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -2402,6 +2402,7 @@ typedef struct fc_port { unsigned int scan_needed:1; unsigned int n2n_flag:1; unsigned int explicit_logout:1; + unsigned int prli_pend_timer:1; struct completion nvme_del_done; uint32_t nvme_prli_service_param; @@ -2428,6 +2429,7 @@ typedef struct fc_port { struct work_struct free_work; struct work_struct reg_work; uint64_t jiffies_at_registration; + unsigned long prli_expired; struct qlt_plogi_ack_t *plogi_link[QLT_PLOGI_LINK_MAX]; uint16_t tgt_id; @@ -2464,6 +2466,7 @@ typedef struct fc_port { struct qla_tgt_sess *tgt_session; struct ct_sns_desc ct_desc; enum discovery_state disc_state; + atomic_t shadow_disc_state; enum discovery_state next_disc_state; enum login_state fw_login_state; unsigned long dm_login_expire; @@ -2510,6 +2513,19 @@ struct event_arg { extern const char *const port_state_str[5]; +static const char * const port_dstate_str[] = { + "DELETED", + "GNN_ID", + "GNL", + "LOGIN_PEND", + "LOGIN_FAILED", + "GPDB", + "UPD_FCPORT", + "LOGIN_COMPLETE", + "ADISC", + "DELETE_PEND" +}; + /* * FC port flags. */ @@ -3263,7 +3279,6 @@ enum qla_work_type { QLA_EVT_IDC_ACK, QLA_EVT_ASYNC_LOGIN, QLA_EVT_ASYNC_LOGOUT, - QLA_EVT_ASYNC_LOGOUT_DONE, QLA_EVT_ASYNC_ADISC, QLA_EVT_UEVENT, QLA_EVT_AENFX, @@ -3953,7 +3968,7 @@ struct qla_hw_data { void *sfp_data; dma_addr_t sfp_data_dma; - void *flt; + struct qla_flt_header *flt; dma_addr_t flt_dma; #define XGMAC_DATA_SIZE 4096 @@ -4845,6 +4860,9 @@ struct sff_8247_a0 { (ha->fc4_type_priority == FC4_PRIORITY_NVME)) || \ NVME_ONLY_TARGET(fcport)) \ +#define PRLI_PHASE(_cls) \ + ((_cls == DSC_LS_PRLI_PEND) || (_cls == DSC_LS_PRLI_COMP)) + #include "qla_target.h" #include "qla_gbl.h" #include "qla_dbg.h" diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h index 9dc09c117416..d641918cdd46 100644 --- a/drivers/scsi/qla2xxx/qla_fw.h +++ b/drivers/scsi/qla2xxx/qla_fw.h @@ -1354,12 +1354,12 @@ struct vp_rpt_id_entry_24xx { uint8_t port_id[3]; uint8_t format; union { - struct { + struct _f0 { /* format 0 loop */ uint8_t vp_idx_map[16]; uint8_t reserved_4[32]; } f0; - struct { + struct _f1 { /* format 1 fabric */ uint8_t vpstat1_subcode; /* vp_status=1 subcode */ uint8_t flags; @@ -1381,21 +1381,22 @@ struct vp_rpt_id_entry_24xx { uint16_t bbcr; uint8_t reserved_5[6]; } f1; - struct { /* format 2: N2N direct connect */ - uint8_t vpstat1_subcode; - uint8_t flags; - uint16_t rsv6; - uint8_t rsv2[12]; - - uint8_t ls_rjt_vendor; - uint8_t ls_rjt_explanation; - uint8_t ls_rjt_reason; - uint8_t rsv3[5]; - - uint8_t port_name[8]; - uint8_t node_name[8]; - uint8_t remote_nport_id[4]; - uint32_t reserved_5; + struct _f2 { /* format 2: N2N direct connect */ + uint8_t vpstat1_subcode; + uint8_t flags; + uint16_t fip_flags; + uint8_t rsv2[12]; + + uint8_t ls_rjt_vendor; + uint8_t ls_rjt_explanation; + uint8_t ls_rjt_reason; + uint8_t rsv3[5]; + + uint8_t port_name[8]; + uint8_t node_name[8]; + uint16_t bbcr; + uint8_t reserved_5[2]; + uint8_t remote_nport_id[4]; } f2; } u; }; @@ -1470,13 +1471,6 @@ struct qla_flt_location { uint16_t checksum; }; -struct qla_flt_header { - uint16_t version; - uint16_t length; - uint16_t checksum; - uint16_t unused; -}; - #define FLT_REG_FW 0x01 #define FLT_REG_BOOT_CODE 0x07 #define FLT_REG_VPD_0 0x14 @@ -1537,6 +1531,14 @@ struct qla_flt_region { uint32_t end; }; +struct qla_flt_header { + uint16_t version; + uint16_t length; + uint16_t checksum; + uint16_t unused; + struct qla_flt_region region[0]; +}; + #define FLT_REGION_SIZE 16 #define FLT_MAX_REGIONS 0xFF #define FLT_REGIONS_SIZE (FLT_REGION_SIZE * FLT_MAX_REGIONS) diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index 5b163ad85c34..2a64729a2bc5 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h @@ -72,14 +72,13 @@ extern int qla2x00_async_adisc(struct scsi_qla_host *, fc_port_t *, extern int qla2x00_async_tm_cmd(fc_port_t *, uint32_t, uint32_t, uint32_t); extern void qla2x00_async_login_done(struct scsi_qla_host *, fc_port_t *, uint16_t *); -extern void qla2x00_async_logout_done(struct scsi_qla_host *, fc_port_t *, - uint16_t *); struct qla_work_evt *qla2x00_alloc_work(struct scsi_qla_host *, enum qla_work_type); extern int qla24xx_async_gnl(struct scsi_qla_host *, fc_port_t *); int qla2x00_post_work(struct scsi_qla_host *vha, struct qla_work_evt *e); extern void *qla2x00_alloc_iocbs_ready(struct qla_qpair *, srb_t *); extern int qla24xx_update_fcport_fcp_prio(scsi_qla_host_t *, fc_port_t *); +extern int qla24xx_async_abort_cmd(srb_t *, bool); extern void qla2x00_set_fcport_state(fc_port_t *fcport, int state); extern fc_port_t * @@ -182,8 +181,6 @@ extern int qla2x00_post_async_login_work(struct scsi_qla_host *, fc_port_t *, uint16_t *); extern int qla2x00_post_async_logout_work(struct scsi_qla_host *, fc_port_t *, uint16_t *); -extern int qla2x00_post_async_logout_done_work(struct scsi_qla_host *, - fc_port_t *, uint16_t *); extern int qla2x00_post_async_adisc_work(struct scsi_qla_host *, fc_port_t *, uint16_t *); extern int qla2x00_post_async_adisc_done_work(struct scsi_qla_host *, @@ -201,6 +198,7 @@ extern void qla2x00_free_host(struct scsi_qla_host *); extern void qla2x00_relogin(struct scsi_qla_host *); extern void qla2x00_do_work(struct scsi_qla_host *); extern void qla2x00_free_fcports(struct scsi_qla_host *); +extern void qla2x00_free_fcport(fc_port_t *); extern void qla83xx_schedule_work(scsi_qla_host_t *, int); extern void qla83xx_service_idc_aen(struct work_struct *); @@ -253,8 +251,9 @@ extern scsi_qla_host_t *qla24xx_create_vhost(struct fc_vport *); extern void qla2x00_sp_free_dma(srb_t *sp); extern char *qla2x00_get_fw_version_str(struct scsi_qla_host *, char *); -extern void qla2x00_mark_device_lost(scsi_qla_host_t *, fc_port_t *, int, int); -extern void qla2x00_mark_all_devices_lost(scsi_qla_host_t *, int); +extern void qla2x00_mark_device_lost(scsi_qla_host_t *, fc_port_t *, int); +extern void qla2x00_mark_all_devices_lost(scsi_qla_host_t *); +extern int qla24xx_async_abort_cmd(srb_t *, bool); extern struct fw_blob *qla2x00_request_firmware(scsi_qla_host_t *); diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c index 446a9d6ba255..aaa4a5bbf2ff 100644 --- a/drivers/scsi/qla2xxx/qla_gs.c +++ b/drivers/scsi/qla2xxx/qla_gs.c @@ -2963,7 +2963,6 @@ int qla24xx_post_gpsc_work(struct scsi_qla_host *vha, fc_port_t *fcport) return QLA_FUNCTION_FAILED; e->u.fcport.fcport = fcport; - fcport->flags |= FCF_ASYNC_ACTIVE; return qla2x00_post_work(vha, e); } @@ -3097,9 +3096,7 @@ int qla24xx_async_gpsc(scsi_qla_host_t *vha, fc_port_t *fcport) done_free_sp: sp->free(sp); - fcport->flags &= ~FCF_ASYNC_SENT; done: - fcport->flags &= ~FCF_ASYNC_ACTIVE; return rval; } @@ -4290,7 +4287,7 @@ int qla24xx_async_gnnid(scsi_qla_host_t *vha, fc_port_t *fcport) if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT)) return rval; - fcport->disc_state = DSC_GNN_ID; + qla2x00_set_fcport_disc_state(fcport, DSC_GNN_ID); sp = qla2x00_get_sp(vha, fcport, GFP_ATOMIC); if (!sp) goto done; @@ -4464,7 +4461,6 @@ int qla24xx_async_gfpnid(scsi_qla_host_t *vha, fc_port_t *fcport) done_free_sp: sp->free(sp); - fcport->flags &= ~FCF_ASYNC_SENT; done: return rval; } diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index aa5204163bec..9e6b56527b25 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -49,16 +49,9 @@ qla2x00_sp_timeout(struct timer_list *t) { srb_t *sp = from_timer(sp, t, u.iocb_cmd.timer); struct srb_iocb *iocb; - struct req_que *req; - unsigned long flags; - struct qla_hw_data *ha = sp->vha->hw; - WARN_ON_ONCE(irqs_disabled()); - spin_lock_irqsave(&ha->hardware_lock, flags); - req = sp->qpair->req; - req->outstanding_cmds[sp->handle] = NULL; + WARN_ON(irqs_disabled()); iocb = &sp->u.iocb_cmd; - spin_unlock_irqrestore(&ha->hardware_lock, flags); iocb->timeout(sp); } @@ -142,7 +135,7 @@ static void qla24xx_abort_sp_done(srb_t *sp, int res) sp->free(sp); } -static int qla24xx_async_abort_cmd(srb_t *cmd_sp, bool wait) +int qla24xx_async_abort_cmd(srb_t *cmd_sp, bool wait) { scsi_qla_host_t *vha = cmd_sp->vha; struct srb_iocb *abt_iocb; @@ -242,6 +235,7 @@ qla2x00_async_iocb_timeout(void *data) case SRB_NACK_PRLI: case SRB_NACK_LOGO: case SRB_CTRL_VP: + default: rc = qla24xx_async_abort_cmd(sp, false); if (rc) { spin_lock_irqsave(sp->qpair->qp_lock_ptr, flags); @@ -258,10 +252,6 @@ qla2x00_async_iocb_timeout(void *data) sp->done(sp, QLA_FUNCTION_TIMEOUT); } break; - default: - WARN_ON_ONCE(true); - sp->done(sp, QLA_FUNCTION_TIMEOUT); - break; } } @@ -326,10 +316,10 @@ qla2x00_async_login(struct scsi_qla_host *vha, fc_port_t *fcport, if (!sp) goto done; + qla2x00_set_fcport_disc_state(fcport, DSC_LOGIN_PEND); fcport->flags |= FCF_ASYNC_SENT; fcport->logout_completed = 0; - fcport->disc_state = DSC_LOGIN_PEND; sp->type = SRB_LOGIN_CMD; sp->name = "login"; sp->gen1 = fcport->rscn_gen; @@ -425,7 +415,7 @@ qla2x00_async_prlo_done(struct scsi_qla_host *vha, fc_port_t *fcport, fcport->flags &= ~FCF_ASYNC_ACTIVE; /* Don't re-login in target mode */ if (!fcport->tgt_session) - qla2x00_mark_device_lost(vha, fcport, 1, 0); + qla2x00_mark_device_lost(vha, fcport, 1); qlt_logo_completion_handler(fcport, data[0]); } @@ -533,7 +523,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; + qla2x00_set_fcport_disc_state(fcport, DSC_LOGIN_PEND); return qla2x00_post_work(vha, e); } @@ -685,7 +675,7 @@ static void qla24xx_handle_gnl_done_event(scsi_qla_host_t *vha, port_id_t id; u64 wwn; u16 data[2]; - u8 current_login_state; + u8 current_login_state, nvme_cls; fcport = ea->fcport; ql_dbg(ql_dbg_disc, vha, 0xffff, @@ -744,10 +734,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 (NVME_TARGET(vha->hw, fcport)) - current_login_state = e->current_login_state >> 4; - else - current_login_state = e->current_login_state & 0xf; + nvme_cls = e->current_login_state >> 4; + current_login_state = e->current_login_state & 0xf; + + if (PRLI_PHASE(nvme_cls)) { + current_login_state = nvme_cls; + fcport->fc4_type &= ~FS_FC4TYPE_FCP; + fcport->fc4_type |= FS_FC4TYPE_NVME; + } else if (PRLI_PHASE(current_login_state)) { + fcport->fc4_type |= FS_FC4TYPE_FCP; + fcport->fc4_type &= ~FS_FC4TYPE_NVME; + } ql_dbg(ql_dbg_disc, vha, 0x20e2, "%s found %8phC CLS [%x|%x] fc4_type %d ID[%06x|%06x] lid[%d|%d]\n", @@ -836,7 +833,8 @@ static void qla24xx_handle_gnl_done_event(scsi_qla_host_t *vha, * with GNL. Push disc_state back to DELETED * so GNL can go out again */ - fcport->disc_state = DSC_DELETED; + qla2x00_set_fcport_disc_state(fcport, + DSC_DELETED); break; case DSC_LS_PRLI_COMP: if ((e->prli_svc_param_word_3[0] & BIT_4) == 0) @@ -912,7 +910,7 @@ static void qla24xx_handle_gnl_done_event(scsi_qla_host_t *vha, qla24xx_fcport_handle_login(vha, fcport); break; case ISP_CFG_N: - fcport->disc_state = DSC_DELETED; + qla2x00_set_fcport_disc_state(fcport, DSC_DELETED); if (time_after_eq(jiffies, fcport->dm_login_expire)) { if (fcport->n2n_link_reset_cnt < 2) { fcport->n2n_link_reset_cnt++; @@ -992,7 +990,7 @@ static void qla24xx_async_gnl_sp_done(srb_t *sp, int res) set_bit(loop_id, vha->hw->loop_id_map); wwn = wwn_to_u64(e->port_name); - ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0x20e8, + ql_dbg(ql_dbg_disc, vha, 0x20e8, "%s %8phC %02x:%02x:%02x CLS %x/%x lid %x \n", __func__, (void *)&wwn, e->port_id[2], e->port_id[1], e->port_id[0], e->current_login_state, e->last_login_state, @@ -1051,6 +1049,16 @@ static void qla24xx_async_gnl_sp_done(srb_t *sp, int res) spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags); vha->gnl.sent = 0; + if (!list_empty(&vha->gnl.fcports)) { + /* retrigger gnl */ + list_for_each_entry_safe(fcport, tf, &vha->gnl.fcports, + gnl_entry) { + list_del_init(&fcport->gnl_entry); + fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE); + if (qla24xx_post_gnl_work(vha, fcport) == QLA_SUCCESS) + break; + } + } spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags); sp->free(sp); @@ -1072,7 +1080,7 @@ int qla24xx_async_gnl(struct scsi_qla_host *vha, fc_port_t *fcport) spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags); fcport->flags |= FCF_ASYNC_SENT; - fcport->disc_state = DSC_GNL; + qla2x00_set_fcport_disc_state(fcport, DSC_GNL); fcport->last_rscn_gen = fcport->rscn_gen; fcport->last_login_gen = fcport->login_gen; @@ -1121,8 +1129,8 @@ int qla24xx_async_gnl(struct scsi_qla_host *vha, fc_port_t *fcport) done_free_sp: sp->free(sp); - fcport->flags &= ~FCF_ASYNC_SENT; done: + fcport->flags &= ~(FCF_ASYNC_ACTIVE | FCF_ASYNC_SENT); return rval; } @@ -1216,12 +1224,19 @@ qla24xx_async_prli(struct scsi_qla_host *vha, fc_port_t *fcport) struct srb_iocb *lio; int rval = QLA_FUNCTION_FAILED; - if (!vha->flags.online) + if (!vha->flags.online) { + ql_dbg(ql_dbg_disc, vha, 0xffff, "%s %d %8phC exit\n", + __func__, __LINE__, fcport->port_name); return rval; + } - if (fcport->fw_login_state == DSC_LS_PLOGI_PEND || - fcport->fw_login_state == DSC_LS_PRLI_PEND) + if ((fcport->fw_login_state == DSC_LS_PLOGI_PEND || + fcport->fw_login_state == DSC_LS_PRLI_PEND) && + qla_dual_mode_enabled(vha)) { + ql_dbg(ql_dbg_disc, vha, 0xffff, "%s %d %8phC exit\n", + __func__, __LINE__, fcport->port_name); return rval; + } sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL); if (!sp) @@ -1295,12 +1310,12 @@ int qla24xx_async_gpdb(struct scsi_qla_host *vha, fc_port_t *fcport, u8 opt) return rval; } - fcport->disc_state = DSC_GPDB; - sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL); if (!sp) goto done; + qla2x00_set_fcport_disc_state(fcport, DSC_GPDB); + fcport->flags |= FCF_ASYNC_SENT; sp->type = SRB_MB_IOCB; sp->name = "gpdb"; @@ -1349,6 +1364,7 @@ done_free_sp: sp->free(sp); fcport->flags &= ~FCF_ASYNC_SENT; done: + fcport->flags &= ~FCF_ASYNC_ACTIVE; qla24xx_post_gpdb_work(vha, fcport, opt); return rval; } @@ -1379,7 +1395,7 @@ void __qla24xx_handle_gpdb_event(scsi_qla_host_t *vha, struct event_arg *ea) ql_dbg(ql_dbg_disc, vha, 0x20d6, "%s %d %8phC session revalidate success\n", __func__, __LINE__, ea->fcport->port_name); - ea->fcport->disc_state = DSC_LOGIN_COMPLETE; + qla2x00_set_fcport_disc_state(ea->fcport, DSC_LOGIN_COMPLETE); } spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags); } @@ -1433,7 +1449,7 @@ void qla24xx_handle_gpdb_event(scsi_qla_host_t *vha, struct event_arg *ea) /* Set discovery state back to GNL to Relogin attempt */ if (qla_dual_mode_enabled(vha) || qla_ini_mode_enabled(vha)) { - fcport->disc_state = DSC_GNL; + qla2x00_set_fcport_disc_state(fcport, DSC_GNL); set_bit(RELOGIN_NEEDED, &vha->dpc_flags); } return; @@ -1600,6 +1616,10 @@ int qla24xx_fcport_handle_login(struct scsi_qla_host *vha, fc_port_t *fcport) break; default: if (fcport->login_pause) { + ql_dbg(ql_dbg_disc, vha, 0x20d8, + "%s %d %8phC exit\n", + __func__, __LINE__, + fcport->port_name); fcport->last_rscn_gen = fcport->rscn_gen; fcport->last_login_gen = fcport->login_gen; set_bit(RELOGIN_NEEDED, &vha->dpc_flags); @@ -1758,9 +1778,23 @@ qla2x00_tmf_iocb_timeout(void *data) { srb_t *sp = data; struct srb_iocb *tmf = &sp->u.iocb_cmd; + int rc, h; + unsigned long flags; - tmf->u.tmf.comp_status = CS_TIMEOUT; - complete(&tmf->u.tmf.comp); + rc = qla24xx_async_abort_cmd(sp, false); + if (rc) { + spin_lock_irqsave(sp->qpair->qp_lock_ptr, flags); + for (h = 1; h < sp->qpair->req->num_outstanding_cmds; h++) { + if (sp->qpair->req->outstanding_cmds[h] == sp) { + sp->qpair->req->outstanding_cmds[h] = NULL; + break; + } + } + spin_unlock_irqrestore(sp->qpair->qp_lock_ptr, flags); + tmf->u.tmf.comp_status = CS_TIMEOUT; + tmf->u.tmf.data = QLA_FUNCTION_FAILED; + complete(&tmf->u.tmf.comp); + } } static void qla2x00_tmf_sp_done(srb_t *sp, int res) @@ -1976,7 +2010,7 @@ qla24xx_handle_plogi_done_event(struct scsi_qla_host *vha, struct event_arg *ea) qla24xx_post_prli_work(vha, ea->fcport); } else { ql_dbg(ql_dbg_disc, vha, 0x20ea, - "%s %d %8phC LoopID 0x%x in use with %06x. post gnl\n", + "%s %d %8phC LoopID 0x%x in use with %06x. post gpdb\n", __func__, __LINE__, ea->fcport->port_name, ea->fcport->loop_id, ea->fcport->d_id.b24); @@ -1996,11 +2030,11 @@ qla24xx_handle_plogi_done_event(struct scsi_qla_host *vha, struct event_arg *ea) __func__, __LINE__, ea->fcport->port_name, ea->data[1]); ea->fcport->flags &= ~FCF_ASYNC_SENT; - ea->fcport->disc_state = DSC_LOGIN_FAILED; + qla2x00_set_fcport_disc_state(ea->fcport, DSC_LOGIN_FAILED); if (ea->data[1] & QLA_LOGIO_LOGIN_RETRIED) set_bit(RELOGIN_NEEDED, &vha->dpc_flags); else - qla2x00_mark_device_lost(vha, ea->fcport, 1, 0); + qla2x00_mark_device_lost(vha, ea->fcport, 1); break; case MBS_LOOP_ID_USED: /* data[1] = IO PARAM 1 = nport ID */ @@ -2047,6 +2081,7 @@ qla24xx_handle_plogi_done_event(struct scsi_qla_host *vha, struct event_arg *ea) set_bit(lid, vha->hw->loop_id_map); ea->fcport->loop_id = lid; ea->fcport->keep_nport_handle = 0; + ea->fcport->logout_on_delete = 1; qlt_schedule_sess_for_deletion(ea->fcport); } break; @@ -2054,16 +2089,6 @@ qla24xx_handle_plogi_done_event(struct scsi_qla_host *vha, struct event_arg *ea) return; } -void -qla2x00_async_logout_done(struct scsi_qla_host *vha, fc_port_t *fcport, - uint16_t *data) -{ - qlt_logo_completion_handler(fcport, data[0]); - fcport->login_gen++; - fcport->flags &= ~FCF_ASYNC_ACTIVE; - return; -} - /****************************************************************************/ /* QLogic ISP2x00 Hardware Support Functions. */ /****************************************************************************/ @@ -4925,12 +4950,8 @@ qla2x00_configure_loop(scsi_qla_host_t *vha) qla2x00_get_data_rate(vha); /* Determine what we need to do */ - if (ha->current_topology == ISP_CFG_FL && - (test_bit(LOCAL_LOOP_UPDATE, &flags))) { - - set_bit(RSCN_UPDATE, &flags); - - } else if (ha->current_topology == ISP_CFG_F && + if ((ha->current_topology == ISP_CFG_FL || + ha->current_topology == ISP_CFG_F) && (test_bit(LOCAL_LOOP_UPDATE, &flags))) { set_bit(RSCN_UPDATE, &flags); @@ -5087,7 +5108,7 @@ skip_login: rval = qla2x00_get_id_list(vha, ha->gid_list, ha->gid_list_dma, &entries); if (rval != QLA_SUCCESS) - goto cleanup_allocation; + goto err; ql_dbg(ql_dbg_disc, vha, 0x2011, "Entries in ID list (%d).\n", entries); @@ -5117,7 +5138,7 @@ skip_login: ql_log(ql_log_warn, vha, 0x2012, "Memory allocation failed for fcport.\n"); rval = QLA_MEMORY_ALLOC_FAILED; - goto cleanup_allocation; + goto err; } new_fcport->flags &= ~FCF_FABRIC_DEVICE; @@ -5207,7 +5228,7 @@ skip_login: ql_log(ql_log_warn, vha, 0xd031, "Failed to allocate memory for fcport.\n"); rval = QLA_MEMORY_ALLOC_FAILED; - goto cleanup_allocation; + goto err; } spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags); new_fcport->flags &= ~FCF_FABRIC_DEVICE; @@ -5230,7 +5251,7 @@ skip_login: qla_ini_mode_enabled(vha)) && atomic_read(&fcport->state) == FCS_ONLINE) { qla2x00_mark_device_lost(vha, fcport, - ql2xplogiabsentdevice, 0); + ql2xplogiabsentdevice); if (fcport->loop_id != FC_NO_LOOP_ID && (fcport->flags & FCF_FCP2_DEVICE) == 0 && fcport->port_type != FCT_INITIATOR && @@ -5250,15 +5271,14 @@ skip_login: qla24xx_fcport_handle_login(vha, fcport); } -cleanup_allocation: - kfree(new_fcport); + qla2x00_free_fcport(new_fcport); - if (rval != QLA_SUCCESS) { - ql_dbg(ql_dbg_disc, vha, 0x2098, - "Configure local loop error exit: rval=%x.\n", rval); - } + return rval; - return (rval); +err: + ql_dbg(ql_dbg_disc, vha, 0x2098, + "Configure local loop error exit: rval=%x.\n", rval); + return rval; } static void @@ -5385,11 +5405,14 @@ qla2x00_update_fcport(scsi_qla_host_t *vha, fc_port_t *fcport) ql_dbg(ql_dbg_disc, vha, 0x20ef, "%s %8phC\n", __func__, fcport->port_name); - fcport->disc_state = DSC_UPD_FCPORT; + qla2x00_set_fcport_disc_state(fcport, DSC_UPD_FCPORT); fcport->login_retry = vha->hw->login_retry_count; fcport->flags &= ~(FCF_LOGIN_NEEDED | FCF_ASYNC_SENT); fcport->deleted = 0; - fcport->logout_on_delete = 1; + if (vha->hw->current_topology == ISP_CFG_NL) + fcport->logout_on_delete = 0; + else + fcport->logout_on_delete = 1; fcport->n2n_chip_reset = fcport->n2n_link_reset_cnt = 0; switch (vha->hw->current_topology) { @@ -5405,7 +5428,7 @@ qla2x00_update_fcport(scsi_qla_host_t *vha, fc_port_t *fcport) if (NVME_TARGET(vha->hw, fcport)) { qla_nvme_register_remote(vha, fcport); - fcport->disc_state = DSC_LOGIN_COMPLETE; + qla2x00_set_fcport_disc_state(fcport, DSC_LOGIN_COMPLETE); qla2x00_set_fcport_state(fcport, FCS_ONLINE); return; } @@ -5450,7 +5473,7 @@ qla2x00_update_fcport(scsi_qla_host_t *vha, fc_port_t *fcport) } } - fcport->disc_state = DSC_LOGIN_COMPLETE; + qla2x00_set_fcport_disc_state(fcport, DSC_LOGIN_COMPLETE); } void qla_register_fcport_fn(struct work_struct *work) @@ -5859,7 +5882,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha) if (NVME_TARGET(vha->hw, fcport)) { if (fcport->disc_state == DSC_DELETE_PEND) { - fcport->disc_state = DSC_GNL; + qla2x00_set_fcport_disc_state(fcport, DSC_GNL); vha->fcport_count--; fcport->login_succ = 0; } @@ -5905,7 +5928,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha) qla_ini_mode_enabled(vha)) && atomic_read(&fcport->state) == FCS_ONLINE) { qla2x00_mark_device_lost(vha, fcport, - ql2xplogiabsentdevice, 0); + ql2xplogiabsentdevice); if (fcport->loop_id != FC_NO_LOOP_ID && (fcport->flags & FCF_FCP2_DEVICE) == 0 && fcport->port_type != FCT_INITIATOR && @@ -6071,7 +6094,7 @@ qla2x00_fabric_login(scsi_qla_host_t *vha, fc_port_t *fcport, ha->isp_ops->fabric_logout(vha, fcport->loop_id, fcport->d_id.b.domain, fcport->d_id.b.area, fcport->d_id.b.al_pa); - qla2x00_mark_device_lost(vha, fcport, 1, 0); + qla2x00_mark_device_lost(vha, fcport, 1); rval = 1; break; @@ -6585,9 +6608,9 @@ qla2x00_quiesce_io(scsi_qla_host_t *vha) atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME); if (atomic_read(&vha->loop_state) != LOOP_DOWN) { atomic_set(&vha->loop_state, LOOP_DOWN); - qla2x00_mark_all_devices_lost(vha, 0); + qla2x00_mark_all_devices_lost(vha); list_for_each_entry(vp, &ha->vp_list, list) - qla2x00_mark_all_devices_lost(vp, 0); + qla2x00_mark_all_devices_lost(vp); } else { if (!atomic_read(&vha->loop_down_timer)) atomic_set(&vha->loop_down_timer, @@ -6663,14 +6686,14 @@ qla2x00_abort_isp_cleanup(scsi_qla_host_t *vha) atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME); if (atomic_read(&vha->loop_state) != LOOP_DOWN) { atomic_set(&vha->loop_state, LOOP_DOWN); - qla2x00_mark_all_devices_lost(vha, 0); + qla2x00_mark_all_devices_lost(vha); spin_lock_irqsave(&ha->vport_slock, flags); list_for_each_entry(vp, &ha->vp_list, list) { atomic_inc(&vp->vref_count); spin_unlock_irqrestore(&ha->vport_slock, flags); - qla2x00_mark_all_devices_lost(vp, 0); + qla2x00_mark_all_devices_lost(vp); spin_lock_irqsave(&ha->vport_slock, flags); atomic_dec(&vp->vref_count); diff --git a/drivers/scsi/qla2xxx/qla_inline.h b/drivers/scsi/qla2xxx/qla_inline.h index 352aba4127f7..364b3db8b2dc 100644 --- a/drivers/scsi/qla2xxx/qla_inline.h +++ b/drivers/scsi/qla2xxx/qla_inline.h @@ -105,6 +105,30 @@ qla2x00_clean_dsd_pool(struct qla_hw_data *ha, struct crc_context *ctx) INIT_LIST_HEAD(&ctx->dsd_list); } +static inline void +qla2x00_set_fcport_disc_state(fc_port_t *fcport, int state) +{ + int old_val; + uint8_t shiftbits, mask; + + /* This will have to change when the max no. of states > 16 */ + shiftbits = 4; + mask = (1 << shiftbits) - 1; + + fcport->disc_state = state; + while (1) { + old_val = atomic_read(&fcport->shadow_disc_state); + if (old_val == atomic_cmpxchg(&fcport->shadow_disc_state, + old_val, (old_val << shiftbits) | state)) { + ql_dbg(ql_dbg_disc, fcport->vha, 0x2134, + "FCPort %8phC disc_state transition: %s to %s - portid=%06x.\n", + fcport->port_name, port_dstate_str[old_val & mask], + port_dstate_str[state], fcport->d_id.b24); + return; + } + } +} + static inline int qla2x00_hba_err_chk_enabled(srb_t *sp) { diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index 8b050f0b4333..47bf60a9490a 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c @@ -2537,13 +2537,32 @@ qla2x00_els_dcmd_iocb_timeout(void *data) fc_port_t *fcport = sp->fcport; struct scsi_qla_host *vha = sp->vha; struct srb_iocb *lio = &sp->u.iocb_cmd; + unsigned long flags = 0; + int res, h; ql_dbg(ql_dbg_io, vha, 0x3069, "%s Timeout, hdl=%x, portid=%02x%02x%02x\n", sp->name, sp->handle, fcport->d_id.b.domain, fcport->d_id.b.area, fcport->d_id.b.al_pa); - complete(&lio->u.els_logo.comp); + /* Abort the exchange */ + res = qla24xx_async_abort_cmd(sp, false); + if (res) { + ql_dbg(ql_dbg_io, vha, 0x3070, + "mbx abort_command failed.\n"); + spin_lock_irqsave(sp->qpair->qp_lock_ptr, flags); + for (h = 1; h < sp->qpair->req->num_outstanding_cmds; h++) { + if (sp->qpair->req->outstanding_cmds[h] == sp) { + sp->qpair->req->outstanding_cmds[h] = NULL; + break; + } + } + spin_unlock_irqrestore(sp->qpair->qp_lock_ptr, flags); + complete(&lio->u.els_logo.comp); + } else { + ql_dbg(ql_dbg_io, vha, 0x3071, + "mbx abort_command success.\n"); + } } static void qla2x00_els_dcmd_sp_done(srb_t *sp, int res) @@ -2717,23 +2736,29 @@ qla2x00_els_dcmd2_iocb_timeout(void *data) srb_t *sp = data; fc_port_t *fcport = sp->fcport; struct scsi_qla_host *vha = sp->vha; - struct qla_hw_data *ha = vha->hw; unsigned long flags = 0; - int res; + int res, h; ql_dbg(ql_dbg_io + ql_dbg_disc, vha, 0x3069, "%s hdl=%x ELS Timeout, %8phC portid=%06x\n", sp->name, sp->handle, fcport->port_name, fcport->d_id.b24); /* Abort the exchange */ - spin_lock_irqsave(&ha->hardware_lock, flags); - res = ha->isp_ops->abort_command(sp); + res = qla24xx_async_abort_cmd(sp, false); ql_dbg(ql_dbg_io, vha, 0x3070, "mbx abort_command %s\n", (res == QLA_SUCCESS) ? "successful" : "failed"); - spin_unlock_irqrestore(&ha->hardware_lock, flags); - - sp->done(sp, QLA_FUNCTION_TIMEOUT); + if (res) { + spin_lock_irqsave(sp->qpair->qp_lock_ptr, flags); + for (h = 1; h < sp->qpair->req->num_outstanding_cmds; h++) { + if (sp->qpair->req->outstanding_cmds[h] == sp) { + sp->qpair->req->outstanding_cmds[h] = NULL; + break; + } + } + spin_unlock_irqrestore(sp->qpair->qp_lock_ptr, flags); + sp->done(sp, QLA_FUNCTION_TIMEOUT); + } } void qla2x00_els_dcmd2_free(scsi_qla_host_t *vha, struct els_plogi *els_plogi) @@ -2852,7 +2877,8 @@ static void qla2x00_els_dcmd2_sp_done(srb_t *sp, int res) fw_status[0], fw_status[1], fw_status[2]); fcport->flags &= ~FCF_ASYNC_SENT; - fcport->disc_state = DSC_LOGIN_FAILED; + qla2x00_set_fcport_disc_state(fcport, + DSC_LOGIN_FAILED); set_bit(RELOGIN_NEEDED, &vha->dpc_flags); break; } @@ -2865,7 +2891,7 @@ static void qla2x00_els_dcmd2_sp_done(srb_t *sp, int res) fw_status[0], fw_status[1], fw_status[2]); sp->fcport->flags &= ~FCF_ASYNC_SENT; - sp->fcport->disc_state = DSC_LOGIN_FAILED; + qla2x00_set_fcport_disc_state(fcport, DSC_LOGIN_FAILED); set_bit(RELOGIN_NEEDED, &vha->dpc_flags); break; } @@ -2898,11 +2924,12 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t *vha, int els_opcode, if (!sp) { ql_log(ql_log_info, vha, 0x70e6, "SRB allocation failed\n"); + fcport->flags &= ~FCF_ASYNC_ACTIVE; return -ENOMEM; } fcport->flags |= FCF_ASYNC_SENT; - fcport->disc_state = DSC_LOGIN_PEND; + qla2x00_set_fcport_disc_state(fcport, DSC_LOGIN_PEND); elsio = &sp->u.iocb_cmd; ql_dbg(ql_dbg_io, vha, 0x3073, "Enter: PLOGI portid=%06x\n", fcport->d_id.b24); @@ -2975,7 +3002,7 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t *vha, int els_opcode, } out: - fcport->flags &= ~(FCF_ASYNC_SENT); + fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE); qla2x00_els_dcmd2_free(vha, &elsio->u.els_plogi); sp->free(sp); done: diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 7b8a6bfcf08d..e40705d38cea 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -788,7 +788,7 @@ skip_rio: if (atomic_read(&vha->loop_state) != LOOP_DOWN) { atomic_set(&vha->loop_state, LOOP_DOWN); atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME); - qla2x00_mark_all_devices_lost(vha, 1); + qla2x00_mark_all_devices_lost(vha); } if (vha->vp_idx) { @@ -861,7 +861,7 @@ skip_rio: } vha->device_flags |= DFLG_NO_CABLE; - qla2x00_mark_all_devices_lost(vha, 1); + qla2x00_mark_all_devices_lost(vha); } if (vha->vp_idx) { @@ -881,7 +881,7 @@ skip_rio: if (atomic_read(&vha->loop_state) != LOOP_DOWN) { atomic_set(&vha->loop_state, LOOP_DOWN); atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME); - qla2x00_mark_all_devices_lost(vha, 1); + qla2x00_mark_all_devices_lost(vha); } if (vha->vp_idx) { @@ -924,7 +924,7 @@ skip_rio: atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME); if (!N2N_TOPO(ha)) - qla2x00_mark_all_devices_lost(vha, 1); + qla2x00_mark_all_devices_lost(vha); } if (vha->vp_idx) { @@ -953,7 +953,7 @@ skip_rio: if (!atomic_read(&vha->loop_down_timer)) atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME); - qla2x00_mark_all_devices_lost(vha, 1); + qla2x00_mark_all_devices_lost(vha); } if (vha->vp_idx) { @@ -1022,7 +1022,6 @@ skip_rio: "Marking port lost loopid=%04x portid=%06x.\n", fcport->loop_id, fcport->d_id.b24); 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(fcport); } @@ -1034,14 +1033,14 @@ global_port_update: atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME); vha->device_flags |= DFLG_NO_CABLE; - qla2x00_mark_all_devices_lost(vha, 1); + qla2x00_mark_all_devices_lost(vha); } if (vha->vp_idx) { atomic_set(&vha->vp_state, VP_FAILED); fc_vport_set_state(vha->fc_vport, FC_VPORT_FAILED); - qla2x00_mark_all_devices_lost(vha, 1); + qla2x00_mark_all_devices_lost(vha); } vha->flags.management_server_logged_in = 0; @@ -1253,11 +1252,33 @@ global_port_update: case MBA_DPORT_DIAGNOSTICS: ql_dbg(ql_dbg_async, vha, 0x5052, - "D-Port Diagnostics: %04x result=%s\n", - mb[0], - mb[1] == 0 ? "start" : - mb[1] == 1 ? "done (pass)" : - mb[1] == 2 ? "done (error)" : "other"); + "D-Port Diagnostics: %04x %04x %04x %04x\n", + mb[0], mb[1], mb[2], mb[3]); + if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) { + static char *results[] = { + "start", "done(pass)", "done(error)", "undefined" }; + static char *types[] = { + "none", "dynamic", "static", "other" }; + uint result = mb[1] >> 0 & 0x3; + uint type = mb[1] >> 6 & 0x3; + uint sw = mb[1] >> 15 & 0x1; + ql_dbg(ql_dbg_async, vha, 0x5052, + "D-Port Diagnostics: result=%s type=%s [sw=%u]\n", + results[result], types[type], sw); + if (result == 2) { + static char *reasons[] = { + "reserved", "unexpected reject", + "unexpected phase", "retry exceeded", + "timed out", "not supported", + "user stopped" }; + uint reason = mb[2] >> 0 & 0xf; + uint phase = mb[2] >> 12 & 0xf; + ql_dbg(ql_dbg_async, vha, 0x5052, + "D-Port Diagnostics: reason=%s phase=%u \n", + reason < 7 ? reasons[reason] : "other", + phase >> 1); + } + } break; case MBA_TEMPERATURE_ALERT: @@ -1918,6 +1939,18 @@ static void qla24xx_nvme_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, inbuf = (uint32_t *)&sts->nvme_ersp_data; outbuf = (uint32_t *)fd->rspaddr; iocb->u.nvme.rsp_pyld_len = le16_to_cpu(sts->nvme_rsp_pyld_len); + if (unlikely(iocb->u.nvme.rsp_pyld_len > + sizeof(struct nvme_fc_ersp_iu))) { + if (ql_mask_match(ql_dbg_io)) { + WARN_ONCE(1, "Unexpected response payload length %u.\n", + iocb->u.nvme.rsp_pyld_len); + ql_log(ql_log_warn, fcport->vha, 0x5100, + "Unexpected response payload length %u.\n", + iocb->u.nvme.rsp_pyld_len); + } + iocb->u.nvme.rsp_pyld_len = + sizeof(struct nvme_fc_ersp_iu); + } iter = iocb->u.nvme.rsp_pyld_len >> 2; for (; iter; iter--) *outbuf++ = swab32(*inbuf++); @@ -2152,12 +2185,12 @@ qla2x00_handle_dif_error(srb_t *sp, struct sts_entry_24xx *sts24) * swab32 of the "data" field in the beginning of qla2x00_status_entry() * would make guard field appear at offset 2 */ - a_guard = le16_to_cpu(*(uint16_t *)(ap + 2)); - a_app_tag = le16_to_cpu(*(uint16_t *)(ap + 0)); - a_ref_tag = le32_to_cpu(*(uint32_t *)(ap + 4)); - e_guard = le16_to_cpu(*(uint16_t *)(ep + 2)); - e_app_tag = le16_to_cpu(*(uint16_t *)(ep + 0)); - e_ref_tag = le32_to_cpu(*(uint32_t *)(ep + 4)); + a_guard = get_unaligned_le16(ap + 2); + a_app_tag = get_unaligned_le16(ap + 0); + a_ref_tag = get_unaligned_le32(ap + 4); + e_guard = get_unaligned_le16(ep + 2); + e_app_tag = get_unaligned_le16(ep + 0); + e_ref_tag = get_unaligned_le32(ep + 4); ql_dbg(ql_dbg_io, vha, 0x3023, "iocb(s) %p Returned STATUS.\n", sts24); @@ -2745,7 +2778,6 @@ check_scsi_status: port_state_str[FCS_ONLINE], comp_status); - qla2x00_mark_device_lost(fcport->vha, fcport, 1, 1); qlt_schedule_sess_for_deletion(fcport); } diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index b7c1108c48e2..9e09964f5c0e 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c @@ -6152,9 +6152,8 @@ qla2x00_dump_mctp_data(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t addr, mcp->mb[7] = LSW(MSD(req_dma)); mcp->mb[8] = MSW(addr); /* Setting RAM ID to valid */ - mcp->mb[10] |= BIT_7; /* For MCTP RAM ID is 0x40 */ - mcp->mb[10] |= 0x40; + mcp->mb[10] = BIT_7 | 0x40; mcp->out_mb |= MBX_10|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1| MBX_0; diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c index eabc5127174e..8ae639d089d1 100644 --- a/drivers/scsi/qla2xxx/qla_mid.c +++ b/drivers/scsi/qla2xxx/qla_mid.c @@ -147,7 +147,7 @@ qla2x00_mark_vp_devices_dead(scsi_qla_host_t *vha) "Marking port dead, loop_id=0x%04x : %x.\n", fcport->loop_id, fcport->vha->vp_idx); - qla2x00_mark_device_lost(vha, fcport, 0, 0); + qla2x00_mark_device_lost(vha, fcport, 0); qla2x00_set_fcport_state(fcport, FCS_UNCONFIGURED); } } @@ -167,7 +167,7 @@ qla24xx_disable_vp(scsi_qla_host_t *vha) list_for_each_entry(fcport, &vha->vp_fcports, list) fcport->logout_on_delete = 0; - qla2x00_mark_all_devices_lost(vha, 0); + qla2x00_mark_all_devices_lost(vha); /* Remove port id from vp target map */ spin_lock_irqsave(&vha->hw->hardware_lock, flags); @@ -327,7 +327,7 @@ qla2x00_vp_abort_isp(scsi_qla_host_t *vha) */ if (atomic_read(&vha->loop_state) != LOOP_DOWN) { atomic_set(&vha->loop_state, LOOP_DOWN); - qla2x00_mark_all_devices_lost(vha, 0); + qla2x00_mark_all_devices_lost(vha); } else { if (!atomic_read(&vha->loop_down_timer)) atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME); diff --git a/drivers/scsi/qla2xxx/qla_mr.c b/drivers/scsi/qla2xxx/qla_mr.c index 605b59c76c90..cad1fc2a1b28 100644 --- a/drivers/scsi/qla2xxx/qla_mr.c +++ b/drivers/scsi/qla2xxx/qla_mr.c @@ -789,7 +789,7 @@ qlafx00_iospace_config(struct qla_hw_data *ha) } ha->cregbase = - ioremap_nocache(pci_resource_start(ha->pdev, 0), BAR0_LEN_FX00); + ioremap(pci_resource_start(ha->pdev, 0), BAR0_LEN_FX00); if (!ha->cregbase) { ql_log_pci(ql_log_fatal, ha->pdev, 0x0128, "cannot remap MMIO (%s), aborting\n", pci_name(ha->pdev)); @@ -810,7 +810,7 @@ qlafx00_iospace_config(struct qla_hw_data *ha) } ha->iobase = - ioremap_nocache(pci_resource_start(ha->pdev, 2), BAR2_LEN_FX00); + ioremap(pci_resource_start(ha->pdev, 2), BAR2_LEN_FX00); if (!ha->iobase) { ql_log_pci(ql_log_fatal, ha->pdev, 0x012b, "cannot remap MMIO (%s), aborting\n", pci_name(ha->pdev)); @@ -1210,9 +1210,9 @@ qlafx00_find_all_targets(scsi_qla_host_t *vha, " Existing TGT-ID %x did not get " " offline event from firmware.\n", fcport->old_tgt_id); - qla2x00_mark_device_lost(vha, fcport, 0, 0); + qla2x00_mark_device_lost(vha, fcport, 0); set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); - kfree(new_fcport); + qla2x00_free_fcport(new_fcport); return rval; } break; @@ -1230,7 +1230,7 @@ qlafx00_find_all_targets(scsi_qla_host_t *vha, return QLA_MEMORY_ALLOC_FAILED; } - kfree(new_fcport); + qla2x00_free_fcport(new_fcport); return rval; } @@ -1274,7 +1274,7 @@ qlafx00_configure_all_targets(scsi_qla_host_t *vha) if (atomic_read(&fcport->state) == FCS_DEVICE_LOST) { if (fcport->port_type != FCT_INITIATOR) - qla2x00_mark_device_lost(vha, fcport, 0, 0); + qla2x00_mark_device_lost(vha, fcport, 0); } } @@ -1298,7 +1298,7 @@ qlafx00_configure_all_targets(scsi_qla_host_t *vha) /* Free all new device structures not processed. */ list_for_each_entry_safe(fcport, rmptemp, &new_fcports, list) { list_del(&fcport->list); - kfree(fcport); + qla2x00_free_fcport(fcport); } return rval; @@ -1706,7 +1706,7 @@ qlafx00_tgt_detach(struct scsi_qla_host *vha, int tgt_id) if (!fcport) return; - qla2x00_mark_device_lost(vha, fcport, 0, 0); + qla2x00_mark_device_lost(vha, fcport, 0); return; } @@ -1740,7 +1740,7 @@ qlafx00_process_aen(struct scsi_qla_host *vha, struct qla_work_evt *evt) set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); } else if (evt->u.aenfx.mbx[2] == 2) { vha->device_flags |= DFLG_NO_CABLE; - qla2x00_mark_all_devices_lost(vha, 1); + qla2x00_mark_all_devices_lost(vha); } } break; @@ -2513,7 +2513,7 @@ check_scsi_status: atomic_read(&fcport->state)); if (atomic_read(&fcport->state) == FCS_ONLINE) - qla2x00_mark_device_lost(fcport->vha, fcport, 1, 1); + qla2x00_mark_device_lost(fcport->vha, fcport, 1); break; case CS_ABORTED: diff --git a/drivers/scsi/qla2xxx/qla_nx.c b/drivers/scsi/qla2xxx/qla_nx.c index 2b2028f2383e..185c5f34d4c1 100644 --- a/drivers/scsi/qla2xxx/qla_nx.c +++ b/drivers/scsi/qla2xxx/qla_nx.c @@ -1612,8 +1612,7 @@ qla82xx_get_bootld_offset(struct qla_hw_data *ha) return (u8 *)&ha->hablob->fw->data[offset]; } -static __le32 -qla82xx_get_fw_size(struct qla_hw_data *ha) +static u32 qla82xx_get_fw_size(struct qla_hw_data *ha) { struct qla82xx_uri_data_desc *uri_desc = NULL; @@ -1624,7 +1623,7 @@ qla82xx_get_fw_size(struct qla_hw_data *ha) return cpu_to_le32(uri_desc->size); } - return cpu_to_le32(*(u32 *)&ha->hablob->fw->data[FW_SIZE_OFFSET]); + return get_unaligned_le32(&ha->hablob->fw->data[FW_SIZE_OFFSET]); } static u8 * @@ -1816,7 +1815,7 @@ qla82xx_fw_load_from_blob(struct qla_hw_data *ha) } flashaddr = FLASH_ADDR_START; - size = (__force u32)qla82xx_get_fw_size(ha) / 8; + size = qla82xx_get_fw_size(ha) / 8; ptr64 = (u64 *)qla82xx_get_fw_offs(ha); for (i = 0; i < size; i++) { @@ -1883,7 +1882,7 @@ qla82xx_set_product_offset(struct qla_hw_data *ha) static int qla82xx_validate_firmware_blob(scsi_qla_host_t *vha, uint8_t fw_type) { - __le32 val; + uint32_t val; uint32_t min_size; struct qla_hw_data *ha = vha->hw; const struct firmware *fw = ha->hablob->fw; @@ -1896,8 +1895,8 @@ qla82xx_validate_firmware_blob(scsi_qla_host_t *vha, uint8_t fw_type) min_size = QLA82XX_URI_FW_MIN_SIZE; } else { - val = cpu_to_le32(*(u32 *)&fw->data[QLA82XX_FW_MAGIC_OFFSET]); - if ((__force u32)val != QLA82XX_BDINFO_MAGIC) + val = get_unaligned_le32(&fw->data[QLA82XX_FW_MAGIC_OFFSET]); + if (val != QLA82XX_BDINFO_MAGIC) return -EINVAL; min_size = QLA82XX_FW_MIN_SIZE; @@ -3030,7 +3029,7 @@ qla8xxx_dev_failed_handler(scsi_qla_host_t *vha) /* Set DEV_FAILED flag to disable timer */ vha->device_flags |= DFLG_DEV_FAILED; qla2x00_abort_all_cmds(vha, DID_NO_CONNECT << 16); - qla2x00_mark_all_devices_lost(vha, 0); + qla2x00_mark_all_devices_lost(vha); vha->flags.online = 0; vha->flags.init_done = 0; } diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 8b84bc4a6ac8..b520a980d1dc 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -1110,7 +1110,7 @@ qla2x00_wait_for_sess_deletion(scsi_qla_host_t *vha) { u8 i; - qla2x00_mark_all_devices_lost(vha, 0); + qla2x00_mark_all_devices_lost(vha); for (i = 0; i < 10; i++) { if (wait_event_timeout(vha->fcport_waitQ, @@ -1667,7 +1667,7 @@ qla2x00_loop_reset(scsi_qla_host_t *vha) if (ha->flags.enable_lip_full_login && !IS_CNA_CAPABLE(ha)) { atomic_set(&vha->loop_state, LOOP_DOWN); atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME); - qla2x00_mark_all_devices_lost(vha, 0); + qla2x00_mark_all_devices_lost(vha); ret = qla2x00_full_login_lip(vha); if (ret != QLA_SUCCESS) { ql_dbg(ql_dbg_taskm, vha, 0x802d, @@ -3854,37 +3854,21 @@ void qla2x00_free_fcports(struct scsi_qla_host *vha) } static inline void -qla2x00_schedule_rport_del(struct scsi_qla_host *vha, fc_port_t *fcport, - int defer) +qla2x00_schedule_rport_del(struct scsi_qla_host *vha, fc_port_t *fcport) { - struct fc_rport *rport; - scsi_qla_host_t *base_vha; - unsigned long flags; + int now; if (!fcport->rport) return; - rport = fcport->rport; - if (defer) { - base_vha = pci_get_drvdata(vha->hw->pdev); - spin_lock_irqsave(vha->host->host_lock, flags); - fcport->drport = rport; - spin_unlock_irqrestore(vha->host->host_lock, flags); - qlt_do_generation_tick(vha, &base_vha->total_fcport_update_gen); - set_bit(FCPORT_UPDATE_NEEDED, &base_vha->dpc_flags); - qla2xxx_wake_dpc(base_vha); - } else { - int now; - - if (rport) { - ql_dbg(ql_dbg_disc, fcport->vha, 0x2109, - "%s %8phN. rport %p roles %x\n", - __func__, fcport->port_name, rport, - rport->roles); - fc_remote_port_delete(rport); - } - qlt_do_generation_tick(vha, &now); + if (fcport->rport) { + ql_dbg(ql_dbg_disc, fcport->vha, 0x2109, + "%s %8phN. rport %p roles %x\n", + __func__, fcport->port_name, fcport->rport, + fcport->rport->roles); + fc_remote_port_delete(fcport->rport); } + qlt_do_generation_tick(vha, &now); } /* @@ -3897,18 +3881,18 @@ qla2x00_schedule_rport_del(struct scsi_qla_host *vha, fc_port_t *fcport, * Context: */ void qla2x00_mark_device_lost(scsi_qla_host_t *vha, fc_port_t *fcport, - int do_login, int defer) + int do_login) { if (IS_QLAFX00(vha->hw)) { qla2x00_set_fcport_state(fcport, FCS_DEVICE_LOST); - qla2x00_schedule_rport_del(vha, fcport, defer); + qla2x00_schedule_rport_del(vha, fcport); return; } if (atomic_read(&fcport->state) == FCS_ONLINE && vha->vp_idx == fcport->vha->vp_idx) { qla2x00_set_fcport_state(fcport, FCS_DEVICE_LOST); - qla2x00_schedule_rport_del(vha, fcport, defer); + qla2x00_schedule_rport_del(vha, fcport); } /* * We may need to retry the login, so don't change the state of the @@ -3937,7 +3921,7 @@ void qla2x00_mark_device_lost(scsi_qla_host_t *vha, fc_port_t *fcport, * Context: */ void -qla2x00_mark_all_devices_lost(scsi_qla_host_t *vha, int defer) +qla2x00_mark_all_devices_lost(scsi_qla_host_t *vha) { fc_port_t *fcport; @@ -3957,13 +3941,6 @@ qla2x00_mark_all_devices_lost(scsi_qla_host_t *vha, int defer) */ if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD) continue; - if (atomic_read(&fcport->state) == FCS_ONLINE) { - qla2x00_set_fcport_state(fcport, FCS_DEVICE_LOST); - if (defer) - qla2x00_schedule_rport_del(vha, fcport, defer); - else if (vha->vp_idx == fcport->vha->vp_idx) - qla2x00_schedule_rport_del(vha, fcport, defer); - } } } @@ -4965,7 +4942,6 @@ int qla2x00_post_async_##name##_work( \ qla2x00_post_async_work(login, QLA_EVT_ASYNC_LOGIN); qla2x00_post_async_work(logout, QLA_EVT_ASYNC_LOGOUT); -qla2x00_post_async_work(logout_done, QLA_EVT_ASYNC_LOGOUT_DONE); qla2x00_post_async_work(adisc, QLA_EVT_ASYNC_ADISC); qla2x00_post_async_work(prlo, QLA_EVT_ASYNC_PRLO); qla2x00_post_async_work(prlo_done, QLA_EVT_ASYNC_PRLO_DONE); @@ -5032,7 +5008,7 @@ void qla24xx_sched_upd_fcport(fc_port_t *fcport) fcport->jiffies_at_registration = jiffies; fcport->sec_since_registration = 0; fcport->next_disc_state = DSC_DELETED; - fcport->disc_state = DSC_UPD_FCPORT; + qla2x00_set_fcport_disc_state(fcport, DSC_UPD_FCPORT); spin_unlock_irqrestore(&fcport->vha->work_lock, flags); queue_work(system_unbound_wq, &fcport->reg_work); @@ -5253,10 +5229,6 @@ qla2x00_do_work(struct scsi_qla_host *vha) case QLA_EVT_ASYNC_LOGOUT: rc = qla2x00_async_logout(vha, e->u.logio.fcport); break; - case QLA_EVT_ASYNC_LOGOUT_DONE: - qla2x00_async_logout_done(vha, e->u.logio.fcport, - e->u.logio.data); - break; case QLA_EVT_ASYNC_ADISC: qla2x00_async_adisc(vha, e->u.logio.fcport, e->u.logio.data); @@ -6899,13 +6871,13 @@ static void qla_pci_error_cleanup(scsi_qla_host_t *vha) qpair->online = 0; mutex_unlock(&ha->mq_lock); - qla2x00_mark_all_devices_lost(vha, 0); + qla2x00_mark_all_devices_lost(vha); spin_lock_irqsave(&ha->vport_slock, flags); list_for_each_entry(vp, &ha->vp_list, list) { atomic_inc(&vp->vref_count); spin_unlock_irqrestore(&ha->vport_slock, flags); - qla2x00_mark_all_devices_lost(vp, 0); + qla2x00_mark_all_devices_lost(vp); spin_lock_irqsave(&ha->vport_slock, flags); atomic_dec(&vp->vref_count); } @@ -7270,6 +7242,8 @@ qla2x00_module_init(void) BUILD_BUG_ON(sizeof(struct sns_cmd_pkt) != 2064); BUILD_BUG_ON(sizeof(struct verify_chip_entry_84xx) != 64); BUILD_BUG_ON(sizeof(struct vf_evfp_entry_24xx) != 56); + BUILD_BUG_ON(sizeof(struct qla_flt_region) != 16); + BUILD_BUG_ON(sizeof(struct qla_flt_header) != 8); /* Allocate cache for SRBs. */ srb_cachep = kmem_cache_create("qla2xxx_srbs", sizeof(srb_t), 0, diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c index bbe90354f49b..76a38bf86cbc 100644 --- a/drivers/scsi/qla2xxx/qla_sup.c +++ b/drivers/scsi/qla2xxx/qla_sup.c @@ -669,8 +669,8 @@ qla2xxx_get_flt_info(scsi_qla_host_t *vha, uint32_t flt_addr) struct qla_hw_data *ha = vha->hw; uint32_t def = IS_QLA81XX(ha) ? 2 : IS_QLA25XX(ha) ? 1 : 0; - struct qla_flt_header *flt = (void *)ha->flt; - struct qla_flt_region *region = (void *)&flt[1]; + struct qla_flt_header *flt = ha->flt; + struct qla_flt_region *region = &flt->region[0]; uint16_t *wptr, cnt, chksum; uint32_t start; @@ -2652,18 +2652,15 @@ qla28xx_get_flash_region(struct scsi_qla_host *vha, uint32_t start, struct qla_flt_region *region) { struct qla_hw_data *ha = vha->hw; - struct qla_flt_header *flt; - struct qla_flt_region *flt_reg; + struct qla_flt_header *flt = ha->flt; + struct qla_flt_region *flt_reg = &flt->region[0]; uint16_t cnt; int rval = QLA_FUNCTION_FAILED; if (!ha->flt) return QLA_FUNCTION_FAILED; - flt = (struct qla_flt_header *)ha->flt; - flt_reg = (struct qla_flt_region *)&flt[1]; cnt = le16_to_cpu(flt->length) / sizeof(struct qla_flt_region); - for (; cnt; cnt--, flt_reg++) { if (flt_reg->start == start) { memcpy((uint8_t *)region, flt_reg, diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index 68c14143e50e..70081b395fb2 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c @@ -596,7 +596,8 @@ static void qla2x00_async_nack_sp_done(srb_t *sp, int res) spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags); } else { sp->fcport->login_retry = 0; - sp->fcport->disc_state = DSC_LOGIN_COMPLETE; + qla2x00_set_fcport_disc_state(sp->fcport, + DSC_LOGIN_COMPLETE); sp->fcport->deleted = 0; sp->fcport->logout_on_delete = 1; } @@ -957,7 +958,7 @@ void qlt_free_session_done(struct work_struct *work) struct qlt_plogi_ack_t *own = sess->plogi_link[QLT_PLOGI_LINK_SAME_WWN]; - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf084, + ql_dbg(ql_dbg_disc, vha, 0xf084, "%s: se_sess %p / sess %p from port %8phC loop_id %#04x" " s_id %02x:%02x:%02x logout %d keep %d els_logo %d\n", __func__, sess->se_sess, sess, sess->port_name, sess->loop_id, @@ -966,7 +967,7 @@ void qlt_free_session_done(struct work_struct *work) sess->send_els_logo); if (!IS_SW_RESV_ADDR(sess->d_id)) { - qla2x00_mark_device_lost(vha, sess, 0, 0); + qla2x00_mark_device_lost(vha, sess, 0); if (sess->send_els_logo) { qlt_port_logo_t logo; @@ -1024,7 +1025,7 @@ void qlt_free_session_done(struct work_struct *work) while (!READ_ONCE(sess->logout_completed)) { if (!traced) { - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf086, + ql_dbg(ql_dbg_disc, vha, 0xf086, "%s: waiting for sess %p logout\n", __func__, sess); traced = true; @@ -1045,6 +1046,10 @@ void qlt_free_session_done(struct work_struct *work) (struct imm_ntfy_from_isp *)sess->iocb, SRB_NACK_LOGO); } + spin_lock_irqsave(&vha->work_lock, flags); + sess->flags &= ~FCF_ASYNC_SENT; + spin_unlock_irqrestore(&vha->work_lock, flags); + spin_lock_irqsave(&ha->tgt.sess_lock, flags); if (sess->se_sess) { sess->se_sess = NULL; @@ -1052,7 +1057,7 @@ void qlt_free_session_done(struct work_struct *work) tgt->sess_count--; } - sess->disc_state = DSC_DELETED; + qla2x00_set_fcport_disc_state(sess, DSC_DELETED); sess->fw_login_state = DSC_LS_PORT_UNAVAIL; sess->deleted = QLA_SESS_DELETED; @@ -1108,7 +1113,7 @@ void qlt_free_session_done(struct work_struct *work) spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); sess->free_pending = 0; - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf001, + ql_dbg(ql_dbg_disc, vha, 0xf001, "Unregistration of sess %p %8phC finished fcp_cnt %d\n", sess, sess->port_name, vha->fcport_count); @@ -1151,13 +1156,18 @@ void qlt_unreg_sess(struct fc_port *sess) return; } sess->free_pending = 1; + /* + * Use FCF_ASYNC_SENT flag to block other cmds used in sess + * management from being sent. + */ + sess->flags |= FCF_ASYNC_SENT; spin_unlock_irqrestore(&sess->vha->work_lock, flags); if (sess->se_sess) vha->hw->tgt.tgt_ops->clear_nacl_from_fcport_map(sess); sess->deleted = QLA_SESS_DELETION_IN_PROGRESS; - sess->disc_state = DSC_DELETE_PEND; + qla2x00_set_fcport_disc_state(sess, DSC_DELETE_PEND); sess->last_rscn_gen = sess->rscn_gen; sess->last_login_gen = sess->login_gen; @@ -1257,7 +1267,8 @@ void qlt_schedule_sess_for_deletion(struct fc_port *sess) sess->deleted = QLA_SESS_DELETION_IN_PROGRESS; spin_unlock_irqrestore(&sess->vha->work_lock, flags); - sess->disc_state = DSC_DELETE_PEND; + sess->prli_pend_timer = 0; + qla2x00_set_fcport_disc_state(sess, DSC_DELETE_PEND); qla24xx_chk_fcp_state(sess); @@ -3446,13 +3457,13 @@ qlt_handle_dif_error(struct qla_qpair *qpair, struct qla_tgt_cmd *cmd, cmd->trc_flags |= TRC_DIF_ERR; - cmd->a_guard = be16_to_cpu(*(uint16_t *)(ap + 0)); - cmd->a_app_tag = be16_to_cpu(*(uint16_t *)(ap + 2)); - cmd->a_ref_tag = be32_to_cpu(*(uint32_t *)(ap + 4)); + cmd->a_guard = get_unaligned_be16(ap + 0); + cmd->a_app_tag = get_unaligned_be16(ap + 2); + cmd->a_ref_tag = get_unaligned_be32(ap + 4); - cmd->e_guard = be16_to_cpu(*(uint16_t *)(ep + 0)); - cmd->e_app_tag = be16_to_cpu(*(uint16_t *)(ep + 2)); - cmd->e_ref_tag = be32_to_cpu(*(uint32_t *)(ep + 4)); + cmd->e_guard = get_unaligned_be16(ep + 0); + cmd->e_app_tag = get_unaligned_be16(ep + 2); + cmd->e_ref_tag = get_unaligned_be32(ep + 4); ql_dbg(ql_dbg_tgt_dif, vha, 0xf075, "%s: aborted %d state %d\n", __func__, cmd->aborted, cmd->state); @@ -4579,7 +4590,7 @@ qlt_find_sess_invalidate_other(scsi_qla_host_t *vha, uint64_t wwn, /* find other sess with nport_id collision */ if (port_id.b24 == other_sess->d_id.b24) { if (loop_id != other_sess->loop_id) { - ql_dbg(ql_dbg_tgt_tmr, vha, 0x1000c, + ql_dbg(ql_dbg_disc, vha, 0x1000c, "Invalidating sess %p loop_id %d wwn %llx.\n", other_sess, other_sess->loop_id, other_wwn); @@ -4595,7 +4606,7 @@ qlt_find_sess_invalidate_other(scsi_qla_host_t *vha, uint64_t wwn, * Another wwn used to have our s_id/loop_id * kill the session, but don't free the loop_id */ - ql_dbg(ql_dbg_tgt_tmr, vha, 0xf01b, + ql_dbg(ql_dbg_disc, vha, 0xf01b, "Invalidating sess %p loop_id %d wwn %llx.\n", other_sess, other_sess->loop_id, other_wwn); @@ -4610,7 +4621,7 @@ qlt_find_sess_invalidate_other(scsi_qla_host_t *vha, uint64_t wwn, /* find other sess with nport handle collision */ if ((loop_id == other_sess->loop_id) && (loop_id != FC_NO_LOOP_ID)) { - ql_dbg(ql_dbg_tgt_tmr, vha, 0x1000d, + ql_dbg(ql_dbg_disc, vha, 0x1000d, "Invalidating sess %p loop_id %d wwn %llx.\n", other_sess, other_sess->loop_id, other_wwn); @@ -6053,7 +6064,7 @@ static fc_port_t *qlt_get_port_database(struct scsi_qla_host *vha, if (!IS_SW_RESV_ADDR(fcport->d_id)) vha->fcport_count++; fcport->login_gen++; - fcport->disc_state = DSC_LOGIN_COMPLETE; + qla2x00_set_fcport_disc_state(fcport, DSC_LOGIN_COMPLETE); fcport->login_succ = 1; newfcport = 1; } diff --git a/drivers/scsi/qla2xxx/qla_target.h b/drivers/scsi/qla2xxx/qla_target.h index d006f0a97b8c..6539499e9e95 100644 --- a/drivers/scsi/qla2xxx/qla_target.h +++ b/drivers/scsi/qla2xxx/qla_target.h @@ -379,8 +379,7 @@ static inline int get_datalen_for_atio(struct atio_from_isp *atio) { int len = atio->u.isp24.fcp_cmnd.add_cdb_len; - return (be32_to_cpu(get_unaligned((uint32_t *) - &atio->u.isp24.fcp_cmnd.add_cdb[len * 4]))); + return get_unaligned_be32(&atio->u.isp24.fcp_cmnd.add_cdb[len * 4]); } #define CTIO_TYPE7 0x12 /* Continue target I/O entry (for 24xx) */ diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h index 03bd3b712b77..bb03c022e023 100644 --- a/drivers/scsi/qla2xxx/qla_version.h +++ b/drivers/scsi/qla2xxx/qla_version.h @@ -7,7 +7,7 @@ /* * Driver version */ -#define QLA2XXX_VERSION "10.01.00.21-k" +#define QLA2XXX_VERSION "10.01.00.22-k" #define QLA_DRIVER_MAJOR_VER 10 #define QLA_DRIVER_MINOR_VER 1 |