diff options
author | James Smart <james.smart@emulex.com> | 2012-06-12 13:54:36 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2012-07-20 03:58:28 -0400 |
commit | 618a5230b8fa62bc7901b8b754b4379b3fcfa0f9 (patch) | |
tree | da409c55a30e8d283f31bb8594df3da6e395a002 | |
parent | bbeb79b90e806da2e2338bd8d89c6fa8a1333357 (diff) |
[SCSI] lpfc 8.3.32: Correct provisioning change failure on local function
Fixed system held-up when performing resource provsion through same PCI
function
Signed-off-by: Alex Iannicelli <alex.iannicelli@emulex.com>
Signed-off-by: James Smart <james.smart@emulex.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
-rw-r--r-- | drivers/scsi/lpfc/lpfc.h | 4 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_crtn.h | 4 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hbadisc.c | 2 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_init.c | 122 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_scsi.c | 2 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.c | 10 |
6 files changed, 98 insertions, 46 deletions
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index e5da6da20f8a..a65c05a8d488 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h | |||
@@ -96,6 +96,10 @@ struct lpfc_sli2_slim; | |||
96 | /* queue dump line buffer size */ | 96 | /* queue dump line buffer size */ |
97 | #define LPFC_LBUF_SZ 128 | 97 | #define LPFC_LBUF_SZ 128 |
98 | 98 | ||
99 | /* mailbox system shutdown options */ | ||
100 | #define LPFC_MBX_NO_WAIT 0 | ||
101 | #define LPFC_MBX_WAIT 1 | ||
102 | |||
99 | enum lpfc_polling_flags { | 103 | enum lpfc_polling_flags { |
100 | ENABLE_FCP_RING_POLLING = 0x1, | 104 | ENABLE_FCP_RING_POLLING = 0x1, |
101 | DISABLE_FCP_RING_INT = 0x2 | 105 | DISABLE_FCP_RING_INT = 0x2 |
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index 9b2a16f3bc79..8a2a514a2553 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h | |||
@@ -183,7 +183,7 @@ int lpfc_post_buffer(struct lpfc_hba *, struct lpfc_sli_ring *, int); | |||
183 | void lpfc_decode_firmware_rev(struct lpfc_hba *, char *, int); | 183 | void lpfc_decode_firmware_rev(struct lpfc_hba *, char *, int); |
184 | int lpfc_online(struct lpfc_hba *); | 184 | int lpfc_online(struct lpfc_hba *); |
185 | void lpfc_unblock_mgmt_io(struct lpfc_hba *); | 185 | void lpfc_unblock_mgmt_io(struct lpfc_hba *); |
186 | void lpfc_offline_prep(struct lpfc_hba *); | 186 | void lpfc_offline_prep(struct lpfc_hba *, int); |
187 | void lpfc_offline(struct lpfc_hba *); | 187 | void lpfc_offline(struct lpfc_hba *); |
188 | void lpfc_reset_hba(struct lpfc_hba *); | 188 | void lpfc_reset_hba(struct lpfc_hba *); |
189 | 189 | ||
@@ -273,7 +273,7 @@ int lpfc_sli_host_down(struct lpfc_vport *); | |||
273 | int lpfc_sli_hba_down(struct lpfc_hba *); | 273 | int lpfc_sli_hba_down(struct lpfc_hba *); |
274 | int lpfc_sli_issue_mbox(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t); | 274 | int lpfc_sli_issue_mbox(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t); |
275 | int lpfc_sli_handle_mb_event(struct lpfc_hba *); | 275 | int lpfc_sli_handle_mb_event(struct lpfc_hba *); |
276 | void lpfc_sli_mbox_sys_shutdown(struct lpfc_hba *); | 276 | void lpfc_sli_mbox_sys_shutdown(struct lpfc_hba *, int); |
277 | int lpfc_sli_check_eratt(struct lpfc_hba *); | 277 | int lpfc_sli_check_eratt(struct lpfc_hba *); |
278 | void lpfc_sli_handle_slow_ring_event(struct lpfc_hba *, | 278 | void lpfc_sli_handle_slow_ring_event(struct lpfc_hba *, |
279 | struct lpfc_sli_ring *, uint32_t); | 279 | struct lpfc_sli_ring *, uint32_t); |
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 5bb269e224f6..9b4f92941dce 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c | |||
@@ -530,7 +530,7 @@ lpfc_work_list_done(struct lpfc_hba *phba) | |||
530 | break; | 530 | break; |
531 | case LPFC_EVT_OFFLINE_PREP: | 531 | case LPFC_EVT_OFFLINE_PREP: |
532 | if (phba->link_state >= LPFC_LINK_DOWN) | 532 | if (phba->link_state >= LPFC_LINK_DOWN) |
533 | lpfc_offline_prep(phba); | 533 | lpfc_offline_prep(phba, LPFC_MBX_WAIT); |
534 | *(int *)(evtp->evt_arg1) = 0; | 534 | *(int *)(evtp->evt_arg1) = 0; |
535 | complete((struct completion *)(evtp->evt_arg2)); | 535 | complete((struct completion *)(evtp->evt_arg2)); |
536 | break; | 536 | break; |
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index a79e2c21c5e4..374c102643fe 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
@@ -73,6 +73,8 @@ static int lpfc_hba_down_post_s4(struct lpfc_hba *phba); | |||
73 | static int lpfc_sli4_cq_event_pool_create(struct lpfc_hba *); | 73 | static int lpfc_sli4_cq_event_pool_create(struct lpfc_hba *); |
74 | static void lpfc_sli4_cq_event_pool_destroy(struct lpfc_hba *); | 74 | static void lpfc_sli4_cq_event_pool_destroy(struct lpfc_hba *); |
75 | static void lpfc_sli4_cq_event_release_all(struct lpfc_hba *); | 75 | static void lpfc_sli4_cq_event_release_all(struct lpfc_hba *); |
76 | static void lpfc_sli4_disable_intr(struct lpfc_hba *); | ||
77 | static uint32_t lpfc_sli4_enable_intr(struct lpfc_hba *, uint32_t); | ||
76 | 78 | ||
77 | static struct scsi_transport_template *lpfc_transport_template = NULL; | 79 | static struct scsi_transport_template *lpfc_transport_template = NULL; |
78 | static struct scsi_transport_template *lpfc_vport_transport_template = NULL; | 80 | static struct scsi_transport_template *lpfc_vport_transport_template = NULL; |
@@ -1169,7 +1171,7 @@ lpfc_offline_eratt(struct lpfc_hba *phba) | |||
1169 | spin_lock_irq(&phba->hbalock); | 1171 | spin_lock_irq(&phba->hbalock); |
1170 | psli->sli_flag &= ~LPFC_SLI_ACTIVE; | 1172 | psli->sli_flag &= ~LPFC_SLI_ACTIVE; |
1171 | spin_unlock_irq(&phba->hbalock); | 1173 | spin_unlock_irq(&phba->hbalock); |
1172 | lpfc_offline_prep(phba); | 1174 | lpfc_offline_prep(phba, LPFC_MBX_NO_WAIT); |
1173 | 1175 | ||
1174 | lpfc_offline(phba); | 1176 | lpfc_offline(phba); |
1175 | lpfc_reset_barrier(phba); | 1177 | lpfc_reset_barrier(phba); |
@@ -1193,7 +1195,7 @@ lpfc_offline_eratt(struct lpfc_hba *phba) | |||
1193 | static void | 1195 | static void |
1194 | lpfc_sli4_offline_eratt(struct lpfc_hba *phba) | 1196 | lpfc_sli4_offline_eratt(struct lpfc_hba *phba) |
1195 | { | 1197 | { |
1196 | lpfc_offline_prep(phba); | 1198 | lpfc_offline_prep(phba, LPFC_MBX_NO_WAIT); |
1197 | lpfc_offline(phba); | 1199 | lpfc_offline(phba); |
1198 | lpfc_sli4_brdreset(phba); | 1200 | lpfc_sli4_brdreset(phba); |
1199 | lpfc_hba_down_post(phba); | 1201 | lpfc_hba_down_post(phba); |
@@ -1251,7 +1253,7 @@ lpfc_handle_deferred_eratt(struct lpfc_hba *phba) | |||
1251 | * There was a firmware error. Take the hba offline and then | 1253 | * There was a firmware error. Take the hba offline and then |
1252 | * attempt to restart it. | 1254 | * attempt to restart it. |
1253 | */ | 1255 | */ |
1254 | lpfc_offline_prep(phba); | 1256 | lpfc_offline_prep(phba, LPFC_MBX_WAIT); |
1255 | lpfc_offline(phba); | 1257 | lpfc_offline(phba); |
1256 | 1258 | ||
1257 | /* Wait for the ER1 bit to clear.*/ | 1259 | /* Wait for the ER1 bit to clear.*/ |
@@ -1372,7 +1374,7 @@ lpfc_handle_eratt_s3(struct lpfc_hba *phba) | |||
1372 | * There was a firmware error. Take the hba offline and then | 1374 | * There was a firmware error. Take the hba offline and then |
1373 | * attempt to restart it. | 1375 | * attempt to restart it. |
1374 | */ | 1376 | */ |
1375 | lpfc_offline_prep(phba); | 1377 | lpfc_offline_prep(phba, LPFC_MBX_NO_WAIT); |
1376 | lpfc_offline(phba); | 1378 | lpfc_offline(phba); |
1377 | lpfc_sli_brdrestart(phba); | 1379 | lpfc_sli_brdrestart(phba); |
1378 | if (lpfc_online(phba) == 0) { /* Initialize the HBA */ | 1380 | if (lpfc_online(phba) == 0) { /* Initialize the HBA */ |
@@ -1428,6 +1430,54 @@ lpfc_handle_eratt_s3(struct lpfc_hba *phba) | |||
1428 | } | 1430 | } |
1429 | 1431 | ||
1430 | /** | 1432 | /** |
1433 | * lpfc_sli4_port_sta_fn_reset - The SLI4 function reset due to port status reg | ||
1434 | * @phba: pointer to lpfc hba data structure. | ||
1435 | * @mbx_action: flag for mailbox shutdown action. | ||
1436 | * | ||
1437 | * This routine is invoked to perform an SLI4 port PCI function reset in | ||
1438 | * response to port status register polling attention. It waits for port | ||
1439 | * status register (ERR, RDY, RN) bits before proceeding with function reset. | ||
1440 | * During this process, interrupt vectors are freed and later requested | ||
1441 | * for handling possible port resource change. | ||
1442 | **/ | ||
1443 | static int | ||
1444 | lpfc_sli4_port_sta_fn_reset(struct lpfc_hba *phba, int mbx_action) | ||
1445 | { | ||
1446 | int rc; | ||
1447 | uint32_t intr_mode; | ||
1448 | |||
1449 | /* | ||
1450 | * On error status condition, driver need to wait for port | ||
1451 | * ready before performing reset. | ||
1452 | */ | ||
1453 | rc = lpfc_sli4_pdev_status_reg_wait(phba); | ||
1454 | if (!rc) { | ||
1455 | /* need reset: attempt for port recovery */ | ||
1456 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
1457 | "2887 Reset Needed: Attempting Port " | ||
1458 | "Recovery...\n"); | ||
1459 | lpfc_offline_prep(phba, mbx_action); | ||
1460 | lpfc_offline(phba); | ||
1461 | /* release interrupt for possible resource change */ | ||
1462 | lpfc_sli4_disable_intr(phba); | ||
1463 | lpfc_sli_brdrestart(phba); | ||
1464 | /* request and enable interrupt */ | ||
1465 | intr_mode = lpfc_sli4_enable_intr(phba, phba->intr_mode); | ||
1466 | if (intr_mode == LPFC_INTR_ERROR) { | ||
1467 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
1468 | "3175 Failed to enable interrupt\n"); | ||
1469 | return -EIO; | ||
1470 | } else { | ||
1471 | phba->intr_mode = intr_mode; | ||
1472 | } | ||
1473 | rc = lpfc_online(phba); | ||
1474 | if (rc == 0) | ||
1475 | lpfc_unblock_mgmt_io(phba); | ||
1476 | } | ||
1477 | return rc; | ||
1478 | } | ||
1479 | |||
1480 | /** | ||
1431 | * lpfc_handle_eratt_s4 - The SLI4 HBA hardware error handler | 1481 | * lpfc_handle_eratt_s4 - The SLI4 HBA hardware error handler |
1432 | * @phba: pointer to lpfc hba data structure. | 1482 | * @phba: pointer to lpfc hba data structure. |
1433 | * | 1483 | * |
@@ -1506,30 +1556,18 @@ lpfc_handle_eratt_s4(struct lpfc_hba *phba) | |||
1506 | reg_err2 == SLIPORT_ERR2_REG_FUNC_PROVISON) | 1556 | reg_err2 == SLIPORT_ERR2_REG_FUNC_PROVISON) |
1507 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 1557 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
1508 | "3145 Port Down: Provisioning\n"); | 1558 | "3145 Port Down: Provisioning\n"); |
1509 | /* | 1559 | |
1510 | * On error status condition, driver need to wait for port | 1560 | /* Check port status register for function reset */ |
1511 | * ready before performing reset. | 1561 | rc = lpfc_sli4_port_sta_fn_reset(phba, LPFC_MBX_NO_WAIT); |
1512 | */ | 1562 | if (rc == 0) { |
1513 | rc = lpfc_sli4_pdev_status_reg_wait(phba); | 1563 | /* don't report event on forced debug dump */ |
1514 | if (!rc) { | 1564 | if (reg_err1 == SLIPORT_ERR1_REG_ERR_CODE_2 && |
1515 | /* need reset: attempt for port recovery */ | 1565 | reg_err2 == SLIPORT_ERR2_REG_FORCED_DUMP) |
1516 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 1566 | return; |
1517 | "2887 Reset Needed: Attempting Port " | 1567 | else |
1518 | "Recovery...\n"); | 1568 | break; |
1519 | lpfc_offline_prep(phba); | ||
1520 | lpfc_offline(phba); | ||
1521 | lpfc_sli_brdrestart(phba); | ||
1522 | if (lpfc_online(phba) == 0) { | ||
1523 | lpfc_unblock_mgmt_io(phba); | ||
1524 | /* don't report event on forced debug dump */ | ||
1525 | if (reg_err1 == SLIPORT_ERR1_REG_ERR_CODE_2 && | ||
1526 | reg_err2 == SLIPORT_ERR2_REG_FORCED_DUMP) | ||
1527 | return; | ||
1528 | else | ||
1529 | break; | ||
1530 | } | ||
1531 | /* fall through for not able to recover */ | ||
1532 | } | 1569 | } |
1570 | /* fall through for not able to recover */ | ||
1533 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 1571 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
1534 | "3152 Unrecoverable error, bring the port " | 1572 | "3152 Unrecoverable error, bring the port " |
1535 | "offline\n"); | 1573 | "offline\n"); |
@@ -2494,15 +2532,19 @@ lpfc_stop_hba_timers(struct lpfc_hba *phba) | |||
2494 | * driver prepares the HBA interface for online or offline. | 2532 | * driver prepares the HBA interface for online or offline. |
2495 | **/ | 2533 | **/ |
2496 | static void | 2534 | static void |
2497 | lpfc_block_mgmt_io(struct lpfc_hba * phba) | 2535 | lpfc_block_mgmt_io(struct lpfc_hba *phba, int mbx_action) |
2498 | { | 2536 | { |
2499 | unsigned long iflag; | 2537 | unsigned long iflag; |
2500 | uint8_t actcmd = MBX_HEARTBEAT; | 2538 | uint8_t actcmd = MBX_HEARTBEAT; |
2501 | unsigned long timeout; | 2539 | unsigned long timeout; |
2502 | 2540 | ||
2503 | timeout = msecs_to_jiffies(LPFC_MBOX_TMO * 1000) + jiffies; | ||
2504 | spin_lock_irqsave(&phba->hbalock, iflag); | 2541 | spin_lock_irqsave(&phba->hbalock, iflag); |
2505 | phba->sli.sli_flag |= LPFC_BLOCK_MGMT_IO; | 2542 | phba->sli.sli_flag |= LPFC_BLOCK_MGMT_IO; |
2543 | spin_unlock_irqrestore(&phba->hbalock, iflag); | ||
2544 | if (mbx_action == LPFC_MBX_NO_WAIT) | ||
2545 | return; | ||
2546 | timeout = msecs_to_jiffies(LPFC_MBOX_TMO * 1000) + jiffies; | ||
2547 | spin_lock_irqsave(&phba->hbalock, iflag); | ||
2506 | if (phba->sli.mbox_active) { | 2548 | if (phba->sli.mbox_active) { |
2507 | actcmd = phba->sli.mbox_active->u.mb.mbxCommand; | 2549 | actcmd = phba->sli.mbox_active->u.mb.mbxCommand; |
2508 | /* Determine how long we might wait for the active mailbox | 2550 | /* Determine how long we might wait for the active mailbox |
@@ -2592,7 +2634,7 @@ lpfc_online(struct lpfc_hba *phba) | |||
2592 | lpfc_printf_log(phba, KERN_WARNING, LOG_INIT, | 2634 | lpfc_printf_log(phba, KERN_WARNING, LOG_INIT, |
2593 | "0458 Bring Adapter online\n"); | 2635 | "0458 Bring Adapter online\n"); |
2594 | 2636 | ||
2595 | lpfc_block_mgmt_io(phba); | 2637 | lpfc_block_mgmt_io(phba, LPFC_MBX_WAIT); |
2596 | 2638 | ||
2597 | if (!lpfc_sli_queue_setup(phba)) { | 2639 | if (!lpfc_sli_queue_setup(phba)) { |
2598 | lpfc_unblock_mgmt_io(phba); | 2640 | lpfc_unblock_mgmt_io(phba); |
@@ -2660,7 +2702,7 @@ lpfc_unblock_mgmt_io(struct lpfc_hba * phba) | |||
2660 | * queue to make it ready to be brought offline. | 2702 | * queue to make it ready to be brought offline. |
2661 | **/ | 2703 | **/ |
2662 | void | 2704 | void |
2663 | lpfc_offline_prep(struct lpfc_hba * phba) | 2705 | lpfc_offline_prep(struct lpfc_hba *phba, int mbx_action) |
2664 | { | 2706 | { |
2665 | struct lpfc_vport *vport = phba->pport; | 2707 | struct lpfc_vport *vport = phba->pport; |
2666 | struct lpfc_nodelist *ndlp, *next_ndlp; | 2708 | struct lpfc_nodelist *ndlp, *next_ndlp; |
@@ -2671,7 +2713,7 @@ lpfc_offline_prep(struct lpfc_hba * phba) | |||
2671 | if (vport->fc_flag & FC_OFFLINE_MODE) | 2713 | if (vport->fc_flag & FC_OFFLINE_MODE) |
2672 | return; | 2714 | return; |
2673 | 2715 | ||
2674 | lpfc_block_mgmt_io(phba); | 2716 | lpfc_block_mgmt_io(phba, mbx_action); |
2675 | 2717 | ||
2676 | lpfc_linkdown(phba); | 2718 | lpfc_linkdown(phba); |
2677 | 2719 | ||
@@ -2718,7 +2760,7 @@ lpfc_offline_prep(struct lpfc_hba * phba) | |||
2718 | } | 2760 | } |
2719 | lpfc_destroy_vport_work_array(phba, vports); | 2761 | lpfc_destroy_vport_work_array(phba, vports); |
2720 | 2762 | ||
2721 | lpfc_sli_mbox_sys_shutdown(phba); | 2763 | lpfc_sli_mbox_sys_shutdown(phba, mbx_action); |
2722 | } | 2764 | } |
2723 | 2765 | ||
2724 | /** | 2766 | /** |
@@ -4312,7 +4354,7 @@ lpfc_reset_hba(struct lpfc_hba *phba) | |||
4312 | phba->link_state = LPFC_HBA_ERROR; | 4354 | phba->link_state = LPFC_HBA_ERROR; |
4313 | return; | 4355 | return; |
4314 | } | 4356 | } |
4315 | lpfc_offline_prep(phba); | 4357 | lpfc_offline_prep(phba, LPFC_MBX_WAIT); |
4316 | lpfc_offline(phba); | 4358 | lpfc_offline(phba); |
4317 | lpfc_sli_brdrestart(phba); | 4359 | lpfc_sli_brdrestart(phba); |
4318 | lpfc_online(phba); | 4360 | lpfc_online(phba); |
@@ -8890,7 +8932,7 @@ lpfc_pci_suspend_one_s3(struct pci_dev *pdev, pm_message_t msg) | |||
8890 | "0473 PCI device Power Management suspend.\n"); | 8932 | "0473 PCI device Power Management suspend.\n"); |
8891 | 8933 | ||
8892 | /* Bring down the device */ | 8934 | /* Bring down the device */ |
8893 | lpfc_offline_prep(phba); | 8935 | lpfc_offline_prep(phba, LPFC_MBX_WAIT); |
8894 | lpfc_offline(phba); | 8936 | lpfc_offline(phba); |
8895 | kthread_stop(phba->worker_thread); | 8937 | kthread_stop(phba->worker_thread); |
8896 | 8938 | ||
@@ -9016,7 +9058,7 @@ lpfc_sli_prep_dev_for_reset(struct lpfc_hba *phba) | |||
9016 | "2710 PCI channel disable preparing for reset\n"); | 9058 | "2710 PCI channel disable preparing for reset\n"); |
9017 | 9059 | ||
9018 | /* Block any management I/Os to the device */ | 9060 | /* Block any management I/Os to the device */ |
9019 | lpfc_block_mgmt_io(phba); | 9061 | lpfc_block_mgmt_io(phba, LPFC_MBX_WAIT); |
9020 | 9062 | ||
9021 | /* Block all SCSI devices' I/Os on the host */ | 9063 | /* Block all SCSI devices' I/Os on the host */ |
9022 | lpfc_scsi_dev_block(phba); | 9064 | lpfc_scsi_dev_block(phba); |
@@ -9160,7 +9202,7 @@ lpfc_io_slot_reset_s3(struct pci_dev *pdev) | |||
9160 | phba->intr_mode = intr_mode; | 9202 | phba->intr_mode = intr_mode; |
9161 | 9203 | ||
9162 | /* Take device offline, it will perform cleanup */ | 9204 | /* Take device offline, it will perform cleanup */ |
9163 | lpfc_offline_prep(phba); | 9205 | lpfc_offline_prep(phba, LPFC_MBX_WAIT); |
9164 | lpfc_offline(phba); | 9206 | lpfc_offline(phba); |
9165 | lpfc_sli_brdrestart(phba); | 9207 | lpfc_sli_brdrestart(phba); |
9166 | 9208 | ||
@@ -9634,7 +9676,7 @@ lpfc_pci_suspend_one_s4(struct pci_dev *pdev, pm_message_t msg) | |||
9634 | "2843 PCI device Power Management suspend.\n"); | 9676 | "2843 PCI device Power Management suspend.\n"); |
9635 | 9677 | ||
9636 | /* Bring down the device */ | 9678 | /* Bring down the device */ |
9637 | lpfc_offline_prep(phba); | 9679 | lpfc_offline_prep(phba, LPFC_MBX_WAIT); |
9638 | lpfc_offline(phba); | 9680 | lpfc_offline(phba); |
9639 | kthread_stop(phba->worker_thread); | 9681 | kthread_stop(phba->worker_thread); |
9640 | 9682 | ||
@@ -9760,7 +9802,7 @@ lpfc_sli4_prep_dev_for_reset(struct lpfc_hba *phba) | |||
9760 | "2826 PCI channel disable preparing for reset\n"); | 9802 | "2826 PCI channel disable preparing for reset\n"); |
9761 | 9803 | ||
9762 | /* Block any management I/Os to the device */ | 9804 | /* Block any management I/Os to the device */ |
9763 | lpfc_block_mgmt_io(phba); | 9805 | lpfc_block_mgmt_io(phba, LPFC_MBX_NO_WAIT); |
9764 | 9806 | ||
9765 | /* Block all SCSI devices' I/Os on the host */ | 9807 | /* Block all SCSI devices' I/Os on the host */ |
9766 | lpfc_scsi_dev_block(phba); | 9808 | lpfc_scsi_dev_block(phba); |
@@ -9933,7 +9975,7 @@ lpfc_io_resume_s4(struct pci_dev *pdev) | |||
9933 | */ | 9975 | */ |
9934 | if (!(phba->sli.sli_flag & LPFC_SLI_ACTIVE)) { | 9976 | if (!(phba->sli.sli_flag & LPFC_SLI_ACTIVE)) { |
9935 | /* Perform device reset */ | 9977 | /* Perform device reset */ |
9936 | lpfc_offline_prep(phba); | 9978 | lpfc_offline_prep(phba, LPFC_MBX_WAIT); |
9937 | lpfc_offline(phba); | 9979 | lpfc_offline(phba); |
9938 | lpfc_sli_brdrestart(phba); | 9980 | lpfc_sli_brdrestart(phba); |
9939 | /* Bring the device back online */ | 9981 | /* Bring the device back online */ |
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 66e09069f281..d2ef8f4e9254 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c | |||
@@ -4982,7 +4982,7 @@ lpfc_host_reset_handler(struct scsi_cmnd *cmnd) | |||
4982 | struct lpfc_hba *phba = vport->phba; | 4982 | struct lpfc_hba *phba = vport->phba; |
4983 | int rc, ret = SUCCESS; | 4983 | int rc, ret = SUCCESS; |
4984 | 4984 | ||
4985 | lpfc_offline_prep(phba); | 4985 | lpfc_offline_prep(phba, LPFC_MBX_WAIT); |
4986 | lpfc_offline(phba); | 4986 | lpfc_offline(phba); |
4987 | rc = lpfc_sli_brdrestart(phba); | 4987 | rc = lpfc_sli_brdrestart(phba); |
4988 | if (rc) | 4988 | if (rc) |
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 3e4f8eaa1fb8..3333e64703a3 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c | |||
@@ -8984,7 +8984,7 @@ lpfc_sli_hba_down(struct lpfc_hba *phba) | |||
8984 | int i; | 8984 | int i; |
8985 | 8985 | ||
8986 | /* Shutdown the mailbox command sub-system */ | 8986 | /* Shutdown the mailbox command sub-system */ |
8987 | lpfc_sli_mbox_sys_shutdown(phba); | 8987 | lpfc_sli_mbox_sys_shutdown(phba, LPFC_MBX_WAIT); |
8988 | 8988 | ||
8989 | lpfc_hba_down_prep(phba); | 8989 | lpfc_hba_down_prep(phba); |
8990 | 8990 | ||
@@ -9996,11 +9996,17 @@ lpfc_sli_issue_mbox_wait(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq, | |||
9996 | * sub-system flush routine to gracefully bring down mailbox sub-system. | 9996 | * sub-system flush routine to gracefully bring down mailbox sub-system. |
9997 | **/ | 9997 | **/ |
9998 | void | 9998 | void |
9999 | lpfc_sli_mbox_sys_shutdown(struct lpfc_hba *phba) | 9999 | lpfc_sli_mbox_sys_shutdown(struct lpfc_hba *phba, int mbx_action) |
10000 | { | 10000 | { |
10001 | struct lpfc_sli *psli = &phba->sli; | 10001 | struct lpfc_sli *psli = &phba->sli; |
10002 | unsigned long timeout; | 10002 | unsigned long timeout; |
10003 | 10003 | ||
10004 | if (mbx_action == LPFC_MBX_NO_WAIT) { | ||
10005 | /* delay 100ms for port state */ | ||
10006 | msleep(100); | ||
10007 | lpfc_sli_mbox_sys_flush(phba); | ||
10008 | return; | ||
10009 | } | ||
10004 | timeout = msecs_to_jiffies(LPFC_MBOX_TMO * 1000) + jiffies; | 10010 | timeout = msecs_to_jiffies(LPFC_MBOX_TMO * 1000) + jiffies; |
10005 | 10011 | ||
10006 | spin_lock_irq(&phba->hbalock); | 10012 | spin_lock_irq(&phba->hbalock); |