Commit be858b65 authored by James Smart's avatar James Smart Committed by James Bottomley

[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: default avatarAlex Iannicelli <alex.iannicelli@emulex.com>
Signed-off-by: default avatarJames Smart <james.smart@emulex.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@suse.de>
parent 395eb202
...@@ -162,7 +162,6 @@ lpfc_bsg_send_mgmt_cmd_cmp(struct lpfc_hba *phba, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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;
......
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