[SCSI] lpfc 8.3.20: Critical fixes
- Use for iocbq->context1 to hold the ndlp pointer. - Set ndlp in all iocbs generated from ioctl functions. - Turn parity and serr bits back on after performing sli4 board reset. Signed-off-by: Alex Iannicelli <alex.iannicelli@emulex.com> Signed-off-by: James Smart <james.smart@emulex.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
This commit is contained in:
parent
395eb20238
commit
be858b65cf
|
@ -162,7 +162,6 @@ lpfc_bsg_send_mgmt_cmd_cmp(struct lpfc_hba *phba,
|
||||||
struct lpfc_iocbq *cmdiocbq,
|
struct lpfc_iocbq *cmdiocbq,
|
||||||
struct lpfc_iocbq *rspiocbq)
|
struct lpfc_iocbq *rspiocbq)
|
||||||
{
|
{
|
||||||
unsigned long iflags;
|
|
||||||
struct bsg_job_data *dd_data;
|
struct bsg_job_data *dd_data;
|
||||||
struct fc_bsg_job *job;
|
struct fc_bsg_job *job;
|
||||||
IOCB_t *rsp;
|
IOCB_t *rsp;
|
||||||
|
@ -173,9 +172,10 @@ lpfc_bsg_send_mgmt_cmd_cmp(struct lpfc_hba *phba,
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
spin_lock_irqsave(&phba->ct_ev_lock, flags);
|
spin_lock_irqsave(&phba->ct_ev_lock, flags);
|
||||||
dd_data = cmdiocbq->context1;
|
dd_data = cmdiocbq->context2;
|
||||||
if (!dd_data) {
|
if (!dd_data) {
|
||||||
spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
|
spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
|
||||||
|
lpfc_sli_release_iocbq(phba, cmdiocbq);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,17 +183,9 @@ lpfc_bsg_send_mgmt_cmd_cmp(struct lpfc_hba *phba,
|
||||||
job = iocb->set_job;
|
job = iocb->set_job;
|
||||||
job->dd_data = NULL; /* so timeout handler does not reply */
|
job->dd_data = NULL; /* so timeout handler does not reply */
|
||||||
|
|
||||||
spin_lock_irqsave(&phba->hbalock, iflags);
|
|
||||||
cmdiocbq->iocb_flag |= LPFC_IO_WAKE;
|
|
||||||
if (cmdiocbq->context2 && rspiocbq)
|
|
||||||
memcpy(&((struct lpfc_iocbq *)cmdiocbq->context2)->iocb,
|
|
||||||
&rspiocbq->iocb, sizeof(IOCB_t));
|
|
||||||
spin_unlock_irqrestore(&phba->hbalock, iflags);
|
|
||||||
|
|
||||||
bmp = iocb->bmp;
|
bmp = iocb->bmp;
|
||||||
rspiocbq = iocb->rspiocbq;
|
|
||||||
rsp = &rspiocbq->iocb;
|
rsp = &rspiocbq->iocb;
|
||||||
ndlp = iocb->ndlp;
|
ndlp = cmdiocbq->context1;
|
||||||
|
|
||||||
pci_unmap_sg(phba->pcidev, job->request_payload.sg_list,
|
pci_unmap_sg(phba->pcidev, job->request_payload.sg_list,
|
||||||
job->request_payload.sg_cnt, DMA_TO_DEVICE);
|
job->request_payload.sg_cnt, DMA_TO_DEVICE);
|
||||||
|
@ -220,7 +212,6 @@ lpfc_bsg_send_mgmt_cmd_cmp(struct lpfc_hba *phba,
|
||||||
rsp->un.genreq64.bdl.bdeSize;
|
rsp->un.genreq64.bdl.bdeSize;
|
||||||
|
|
||||||
lpfc_mbuf_free(phba, bmp->virt, bmp->phys);
|
lpfc_mbuf_free(phba, bmp->virt, bmp->phys);
|
||||||
lpfc_sli_release_iocbq(phba, rspiocbq);
|
|
||||||
lpfc_sli_release_iocbq(phba, cmdiocbq);
|
lpfc_sli_release_iocbq(phba, cmdiocbq);
|
||||||
lpfc_nlp_put(ndlp);
|
lpfc_nlp_put(ndlp);
|
||||||
kfree(bmp);
|
kfree(bmp);
|
||||||
|
@ -247,9 +238,7 @@ lpfc_bsg_send_mgmt_cmd(struct fc_bsg_job *job)
|
||||||
struct ulp_bde64 *bpl = NULL;
|
struct ulp_bde64 *bpl = NULL;
|
||||||
uint32_t timeout;
|
uint32_t timeout;
|
||||||
struct lpfc_iocbq *cmdiocbq = NULL;
|
struct lpfc_iocbq *cmdiocbq = NULL;
|
||||||
struct lpfc_iocbq *rspiocbq = NULL;
|
|
||||||
IOCB_t *cmd;
|
IOCB_t *cmd;
|
||||||
IOCB_t *rsp;
|
|
||||||
struct lpfc_dmabuf *bmp = NULL;
|
struct lpfc_dmabuf *bmp = NULL;
|
||||||
int request_nseg;
|
int request_nseg;
|
||||||
int reply_nseg;
|
int reply_nseg;
|
||||||
|
@ -296,17 +285,10 @@ lpfc_bsg_send_mgmt_cmd(struct fc_bsg_job *job)
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd = &cmdiocbq->iocb;
|
cmd = &cmdiocbq->iocb;
|
||||||
rspiocbq = lpfc_sli_get_iocbq(phba);
|
|
||||||
if (!rspiocbq) {
|
|
||||||
rc = -ENOMEM;
|
|
||||||
goto free_cmdiocbq;
|
|
||||||
}
|
|
||||||
|
|
||||||
rsp = &rspiocbq->iocb;
|
|
||||||
bmp->virt = lpfc_mbuf_alloc(phba, 0, &bmp->phys);
|
bmp->virt = lpfc_mbuf_alloc(phba, 0, &bmp->phys);
|
||||||
if (!bmp->virt) {
|
if (!bmp->virt) {
|
||||||
rc = -ENOMEM;
|
rc = -ENOMEM;
|
||||||
goto free_rspiocbq;
|
goto free_cmdiocbq;
|
||||||
}
|
}
|
||||||
|
|
||||||
INIT_LIST_HEAD(&bmp->list);
|
INIT_LIST_HEAD(&bmp->list);
|
||||||
|
@ -358,14 +340,12 @@ lpfc_bsg_send_mgmt_cmd(struct fc_bsg_job *job)
|
||||||
cmd->ulpTimeout = timeout;
|
cmd->ulpTimeout = timeout;
|
||||||
|
|
||||||
cmdiocbq->iocb_cmpl = lpfc_bsg_send_mgmt_cmd_cmp;
|
cmdiocbq->iocb_cmpl = lpfc_bsg_send_mgmt_cmd_cmp;
|
||||||
cmdiocbq->context1 = dd_data;
|
cmdiocbq->context1 = ndlp;
|
||||||
cmdiocbq->context2 = rspiocbq;
|
cmdiocbq->context2 = dd_data;
|
||||||
dd_data->type = TYPE_IOCB;
|
dd_data->type = TYPE_IOCB;
|
||||||
dd_data->context_un.iocb.cmdiocbq = cmdiocbq;
|
dd_data->context_un.iocb.cmdiocbq = cmdiocbq;
|
||||||
dd_data->context_un.iocb.rspiocbq = rspiocbq;
|
|
||||||
dd_data->context_un.iocb.set_job = job;
|
dd_data->context_un.iocb.set_job = job;
|
||||||
dd_data->context_un.iocb.bmp = bmp;
|
dd_data->context_un.iocb.bmp = bmp;
|
||||||
dd_data->context_un.iocb.ndlp = ndlp;
|
|
||||||
|
|
||||||
if (phba->cfg_poll & DISABLE_FCP_RING_INT) {
|
if (phba->cfg_poll & DISABLE_FCP_RING_INT) {
|
||||||
creg_val = readl(phba->HCregaddr);
|
creg_val = readl(phba->HCregaddr);
|
||||||
|
@ -391,8 +371,6 @@ lpfc_bsg_send_mgmt_cmd(struct fc_bsg_job *job)
|
||||||
|
|
||||||
lpfc_mbuf_free(phba, bmp->virt, bmp->phys);
|
lpfc_mbuf_free(phba, bmp->virt, bmp->phys);
|
||||||
|
|
||||||
free_rspiocbq:
|
|
||||||
lpfc_sli_release_iocbq(phba, rspiocbq);
|
|
||||||
free_cmdiocbq:
|
free_cmdiocbq:
|
||||||
lpfc_sli_release_iocbq(phba, cmdiocbq);
|
lpfc_sli_release_iocbq(phba, cmdiocbq);
|
||||||
free_bmp:
|
free_bmp:
|
||||||
|
@ -1220,7 +1198,7 @@ lpfc_issue_ct_rsp_cmp(struct lpfc_hba *phba,
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
spin_lock_irqsave(&phba->ct_ev_lock, flags);
|
spin_lock_irqsave(&phba->ct_ev_lock, flags);
|
||||||
dd_data = cmdiocbq->context1;
|
dd_data = cmdiocbq->context2;
|
||||||
/* normal completion and timeout crossed paths, already done */
|
/* normal completion and timeout crossed paths, already done */
|
||||||
if (!dd_data) {
|
if (!dd_data) {
|
||||||
spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
|
spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
|
||||||
|
@ -1369,8 +1347,8 @@ lpfc_issue_ct_rsp(struct lpfc_hba *phba, struct fc_bsg_job *job, uint32_t tag,
|
||||||
ctiocb->context3 = bmp;
|
ctiocb->context3 = bmp;
|
||||||
|
|
||||||
ctiocb->iocb_cmpl = lpfc_issue_ct_rsp_cmp;
|
ctiocb->iocb_cmpl = lpfc_issue_ct_rsp_cmp;
|
||||||
ctiocb->context1 = dd_data;
|
ctiocb->context2 = dd_data;
|
||||||
ctiocb->context2 = NULL;
|
ctiocb->context1 = ndlp;
|
||||||
dd_data->type = TYPE_IOCB;
|
dd_data->type = TYPE_IOCB;
|
||||||
dd_data->context_un.iocb.cmdiocbq = ctiocb;
|
dd_data->context_un.iocb.cmdiocbq = ctiocb;
|
||||||
dd_data->context_un.iocb.rspiocbq = NULL;
|
dd_data->context_un.iocb.rspiocbq = NULL;
|
||||||
|
|
|
@ -871,11 +871,9 @@ __lpfc_sli_get_sglq(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq)
|
||||||
if (piocbq->iocb_flag & LPFC_IO_FCP) {
|
if (piocbq->iocb_flag & LPFC_IO_FCP) {
|
||||||
lpfc_cmd = (struct lpfc_scsi_buf *) piocbq->context1;
|
lpfc_cmd = (struct lpfc_scsi_buf *) piocbq->context1;
|
||||||
ndlp = lpfc_cmd->rdata->pnode;
|
ndlp = lpfc_cmd->rdata->pnode;
|
||||||
} else if (piocbq->iocb.ulpCommand == CMD_GEN_REQUEST64_CR)
|
} else if ((piocbq->iocb.ulpCommand == CMD_GEN_REQUEST64_CR) &&
|
||||||
|
!(piocbq->iocb_flag & LPFC_IO_LIBDFC))
|
||||||
ndlp = piocbq->context_un.ndlp;
|
ndlp = piocbq->context_un.ndlp;
|
||||||
else if (piocbq->iocb.ulpCommand == CMD_XMIT_BLS_RSP64_CX)
|
|
||||||
ndlp = lpfc_findnode_did(piocbq->vport,
|
|
||||||
piocbq->iocb.ulpContext);
|
|
||||||
else
|
else
|
||||||
ndlp = piocbq->context1;
|
ndlp = piocbq->context1;
|
||||||
|
|
||||||
|
@ -3855,12 +3853,6 @@ lpfc_sli4_brdreset(struct lpfc_hba *phba)
|
||||||
phba->pport->fc_myDID = 0;
|
phba->pport->fc_myDID = 0;
|
||||||
phba->pport->fc_prevDID = 0;
|
phba->pport->fc_prevDID = 0;
|
||||||
|
|
||||||
/* Turn off parity checking and serr during the physical reset */
|
|
||||||
pci_read_config_word(phba->pcidev, PCI_COMMAND, &cfg_value);
|
|
||||||
pci_write_config_word(phba->pcidev, PCI_COMMAND,
|
|
||||||
(cfg_value &
|
|
||||||
~(PCI_COMMAND_PARITY | PCI_COMMAND_SERR)));
|
|
||||||
|
|
||||||
spin_lock_irq(&phba->hbalock);
|
spin_lock_irq(&phba->hbalock);
|
||||||
psli->sli_flag &= ~(LPFC_PROCESS_LA);
|
psli->sli_flag &= ~(LPFC_PROCESS_LA);
|
||||||
phba->fcf.fcf_flag = 0;
|
phba->fcf.fcf_flag = 0;
|
||||||
|
@ -3880,9 +3872,18 @@ lpfc_sli4_brdreset(struct lpfc_hba *phba)
|
||||||
/* Now physically reset the device */
|
/* Now physically reset the device */
|
||||||
lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
|
lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
|
||||||
"0389 Performing PCI function reset!\n");
|
"0389 Performing PCI function reset!\n");
|
||||||
|
|
||||||
|
/* Turn off parity checking and serr during the physical reset */
|
||||||
|
pci_read_config_word(phba->pcidev, PCI_COMMAND, &cfg_value);
|
||||||
|
pci_write_config_word(phba->pcidev, PCI_COMMAND, (cfg_value &
|
||||||
|
~(PCI_COMMAND_PARITY | PCI_COMMAND_SERR)));
|
||||||
|
|
||||||
/* Perform FCoE PCI function reset */
|
/* Perform FCoE PCI function reset */
|
||||||
lpfc_pci_function_reset(phba);
|
lpfc_pci_function_reset(phba);
|
||||||
|
|
||||||
|
/* Restore PCI cmd register */
|
||||||
|
pci_write_config_word(phba->pcidev, PCI_COMMAND, cfg_value);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11969,6 +11970,7 @@ lpfc_sli4_seq_abort_acc(struct lpfc_hba *phba,
|
||||||
icmd->ulpLe = 1;
|
icmd->ulpLe = 1;
|
||||||
icmd->ulpClass = CLASS3;
|
icmd->ulpClass = CLASS3;
|
||||||
icmd->ulpContext = ndlp->nlp_rpi;
|
icmd->ulpContext = ndlp->nlp_rpi;
|
||||||
|
ctiocb->context1 = ndlp;
|
||||||
|
|
||||||
ctiocb->iocb_cmpl = NULL;
|
ctiocb->iocb_cmpl = NULL;
|
||||||
ctiocb->vport = phba->pport;
|
ctiocb->vport = phba->pport;
|
||||||
|
|
Loading…
Reference in a new issue