aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc
diff options
context:
space:
mode:
authorJames Smart <james.smart@emulex.com>2010-12-15 17:57:20 -0500
committerJames Bottomley <James.Bottomley@suse.de>2010-12-21 13:37:19 -0500
commitbe858b65cf9701e75bc49ed38c56e5b51ff281cd (patch)
treebbfded30cbea9fb82f3a1d604c0fc5302e23d855 /drivers/scsi/lpfc
parent395eb20238f5f1d5fba0ae284760a68095dd9e66 (diff)
[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>
Diffstat (limited to 'drivers/scsi/lpfc')
-rw-r--r--drivers/scsi/lpfc/lpfc_bsg.c40
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c22
2 files changed, 21 insertions, 41 deletions
diff --git a/drivers/scsi/lpfc/lpfc_bsg.c b/drivers/scsi/lpfc/lpfc_bsg.c
index 50dbfc8018f6..3330d7951b42 100644
--- a/drivers/scsi/lpfc/lpfc_bsg.c
+++ b/drivers/scsi/lpfc/lpfc_bsg.c
@@ -162,7 +162,6 @@ lpfc_bsg_send_mgmt_cmd_cmp(struct lpfc_hba *phba,
162 struct lpfc_iocbq *cmdiocbq, 162 struct lpfc_iocbq *cmdiocbq,
163 struct lpfc_iocbq *rspiocbq) 163 struct lpfc_iocbq *rspiocbq)
164{ 164{
165 unsigned long iflags;
166 struct bsg_job_data *dd_data; 165 struct bsg_job_data *dd_data;
167 struct fc_bsg_job *job; 166 struct fc_bsg_job *job;
168 IOCB_t *rsp; 167 IOCB_t *rsp;
@@ -173,9 +172,10 @@ lpfc_bsg_send_mgmt_cmd_cmp(struct lpfc_hba *phba,
173 int rc = 0; 172 int rc = 0;
174 173
175 spin_lock_irqsave(&phba->ct_ev_lock, flags); 174 spin_lock_irqsave(&phba->ct_ev_lock, flags);
176 dd_data = cmdiocbq->context1; 175 dd_data = cmdiocbq->context2;
177 if (!dd_data) { 176 if (!dd_data) {
178 spin_unlock_irqrestore(&phba->ct_ev_lock, flags); 177 spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
178 lpfc_sli_release_iocbq(phba, cmdiocbq);
179 return; 179 return;
180 } 180 }
181 181
@@ -183,17 +183,9 @@ lpfc_bsg_send_mgmt_cmd_cmp(struct lpfc_hba *phba,
183 job = iocb->set_job; 183 job = iocb->set_job;
184 job->dd_data = NULL; /* so timeout handler does not reply */ 184 job->dd_data = NULL; /* so timeout handler does not reply */
185 185
186 spin_lock_irqsave(&phba->hbalock, iflags);
187 cmdiocbq->iocb_flag |= LPFC_IO_WAKE;
188 if (cmdiocbq->context2 && rspiocbq)
189 memcpy(&((struct lpfc_iocbq *)cmdiocbq->context2)->iocb,
190 &rspiocbq->iocb, sizeof(IOCB_t));
191 spin_unlock_irqrestore(&phba->hbalock, iflags);
192
193 bmp = iocb->bmp; 186 bmp = iocb->bmp;
194 rspiocbq = iocb->rspiocbq;
195 rsp = &rspiocbq->iocb; 187 rsp = &rspiocbq->iocb;
196 ndlp = iocb->ndlp; 188 ndlp = cmdiocbq->context1;
197 189
198 pci_unmap_sg(phba->pcidev, job->request_payload.sg_list, 190 pci_unmap_sg(phba->pcidev, job->request_payload.sg_list,
199 job->request_payload.sg_cnt, DMA_TO_DEVICE); 191 job->request_payload.sg_cnt, DMA_TO_DEVICE);
@@ -220,7 +212,6 @@ lpfc_bsg_send_mgmt_cmd_cmp(struct lpfc_hba *phba,
220 rsp->un.genreq64.bdl.bdeSize; 212 rsp->un.genreq64.bdl.bdeSize;
221 213
222 lpfc_mbuf_free(phba, bmp->virt, bmp->phys); 214 lpfc_mbuf_free(phba, bmp->virt, bmp->phys);
223 lpfc_sli_release_iocbq(phba, rspiocbq);
224 lpfc_sli_release_iocbq(phba, cmdiocbq); 215 lpfc_sli_release_iocbq(phba, cmdiocbq);
225 lpfc_nlp_put(ndlp); 216 lpfc_nlp_put(ndlp);
226 kfree(bmp); 217 kfree(bmp);
@@ -247,9 +238,7 @@ lpfc_bsg_send_mgmt_cmd(struct fc_bsg_job *job)
247 struct ulp_bde64 *bpl = NULL; 238 struct ulp_bde64 *bpl = NULL;
248 uint32_t timeout; 239 uint32_t timeout;
249 struct lpfc_iocbq *cmdiocbq = NULL; 240 struct lpfc_iocbq *cmdiocbq = NULL;
250 struct lpfc_iocbq *rspiocbq = NULL;
251 IOCB_t *cmd; 241 IOCB_t *cmd;
252 IOCB_t *rsp;
253 struct lpfc_dmabuf *bmp = NULL; 242 struct lpfc_dmabuf *bmp = NULL;
254 int request_nseg; 243 int request_nseg;
255 int reply_nseg; 244 int reply_nseg;
@@ -296,17 +285,10 @@ lpfc_bsg_send_mgmt_cmd(struct fc_bsg_job *job)
296 } 285 }
297 286
298 cmd = &cmdiocbq->iocb; 287 cmd = &cmdiocbq->iocb;
299 rspiocbq = lpfc_sli_get_iocbq(phba);
300 if (!rspiocbq) {
301 rc = -ENOMEM;
302 goto free_cmdiocbq;
303 }
304
305 rsp = &rspiocbq->iocb;
306 bmp->virt = lpfc_mbuf_alloc(phba, 0, &bmp->phys); 288 bmp->virt = lpfc_mbuf_alloc(phba, 0, &bmp->phys);
307 if (!bmp->virt) { 289 if (!bmp->virt) {
308 rc = -ENOMEM; 290 rc = -ENOMEM;
309 goto free_rspiocbq; 291 goto free_cmdiocbq;
310 } 292 }
311 293
312 INIT_LIST_HEAD(&bmp->list); 294 INIT_LIST_HEAD(&bmp->list);
@@ -358,14 +340,12 @@ lpfc_bsg_send_mgmt_cmd(struct fc_bsg_job *job)
358 cmd->ulpTimeout = timeout; 340 cmd->ulpTimeout = timeout;
359 341
360 cmdiocbq->iocb_cmpl = lpfc_bsg_send_mgmt_cmd_cmp; 342 cmdiocbq->iocb_cmpl = lpfc_bsg_send_mgmt_cmd_cmp;
361 cmdiocbq->context1 = dd_data; 343 cmdiocbq->context1 = ndlp;
362 cmdiocbq->context2 = rspiocbq; 344 cmdiocbq->context2 = dd_data;
363 dd_data->type = TYPE_IOCB; 345 dd_data->type = TYPE_IOCB;
364 dd_data->context_un.iocb.cmdiocbq = cmdiocbq; 346 dd_data->context_un.iocb.cmdiocbq = cmdiocbq;
365 dd_data->context_un.iocb.rspiocbq = rspiocbq;
366 dd_data->context_un.iocb.set_job = job; 347 dd_data->context_un.iocb.set_job = job;
367 dd_data->context_un.iocb.bmp = bmp; 348 dd_data->context_un.iocb.bmp = bmp;
368 dd_data->context_un.iocb.ndlp = ndlp;
369 349
370 if (phba->cfg_poll & DISABLE_FCP_RING_INT) { 350 if (phba->cfg_poll & DISABLE_FCP_RING_INT) {
371 creg_val = readl(phba->HCregaddr); 351 creg_val = readl(phba->HCregaddr);
@@ -391,8 +371,6 @@ lpfc_bsg_send_mgmt_cmd(struct fc_bsg_job *job)
391 371
392 lpfc_mbuf_free(phba, bmp->virt, bmp->phys); 372 lpfc_mbuf_free(phba, bmp->virt, bmp->phys);
393 373
394free_rspiocbq:
395 lpfc_sli_release_iocbq(phba, rspiocbq);
396free_cmdiocbq: 374free_cmdiocbq:
397 lpfc_sli_release_iocbq(phba, cmdiocbq); 375 lpfc_sli_release_iocbq(phba, cmdiocbq);
398free_bmp: 376free_bmp:
@@ -1220,7 +1198,7 @@ lpfc_issue_ct_rsp_cmp(struct lpfc_hba *phba,
1220 int rc = 0; 1198 int rc = 0;
1221 1199
1222 spin_lock_irqsave(&phba->ct_ev_lock, flags); 1200 spin_lock_irqsave(&phba->ct_ev_lock, flags);
1223 dd_data = cmdiocbq->context1; 1201 dd_data = cmdiocbq->context2;
1224 /* normal completion and timeout crossed paths, already done */ 1202 /* normal completion and timeout crossed paths, already done */
1225 if (!dd_data) { 1203 if (!dd_data) {
1226 spin_unlock_irqrestore(&phba->ct_ev_lock, flags); 1204 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 ctiocb->context3 = bmp; 1347 ctiocb->context3 = bmp;
1370 1348
1371 ctiocb->iocb_cmpl = lpfc_issue_ct_rsp_cmp; 1349 ctiocb->iocb_cmpl = lpfc_issue_ct_rsp_cmp;
1372 ctiocb->context1 = dd_data; 1350 ctiocb->context2 = dd_data;
1373 ctiocb->context2 = NULL; 1351 ctiocb->context1 = ndlp;
1374 dd_data->type = TYPE_IOCB; 1352 dd_data->type = TYPE_IOCB;
1375 dd_data->context_un.iocb.cmdiocbq = ctiocb; 1353 dd_data->context_un.iocb.cmdiocbq = ctiocb;
1376 dd_data->context_un.iocb.rspiocbq = NULL; 1354 dd_data->context_un.iocb.rspiocbq = NULL;
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 752601509549..7509de2f4566 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -871,11 +871,9 @@ __lpfc_sli_get_sglq(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq)
871 if (piocbq->iocb_flag & LPFC_IO_FCP) { 871 if (piocbq->iocb_flag & LPFC_IO_FCP) {
872 lpfc_cmd = (struct lpfc_scsi_buf *) piocbq->context1; 872 lpfc_cmd = (struct lpfc_scsi_buf *) piocbq->context1;
873 ndlp = lpfc_cmd->rdata->pnode; 873 ndlp = lpfc_cmd->rdata->pnode;
874 } else if (piocbq->iocb.ulpCommand == CMD_GEN_REQUEST64_CR) 874 } else if ((piocbq->iocb.ulpCommand == CMD_GEN_REQUEST64_CR) &&
875 !(piocbq->iocb_flag & LPFC_IO_LIBDFC))
875 ndlp = piocbq->context_un.ndlp; 876 ndlp = piocbq->context_un.ndlp;
876 else if (piocbq->iocb.ulpCommand == CMD_XMIT_BLS_RSP64_CX)
877 ndlp = lpfc_findnode_did(piocbq->vport,
878 piocbq->iocb.ulpContext);
879 else 877 else
880 ndlp = piocbq->context1; 878 ndlp = piocbq->context1;
881 879
@@ -3855,12 +3853,6 @@ lpfc_sli4_brdreset(struct lpfc_hba *phba)
3855 phba->pport->fc_myDID = 0; 3853 phba->pport->fc_myDID = 0;
3856 phba->pport->fc_prevDID = 0; 3854 phba->pport->fc_prevDID = 0;
3857 3855
3858 /* Turn off parity checking and serr during the physical reset */
3859 pci_read_config_word(phba->pcidev, PCI_COMMAND, &cfg_value);
3860 pci_write_config_word(phba->pcidev, PCI_COMMAND,
3861 (cfg_value &
3862 ~(PCI_COMMAND_PARITY | PCI_COMMAND_SERR)));
3863
3864 spin_lock_irq(&phba->hbalock); 3856 spin_lock_irq(&phba->hbalock);
3865 psli->sli_flag &= ~(LPFC_PROCESS_LA); 3857 psli->sli_flag &= ~(LPFC_PROCESS_LA);
3866 phba->fcf.fcf_flag = 0; 3858 phba->fcf.fcf_flag = 0;
@@ -3880,9 +3872,18 @@ lpfc_sli4_brdreset(struct lpfc_hba *phba)
3880 /* Now physically reset the device */ 3872 /* Now physically reset the device */
3881 lpfc_printf_log(phba, KERN_INFO, LOG_INIT, 3873 lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
3882 "0389 Performing PCI function reset!\n"); 3874 "0389 Performing PCI function reset!\n");
3875
3876 /* Turn off parity checking and serr during the physical reset */
3877 pci_read_config_word(phba->pcidev, PCI_COMMAND, &cfg_value);
3878 pci_write_config_word(phba->pcidev, PCI_COMMAND, (cfg_value &
3879 ~(PCI_COMMAND_PARITY | PCI_COMMAND_SERR)));
3880
3883 /* Perform FCoE PCI function reset */ 3881 /* Perform FCoE PCI function reset */
3884 lpfc_pci_function_reset(phba); 3882 lpfc_pci_function_reset(phba);
3885 3883
3884 /* Restore PCI cmd register */
3885 pci_write_config_word(phba->pcidev, PCI_COMMAND, cfg_value);
3886
3886 return 0; 3887 return 0;
3887} 3888}
3888 3889
@@ -11969,6 +11970,7 @@ lpfc_sli4_seq_abort_acc(struct lpfc_hba *phba,
11969 icmd->ulpLe = 1; 11970 icmd->ulpLe = 1;
11970 icmd->ulpClass = CLASS3; 11971 icmd->ulpClass = CLASS3;
11971 icmd->ulpContext = ndlp->nlp_rpi; 11972 icmd->ulpContext = ndlp->nlp_rpi;
11973 ctiocb->context1 = ndlp;
11972 11974
11973 ctiocb->iocb_cmpl = NULL; 11975 ctiocb->iocb_cmpl = NULL;
11974 ctiocb->vport = phba->pport; 11976 ctiocb->vport = phba->pport;