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; ...@@ -33,6 +33,7 @@ struct lpfc_sli2_slim;
#define LPFC_MAX_SG_SEG_CNT 256 /* sg element count per scsi cmnd */ #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_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_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 * Following time intervals are used of adjusting SCSI device
......
...@@ -1995,8 +1995,7 @@ sysfs_mbox_read(struct kobject *kobj, struct bin_attribute *bin_attr, ...@@ -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 /* Don't allow mailbox commands to be sent when blocked
* or when in the middle of discovery * or when in the middle of discovery
*/ */
if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO || if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO) {
vport->fc_flag & FC_NDISC_ACTIVE) {
sysfs_mbox_idle(phba); sysfs_mbox_idle(phba);
spin_unlock_irq(&phba->hbalock); spin_unlock_irq(&phba->hbalock);
return -EAGAIN; return -EAGAIN;
......
...@@ -142,7 +142,7 @@ int lpfc_config_port_post(struct lpfc_hba *); ...@@ -142,7 +142,7 @@ int lpfc_config_port_post(struct lpfc_hba *);
int lpfc_hba_down_prep(struct lpfc_hba *); int lpfc_hba_down_prep(struct lpfc_hba *);
int lpfc_hba_down_post(struct lpfc_hba *); int lpfc_hba_down_post(struct lpfc_hba *);
void lpfc_hba_init(struct lpfc_hba *, uint32_t *); 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); void lpfc_decode_firmware_rev(struct lpfc_hba *, char *, int);
int lpfc_online(struct lpfc_hba *); int lpfc_online(struct lpfc_hba *);
void lpfc_unblock_mgmt_io(struct lpfc_hba *); void lpfc_unblock_mgmt_io(struct lpfc_hba *);
...@@ -263,6 +263,7 @@ extern int lpfc_sli_mode; ...@@ -263,6 +263,7 @@ extern int lpfc_sli_mode;
extern int lpfc_enable_npiv; extern int lpfc_enable_npiv;
int lpfc_vport_symbolic_node_name(struct lpfc_vport *, char *, size_t); 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_terminate_rport_io(struct fc_rport *);
void lpfc_dev_loss_tmo_callbk(struct fc_rport *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, ...@@ -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 */ /* Not enough posted buffers; Try posting more buffers */
phba->fc_stat.NoRcvBuf++; phba->fc_stat.NoRcvBuf++;
if (!(phba->sli3_options & LPFC_SLI3_HBQ_ENABLED)) if (!(phba->sli3_options & LPFC_SLI3_HBQ_ENABLED))
lpfc_post_buffer(phba, pring, 2, 1); lpfc_post_buffer(phba, pring, 2);
return; return;
} }
...@@ -151,7 +151,7 @@ lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, ...@@ -151,7 +151,7 @@ lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
} }
list_del(&iocbq->list); list_del(&iocbq->list);
lpfc_sli_release_iocbq(phba, iocbq); 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, ...@@ -990,7 +990,7 @@ lpfc_cmpl_ct_cmd_rff_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
return; return;
} }
static int int
lpfc_vport_symbolic_port_name(struct lpfc_vport *vport, char *symbol, lpfc_vport_symbolic_port_name(struct lpfc_vport *vport, char *symbol,
size_t size) size_t size)
{ {
......
...@@ -3857,9 +3857,6 @@ lpfc_els_timeout_handler(struct lpfc_vport *vport) ...@@ -3857,9 +3857,6 @@ lpfc_els_timeout_handler(struct lpfc_vport *vport)
els_command == ELS_CMD_FDISC) els_command == ELS_CMD_FDISC)
continue; continue;
if (vport != piocb->vport)
continue;
if (piocb->drvrTimeout > 0) { if (piocb->drvrTimeout > 0) {
if (piocb->drvrTimeout >= timeout) if (piocb->drvrTimeout >= timeout)
piocb->drvrTimeout -= timeout; piocb->drvrTimeout -= timeout;
...@@ -4013,7 +4010,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, ...@@ -4013,7 +4010,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
payload = ((struct lpfc_dmabuf *)elsiocb->context2)->virt; payload = ((struct lpfc_dmabuf *)elsiocb->context2)->virt;
cmd = *payload; cmd = *payload;
if ((phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) == 0) 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; did = icmd->un.rcvels.remoteID;
if (icmd->ulpStatus) { if (icmd->ulpStatus) {
...@@ -4322,7 +4319,7 @@ lpfc_els_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, ...@@ -4322,7 +4319,7 @@ lpfc_els_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
phba->fc_stat.NoRcvBuf++; phba->fc_stat.NoRcvBuf++;
/* Not enough posted buffers; Try posting more buffers */ /* Not enough posted buffers; Try posting more buffers */
if (!(phba->sli3_options & LPFC_SLI3_HBQ_ENABLED)) if (!(phba->sli3_options & LPFC_SLI3_HBQ_ENABLED))
lpfc_post_buffer(phba, pring, 0, 1); lpfc_post_buffer(phba, pring, 0);
return; return;
} }
......
...@@ -917,6 +917,10 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la) ...@@ -917,6 +917,10 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la)
if (phba->fc_topology == TOPOLOGY_LOOP) { if (phba->fc_topology == TOPOLOGY_LOOP) {
phba->sli3_options &= ~LPFC_SLI3_NPIV_ENABLED; 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 */ /* Get Loop Map information */
if (la->il) if (la->il)
vport->fc_flag |= FC_LBIT; vport->fc_flag |= FC_LBIT;
......
...@@ -145,8 +145,10 @@ lpfc_config_port_prep(struct lpfc_hba *phba) ...@@ -145,8 +145,10 @@ lpfc_config_port_prep(struct lpfc_hba *phba)
return -ERESTART; 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; return -EINVAL;
}
/* Save information as VPD data */ /* Save information as VPD data */
vp->rev.rBit = 1; vp->rev.rBit = 1;
...@@ -1197,8 +1199,7 @@ lpfc_get_hba_model_desc(struct lpfc_hba *phba, uint8_t *mdp, uint8_t *descp) ...@@ -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. */ /* Returns the number of buffers NOT posted. */
/**************************************************/ /**************************************************/
int int
lpfc_post_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, int cnt, lpfc_post_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, int cnt)
int type)
{ {
IOCB_t *icmd; IOCB_t *icmd;
struct lpfc_iocbq *iocb; struct lpfc_iocbq *iocb;
...@@ -1298,7 +1299,7 @@ lpfc_post_rcv_buf(struct lpfc_hba *phba) ...@@ -1298,7 +1299,7 @@ lpfc_post_rcv_buf(struct lpfc_hba *phba)
struct lpfc_sli *psli = &phba->sli; struct lpfc_sli *psli = &phba->sli;
/* Ring 0, ELS / CT buffers */ /* 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 */ /* Ring 2 - FCP no buffers needed */
return 0; return 0;
...@@ -1457,6 +1458,15 @@ lpfc_cleanup(struct lpfc_vport *vport) ...@@ -1457,6 +1458,15 @@ lpfc_cleanup(struct lpfc_vport *vport)
lpfc_disc_state_machine(vport, ndlp, NULL, lpfc_disc_state_machine(vport, ndlp, NULL,
NLP_EVT_DEVICE_RM); 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 /* 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, ...@@ -605,9 +605,6 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
result = cmd->result; result = cmd->result;
sdev = cmd->device; sdev = cmd->device;
lpfc_scsi_unprep_dma_buf(phba, lpfc_cmd); 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); cmd->scsi_done(cmd);
if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) { 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, ...@@ -616,6 +613,7 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
* wake up the thread. * wake up the thread.
*/ */
spin_lock_irqsave(sdev->host->host_lock, flags); spin_lock_irqsave(sdev->host->host_lock, flags);
lpfc_cmd->pCmd = NULL;
if (lpfc_cmd->waitq) if (lpfc_cmd->waitq)
wake_up(lpfc_cmd->waitq); wake_up(lpfc_cmd->waitq);
spin_unlock_irqrestore(sdev->host->host_lock, flags); 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, ...@@ -686,6 +684,7 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
* wake up the thread. * wake up the thread.
*/ */
spin_lock_irqsave(sdev->host->host_lock, flags); spin_lock_irqsave(sdev->host->host_lock, flags);
lpfc_cmd->pCmd = NULL;
if (lpfc_cmd->waitq) if (lpfc_cmd->waitq)
wake_up(lpfc_cmd->waitq); wake_up(lpfc_cmd->waitq);
spin_unlock_irqrestore(sdev->host->host_lock, flags); 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, ...@@ -3763,7 +3763,6 @@ lpfc_sli_validate_fcp_iocb(struct lpfc_iocbq *iocbq, struct lpfc_vport *vport,
lpfc_ctx_cmd ctx_cmd) lpfc_ctx_cmd ctx_cmd)
{ {
struct lpfc_scsi_buf *lpfc_cmd; struct lpfc_scsi_buf *lpfc_cmd;
struct scsi_cmnd *cmnd;
int rc = 1; int rc = 1;
if (!(iocbq->iocb_flag & LPFC_IO_FCP)) if (!(iocbq->iocb_flag & LPFC_IO_FCP))
...@@ -3773,19 +3772,20 @@ lpfc_sli_validate_fcp_iocb(struct lpfc_iocbq *iocbq, struct lpfc_vport *vport, ...@@ -3773,19 +3772,20 @@ lpfc_sli_validate_fcp_iocb(struct lpfc_iocbq *iocbq, struct lpfc_vport *vport,
return rc; return rc;
lpfc_cmd = container_of(iocbq, struct lpfc_scsi_buf, cur_iocbq); 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; return rc;
switch (ctx_cmd) { switch (ctx_cmd) {
case LPFC_CTX_LUN: case LPFC_CTX_LUN:
if ((cmnd->device->id == tgt_id) && if ((lpfc_cmd->rdata->pnode) &&
(cmnd->device->lun == lun_id)) (lpfc_cmd->rdata->pnode->nlp_sid == tgt_id) &&
(scsilun_to_int(&lpfc_cmd->fcp_cmnd->fcp_lun) == lun_id))
rc = 0; rc = 0;
break; break;
case LPFC_CTX_TGT: 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; rc = 0;
break; break;
case LPFC_CTX_HOST: case LPFC_CTX_HOST:
...@@ -3995,6 +3995,7 @@ lpfc_sli_issue_mbox_wait(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq, ...@@ -3995,6 +3995,7 @@ lpfc_sli_issue_mbox_wait(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq,
if (pmboxq->context1) if (pmboxq->context1)
return MBX_NOT_FINISHED; return MBX_NOT_FINISHED;
pmboxq->mbox_flag &= ~LPFC_MBX_WAKE;
/* setup wake call as IOCB callback */ /* setup wake call as IOCB callback */
pmboxq->mbox_cmpl = lpfc_sli_wake_mbox_wait; pmboxq->mbox_cmpl = lpfc_sli_wake_mbox_wait;
/* setup context field to pass wait_queue pointer to wake function */ /* 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) ...@@ -216,6 +216,7 @@ lpfc_vport_create(struct fc_vport *fc_vport, bool disable)
int vpi; int vpi;
int rc = VPORT_ERROR; int rc = VPORT_ERROR;
int status; int status;
int size;
if ((phba->sli_rev < 3) || if ((phba->sli_rev < 3) ||
!(phba->sli3_options & LPFC_SLI3_NPIV_ENABLED)) { !(phba->sli3_options & LPFC_SLI3_NPIV_ENABLED)) {
...@@ -278,7 +279,20 @@ lpfc_vport_create(struct fc_vport *fc_vport, bool disable) ...@@ -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_portname.u.wwn, vport->fc_sparam.portName.u.wwn, 8);
memcpy(vport->fc_nodename.u.wwn, vport->fc_sparam.nodeName.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) if (fc_vport->node_name != 0)
u64_to_wwn(fc_vport->node_name, vport->fc_nodename.u.wwn); u64_to_wwn(fc_vport->node_name, vport->fc_nodename.u.wwn);
if (fc_vport->port_name != 0) 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