diff options
author | James Smart <James.Smart@Emulex.Com> | 2007-04-25 09:51:30 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2007-05-06 10:33:12 -0400 |
commit | 1dcb58e5680b6673bf984696d3d8b9033b6e41bf (patch) | |
tree | 7421ad398ef2ee04d2c7b22bb975219593885f01 | |
parent | e555db930f7512491485cfc43df4306192835373 (diff) |
[SCSI] lpfc 8.1.12 : Misc bug fixes and code cleanup
Misc bug fixes and code cleanup:
- Fix system hang while running on systems with IOMMU
- Fix use after free issues with rports
- Don't free mailbox structure if it's still on the mboxq list
- Decrement txq_cnt rather than txcmplq_cnt when parsing the txq list
- Use msleep for long delays to prevent soft lockup bug check
- Don't remove node during dev_loss_tmo if discovery is active
- Fix memory leaks in get/reset statistics and link attention paths
- Fixed lpfc_ns_rsp to handle entire GID_FT response.
- mbox interface should use MAILBOX_CMD_SIZE rather than sizeof(MAILBOX_t)
- Fixed bug check in add_timer.
- Fixup messages 0116, 0117, and 0128 to report ELS I/O tag.
- Remove unused parameter to lpfc_cleanup.
- Change mailbox timeout handling.
- Remove unused buflist. Code cleanup.
Signed-off-by: James Smart <James.Smart@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
-rw-r--r-- | drivers/scsi/lpfc/lpfc.h | 3 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_attr.c | 19 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_ct.c | 5 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_els.c | 17 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hbadisc.c | 29 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_init.c | 31 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_scsi.c | 7 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.c | 98 |
8 files changed, 80 insertions, 129 deletions
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index a7de0bca5bdd..e57a9f5b9d84 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h | |||
@@ -387,9 +387,6 @@ struct lpfc_hba { | |||
387 | 387 | ||
388 | mempool_t *mbox_mem_pool; | 388 | mempool_t *mbox_mem_pool; |
389 | mempool_t *nlp_mem_pool; | 389 | mempool_t *nlp_mem_pool; |
390 | struct list_head freebufList; | ||
391 | struct list_head ctrspbuflist; | ||
392 | struct list_head rnidrspbuflist; | ||
393 | 390 | ||
394 | struct fc_host_statistics link_stats; | 391 | struct fc_host_statistics link_stats; |
395 | }; | 392 | }; |
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index f247e786af99..6cc88b198fa3 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c | |||
@@ -1227,11 +1227,11 @@ sysfs_mbox_read(struct kobject *kobj, char *buf, loff_t off, size_t count) | |||
1227 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; | 1227 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; |
1228 | int rc; | 1228 | int rc; |
1229 | 1229 | ||
1230 | if (off > sizeof(MAILBOX_t)) | 1230 | if (off > MAILBOX_CMD_SIZE) |
1231 | return -ERANGE; | 1231 | return -ERANGE; |
1232 | 1232 | ||
1233 | if ((count + off) > sizeof(MAILBOX_t)) | 1233 | if ((count + off) > MAILBOX_CMD_SIZE) |
1234 | count = sizeof(MAILBOX_t) - off; | 1234 | count = MAILBOX_CMD_SIZE - off; |
1235 | 1235 | ||
1236 | if (off % 4 || count % 4 || (unsigned long)buf % 4) | 1236 | if (off % 4 || count % 4 || (unsigned long)buf % 4) |
1237 | return -EINVAL; | 1237 | return -EINVAL; |
@@ -1326,6 +1326,11 @@ sysfs_mbox_read(struct kobject *kobj, char *buf, loff_t off, size_t count) | |||
1326 | } | 1326 | } |
1327 | 1327 | ||
1328 | if (rc != MBX_SUCCESS) { | 1328 | if (rc != MBX_SUCCESS) { |
1329 | if (rc == MBX_TIMEOUT) { | ||
1330 | phba->sysfs_mbox.mbox->mbox_cmpl = | ||
1331 | lpfc_sli_def_mbox_cmpl; | ||
1332 | phba->sysfs_mbox.mbox = NULL; | ||
1333 | } | ||
1329 | sysfs_mbox_idle(phba); | 1334 | sysfs_mbox_idle(phba); |
1330 | spin_unlock_irq(host->host_lock); | 1335 | spin_unlock_irq(host->host_lock); |
1331 | return (rc == MBX_TIMEOUT) ? -ETIME : -ENODEV; | 1336 | return (rc == MBX_TIMEOUT) ? -ETIME : -ENODEV; |
@@ -1344,7 +1349,7 @@ sysfs_mbox_read(struct kobject *kobj, char *buf, loff_t off, size_t count) | |||
1344 | 1349 | ||
1345 | phba->sysfs_mbox.offset = off + count; | 1350 | phba->sysfs_mbox.offset = off + count; |
1346 | 1351 | ||
1347 | if (phba->sysfs_mbox.offset == sizeof(MAILBOX_t)) | 1352 | if (phba->sysfs_mbox.offset == MAILBOX_CMD_SIZE) |
1348 | sysfs_mbox_idle(phba); | 1353 | sysfs_mbox_idle(phba); |
1349 | 1354 | ||
1350 | spin_unlock_irq(phba->host->host_lock); | 1355 | spin_unlock_irq(phba->host->host_lock); |
@@ -1358,7 +1363,7 @@ static struct bin_attribute sysfs_mbox_attr = { | |||
1358 | .mode = S_IRUSR | S_IWUSR, | 1363 | .mode = S_IRUSR | S_IWUSR, |
1359 | .owner = THIS_MODULE, | 1364 | .owner = THIS_MODULE, |
1360 | }, | 1365 | }, |
1361 | .size = sizeof(MAILBOX_t), | 1366 | .size = MAILBOX_CMD_SIZE, |
1362 | .read = sysfs_mbox_read, | 1367 | .read = sysfs_mbox_read, |
1363 | .write = sysfs_mbox_write, | 1368 | .write = sysfs_mbox_write, |
1364 | }; | 1369 | }; |
@@ -1631,6 +1636,8 @@ lpfc_get_stats(struct Scsi_Host *shost) | |||
1631 | else | 1636 | else |
1632 | hs->seconds_since_last_reset = seconds - psli->stats_start; | 1637 | hs->seconds_since_last_reset = seconds - psli->stats_start; |
1633 | 1638 | ||
1639 | mempool_free(pmboxq, phba->mbox_mem_pool); | ||
1640 | |||
1634 | return hs; | 1641 | return hs; |
1635 | } | 1642 | } |
1636 | 1643 | ||
@@ -1699,6 +1706,8 @@ lpfc_reset_stats(struct Scsi_Host *shost) | |||
1699 | 1706 | ||
1700 | psli->stats_start = get_seconds(); | 1707 | psli->stats_start = get_seconds(); |
1701 | 1708 | ||
1709 | mempool_free(pmboxq, phba->mbox_mem_pool); | ||
1710 | |||
1702 | return; | 1711 | return; |
1703 | } | 1712 | } |
1704 | 1713 | ||
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index a51a41b7f15d..50f45339e0c0 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c | |||
@@ -342,9 +342,10 @@ lpfc_ns_rsp(struct lpfc_hba * phba, struct lpfc_dmabuf * mp, uint32_t Size) | |||
342 | 342 | ||
343 | Size -= Cnt; | 343 | Size -= Cnt; |
344 | 344 | ||
345 | if (!ctptr) | 345 | if (!ctptr) { |
346 | Cnt = FCELSSIZE; | ||
346 | ctptr = (uint32_t *) mlast->virt; | 347 | ctptr = (uint32_t *) mlast->virt; |
347 | else | 348 | } else |
348 | Cnt -= 16; /* subtract length of CT header */ | 349 | Cnt -= 16; /* subtract length of CT header */ |
349 | 350 | ||
350 | /* Loop through entire NameServer list of DIDs */ | 351 | /* Loop through entire NameServer list of DIDs */ |
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index a5f33a0dd4e7..e1c61dbb3d0f 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c | |||
@@ -222,16 +222,16 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba, uint8_t expectRsp, | |||
222 | /* Xmit ELS command <elsCmd> to remote NPORT <did> */ | 222 | /* Xmit ELS command <elsCmd> to remote NPORT <did> */ |
223 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, | 223 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, |
224 | "%d:0116 Xmit ELS command x%x to remote " | 224 | "%d:0116 Xmit ELS command x%x to remote " |
225 | "NPORT x%x Data: x%x x%x\n", | 225 | "NPORT x%x I/O tag: x%x, HBA state: x%x\n", |
226 | phba->brd_no, elscmd, | 226 | phba->brd_no, elscmd, |
227 | did, icmd->ulpIoTag, phba->hba_state); | 227 | did, elsiocb->iotag, phba->hba_state); |
228 | } else { | 228 | } else { |
229 | /* Xmit ELS response <elsCmd> to remote NPORT <did> */ | 229 | /* Xmit ELS response <elsCmd> to remote NPORT <did> */ |
230 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, | 230 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, |
231 | "%d:0117 Xmit ELS response x%x to remote " | 231 | "%d:0117 Xmit ELS response x%x to remote " |
232 | "NPORT x%x Data: x%x x%x\n", | 232 | "NPORT x%x I/O tag: x%x, size: x%x\n", |
233 | phba->brd_no, elscmd, | 233 | phba->brd_no, elscmd, |
234 | ndlp->nlp_DID, icmd->ulpIoTag, cmdSize); | 234 | ndlp->nlp_DID, elsiocb->iotag, cmdSize); |
235 | } | 235 | } |
236 | 236 | ||
237 | return elsiocb; | 237 | return elsiocb; |
@@ -2017,10 +2017,9 @@ lpfc_els_rsp_acc(struct lpfc_hba * phba, uint32_t flag, | |||
2017 | 2017 | ||
2018 | /* Xmit ELS ACC response tag <ulpIoTag> */ | 2018 | /* Xmit ELS ACC response tag <ulpIoTag> */ |
2019 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, | 2019 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, |
2020 | "%d:0128 Xmit ELS ACC response tag x%x " | 2020 | "%d:0128 Xmit ELS ACC response tag x%x, XRI: x%x, " |
2021 | "Data: x%x x%x x%x x%x x%x\n", | 2021 | "DID: x%x, nlp_flag: x%x nlp_state: x%x RPI: x%x\n", |
2022 | phba->brd_no, | 2022 | phba->brd_no, elsiocb->iotag, |
2023 | elsiocb->iocb.ulpIoTag, | ||
2024 | elsiocb->iocb.ulpContext, ndlp->nlp_DID, | 2023 | elsiocb->iocb.ulpContext, ndlp->nlp_DID, |
2025 | ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi); | 2024 | ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi); |
2026 | 2025 | ||
@@ -3363,7 +3362,7 @@ lpfc_els_flush_cmd(struct lpfc_hba * phba) | |||
3363 | els_command = *elscmd; | 3362 | els_command = *elscmd; |
3364 | 3363 | ||
3365 | list_del(&piocb->list); | 3364 | list_del(&piocb->list); |
3366 | pring->txcmplq_cnt--; | 3365 | pring->txq_cnt--; |
3367 | 3366 | ||
3368 | cmd->ulpStatus = IOSTAT_LOCAL_REJECT; | 3367 | cmd->ulpStatus = IOSTAT_LOCAL_REJECT; |
3369 | cmd->un.ulpWord[4] = IOERR_SLI_ABORTED; | 3368 | cmd->un.ulpWord[4] = IOERR_SLI_ABORTED; |
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index c39564e85e94..bd7bbedb941e 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c | |||
@@ -147,11 +147,14 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport) | |||
147 | ndlp->nlp_state, ndlp->nlp_rpi); | 147 | ndlp->nlp_state, ndlp->nlp_rpi); |
148 | } | 148 | } |
149 | 149 | ||
150 | ndlp->rport = NULL; | 150 | if (!(phba->fc_flag & FC_UNLOADING) && |
151 | rdata->pnode = NULL; | 151 | !(ndlp->nlp_flag & NLP_DELAY_TMO) && |
152 | 152 | !(ndlp->nlp_flag & NLP_NPR_2B_DISC)) | |
153 | if (!(phba->fc_flag & FC_UNLOADING)) | ||
154 | lpfc_disc_state_machine(phba, ndlp, NULL, NLP_EVT_DEVICE_RM); | 153 | lpfc_disc_state_machine(phba, ndlp, NULL, NLP_EVT_DEVICE_RM); |
154 | else { | ||
155 | rdata->pnode = NULL; | ||
156 | ndlp->rport = NULL; | ||
157 | } | ||
155 | 158 | ||
156 | return; | 159 | return; |
157 | } | 160 | } |
@@ -1569,16 +1572,6 @@ lpfc_freenode(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) | |||
1569 | 1572 | ||
1570 | lpfc_nlp_list(phba, ndlp, NLP_JUST_DQ); | 1573 | lpfc_nlp_list(phba, ndlp, NLP_JUST_DQ); |
1571 | 1574 | ||
1572 | /* | ||
1573 | * if unloading the driver - just leave the remote port in place. | ||
1574 | * The driver unload will force the attached devices to detach | ||
1575 | * and flush cache's w/o generating flush errors. | ||
1576 | */ | ||
1577 | if ((ndlp->rport) && !(phba->fc_flag & FC_UNLOADING)) { | ||
1578 | lpfc_unregister_remote_port(phba, ndlp); | ||
1579 | ndlp->nlp_sid = NLP_NO_SID; | ||
1580 | } | ||
1581 | |||
1582 | /* cleanup any ndlp on mbox q waiting for reglogin cmpl */ | 1575 | /* cleanup any ndlp on mbox q waiting for reglogin cmpl */ |
1583 | if ((mb = phba->sli.mbox_active)) { | 1576 | if ((mb = phba->sli.mbox_active)) { |
1584 | if ((mb->mb.mbxCommand == MBX_REG_LOGIN64) && | 1577 | if ((mb->mb.mbxCommand == MBX_REG_LOGIN64) && |
@@ -1627,6 +1620,7 @@ lpfc_freenode(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) | |||
1627 | int | 1620 | int |
1628 | lpfc_nlp_remove(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) | 1621 | lpfc_nlp_remove(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) |
1629 | { | 1622 | { |
1623 | struct lpfc_rport_data *rdata; | ||
1630 | 1624 | ||
1631 | if (ndlp->nlp_flag & NLP_DELAY_TMO) { | 1625 | if (ndlp->nlp_flag & NLP_DELAY_TMO) { |
1632 | lpfc_cancel_retry_delay_tmo(phba, ndlp); | 1626 | lpfc_cancel_retry_delay_tmo(phba, ndlp); |
@@ -1638,6 +1632,13 @@ lpfc_nlp_remove(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) | |||
1638 | spin_unlock_irq(phba->host->host_lock); | 1632 | spin_unlock_irq(phba->host->host_lock); |
1639 | } else { | 1633 | } else { |
1640 | lpfc_freenode(phba, ndlp); | 1634 | lpfc_freenode(phba, ndlp); |
1635 | |||
1636 | if ((ndlp->rport) && !(phba->fc_flag & FC_UNLOADING)) { | ||
1637 | rdata = ndlp->rport->dd_data; | ||
1638 | rdata->pnode = NULL; | ||
1639 | ndlp->rport = NULL; | ||
1640 | } | ||
1641 | |||
1641 | mempool_free( ndlp, phba->nlp_mem_pool); | 1642 | mempool_free( ndlp, phba->nlp_mem_pool); |
1642 | } | 1643 | } |
1643 | return 0; | 1644 | return 0; |
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index dcf6106f557a..62677da28c9d 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
@@ -386,8 +386,7 @@ lpfc_config_port_post(struct lpfc_hba * phba) | |||
386 | * Setup the ring 0 (els) timeout handler | 386 | * Setup the ring 0 (els) timeout handler |
387 | */ | 387 | */ |
388 | timeout = phba->fc_ratov << 1; | 388 | timeout = phba->fc_ratov << 1; |
389 | phba->els_tmofunc.expires = jiffies + HZ * timeout; | 389 | mod_timer(&phba->els_tmofunc, jiffies + HZ * timeout); |
390 | add_timer(&phba->els_tmofunc); | ||
391 | 390 | ||
392 | lpfc_init_link(phba, pmb, phba->cfg_topology, phba->cfg_link_speed); | 391 | lpfc_init_link(phba, pmb, phba->cfg_topology, phba->cfg_link_speed); |
393 | pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl; | 392 | pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl; |
@@ -633,7 +632,7 @@ lpfc_handle_latt_free_mbuf: | |||
633 | lpfc_handle_latt_free_mp: | 632 | lpfc_handle_latt_free_mp: |
634 | kfree(mp); | 633 | kfree(mp); |
635 | lpfc_handle_latt_free_pmb: | 634 | lpfc_handle_latt_free_pmb: |
636 | kfree(pmb); | 635 | mempool_free(pmb, phba->mbox_mem_pool); |
637 | lpfc_handle_latt_err_exit: | 636 | lpfc_handle_latt_err_exit: |
638 | /* Enable Link attention interrupts */ | 637 | /* Enable Link attention interrupts */ |
639 | spin_lock_irq(phba->host->host_lock); | 638 | spin_lock_irq(phba->host->host_lock); |
@@ -1174,7 +1173,7 @@ lpfc_hba_init(struct lpfc_hba *phba, uint32_t *hbainit) | |||
1174 | } | 1173 | } |
1175 | 1174 | ||
1176 | static void | 1175 | static void |
1177 | lpfc_cleanup(struct lpfc_hba * phba, uint32_t save_bind) | 1176 | lpfc_cleanup(struct lpfc_hba * phba) |
1178 | { | 1177 | { |
1179 | struct lpfc_nodelist *ndlp, *next_ndlp; | 1178 | struct lpfc_nodelist *ndlp, *next_ndlp; |
1180 | 1179 | ||
@@ -1262,21 +1261,6 @@ lpfc_stop_timer(struct lpfc_hba * phba) | |||
1262 | { | 1261 | { |
1263 | struct lpfc_sli *psli = &phba->sli; | 1262 | struct lpfc_sli *psli = &phba->sli; |
1264 | 1263 | ||
1265 | /* Instead of a timer, this has been converted to a | ||
1266 | * deferred procedding list. | ||
1267 | */ | ||
1268 | while (!list_empty(&phba->freebufList)) { | ||
1269 | |||
1270 | struct lpfc_dmabuf *mp = NULL; | ||
1271 | |||
1272 | list_remove_head((&phba->freebufList), mp, | ||
1273 | struct lpfc_dmabuf, list); | ||
1274 | if (mp) { | ||
1275 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | ||
1276 | kfree(mp); | ||
1277 | } | ||
1278 | } | ||
1279 | |||
1280 | del_timer_sync(&phba->fcp_poll_timer); | 1264 | del_timer_sync(&phba->fcp_poll_timer); |
1281 | del_timer_sync(&phba->fc_estabtmo); | 1265 | del_timer_sync(&phba->fc_estabtmo); |
1282 | del_timer_sync(&phba->fc_disctmo); | 1266 | del_timer_sync(&phba->fc_disctmo); |
@@ -1339,7 +1323,7 @@ lpfc_offline(struct lpfc_hba * phba) | |||
1339 | pring = &psli->ring[i]; | 1323 | pring = &psli->ring[i]; |
1340 | /* The linkdown event takes 30 seconds to timeout. */ | 1324 | /* The linkdown event takes 30 seconds to timeout. */ |
1341 | while (pring->txcmplq_cnt) { | 1325 | while (pring->txcmplq_cnt) { |
1342 | mdelay(10); | 1326 | msleep(10); |
1343 | if (cnt++ > 3000) { | 1327 | if (cnt++ > 3000) { |
1344 | lpfc_printf_log(phba, | 1328 | lpfc_printf_log(phba, |
1345 | KERN_WARNING, LOG_INIT, | 1329 | KERN_WARNING, LOG_INIT, |
@@ -1366,7 +1350,7 @@ lpfc_offline(struct lpfc_hba * phba) | |||
1366 | /* Bring down the SLI Layer and cleanup. The HBA is offline | 1350 | /* Bring down the SLI Layer and cleanup. The HBA is offline |
1367 | now. */ | 1351 | now. */ |
1368 | lpfc_sli_hba_down(phba); | 1352 | lpfc_sli_hba_down(phba); |
1369 | lpfc_cleanup(phba, 1); | 1353 | lpfc_cleanup(phba); |
1370 | spin_lock_irqsave(phba->host->host_lock, iflag); | 1354 | spin_lock_irqsave(phba->host->host_lock, iflag); |
1371 | phba->fc_flag |= FC_OFFLINE_MODE; | 1355 | phba->fc_flag |= FC_OFFLINE_MODE; |
1372 | spin_unlock_irqrestore(phba->host->host_lock, iflag); | 1356 | spin_unlock_irqrestore(phba->host->host_lock, iflag); |
@@ -1445,9 +1429,6 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) | |||
1445 | goto out_put_host; | 1429 | goto out_put_host; |
1446 | 1430 | ||
1447 | host->unique_id = phba->brd_no; | 1431 | host->unique_id = phba->brd_no; |
1448 | INIT_LIST_HEAD(&phba->ctrspbuflist); | ||
1449 | INIT_LIST_HEAD(&phba->rnidrspbuflist); | ||
1450 | INIT_LIST_HEAD(&phba->freebufList); | ||
1451 | 1432 | ||
1452 | /* Initialize timers used by driver */ | 1433 | /* Initialize timers used by driver */ |
1453 | init_timer(&phba->fc_estabtmo); | 1434 | init_timer(&phba->fc_estabtmo); |
@@ -1773,7 +1754,7 @@ lpfc_pci_remove_one(struct pci_dev *pdev) | |||
1773 | free_irq(phba->pcidev->irq, phba); | 1754 | free_irq(phba->pcidev->irq, phba); |
1774 | pci_disable_msi(phba->pcidev); | 1755 | pci_disable_msi(phba->pcidev); |
1775 | 1756 | ||
1776 | lpfc_cleanup(phba, 0); | 1757 | lpfc_cleanup(phba); |
1777 | lpfc_stop_timer(phba); | 1758 | lpfc_stop_timer(phba); |
1778 | phba->work_hba_events = 0; | 1759 | phba->work_hba_events = 0; |
1779 | 1760 | ||
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index c3e68e0d8f74..28dbd6be72ee 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c | |||
@@ -146,6 +146,10 @@ lpfc_get_scsi_buf(struct lpfc_hba * phba) | |||
146 | 146 | ||
147 | spin_lock_irqsave(&phba->scsi_buf_list_lock, iflag); | 147 | spin_lock_irqsave(&phba->scsi_buf_list_lock, iflag); |
148 | list_remove_head(scsi_buf_list, lpfc_cmd, struct lpfc_scsi_buf, list); | 148 | list_remove_head(scsi_buf_list, lpfc_cmd, struct lpfc_scsi_buf, list); |
149 | if (lpfc_cmd) { | ||
150 | lpfc_cmd->seg_cnt = 0; | ||
151 | lpfc_cmd->nonsg_phys = 0; | ||
152 | } | ||
149 | spin_unlock_irqrestore(&phba->scsi_buf_list_lock, iflag); | 153 | spin_unlock_irqrestore(&phba->scsi_buf_list_lock, iflag); |
150 | return lpfc_cmd; | 154 | return lpfc_cmd; |
151 | } | 155 | } |
@@ -466,10 +470,10 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, | |||
466 | 470 | ||
467 | result = cmd->result; | 471 | result = cmd->result; |
468 | sdev = cmd->device; | 472 | sdev = cmd->device; |
473 | lpfc_scsi_unprep_dma_buf(phba, lpfc_cmd); | ||
469 | cmd->scsi_done(cmd); | 474 | cmd->scsi_done(cmd); |
470 | 475 | ||
471 | if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) { | 476 | if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) { |
472 | lpfc_scsi_unprep_dma_buf(phba, lpfc_cmd); | ||
473 | lpfc_release_scsi_buf(phba, lpfc_cmd); | 477 | lpfc_release_scsi_buf(phba, lpfc_cmd); |
474 | return; | 478 | return; |
475 | } | 479 | } |
@@ -527,7 +531,6 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, | |||
527 | } | 531 | } |
528 | } | 532 | } |
529 | 533 | ||
530 | lpfc_scsi_unprep_dma_buf(phba, lpfc_cmd); | ||
531 | lpfc_release_scsi_buf(phba, lpfc_cmd); | 534 | lpfc_release_scsi_buf(phba, lpfc_cmd); |
532 | } | 535 | } |
533 | 536 | ||
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 9fb6960a8ada..54a8f4d3db13 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c | |||
@@ -693,25 +693,8 @@ lpfc_sli_handle_mb_event(struct lpfc_hba * phba) | |||
693 | } else { | 693 | } else { |
694 | spin_unlock_irq(phba->host->host_lock); | 694 | spin_unlock_irq(phba->host->host_lock); |
695 | /* Turn on IOCB processing */ | 695 | /* Turn on IOCB processing */ |
696 | for (i = 0; i < phba->sli.num_rings; i++) { | 696 | for (i = 0; i < phba->sli.num_rings; i++) |
697 | lpfc_sli_turn_on_ring(phba, i); | 697 | lpfc_sli_turn_on_ring(phba, i); |
698 | } | ||
699 | |||
700 | /* Free any lpfc_dmabuf's waiting for mbox cmd cmpls */ | ||
701 | while (!list_empty(&phba->freebufList)) { | ||
702 | struct lpfc_dmabuf *mp; | ||
703 | |||
704 | mp = NULL; | ||
705 | list_remove_head((&phba->freebufList), | ||
706 | mp, | ||
707 | struct lpfc_dmabuf, | ||
708 | list); | ||
709 | if (mp) { | ||
710 | lpfc_mbuf_free(phba, mp->virt, | ||
711 | mp->phys); | ||
712 | kfree(mp); | ||
713 | } | ||
714 | } | ||
715 | } | 698 | } |
716 | 699 | ||
717 | } while (process_next); | 700 | } while (process_next); |
@@ -1985,42 +1968,6 @@ lpfc_sli_hba_setup_exit: | |||
1985 | return rc; | 1968 | return rc; |
1986 | } | 1969 | } |
1987 | 1970 | ||
1988 | static void | ||
1989 | lpfc_mbox_abort(struct lpfc_hba * phba) | ||
1990 | { | ||
1991 | LPFC_MBOXQ_t *pmbox; | ||
1992 | MAILBOX_t *mb; | ||
1993 | |||
1994 | if (phba->sli.mbox_active) { | ||
1995 | del_timer_sync(&phba->sli.mbox_tmo); | ||
1996 | phba->work_hba_events &= ~WORKER_MBOX_TMO; | ||
1997 | pmbox = phba->sli.mbox_active; | ||
1998 | mb = &pmbox->mb; | ||
1999 | phba->sli.mbox_active = NULL; | ||
2000 | if (pmbox->mbox_cmpl) { | ||
2001 | mb->mbxStatus = MBX_NOT_FINISHED; | ||
2002 | (pmbox->mbox_cmpl) (phba, pmbox); | ||
2003 | } | ||
2004 | phba->sli.sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; | ||
2005 | } | ||
2006 | |||
2007 | /* Abort all the non active mailbox commands. */ | ||
2008 | spin_lock_irq(phba->host->host_lock); | ||
2009 | pmbox = lpfc_mbox_get(phba); | ||
2010 | while (pmbox) { | ||
2011 | mb = &pmbox->mb; | ||
2012 | if (pmbox->mbox_cmpl) { | ||
2013 | mb->mbxStatus = MBX_NOT_FINISHED; | ||
2014 | spin_unlock_irq(phba->host->host_lock); | ||
2015 | (pmbox->mbox_cmpl) (phba, pmbox); | ||
2016 | spin_lock_irq(phba->host->host_lock); | ||
2017 | } | ||
2018 | pmbox = lpfc_mbox_get(phba); | ||
2019 | } | ||
2020 | spin_unlock_irq(phba->host->host_lock); | ||
2021 | return; | ||
2022 | } | ||
2023 | |||
2024 | /*! lpfc_mbox_timeout | 1971 | /*! lpfc_mbox_timeout |
2025 | * | 1972 | * |
2026 | * \pre | 1973 | * \pre |
@@ -2055,6 +2002,8 @@ lpfc_mbox_timeout_handler(struct lpfc_hba *phba) | |||
2055 | { | 2002 | { |
2056 | LPFC_MBOXQ_t *pmbox; | 2003 | LPFC_MBOXQ_t *pmbox; |
2057 | MAILBOX_t *mb; | 2004 | MAILBOX_t *mb; |
2005 | struct lpfc_sli *psli = &phba->sli; | ||
2006 | struct lpfc_sli_ring *pring; | ||
2058 | 2007 | ||
2059 | spin_lock_irq(phba->host->host_lock); | 2008 | spin_lock_irq(phba->host->host_lock); |
2060 | if (!(phba->work_hba_events & WORKER_MBOX_TMO)) { | 2009 | if (!(phba->work_hba_events & WORKER_MBOX_TMO)) { |
@@ -2062,8 +2011,6 @@ lpfc_mbox_timeout_handler(struct lpfc_hba *phba) | |||
2062 | return; | 2011 | return; |
2063 | } | 2012 | } |
2064 | 2013 | ||
2065 | phba->work_hba_events &= ~WORKER_MBOX_TMO; | ||
2066 | |||
2067 | pmbox = phba->sli.mbox_active; | 2014 | pmbox = phba->sli.mbox_active; |
2068 | mb = &pmbox->mb; | 2015 | mb = &pmbox->mb; |
2069 | 2016 | ||
@@ -2078,17 +2025,32 @@ lpfc_mbox_timeout_handler(struct lpfc_hba *phba) | |||
2078 | phba->sli.sli_flag, | 2025 | phba->sli.sli_flag, |
2079 | phba->sli.mbox_active); | 2026 | phba->sli.mbox_active); |
2080 | 2027 | ||
2081 | phba->sli.mbox_active = NULL; | 2028 | /* Setting state unknown so lpfc_sli_abort_iocb_ring |
2082 | if (pmbox->mbox_cmpl) { | 2029 | * would get IOCB_ERROR from lpfc_sli_issue_iocb, allowing |
2083 | mb->mbxStatus = MBX_NOT_FINISHED; | 2030 | * it to fail all oustanding SCSI IO. |
2084 | spin_unlock_irq(phba->host->host_lock); | 2031 | */ |
2085 | (pmbox->mbox_cmpl) (phba, pmbox); | 2032 | phba->hba_state = LPFC_STATE_UNKNOWN; |
2086 | spin_lock_irq(phba->host->host_lock); | 2033 | phba->work_hba_events &= ~WORKER_MBOX_TMO; |
2087 | } | 2034 | phba->fc_flag |= FC_ESTABLISH_LINK; |
2088 | phba->sli.sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; | 2035 | psli->sli_flag &= ~LPFC_SLI2_ACTIVE; |
2089 | |||
2090 | spin_unlock_irq(phba->host->host_lock); | 2036 | spin_unlock_irq(phba->host->host_lock); |
2091 | lpfc_mbox_abort(phba); | 2037 | |
2038 | pring = &psli->ring[psli->fcp_ring]; | ||
2039 | lpfc_sli_abort_iocb_ring(phba, pring); | ||
2040 | |||
2041 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI, | ||
2042 | "%d:0316 Resetting board due to mailbox timeout\n", | ||
2043 | phba->brd_no); | ||
2044 | /* | ||
2045 | * lpfc_offline calls lpfc_sli_hba_down which will clean up | ||
2046 | * on oustanding mailbox commands. | ||
2047 | */ | ||
2048 | lpfc_offline_prep(phba); | ||
2049 | lpfc_offline(phba); | ||
2050 | lpfc_sli_brdrestart(phba); | ||
2051 | if (lpfc_online(phba) == 0) /* Initialize the HBA */ | ||
2052 | mod_timer(&phba->fc_estabtmo, jiffies + HZ * 60); | ||
2053 | lpfc_unblock_mgmt_io(phba); | ||
2092 | return; | 2054 | return; |
2093 | } | 2055 | } |
2094 | 2056 | ||
@@ -2320,9 +2282,7 @@ lpfc_sli_issue_mbox(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmbox, uint32_t flag) | |||
2320 | spin_unlock_irqrestore(phba->host->host_lock, | 2282 | spin_unlock_irqrestore(phba->host->host_lock, |
2321 | drvr_flag); | 2283 | drvr_flag); |
2322 | 2284 | ||
2323 | /* Can be in interrupt context, do not sleep */ | 2285 | msleep(1); |
2324 | /* (or might be called with interrupts disabled) */ | ||
2325 | mdelay(1); | ||
2326 | 2286 | ||
2327 | spin_lock_irqsave(phba->host->host_lock, drvr_flag); | 2287 | spin_lock_irqsave(phba->host->host_lock, drvr_flag); |
2328 | 2288 | ||