diff options
author | James Smart <james.smart@emulex.com> | 2010-12-15 17:57:20 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2010-12-21 13:37:19 -0500 |
commit | be858b65cf9701e75bc49ed38c56e5b51ff281cd (patch) | |
tree | bbfded30cbea9fb82f3a1d604c0fc5302e23d855 /drivers | |
parent | 395eb20238f5f1d5fba0ae284760a68095dd9e66 (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')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_bsg.c | 40 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.c | 22 |
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 | ||
394 | free_rspiocbq: | ||
395 | lpfc_sli_release_iocbq(phba, rspiocbq); | ||
396 | free_cmdiocbq: | 374 | free_cmdiocbq: |
397 | lpfc_sli_release_iocbq(phba, cmdiocbq); | 375 | lpfc_sli_release_iocbq(phba, cmdiocbq); |
398 | free_bmp: | 376 | free_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; |