Merge patch series "Update lpfc to revision 14.4.0.7"

Justin Tee <justintee8345@gmail.com> says:

Update lpfc to revision 14.4.0.7

This patch set contains fixes related to smatch, clean up of obsolete code
and global spinlocks, changes to ADISC and LS_RJT handling, and support for
large fw object reads used in proprietary applications.

The patches were cut against Martin's 6.14/scsi-queue tree.

Link: https://lore.kernel.org/r/20241212233309.71356-1-justintee8345@gmail.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
Martin K. Petersen 2025-01-02 15:02:19 -05:00
commit 1edc2a60e1
15 changed files with 349 additions and 172 deletions

View File

@ -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;
@ -3538,6 +3548,103 @@ lpfc_bsg_mbox_ext_session_reset(struct lpfc_hba *phba)
return;
}
/**
* 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.
@ -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.
*/

View File

@ -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 {

View File

@ -1646,14 +1646,12 @@ lpfc_cmpl_ct(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
/* 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);

View File

@ -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 */

View File

@ -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 @@ lpfc_cmpl_els_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
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. */

View File

@ -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

View File

@ -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;

View File

@ -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 {

View File

@ -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);

View File

@ -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)

View File

@ -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));
/* 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));
/* Save the ELS cmd */
elsiocb->drvrTimeout = cmd;
elsiocb->drvrTimeout = cmd;
if (lpfc_sli4_resume_rpi(ndlp,
lpfc_mbx_cmpl_resume_rpi,
elsiocb))
kfree(elsiocb);
goto out;
rc = lpfc_sli4_resume_rpi(ndlp,
lpfc_mbx_cmpl_resume_rpi,
elsiocb);
if (rc)
kfree(elsiocb);
goto out;
}
}
}
@ -815,7 +821,6 @@ lpfc_rcv_padisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
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;
}

View File

@ -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))

View File

@ -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;

View File

@ -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 */

View File

@ -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: