diff options
-rw-r--r-- | drivers/scsi/lpfc/lpfc_bsg.c | 210 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_bsg.h | 19 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_ct.c | 6 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_disc.h | 11 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_els.c | 55 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hbadisc.c | 13 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hw.h | 3 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hw4.h | 85 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_init.c | 11 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_mbox.c | 6 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_nportdisc.c | 53 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_scsi.c | 27 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli4.h | 2 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_version.h | 2 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_vport.c | 22 |
15 files changed, 351 insertions, 174 deletions
diff --git a/drivers/scsi/lpfc/lpfc_bsg.c b/drivers/scsi/lpfc/lpfc_bsg.c index 1c6b024160da..c8f8496bbdf8 100644 --- a/drivers/scsi/lpfc/lpfc_bsg.c +++ b/drivers/scsi/lpfc/lpfc_bsg.c @@ -120,6 +120,16 @@ enum ELX_LOOPBACK_CMD { #define ELX_LOOPBACK_HEADER_SZ \ (size_t)(&((struct lpfc_sli_ct_request *)NULL)->un) +/* For non-embedded read object command */ +#define READ_OBJ_EMB0_SCHEME_0 {1, 10, 256, 128} +#define READ_OBJ_EMB0_SCHEME_1 {11, LPFC_EMB0_MAX_RD_OBJ_HBD_CNT, 512, 192} +static const struct lpfc_read_object_cmd_scheme { + u32 min_hbd_cnt; + u32 max_hbd_cnt; + u32 cmd_size; + u32 payload_word_offset; +} rd_obj_scheme[2] = {READ_OBJ_EMB0_SCHEME_0, READ_OBJ_EMB0_SCHEME_1}; + struct lpfc_dmabufext { struct lpfc_dmabuf dma; uint32_t size; @@ -3539,6 +3549,103 @@ lpfc_bsg_mbox_ext_session_reset(struct lpfc_hba *phba) } /** + * lpfc_rd_obj_emb0_handle_job - Handles completion for non-embedded + * READ_OBJECT_V0 mailbox commands + * @phba: pointer to lpfc_hba data struct + * @pmb_buf: pointer to mailbox buffer + * @sli_cfg_mbx: pointer to SLI_CONFIG mailbox memory region + * @job: pointer to bsg_job struct + * @bsg_reply: point to bsg_reply struct + * + * Given a non-embedded READ_OBJECT_V0's HBD_CNT, this routine copies + * a READ_OBJECT_V0 mailbox command's read data payload into a bsg_job + * structure for passing back to application layer. + * + * Return codes + * 0 - successful + * -EINVAL - invalid HBD_CNT + * -ENODEV - pointer to bsg_job struct is NULL + **/ +static int +lpfc_rd_obj_emb0_handle_job(struct lpfc_hba *phba, u8 *pmb_buf, + struct lpfc_sli_config_mbox *sli_cfg_mbx, + struct bsg_job *job, + struct fc_bsg_reply *bsg_reply) +{ + struct lpfc_dmabuf *curr_dmabuf, *next_dmabuf; + struct lpfc_sli_config_emb0_subsys *emb0_subsys; + u32 hbd_cnt; + u32 dma_buf_len; + u8 i = 0; + size_t extra_bytes; + off_t skip = 0; + + if (!job) { + lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC, + "2496 NULL job\n"); + return -ENODEV; + } + + if (!bsg_reply) { + lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC, + "2498 NULL bsg_reply\n"); + return -ENODEV; + } + + emb0_subsys = &sli_cfg_mbx->un.sli_config_emb0_subsys; + + hbd_cnt = bsg_bf_get(lpfc_emb0_subcmnd_rd_obj_hbd_cnt, + emb0_subsys); + + /* Calculate where the read object's read data payload is located based + * on HBD count scheme. + */ + if (hbd_cnt >= rd_obj_scheme[0].min_hbd_cnt && + hbd_cnt <= rd_obj_scheme[0].max_hbd_cnt) { + skip = rd_obj_scheme[0].payload_word_offset * 4; + } else if (hbd_cnt >= rd_obj_scheme[1].min_hbd_cnt && + hbd_cnt <= rd_obj_scheme[1].max_hbd_cnt) { + skip = rd_obj_scheme[1].payload_word_offset * 4; + } else { + lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC, + "2497 bad hbd_count 0x%08x\n", + hbd_cnt); + return -EINVAL; + } + + /* Copy SLI_CONFIG command and READ_OBJECT response first */ + bsg_reply->reply_payload_rcv_len = + sg_copy_from_buffer(job->reply_payload.sg_list, + job->reply_payload.sg_cnt, + pmb_buf, skip); + + /* Copy data from hbds */ + list_for_each_entry_safe(curr_dmabuf, next_dmabuf, + &phba->mbox_ext_buf_ctx.ext_dmabuf_list, + list) { + dma_buf_len = emb0_subsys->hbd[i].buf_len; + + /* Use sg_copy_buffer to specify a skip offset */ + extra_bytes = sg_copy_buffer(job->reply_payload.sg_list, + job->reply_payload.sg_cnt, + curr_dmabuf->virt, + dma_buf_len, skip, false); + + bsg_reply->reply_payload_rcv_len += extra_bytes; + + skip += extra_bytes; + + lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC, + "2499 copied hbd[%d] " + "0x%zx bytes\n", + i, extra_bytes); + i++; + } + + return 0; +} + +/** * lpfc_bsg_issue_mbox_ext_handle_job - job handler for multi-buffer mbox cmpl * @phba: Pointer to HBA context object. * @pmboxq: Pointer to mailbox command. @@ -3551,10 +3658,10 @@ lpfc_bsg_issue_mbox_ext_handle_job(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq) { struct bsg_job_data *dd_data; struct bsg_job *job; - struct fc_bsg_reply *bsg_reply; + struct fc_bsg_reply *bsg_reply = NULL; uint8_t *pmb, *pmb_buf; unsigned long flags; - uint32_t size; + u32 size, opcode; int rc = 0; struct lpfc_dmabuf *dmabuf; struct lpfc_sli_config_mbox *sli_cfg_mbx; @@ -3591,6 +3698,24 @@ lpfc_bsg_issue_mbox_ext_handle_job(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq) lpfc_sli_pcimem_bcopy(&pmbx[sizeof(MAILBOX_t)], &pmbx[sizeof(MAILBOX_t)], sli_cfg_mbx->un.sli_config_emb0_subsys.mse[0].buf_len); + + /* Special handling for non-embedded READ_OBJECT */ + opcode = bsg_bf_get(lpfc_emb0_subcmnd_opcode, + &sli_cfg_mbx->un.sli_config_emb0_subsys); + switch (opcode) { + case COMN_OPCODE_READ_OBJECT: + if (job) { + rc = lpfc_rd_obj_emb0_handle_job(phba, pmb_buf, + sli_cfg_mbx, + job, + bsg_reply); + bsg_reply->result = rc; + goto done; + } + break; + default: + break; + } } /* Complete the job if the job is still active */ @@ -3604,12 +3729,14 @@ lpfc_bsg_issue_mbox_ext_handle_job(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq) /* result for successful */ bsg_reply->result = 0; +done: lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC, "2937 SLI_CONFIG ext-buffer mailbox command " "(x%x/x%x) complete bsg job done, bsize:%d\n", phba->mbox_ext_buf_ctx.nembType, - phba->mbox_ext_buf_ctx.mboxType, size); + phba->mbox_ext_buf_ctx.mboxType, + job->reply_payload.payload_len); lpfc_idiag_mbxacc_dump_bsg_mbox(phba, phba->mbox_ext_buf_ctx.nembType, phba->mbox_ext_buf_ctx.mboxType, @@ -3819,14 +3946,16 @@ lpfc_bsg_sli_cfg_read_cmd_ext(struct lpfc_hba *phba, struct bsg_job *job, { struct fc_bsg_request *bsg_request = job->request; struct lpfc_sli_config_mbox *sli_cfg_mbx; + struct lpfc_sli_config_emb0_subsys *emb0_subsys; + struct list_head *ext_dmabuf_list; struct dfc_mbox_req *mbox_req; struct lpfc_dmabuf *curr_dmabuf, *next_dmabuf; - uint32_t ext_buf_cnt, ext_buf_index; + u32 ext_buf_cnt, ext_buf_index, hbd_cnt; struct lpfc_dmabuf *ext_dmabuf = NULL; struct bsg_job_data *dd_data = NULL; LPFC_MBOXQ_t *pmboxq = NULL; MAILBOX_t *pmb; - uint8_t *pmbx; + u8 *pmbx, opcode; int rc, i; mbox_req = @@ -3836,8 +3965,9 @@ lpfc_bsg_sli_cfg_read_cmd_ext(struct lpfc_hba *phba, struct bsg_job *job, sli_cfg_mbx = (struct lpfc_sli_config_mbox *)dmabuf->virt; if (nemb_tp == nemb_mse) { + emb0_subsys = &sli_cfg_mbx->un.sli_config_emb0_subsys; ext_buf_cnt = bsg_bf_get(lpfc_mbox_hdr_mse_cnt, - &sli_cfg_mbx->un.sli_config_emb0_subsys.sli_config_hdr); + &emb0_subsys->sli_config_hdr); if (ext_buf_cnt > LPFC_MBX_SLI_CONFIG_MAX_MSE) { lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC, "2945 Handled SLI_CONFIG(mse) rd, " @@ -3847,6 +3977,57 @@ lpfc_bsg_sli_cfg_read_cmd_ext(struct lpfc_hba *phba, struct bsg_job *job, rc = -ERANGE; goto job_error; } + + /* Special handling for non-embedded READ_OBJECT */ + opcode = bsg_bf_get(lpfc_emb0_subcmnd_opcode, emb0_subsys); + switch (opcode) { + case COMN_OPCODE_READ_OBJECT: + hbd_cnt = bsg_bf_get(lpfc_emb0_subcmnd_rd_obj_hbd_cnt, + emb0_subsys); + lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC, + "2449 SLI_CONFIG(mse) rd non-embedded " + "hbd count = %d\n", + hbd_cnt); + + ext_dmabuf_list = + &phba->mbox_ext_buf_ctx.ext_dmabuf_list; + + /* Allocate hbds */ + for (i = 0; i < hbd_cnt; i++) { + ext_dmabuf = lpfc_bsg_dma_page_alloc(phba); + if (!ext_dmabuf) { + rc = -ENOMEM; + goto job_error; + } + list_add_tail(&ext_dmabuf->list, + ext_dmabuf_list); + } + + /* Fill out the physical memory addresses for the + * hbds + */ + i = 0; + list_for_each_entry_safe(curr_dmabuf, next_dmabuf, + ext_dmabuf_list, list) { + emb0_subsys->hbd[i].pa_hi = + putPaddrHigh(curr_dmabuf->phys); + emb0_subsys->hbd[i].pa_lo = + putPaddrLow(curr_dmabuf->phys); + + lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC, + "2495 SLI_CONFIG(hbd)[%d], " + "bufLen:%d, addrHi:x%x, " + "addrLo:x%x\n", i, + emb0_subsys->hbd[i].buf_len, + emb0_subsys->hbd[i].pa_hi, + emb0_subsys->hbd[i].pa_lo); + i++; + } + break; + default: + break; + } + lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC, "2941 Handled SLI_CONFIG(mse) rd, " "ext_buf_cnt:%d\n", ext_buf_cnt); @@ -4223,6 +4404,7 @@ lpfc_bsg_handle_sli_cfg_mbox(struct lpfc_hba *phba, struct bsg_job *job, case COMN_OPCODE_GET_CNTL_ATTRIBUTES: case COMN_OPCODE_GET_PROFILE_CONFIG: case COMN_OPCODE_SET_FEATURES: + case COMN_OPCODE_READ_OBJECT: lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC, "3106 Handled SLI_CONFIG " "subsys_comn, opcode:x%x\n", @@ -4665,8 +4847,7 @@ lpfc_bsg_issue_mbox(struct lpfc_hba *phba, struct bsg_job *job, bsg_reply->reply_payload_rcv_len = 0; /* sanity check to protect driver */ - if (job->reply_payload.payload_len > BSG_MBOX_SIZE || - job->request_payload.payload_len > BSG_MBOX_SIZE) { + if (job->request_payload.payload_len > BSG_MBOX_SIZE) { rc = -ERANGE; goto job_done; } @@ -4737,6 +4918,19 @@ lpfc_bsg_issue_mbox(struct lpfc_hba *phba, struct bsg_job *job, pmb->mbxOwner = OWN_HOST; pmboxq->vport = vport; + /* non-embedded SLI_CONFIG requests already parsed, check others */ + if (unlikely(job->reply_payload.payload_len > BSG_MBOX_SIZE)) { + lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC, + "2729 Cmd x%x (x%x/x%x) request has " + "out-of-range reply payload length x%x\n", + pmb->mbxCommand, + lpfc_sli_config_mbox_subsys_get(phba, pmboxq), + lpfc_sli_config_mbox_opcode_get(phba, pmboxq), + job->reply_payload.payload_len); + rc = -ERANGE; + goto job_done; + } + /* If HBA encountered an error attention, allow only DUMP * or RESTART mailbox commands until the HBA is restarted. */ diff --git a/drivers/scsi/lpfc/lpfc_bsg.h b/drivers/scsi/lpfc/lpfc_bsg.h index 3c04ca2d7455..27e7a033b53d 100644 --- a/drivers/scsi/lpfc/lpfc_bsg.h +++ b/drivers/scsi/lpfc/lpfc_bsg.h @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2017-2022 Broadcom. All Rights Reserved. The term * + * Copyright (C) 2017-2024 Broadcom. All Rights Reserved. The term * * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. * * Copyright (C) 2010-2015 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * @@ -239,12 +239,27 @@ struct lpfc_sli_config_emb0_subsys { uint32_t timeout; /* comn_set_feature timeout */ uint32_t request_length; /* comn_set_feature request len */ uint32_t version; /* comn_set_feature version */ - uint32_t csf_feature; /* comn_set_feature feature */ + uint32_t word68; /* comn_set_feature feature */ +#define lpfc_emb0_subcmnd_csf_feat_SHIFT 0 +#define lpfc_emb0_subcmnd_csf_feat_MASK 0xffffffff +#define lpfc_emb0_subcmnd_csf_feat_WORD word68 +#define lpfc_emb0_subcmnd_rd_obj_des_rd_len_SHIFT 0 +#define lpfc_emb0_subcmnd_rd_obj_des_rd_len_MASK 0x00ffffff +#define lpfc_emb0_subcmnd_rd_obj_des_rd_len_WORD word68 uint32_t word69; /* comn_set_feature parameter len */ uint32_t word70; /* comn_set_feature parameter val0 */ #define lpfc_emb0_subcmnd_csf_p0_SHIFT 0 #define lpfc_emb0_subcmnd_csf_p0_MASK 0x3 #define lpfc_emb0_subcmnd_csf_p0_WORD word70 + uint32_t reserved71[25]; + uint32_t word96; /* rd_obj hbd_count */ +#define lpfc_emb0_subcmnd_rd_obj_hbd_cnt_SHIFT 0 +#define lpfc_emb0_subcmnd_rd_obj_hbd_cnt_MASK 0xffffffff +#define lpfc_emb0_subcmnd_rd_obj_hbd_cnt_WORD word96 +#define LPFC_EMB0_MAX_RD_OBJ_HBD_CNT 31 + struct lpfc_sli_config_hbd hbd[LPFC_EMB0_MAX_RD_OBJ_HBD_CNT]; + uint32_t word190; + uint32_t word191; }; struct lpfc_sli_config_emb1_subsys { diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index 30891ad17e2a..12c67cdd7c19 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c @@ -1646,14 +1646,12 @@ out: /* If the caller wanted a synchronous DA_ID completion, signal the * wait obj and clear flag to reset the vport. */ - if (ndlp->save_flags & NLP_WAIT_FOR_DA_ID) { + if (test_bit(NLP_WAIT_FOR_DA_ID, &ndlp->save_flags)) { if (ndlp->da_id_waitq) wake_up(ndlp->da_id_waitq); } - spin_lock_irq(&ndlp->lock); - ndlp->save_flags &= ~NLP_WAIT_FOR_DA_ID; - spin_unlock_irq(&ndlp->lock); + clear_bit(NLP_WAIT_FOR_DA_ID, &ndlp->save_flags); lpfc_ct_free_iocb(phba, cmdiocb); lpfc_nlp_put(ndlp); diff --git a/drivers/scsi/lpfc/lpfc_disc.h b/drivers/scsi/lpfc/lpfc_disc.h index 3e173b5d00e0..3d47dc7458d1 100644 --- a/drivers/scsi/lpfc/lpfc_disc.h +++ b/drivers/scsi/lpfc/lpfc_disc.h @@ -85,13 +85,13 @@ enum lpfc_fc4_xpt_flags { NLP_XPT_HAS_HH = 0x10 }; -enum lpfc_nlp_save_flags { +enum lpfc_nlp_save_flags { /* mask bits */ /* devloss occurred during recovery */ - NLP_IN_RECOV_POST_DEV_LOSS = 0x1, + NLP_IN_RECOV_POST_DEV_LOSS, /* wait for outstanding LOGO to cmpl */ - NLP_WAIT_FOR_LOGO = 0x2, + NLP_WAIT_FOR_LOGO, /* wait for outstanding DA_ID to finish */ - NLP_WAIT_FOR_DA_ID = 0x4 + NLP_WAIT_FOR_DA_ID }; struct lpfc_nodelist { @@ -154,7 +154,7 @@ struct lpfc_nodelist { uint32_t fc4_prli_sent; /* flags to keep ndlp alive until special conditions are met */ - enum lpfc_nlp_save_flags save_flags; + unsigned long save_flags; enum lpfc_fc4_xpt_flags fc4_xpt_flags; @@ -208,7 +208,6 @@ enum lpfc_nlp_flag { NPR list */ NLP_RM_DFLT_RPI = 26, /* need to remove leftover dflt RPI */ NLP_NODEV_REMOVE = 27, /* Defer removal till discovery ends */ - NLP_TARGET_REMOVE = 28, /* Target remove in process */ NLP_SC_REQ = 29, /* Target requires authentication */ NLP_FIRSTBURST = 30, /* Target supports FirstBurst */ NLP_RPI_REGISTERED = 31 /* nlp_rpi is valid */ diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 37f0a930d469..1d7db49a8fe4 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -2988,12 +2988,8 @@ lpfc_cmpl_els_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, } clear_bit(NLP_LOGO_SND, &ndlp->nlp_flag); - spin_lock_irq(&ndlp->lock); - if (ndlp->save_flags & NLP_WAIT_FOR_LOGO) { + if (test_and_clear_bit(NLP_WAIT_FOR_LOGO, &ndlp->save_flags)) wake_up_waiter = 1; - ndlp->save_flags &= ~NLP_WAIT_FOR_LOGO; - } - spin_unlock_irq(&ndlp->lock); lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD, "LOGO cmpl: status:x%x/x%x did:x%x", @@ -3035,19 +3031,6 @@ lpfc_cmpl_els_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, /* Call state machine. This will unregister the rpi if needed. */ lpfc_disc_state_machine(vport, ndlp, cmdiocb, NLP_EVT_CMPL_LOGO); - if (skip_recovery) - goto out; - - /* The driver sets this flag for an NPIV instance that doesn't want to - * log into the remote port. - */ - if (test_bit(NLP_TARGET_REMOVE, &ndlp->nlp_flag)) { - clear_bit(NLP_NPR_2B_DISC, &ndlp->nlp_flag); - lpfc_disc_state_machine(vport, ndlp, cmdiocb, - NLP_EVT_DEVICE_RM); - goto out_rsrc_free; - } - out: /* At this point, the LOGO processing is complete. NOTE: For a * pt2pt topology, we are assuming the NPortID will only change @@ -3091,7 +3074,7 @@ out: lpfc_disc_state_machine(vport, ndlp, cmdiocb, NLP_EVT_DEVICE_RM); } -out_rsrc_free: + /* Driver is done with the I/O. */ lpfc_els_free_iocb(phba, cmdiocb); lpfc_nlp_put(ndlp); @@ -4583,6 +4566,7 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, int link_reset = 0, rc; u32 ulp_status = get_job_ulpstatus(phba, rspiocb); u32 ulp_word4 = get_job_word4(phba, rspiocb); + u8 rsn_code_exp = 0; /* Note: cmd_dmabuf may be 0 for internal driver abort @@ -4798,11 +4782,22 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, break; case LSRJT_LOGICAL_BSY: + rsn_code_exp = stat.un.b.lsRjtRsnCodeExp; if ((cmd == ELS_CMD_PLOGI) || (cmd == ELS_CMD_PRLI) || (cmd == ELS_CMD_NVMEPRLI)) { delay = 1000; maxretry = 48; + + /* An authentication LS_RJT reason code + * explanation means some error in the + * security settings end-to-end. Reduce + * the retry count to allow lpfc to clear + * RSCN mode and not race with dev_loss. + */ + if (cmd == ELS_CMD_PLOGI && + rsn_code_exp == LSEXP_AUTH_REQ) + maxretry = 8; } else if (cmd == ELS_CMD_FDISC) { /* FDISC retry policy */ maxretry = 48; @@ -4831,6 +4826,20 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, "0820 FLOGI (x%x). " "BBCredit Not Supported\n", stat.un.lsRjtError); + } else if (cmd == ELS_CMD_PLOGI) { + rsn_code_exp = stat.un.b.lsRjtRsnCodeExp; + + /* An authentication LS_RJT reason code + * explanation means some error in the + * security settings end-to-end. Reduce + * the retry count to allow lpfc to clear + * RSCN mode and not race with dev_loss. + */ + if (rsn_code_exp == LSEXP_AUTH_REQ) { + delay = 1000; + retry = 1; + maxretry = 8; + } } break; @@ -10411,8 +10420,6 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, } } - clear_bit(NLP_TARGET_REMOVE, &ndlp->nlp_flag); - lpfc_disc_state_machine(vport, ndlp, elsiocb, NLP_EVT_RCV_PLOGI); @@ -11498,15 +11505,13 @@ lpfc_cmpl_els_npiv_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, lpfc_can_disctmo(vport); } - if (ndlp->save_flags & NLP_WAIT_FOR_LOGO) { + if (test_bit(NLP_WAIT_FOR_LOGO, &ndlp->save_flags)) { /* Wake up lpfc_vport_delete if waiting...*/ if (ndlp->logo_waitq) wake_up(ndlp->logo_waitq); clear_bit(NLP_ISSUE_LOGO, &ndlp->nlp_flag); clear_bit(NLP_LOGO_SND, &ndlp->nlp_flag); - spin_lock_irq(&ndlp->lock); - ndlp->save_flags &= ~NLP_WAIT_FOR_LOGO; - spin_unlock_irq(&ndlp->lock); + clear_bit(NLP_WAIT_FOR_LOGO, &ndlp->save_flags); } /* Safe to release resources now. */ diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 4036a9838bb5..36e66df36a18 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -414,12 +414,7 @@ void lpfc_check_nlp_post_devloss(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) { - unsigned long iflags; - - spin_lock_irqsave(&ndlp->lock, iflags); - if (ndlp->save_flags & NLP_IN_RECOV_POST_DEV_LOSS) { - ndlp->save_flags &= ~NLP_IN_RECOV_POST_DEV_LOSS; - spin_unlock_irqrestore(&ndlp->lock, iflags); + if (test_and_clear_bit(NLP_IN_RECOV_POST_DEV_LOSS, &ndlp->save_flags)) { lpfc_nlp_get(ndlp); lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY | LOG_NODE, "8438 Devloss timeout reversed on DID x%x " @@ -427,9 +422,7 @@ lpfc_check_nlp_post_devloss(struct lpfc_vport *vport, "port_state = x%x\n", ndlp->nlp_DID, kref_read(&ndlp->kref), ndlp, ndlp->nlp_flag, vport->port_state); - return; } - spin_unlock_irqrestore(&ndlp->lock, iflags); } /** @@ -546,9 +539,7 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp) ndlp->nlp_DID, kref_read(&ndlp->kref), ndlp, ndlp->nlp_flag, vport->port_state); - spin_lock_irqsave(&ndlp->lock, iflags); - ndlp->save_flags |= NLP_IN_RECOV_POST_DEV_LOSS; - spin_unlock_irqrestore(&ndlp->lock, iflags); + set_bit(NLP_IN_RECOV_POST_DEV_LOSS, &ndlp->save_flags); return fcf_inuse; } else if (ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) { /* Fabric node fully recovered before this dev_loss_tmo diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h index d5c15742f7f2..32298285ea5e 100644 --- a/drivers/scsi/lpfc/lpfc_hw.h +++ b/drivers/scsi/lpfc/lpfc_hw.h @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2017-2023 Broadcom. All Rights Reserved. The term * + * Copyright (C) 2017-2024 Broadcom. All Rights Reserved. The term * * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. * * Copyright (C) 2004-2016 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * @@ -724,6 +724,7 @@ struct ls_rjt { /* Structure is in Big Endian format */ #define LSEXP_OUT_OF_RESOURCE 0x29 #define LSEXP_CANT_GIVE_DATA 0x2A #define LSEXP_REQ_UNSUPPORTED 0x2C +#define LSEXP_AUTH_REQ 0x48 #define LSEXP_NO_RSRC_ASSIGN 0x52 uint8_t vendorUnique; /* FC Word 0, bit 0: 7 */ } b; diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h index 26e1313ebb21..2dedb273b091 100644 --- a/drivers/scsi/lpfc/lpfc_hw4.h +++ b/drivers/scsi/lpfc/lpfc_hw4.h @@ -1907,22 +1907,22 @@ struct lpfc_mbx_query_fw_config { uint32_t asic_revision; uint32_t physical_port; uint32_t function_mode; -#define LPFC_FCOE_INI_MODE 0x00000040 -#define LPFC_FCOE_TGT_MODE 0x00000080 +#define LPFC_FC_INI_MODE 0x00000040 +#define LPFC_FC_TGT_MODE 0x00000080 #define LPFC_DUA_MODE 0x00000800 - uint32_t ulp0_mode; -#define LPFC_ULP_FCOE_INIT_MODE 0x00000040 -#define LPFC_ULP_FCOE_TGT_MODE 0x00000080 - uint32_t ulp0_nap_words[12]; - uint32_t ulp1_mode; - uint32_t ulp1_nap_words[12]; + uint32_t oper_mode; + uint32_t rsvd9[2]; + uint32_t wqid_base; + uint32_t wqid_tot; + uint32_t rqid_base; + uint32_t rqid_tot; + uint32_t rsvd15[19]; uint32_t function_capabilities; uint32_t cqid_base; uint32_t cqid_tot; uint32_t eqid_base; uint32_t eqid_tot; - uint32_t ulp0_nap2_words[2]; - uint32_t ulp1_nap2_words[2]; + uint32_t rsvd39[4]; } rsp; }; @@ -3778,25 +3778,22 @@ struct lpfc_mbx_get_prof_cfg { struct lpfc_controller_attribute { uint32_t version_string[8]; uint32_t manufacturer_name[8]; - uint32_t supported_modes; + uint32_t rsvd16; uint32_t word17; -#define lpfc_cntl_attr_eprom_ver_lo_SHIFT 0 -#define lpfc_cntl_attr_eprom_ver_lo_MASK 0x000000ff -#define lpfc_cntl_attr_eprom_ver_lo_WORD word17 -#define lpfc_cntl_attr_eprom_ver_hi_SHIFT 8 -#define lpfc_cntl_attr_eprom_ver_hi_MASK 0x000000ff -#define lpfc_cntl_attr_eprom_ver_hi_WORD word17 #define lpfc_cntl_attr_flash_id_SHIFT 16 #define lpfc_cntl_attr_flash_id_MASK 0x000000ff #define lpfc_cntl_attr_flash_id_WORD word17 - uint32_t mbx_da_struct_ver; - uint32_t ep_fw_da_struct_ver; +#define lpfc_cntl_attr_boot_enable_SHIFT 24 +#define lpfc_cntl_attr_boot_enable_MASK 0x00000001 +#define lpfc_cntl_attr_boot_enable_WORD word17 + uint32_t rsvd18[2]; uint32_t ncsi_ver_str[3]; - uint32_t dflt_ext_timeout; + uint32_t rsvd23; uint32_t model_number[8]; uint32_t description[16]; uint32_t serial_number[8]; - uint32_t ip_ver_str[8]; + uint32_t ipl_name[5]; + uint32_t rsvd61[3]; uint32_t fw_ver_str[8]; uint32_t bios_ver_str[8]; uint32_t redboot_ver_str[8]; @@ -3804,53 +3801,31 @@ struct lpfc_controller_attribute { uint32_t flash_fw_ver_str[8]; uint32_t functionality; uint32_t word105; -#define lpfc_cntl_attr_max_cbd_len_SHIFT 0 -#define lpfc_cntl_attr_max_cbd_len_MASK 0x0000ffff -#define lpfc_cntl_attr_max_cbd_len_WORD word105 #define lpfc_cntl_attr_asic_rev_SHIFT 16 #define lpfc_cntl_attr_asic_rev_MASK 0x000000ff #define lpfc_cntl_attr_asic_rev_WORD word105 -#define lpfc_cntl_attr_gen_guid0_SHIFT 24 -#define lpfc_cntl_attr_gen_guid0_MASK 0x000000ff -#define lpfc_cntl_attr_gen_guid0_WORD word105 - uint32_t gen_guid1_12[3]; + uint32_t rsvd106[3]; uint32_t word109; -#define lpfc_cntl_attr_gen_guid13_14_SHIFT 0 -#define lpfc_cntl_attr_gen_guid13_14_MASK 0x0000ffff -#define lpfc_cntl_attr_gen_guid13_14_WORD word109 -#define lpfc_cntl_attr_gen_guid15_SHIFT 16 -#define lpfc_cntl_attr_gen_guid15_MASK 0x000000ff -#define lpfc_cntl_attr_gen_guid15_WORD word109 #define lpfc_cntl_attr_hba_port_cnt_SHIFT 24 #define lpfc_cntl_attr_hba_port_cnt_MASK 0x000000ff #define lpfc_cntl_attr_hba_port_cnt_WORD word109 - uint32_t word110; -#define lpfc_cntl_attr_dflt_lnk_tmo_SHIFT 0 -#define lpfc_cntl_attr_dflt_lnk_tmo_MASK 0x0000ffff -#define lpfc_cntl_attr_dflt_lnk_tmo_WORD word110 -#define lpfc_cntl_attr_multi_func_dev_SHIFT 24 -#define lpfc_cntl_attr_multi_func_dev_MASK 0x000000ff -#define lpfc_cntl_attr_multi_func_dev_WORD word110 + uint32_t rsvd110; uint32_t word111; -#define lpfc_cntl_attr_cache_valid_SHIFT 0 -#define lpfc_cntl_attr_cache_valid_MASK 0x000000ff -#define lpfc_cntl_attr_cache_valid_WORD word111 #define lpfc_cntl_attr_hba_status_SHIFT 8 #define lpfc_cntl_attr_hba_status_MASK 0x000000ff #define lpfc_cntl_attr_hba_status_WORD word111 -#define lpfc_cntl_attr_max_domain_SHIFT 16 -#define lpfc_cntl_attr_max_domain_MASK 0x000000ff -#define lpfc_cntl_attr_max_domain_WORD word111 #define lpfc_cntl_attr_lnk_numb_SHIFT 24 #define lpfc_cntl_attr_lnk_numb_MASK 0x0000003f #define lpfc_cntl_attr_lnk_numb_WORD word111 #define lpfc_cntl_attr_lnk_type_SHIFT 30 #define lpfc_cntl_attr_lnk_type_MASK 0x00000003 #define lpfc_cntl_attr_lnk_type_WORD word111 - uint32_t fw_post_status; - uint32_t hba_mtu[8]; + uint32_t rsvd112[9]; uint32_t word121; - uint32_t reserved1[3]; +#define lpfc_cntl_attr_asic_gen_SHIFT 8 +#define lpfc_cntl_attr_asic_gen_MASK 0x000000ff +#define lpfc_cntl_attr_asic_gen_WORD word121 + uint32_t rsvd122[3]; uint32_t word125; #define lpfc_cntl_attr_pci_vendor_id_SHIFT 0 #define lpfc_cntl_attr_pci_vendor_id_MASK 0x0000ffff @@ -3875,15 +3850,7 @@ struct lpfc_controller_attribute { #define lpfc_cntl_attr_pci_fnc_num_SHIFT 16 #define lpfc_cntl_attr_pci_fnc_num_MASK 0x000000ff #define lpfc_cntl_attr_pci_fnc_num_WORD word127 -#define lpfc_cntl_attr_inf_type_SHIFT 24 -#define lpfc_cntl_attr_inf_type_MASK 0x000000ff -#define lpfc_cntl_attr_inf_type_WORD word127 - uint32_t unique_id[2]; - uint32_t word130; -#define lpfc_cntl_attr_num_netfil_SHIFT 0 -#define lpfc_cntl_attr_num_netfil_MASK 0x000000ff -#define lpfc_cntl_attr_num_netfil_WORD word130 - uint32_t reserved2[4]; + uint32_t rsvd128[7]; }; struct lpfc_mbx_get_cntl_attributes { diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 7f57397d91a9..b94624789771 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -3847,8 +3847,8 @@ lpfc_offline_prep(struct lpfc_hba *phba, int mbx_action) * Otherwise, let dev_loss take care of * the node. */ - if (!(ndlp->save_flags & - NLP_IN_RECOV_POST_DEV_LOSS) && + if (!test_bit(NLP_IN_RECOV_POST_DEV_LOSS, + &ndlp->save_flags) && !(ndlp->fc4_xpt_flags & (NVME_XPT_REGD | SCSI_XPT_REGD))) lpfc_disc_state_machine @@ -11109,14 +11109,11 @@ lpfc_sli4_queue_setup(struct lpfc_hba *phba) phba->sli4_hba.fw_func_mode = mboxq->u.mqe.un.query_fw_cfg.rsp.function_mode; - phba->sli4_hba.ulp0_mode = mboxq->u.mqe.un.query_fw_cfg.rsp.ulp0_mode; - phba->sli4_hba.ulp1_mode = mboxq->u.mqe.un.query_fw_cfg.rsp.ulp1_mode; phba->sli4_hba.physical_port = mboxq->u.mqe.un.query_fw_cfg.rsp.physical_port; lpfc_printf_log(phba, KERN_INFO, LOG_INIT, - "3251 QUERY_FW_CFG: func_mode:x%x, ulp0_mode:x%x, " - "ulp1_mode:x%x\n", phba->sli4_hba.fw_func_mode, - phba->sli4_hba.ulp0_mode, phba->sli4_hba.ulp1_mode); + "3251 QUERY_FW_CFG: func_mode:x%x\n", + phba->sli4_hba.fw_func_mode); mempool_free(mboxq, phba->mbox_mem_pool); diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c index e98f1c2b2220..fb6dbcb86c09 100644 --- a/drivers/scsi/lpfc/lpfc_mbox.c +++ b/drivers/scsi/lpfc/lpfc_mbox.c @@ -2524,8 +2524,10 @@ lpfc_reg_fcfi(struct lpfc_hba *phba, struct lpfcMboxq *mbox) bf_set(lpfc_reg_fcfi_rq_id1, reg_fcfi, REG_FCF_INVALID_QID); /* addr mode is bit wise inverted value of fcf addr_mode */ - bf_set(lpfc_reg_fcfi_mam, reg_fcfi, - (~phba->fcf.addr_mode) & 0x3); + if (test_bit(HBA_FCOE_MODE, &phba->hba_flag)) { + bf_set(lpfc_reg_fcfi_mam, reg_fcfi, + (~phba->fcf.addr_mode) & 0x3); + } } else { /* This is ONLY for NVMET MRQ == 1 */ if (phba->cfg_nvmet_mrq != 1) diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index 4d88cfe71cae..5aa21c683ac6 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c @@ -64,9 +64,6 @@ static int lpfc_check_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, struct lpfc_name *nn, struct lpfc_name *pn) { - /* First, we MUST have a RPI registered */ - if (!test_bit(NLP_RPI_REGISTERED, &ndlp->nlp_flag)) - return 0; /* Compare the ADISC rsp WWNN / WWPN matches our internal node * table entry for that node. @@ -735,6 +732,7 @@ lpfc_rcv_padisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, ADISC *ap; uint32_t *lp; uint32_t cmd; + int rc; pcmd = cmdiocb->cmd_dmabuf; lp = (uint32_t *) pcmd->virt; @@ -759,21 +757,29 @@ lpfc_rcv_padisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, * resume the RPI before the ACC goes out. */ if (vport->phba->sli_rev == LPFC_SLI_REV4) { - elsiocb = kmalloc(sizeof(struct lpfc_iocbq), - GFP_KERNEL); - if (elsiocb) { - /* Save info from cmd IOCB used in rsp */ - memcpy((uint8_t *)elsiocb, (uint8_t *)cmdiocb, - sizeof(struct lpfc_iocbq)); - - /* Save the ELS cmd */ - elsiocb->drvrTimeout = cmd; - - if (lpfc_sli4_resume_rpi(ndlp, - lpfc_mbx_cmpl_resume_rpi, - elsiocb)) - kfree(elsiocb); - goto out; + /* Don't resume an unregistered RPI - unnecessary + * mailbox. Just send the ACC when the RPI is not + * registered. + */ + if (test_bit(NLP_RPI_REGISTERED, &ndlp->nlp_flag)) { + elsiocb = kmalloc(sizeof(*elsiocb), GFP_KERNEL); + if (elsiocb) { + /* Save info from cmd IOCB used in + * rsp + */ + memcpy(elsiocb, cmdiocb, + sizeof(*elsiocb)); + + elsiocb->drvrTimeout = cmd; + + rc = lpfc_sli4_resume_rpi(ndlp, + lpfc_mbx_cmpl_resume_rpi, + elsiocb); + if (rc) + kfree(elsiocb); + + goto out; + } } } @@ -815,7 +821,6 @@ out: set_bit(NLP_DELAY_TMO, &ndlp->nlp_flag); ndlp->nlp_last_elscmd = ELS_CMD_PLOGI; ndlp->nlp_prev_state = ndlp->nlp_state; - lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); return 0; } @@ -2255,11 +2260,13 @@ lpfc_cmpl_prli_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, (vport->port_type == LPFC_NPIV_PORT) && vport->cfg_restrict_login) { out: - set_bit(NLP_TARGET_REMOVE, &ndlp->nlp_flag); + lpfc_printf_vlog(vport, KERN_INFO, + LOG_ELS | LOG_DISCOVERY | LOG_NODE, + "6228 Sending LOGO, determined nlp_type " + "0x%x nlp_flag x%lx refcnt %u\n", + ndlp->nlp_type, ndlp->nlp_flag, + kref_read(&ndlp->kref)); lpfc_issue_els_logo(vport, ndlp, 0); - - ndlp->nlp_prev_state = NLP_STE_PRLI_ISSUE; - lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); return ndlp->nlp_state; } diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index b83627108eca..055ed632c14d 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -5136,6 +5136,12 @@ lpfc_info(struct Scsi_Host *host) goto buffer_done; } + /* Support for BSG ioctls */ + scnprintf(tmp, sizeof(tmp), " BSG"); + if (strlcat(lpfcinfobuf, tmp, sizeof(lpfcinfobuf)) >= + sizeof(lpfcinfobuf)) + goto buffer_done; + /* PCI resettable */ if (!lpfc_check_pci_resettable(phba)) { scnprintf(tmp, sizeof(tmp), " PCI resettable"); @@ -6120,31 +6126,28 @@ lpfc_target_reset_handler(struct scsi_cmnd *cmnd) /* Issue LOGO, if no LOGO is outstanding */ spin_lock_irqsave(&pnode->lock, flags); - if (!(pnode->save_flags & NLP_WAIT_FOR_LOGO) && + if (!test_bit(NLP_WAIT_FOR_LOGO, &pnode->save_flags) && !pnode->logo_waitq) { pnode->logo_waitq = &waitq; pnode->nlp_fcp_info &= ~NLP_FCP_2_DEVICE; - set_bit(NLP_ISSUE_LOGO, &pnode->nlp_flag); - pnode->save_flags |= NLP_WAIT_FOR_LOGO; spin_unlock_irqrestore(&pnode->lock, flags); + set_bit(NLP_ISSUE_LOGO, &pnode->nlp_flag); + set_bit(NLP_WAIT_FOR_LOGO, &pnode->save_flags); lpfc_unreg_rpi(vport, pnode); wait_event_timeout(waitq, - (!(pnode->save_flags & - NLP_WAIT_FOR_LOGO)), + !test_bit(NLP_WAIT_FOR_LOGO, + &pnode->save_flags), msecs_to_jiffies(dev_loss_tmo * 1000)); - if (pnode->save_flags & NLP_WAIT_FOR_LOGO) { + if (test_and_clear_bit(NLP_WAIT_FOR_LOGO, + &pnode->save_flags)) lpfc_printf_vlog(vport, KERN_ERR, logit, "0725 SCSI layer TGTRST " "failed & LOGO TMO (%d, %llu) " "return x%x\n", tgt_id, lun_id, status); - spin_lock_irqsave(&pnode->lock, flags); - pnode->save_flags &= ~NLP_WAIT_FOR_LOGO; - } else { - spin_lock_irqsave(&pnode->lock, flags); - } + spin_lock_irqsave(&pnode->lock, flags); pnode->logo_waitq = NULL; spin_unlock_irqrestore(&pnode->lock, flags); status = SUCCESS; @@ -6423,7 +6426,7 @@ lpfc_create_device_data(struct lpfc_hba *phba, struct lpfc_name *vport_wwpn, { struct lpfc_device_data *lun_info; - int memory_flags; + gfp_t memory_flags; if (unlikely(!phba) || !vport_wwpn || !target_wwpn || !(phba->cfg_fof)) diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h index c1e9ec0243ba..9be3da91c923 100644 --- a/drivers/scsi/lpfc/lpfc_sli4.h +++ b/drivers/scsi/lpfc/lpfc_sli4.h @@ -865,8 +865,6 @@ struct lpfc_sli4_hba { struct lpfc_name wwpn; uint32_t fw_func_mode; /* FW function protocol mode */ - uint32_t ulp0_mode; /* ULP0 protocol mode */ - uint32_t ulp1_mode; /* ULP1 protocol mode */ /* Optimized Access Storage specific queues/structures */ uint64_t oas_next_lun; diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h index 61fe1220f8ad..c35f7225058e 100644 --- a/drivers/scsi/lpfc/lpfc_version.h +++ b/drivers/scsi/lpfc/lpfc_version.h @@ -20,7 +20,7 @@ * included with this package. * *******************************************************************/ -#define LPFC_DRIVER_VERSION "14.4.0.6" +#define LPFC_DRIVER_VERSION "14.4.0.7" #define LPFC_DRIVER_NAME "lpfc" /* Used for SLI 2/3 */ diff --git a/drivers/scsi/lpfc/lpfc_vport.c b/drivers/scsi/lpfc/lpfc_vport.c index 9e0e35763377..3d70cc517573 100644 --- a/drivers/scsi/lpfc/lpfc_vport.c +++ b/drivers/scsi/lpfc/lpfc_vport.c @@ -492,21 +492,22 @@ lpfc_send_npiv_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) DECLARE_WAIT_QUEUE_HEAD_ONSTACK(waitq); spin_lock_irq(&ndlp->lock); - if (!(ndlp->save_flags & NLP_WAIT_FOR_LOGO) && + if (!test_bit(NLP_WAIT_FOR_LOGO, &ndlp->save_flags) && !ndlp->logo_waitq) { ndlp->logo_waitq = &waitq; ndlp->nlp_fcp_info &= ~NLP_FCP_2_DEVICE; set_bit(NLP_ISSUE_LOGO, &ndlp->nlp_flag); - ndlp->save_flags |= NLP_WAIT_FOR_LOGO; + set_bit(NLP_WAIT_FOR_LOGO, &ndlp->save_flags); } spin_unlock_irq(&ndlp->lock); rc = lpfc_issue_els_npiv_logo(vport, ndlp); if (!rc) { wait_event_timeout(waitq, - (!(ndlp->save_flags & NLP_WAIT_FOR_LOGO)), + !test_bit(NLP_WAIT_FOR_LOGO, + &ndlp->save_flags), msecs_to_jiffies(phba->fc_ratov * 2000)); - if (!(ndlp->save_flags & NLP_WAIT_FOR_LOGO)) + if (!test_bit(NLP_WAIT_FOR_LOGO, &ndlp->save_flags)) goto logo_cmpl; /* LOGO wait failed. Correct status. */ rc = -EINTR; @@ -516,9 +517,7 @@ lpfc_send_npiv_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) /* Error - clean up node flags. */ clear_bit(NLP_ISSUE_LOGO, &ndlp->nlp_flag); - spin_lock_irq(&ndlp->lock); - ndlp->save_flags &= ~NLP_WAIT_FOR_LOGO; - spin_unlock_irq(&ndlp->lock); + clear_bit(NLP_WAIT_FOR_LOGO, &ndlp->save_flags); logo_cmpl: lpfc_printf_vlog(vport, KERN_INFO, LOG_VPORT, @@ -696,19 +695,20 @@ lpfc_vport_delete(struct fc_vport *fc_vport) spin_lock_irq(&ndlp->lock); ndlp->da_id_waitq = &waitq; - ndlp->save_flags |= NLP_WAIT_FOR_DA_ID; spin_unlock_irq(&ndlp->lock); + set_bit(NLP_WAIT_FOR_DA_ID, &ndlp->save_flags); rc = lpfc_ns_cmd(vport, SLI_CTNS_DA_ID, 0, 0); if (!rc) { wait_event_timeout(waitq, - !(ndlp->save_flags & NLP_WAIT_FOR_DA_ID), + !test_bit(NLP_WAIT_FOR_DA_ID, + &ndlp->save_flags), msecs_to_jiffies(phba->fc_ratov * 2000)); } lpfc_printf_vlog(vport, KERN_INFO, LOG_VPORT | LOG_ELS, "1829 DA_ID issue status %d. " - "SFlag x%x NState x%x, NFlag x%lx " + "SFlag x%lx NState x%x, NFlag x%lx " "Rpi x%x\n", rc, ndlp->save_flags, ndlp->nlp_state, ndlp->nlp_flag, ndlp->nlp_rpi); @@ -718,8 +718,8 @@ lpfc_vport_delete(struct fc_vport *fc_vport) */ spin_lock_irq(&ndlp->lock); ndlp->da_id_waitq = NULL; - ndlp->save_flags &= ~NLP_WAIT_FOR_DA_ID; spin_unlock_irq(&ndlp->lock); + clear_bit(NLP_WAIT_FOR_DA_ID, &ndlp->save_flags); } issue_logo: |