Commit 495a714c authored by James Smart's avatar James Smart Committed by James Bottomley

[SCSI] lpfc 8.2.7 : Miscellaneous Fixes

Miscellaneous Fixes:
- Fix bug in mbox sysfs interface that locked in EAGAIN if discovery stalled.
- Fix missing error message when npiv and loop are true when link up occurs.
- Fix panic in lpfc_scsi_cmd_iocb_cmpl: scsi_buf was NULL, but created
  race conditions with other code paths.
- Fix error in sysfs mailbox structure that didn't rezero on next use.
- Add missing mempool_free() to attachment failure path
- Fix missing put of ndlp structure during driver unload.
- Fix applications unable to send mailbox commands during discovery.
- Remove unused argument (type) from function lpfc_post_buffer() API
- Fix vport name is not shown after hbacmd vportcreate.
- Remove repeated code statements.
Signed-off-by: default avatarJames Smart <james.smart@emulex.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@HansenPartnership.com>
parent 5e9d9b82
......@@ -33,6 +33,7 @@ struct lpfc_sli2_slim;
#define LPFC_MAX_SG_SEG_CNT 256 /* sg element count per scsi cmnd */
#define LPFC_IOCB_LIST_CNT 2250 /* list of IOCBs for fast-path usage. */
#define LPFC_Q_RAMP_UP_INTERVAL 120 /* lun q_depth ramp up interval */
#define LPFC_VNAME_LEN 100 /* vport symbolic name length */
/*
* Following time intervals are used of adjusting SCSI device
......
......@@ -1995,8 +1995,7 @@ sysfs_mbox_read(struct kobject *kobj, struct bin_attribute *bin_attr,
/* Don't allow mailbox commands to be sent when blocked
* or when in the middle of discovery
*/
if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO ||
vport->fc_flag & FC_NDISC_ACTIVE) {
if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO) {
sysfs_mbox_idle(phba);
spin_unlock_irq(&phba->hbalock);
return -EAGAIN;
......
......@@ -142,7 +142,7 @@ int lpfc_config_port_post(struct lpfc_hba *);
int lpfc_hba_down_prep(struct lpfc_hba *);
int lpfc_hba_down_post(struct lpfc_hba *);
void lpfc_hba_init(struct lpfc_hba *, uint32_t *);
int lpfc_post_buffer(struct lpfc_hba *, struct lpfc_sli_ring *, int, int);
int lpfc_post_buffer(struct lpfc_hba *, struct lpfc_sli_ring *, int);
void lpfc_decode_firmware_rev(struct lpfc_hba *, char *, int);
int lpfc_online(struct lpfc_hba *);
void lpfc_unblock_mgmt_io(struct lpfc_hba *);
......@@ -263,6 +263,7 @@ extern int lpfc_sli_mode;
extern int lpfc_enable_npiv;
int lpfc_vport_symbolic_node_name(struct lpfc_vport *, char *, size_t);
int lpfc_vport_symbolic_port_name(struct lpfc_vport *, char *, size_t);
void lpfc_terminate_rport_io(struct fc_rport *);
void lpfc_dev_loss_tmo_callbk(struct fc_rport *rport);
......
......@@ -101,7 +101,7 @@ lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
/* Not enough posted buffers; Try posting more buffers */
phba->fc_stat.NoRcvBuf++;
if (!(phba->sli3_options & LPFC_SLI3_HBQ_ENABLED))
lpfc_post_buffer(phba, pring, 2, 1);
lpfc_post_buffer(phba, pring, 2);
return;
}
......@@ -151,7 +151,7 @@ lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
}
list_del(&iocbq->list);
lpfc_sli_release_iocbq(phba, iocbq);
lpfc_post_buffer(phba, pring, i, 1);
lpfc_post_buffer(phba, pring, i);
}
}
}
......@@ -990,7 +990,7 @@ lpfc_cmpl_ct_cmd_rff_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
return;
}
static int
int
lpfc_vport_symbolic_port_name(struct lpfc_vport *vport, char *symbol,
size_t size)
{
......
......@@ -3857,9 +3857,6 @@ lpfc_els_timeout_handler(struct lpfc_vport *vport)
els_command == ELS_CMD_FDISC)
continue;
if (vport != piocb->vport)
continue;
if (piocb->drvrTimeout > 0) {
if (piocb->drvrTimeout >= timeout)
piocb->drvrTimeout -= timeout;
......@@ -4013,7 +4010,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
payload = ((struct lpfc_dmabuf *)elsiocb->context2)->virt;
cmd = *payload;
if ((phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) == 0)
lpfc_post_buffer(phba, pring, 1, 1);
lpfc_post_buffer(phba, pring, 1);
did = icmd->un.rcvels.remoteID;
if (icmd->ulpStatus) {
......@@ -4322,7 +4319,7 @@ lpfc_els_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
phba->fc_stat.NoRcvBuf++;
/* Not enough posted buffers; Try posting more buffers */
if (!(phba->sli3_options & LPFC_SLI3_HBQ_ENABLED))
lpfc_post_buffer(phba, pring, 0, 1);
lpfc_post_buffer(phba, pring, 0);
return;
}
......
......@@ -917,6 +917,10 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la)
if (phba->fc_topology == TOPOLOGY_LOOP) {
phba->sli3_options &= ~LPFC_SLI3_NPIV_ENABLED;
if (phba->cfg_enable_npiv)
lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT,
"1309 Link Up Event npiv not supported in loop "
"topology\n");
/* Get Loop Map information */
if (la->il)
vport->fc_flag |= FC_LBIT;
......
......@@ -145,8 +145,10 @@ lpfc_config_port_prep(struct lpfc_hba *phba)
return -ERESTART;
}
if (phba->sli_rev == 3 && !mb->un.varRdRev.v3rsp)
if (phba->sli_rev == 3 && !mb->un.varRdRev.v3rsp) {
mempool_free(pmb, phba->mbox_mem_pool);
return -EINVAL;
}
/* Save information as VPD data */
vp->rev.rBit = 1;
......@@ -1197,8 +1199,7 @@ lpfc_get_hba_model_desc(struct lpfc_hba *phba, uint8_t *mdp, uint8_t *descp)
/* Returns the number of buffers NOT posted. */
/**************************************************/
int
lpfc_post_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, int cnt,
int type)
lpfc_post_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, int cnt)
{
IOCB_t *icmd;
struct lpfc_iocbq *iocb;
......@@ -1298,7 +1299,7 @@ lpfc_post_rcv_buf(struct lpfc_hba *phba)
struct lpfc_sli *psli = &phba->sli;
/* Ring 0, ELS / CT buffers */
lpfc_post_buffer(phba, &psli->ring[LPFC_ELS_RING], LPFC_BUF_RING0, 1);
lpfc_post_buffer(phba, &psli->ring[LPFC_ELS_RING], LPFC_BUF_RING0);
/* Ring 2 - FCP no buffers needed */
return 0;
......@@ -1457,6 +1458,15 @@ lpfc_cleanup(struct lpfc_vport *vport)
lpfc_disc_state_machine(vport, ndlp, NULL,
NLP_EVT_DEVICE_RM);
/* nlp_type zero is not defined, nlp_flag zero also not defined,
* nlp_state is unused, this happens when
* an initiator has logged
* into us so cleanup this ndlp.
*/
if ((ndlp->nlp_type == 0) && (ndlp->nlp_flag == 0) &&
(ndlp->nlp_state == 0))
lpfc_nlp_put(ndlp);
}
/* At this point, ALL ndlp's should be gone
......
......@@ -605,9 +605,6 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
result = cmd->result;
sdev = cmd->device;
lpfc_scsi_unprep_dma_buf(phba, lpfc_cmd);
spin_lock_irqsave(sdev->host->host_lock, flags);
lpfc_cmd->pCmd = NULL; /* This must be done before scsi_done */
spin_unlock_irqrestore(sdev->host->host_lock, flags);
cmd->scsi_done(cmd);
if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) {
......@@ -616,6 +613,7 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
* wake up the thread.
*/
spin_lock_irqsave(sdev->host->host_lock, flags);
lpfc_cmd->pCmd = NULL;
if (lpfc_cmd->waitq)
wake_up(lpfc_cmd->waitq);
spin_unlock_irqrestore(sdev->host->host_lock, flags);
......@@ -686,6 +684,7 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
* wake up the thread.
*/
spin_lock_irqsave(sdev->host->host_lock, flags);
lpfc_cmd->pCmd = NULL;
if (lpfc_cmd->waitq)
wake_up(lpfc_cmd->waitq);
spin_unlock_irqrestore(sdev->host->host_lock, flags);
......
......@@ -3763,7 +3763,6 @@ lpfc_sli_validate_fcp_iocb(struct lpfc_iocbq *iocbq, struct lpfc_vport *vport,
lpfc_ctx_cmd ctx_cmd)
{
struct lpfc_scsi_buf *lpfc_cmd;
struct scsi_cmnd *cmnd;
int rc = 1;
if (!(iocbq->iocb_flag & LPFC_IO_FCP))
......@@ -3773,19 +3772,20 @@ lpfc_sli_validate_fcp_iocb(struct lpfc_iocbq *iocbq, struct lpfc_vport *vport,
return rc;
lpfc_cmd = container_of(iocbq, struct lpfc_scsi_buf, cur_iocbq);
cmnd = lpfc_cmd->pCmd;
if (cmnd == NULL)
if (lpfc_cmd->pCmd == NULL)
return rc;
switch (ctx_cmd) {
case LPFC_CTX_LUN:
if ((cmnd->device->id == tgt_id) &&
(cmnd->device->lun == lun_id))
if ((lpfc_cmd->rdata->pnode) &&
(lpfc_cmd->rdata->pnode->nlp_sid == tgt_id) &&
(scsilun_to_int(&lpfc_cmd->fcp_cmnd->fcp_lun) == lun_id))
rc = 0;
break;
case LPFC_CTX_TGT:
if (cmnd->device->id == tgt_id)
if ((lpfc_cmd->rdata->pnode) &&
(lpfc_cmd->rdata->pnode->nlp_sid == tgt_id))
rc = 0;
break;
case LPFC_CTX_HOST:
......@@ -3995,6 +3995,7 @@ lpfc_sli_issue_mbox_wait(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq,
if (pmboxq->context1)
return MBX_NOT_FINISHED;
pmboxq->mbox_flag &= ~LPFC_MBX_WAKE;
/* setup wake call as IOCB callback */
pmboxq->mbox_cmpl = lpfc_sli_wake_mbox_wait;
/* setup context field to pass wait_queue pointer to wake function */
......
......@@ -216,6 +216,7 @@ lpfc_vport_create(struct fc_vport *fc_vport, bool disable)
int vpi;
int rc = VPORT_ERROR;
int status;
int size;
if ((phba->sli_rev < 3) ||
!(phba->sli3_options & LPFC_SLI3_NPIV_ENABLED)) {
......@@ -278,7 +279,20 @@ lpfc_vport_create(struct fc_vport *fc_vport, bool disable)
memcpy(vport->fc_portname.u.wwn, vport->fc_sparam.portName.u.wwn, 8);
memcpy(vport->fc_nodename.u.wwn, vport->fc_sparam.nodeName.u.wwn, 8);
size = strnlen(fc_vport->symbolic_name, LPFC_VNAME_LEN);
if (size) {
vport->vname = kzalloc(size+1, GFP_KERNEL);
if (!vport->vname) {
lpfc_printf_vlog(vport, KERN_ERR, LOG_VPORT,
"1814 Create VPORT failed. "
"vname allocation failed.\n");
rc = VPORT_ERROR;
lpfc_free_vpi(phba, vpi);
destroy_port(vport);
goto error_out;
}
memcpy(vport->vname, fc_vport->symbolic_name, size+1);
}
if (fc_vport->node_name != 0)
u64_to_wwn(fc_vport->node_name, vport->fc_nodename.u.wwn);
if (fc_vport->port_name != 0)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment