diff options
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_init.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_init.c | 279 |
1 files changed, 245 insertions, 34 deletions
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index cd9697edf860..2786ee3b605d 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
@@ -621,6 +621,7 @@ lpfc_config_port_post(struct lpfc_hba *phba) | |||
621 | /** | 621 | /** |
622 | * lpfc_hba_init_link - Initialize the FC link | 622 | * lpfc_hba_init_link - Initialize the FC link |
623 | * @phba: pointer to lpfc hba data structure. | 623 | * @phba: pointer to lpfc hba data structure. |
624 | * @flag: mailbox command issue mode - either MBX_POLL or MBX_NOWAIT | ||
624 | * | 625 | * |
625 | * This routine will issue the INIT_LINK mailbox command call. | 626 | * This routine will issue the INIT_LINK mailbox command call. |
626 | * It is available to other drivers through the lpfc_hba data | 627 | * It is available to other drivers through the lpfc_hba data |
@@ -632,7 +633,7 @@ lpfc_config_port_post(struct lpfc_hba *phba) | |||
632 | * Any other value - error | 633 | * Any other value - error |
633 | **/ | 634 | **/ |
634 | int | 635 | int |
635 | lpfc_hba_init_link(struct lpfc_hba *phba) | 636 | lpfc_hba_init_link(struct lpfc_hba *phba, uint32_t flag) |
636 | { | 637 | { |
637 | struct lpfc_vport *vport = phba->pport; | 638 | struct lpfc_vport *vport = phba->pport; |
638 | LPFC_MBOXQ_t *pmb; | 639 | LPFC_MBOXQ_t *pmb; |
@@ -651,7 +652,7 @@ lpfc_hba_init_link(struct lpfc_hba *phba) | |||
651 | phba->cfg_link_speed); | 652 | phba->cfg_link_speed); |
652 | pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl; | 653 | pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl; |
653 | lpfc_set_loopback_flag(phba); | 654 | lpfc_set_loopback_flag(phba); |
654 | rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT); | 655 | rc = lpfc_sli_issue_mbox(phba, pmb, flag); |
655 | if (rc != MBX_SUCCESS) { | 656 | if (rc != MBX_SUCCESS) { |
656 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 657 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
657 | "0498 Adapter failed to init, mbxCmd x%x " | 658 | "0498 Adapter failed to init, mbxCmd x%x " |
@@ -664,17 +665,21 @@ lpfc_hba_init_link(struct lpfc_hba *phba) | |||
664 | writel(0xffffffff, phba->HAregaddr); | 665 | writel(0xffffffff, phba->HAregaddr); |
665 | readl(phba->HAregaddr); /* flush */ | 666 | readl(phba->HAregaddr); /* flush */ |
666 | phba->link_state = LPFC_HBA_ERROR; | 667 | phba->link_state = LPFC_HBA_ERROR; |
667 | if (rc != MBX_BUSY) | 668 | if (rc != MBX_BUSY || flag == MBX_POLL) |
668 | mempool_free(pmb, phba->mbox_mem_pool); | 669 | mempool_free(pmb, phba->mbox_mem_pool); |
669 | return -EIO; | 670 | return -EIO; |
670 | } | 671 | } |
671 | phba->cfg_suppress_link_up = LPFC_INITIALIZE_LINK; | 672 | phba->cfg_suppress_link_up = LPFC_INITIALIZE_LINK; |
673 | if (flag == MBX_POLL) | ||
674 | mempool_free(pmb, phba->mbox_mem_pool); | ||
672 | 675 | ||
673 | return 0; | 676 | return 0; |
674 | } | 677 | } |
675 | 678 | ||
676 | /** | 679 | /** |
677 | * lpfc_hba_down_link - this routine downs the FC link | 680 | * lpfc_hba_down_link - this routine downs the FC link |
681 | * @phba: pointer to lpfc hba data structure. | ||
682 | * @flag: mailbox command issue mode - either MBX_POLL or MBX_NOWAIT | ||
678 | * | 683 | * |
679 | * This routine will issue the DOWN_LINK mailbox command call. | 684 | * This routine will issue the DOWN_LINK mailbox command call. |
680 | * It is available to other drivers through the lpfc_hba data | 685 | * It is available to other drivers through the lpfc_hba data |
@@ -685,7 +690,7 @@ lpfc_hba_init_link(struct lpfc_hba *phba) | |||
685 | * Any other value - error | 690 | * Any other value - error |
686 | **/ | 691 | **/ |
687 | int | 692 | int |
688 | lpfc_hba_down_link(struct lpfc_hba *phba) | 693 | lpfc_hba_down_link(struct lpfc_hba *phba, uint32_t flag) |
689 | { | 694 | { |
690 | LPFC_MBOXQ_t *pmb; | 695 | LPFC_MBOXQ_t *pmb; |
691 | int rc; | 696 | int rc; |
@@ -701,7 +706,7 @@ lpfc_hba_down_link(struct lpfc_hba *phba) | |||
701 | "0491 Adapter Link is disabled.\n"); | 706 | "0491 Adapter Link is disabled.\n"); |
702 | lpfc_down_link(phba, pmb); | 707 | lpfc_down_link(phba, pmb); |
703 | pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl; | 708 | pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl; |
704 | rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT); | 709 | rc = lpfc_sli_issue_mbox(phba, pmb, flag); |
705 | if ((rc != MBX_SUCCESS) && (rc != MBX_BUSY)) { | 710 | if ((rc != MBX_SUCCESS) && (rc != MBX_BUSY)) { |
706 | lpfc_printf_log(phba, | 711 | lpfc_printf_log(phba, |
707 | KERN_ERR, LOG_INIT, | 712 | KERN_ERR, LOG_INIT, |
@@ -711,6 +716,9 @@ lpfc_hba_down_link(struct lpfc_hba *phba) | |||
711 | mempool_free(pmb, phba->mbox_mem_pool); | 716 | mempool_free(pmb, phba->mbox_mem_pool); |
712 | return -EIO; | 717 | return -EIO; |
713 | } | 718 | } |
719 | if (flag == MBX_POLL) | ||
720 | mempool_free(pmb, phba->mbox_mem_pool); | ||
721 | |||
714 | return 0; | 722 | return 0; |
715 | } | 723 | } |
716 | 724 | ||
@@ -1818,6 +1826,10 @@ lpfc_get_hba_model_desc(struct lpfc_hba *phba, uint8_t *mdp, uint8_t *descp) | |||
1818 | m = (typeof(m)){"LPSe12002-ML1-E", "PCIe", | 1826 | m = (typeof(m)){"LPSe12002-ML1-E", "PCIe", |
1819 | "EmulexSecure Fibre"}; | 1827 | "EmulexSecure Fibre"}; |
1820 | break; | 1828 | break; |
1829 | case PCI_DEVICE_ID_BALIUS: | ||
1830 | m = (typeof(m)){"LPVe12002", "PCIe Shared I/O", | ||
1831 | "Fibre Channel Adapter"}; | ||
1832 | break; | ||
1821 | default: | 1833 | default: |
1822 | m = (typeof(m)){"Unknown", "", ""}; | 1834 | m = (typeof(m)){"Unknown", "", ""}; |
1823 | break; | 1835 | break; |
@@ -2279,10 +2291,32 @@ static void | |||
2279 | lpfc_block_mgmt_io(struct lpfc_hba * phba) | 2291 | lpfc_block_mgmt_io(struct lpfc_hba * phba) |
2280 | { | 2292 | { |
2281 | unsigned long iflag; | 2293 | unsigned long iflag; |
2294 | uint8_t actcmd = MBX_HEARTBEAT; | ||
2295 | unsigned long timeout; | ||
2296 | |||
2282 | 2297 | ||
2283 | spin_lock_irqsave(&phba->hbalock, iflag); | 2298 | spin_lock_irqsave(&phba->hbalock, iflag); |
2284 | phba->sli.sli_flag |= LPFC_BLOCK_MGMT_IO; | 2299 | phba->sli.sli_flag |= LPFC_BLOCK_MGMT_IO; |
2300 | if (phba->sli.mbox_active) | ||
2301 | actcmd = phba->sli.mbox_active->u.mb.mbxCommand; | ||
2285 | spin_unlock_irqrestore(&phba->hbalock, iflag); | 2302 | spin_unlock_irqrestore(&phba->hbalock, iflag); |
2303 | /* Determine how long we might wait for the active mailbox | ||
2304 | * command to be gracefully completed by firmware. | ||
2305 | */ | ||
2306 | timeout = msecs_to_jiffies(lpfc_mbox_tmo_val(phba, actcmd) * 1000) + | ||
2307 | jiffies; | ||
2308 | /* Wait for the outstnading mailbox command to complete */ | ||
2309 | while (phba->sli.mbox_active) { | ||
2310 | /* Check active mailbox complete status every 2ms */ | ||
2311 | msleep(2); | ||
2312 | if (time_after(jiffies, timeout)) { | ||
2313 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, | ||
2314 | "2813 Mgmt IO is Blocked %x " | ||
2315 | "- mbox cmd %x still active\n", | ||
2316 | phba->sli.sli_flag, actcmd); | ||
2317 | break; | ||
2318 | } | ||
2319 | } | ||
2286 | } | 2320 | } |
2287 | 2321 | ||
2288 | /** | 2322 | /** |
@@ -3323,22 +3357,14 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba, | |||
3323 | "evt_tag:x%x, fcf_index:x%x\n", | 3357 | "evt_tag:x%x, fcf_index:x%x\n", |
3324 | acqe_fcoe->event_tag, | 3358 | acqe_fcoe->event_tag, |
3325 | acqe_fcoe->index); | 3359 | acqe_fcoe->index); |
3360 | /* If the FCF discovery is in progress, do nothing. */ | ||
3326 | spin_lock_irq(&phba->hbalock); | 3361 | spin_lock_irq(&phba->hbalock); |
3327 | if ((phba->fcf.fcf_flag & FCF_SCAN_DONE) || | 3362 | if (phba->hba_flag & FCF_DISC_INPROGRESS) { |
3328 | (phba->hba_flag & FCF_DISC_INPROGRESS)) { | ||
3329 | /* | ||
3330 | * If the current FCF is in discovered state or | ||
3331 | * FCF discovery is in progress, do nothing. | ||
3332 | */ | ||
3333 | spin_unlock_irq(&phba->hbalock); | 3363 | spin_unlock_irq(&phba->hbalock); |
3334 | break; | 3364 | break; |
3335 | } | 3365 | } |
3336 | 3366 | /* If fast FCF failover rescan event is pending, do nothing */ | |
3337 | if (phba->fcf.fcf_flag & FCF_REDISC_EVT) { | 3367 | if (phba->fcf.fcf_flag & FCF_REDISC_EVT) { |
3338 | /* | ||
3339 | * If fast FCF failover rescan event is pending, | ||
3340 | * do nothing. | ||
3341 | */ | ||
3342 | spin_unlock_irq(&phba->hbalock); | 3368 | spin_unlock_irq(&phba->hbalock); |
3343 | break; | 3369 | break; |
3344 | } | 3370 | } |
@@ -3359,7 +3385,13 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba, | |||
3359 | acqe_fcoe->index); | 3385 | acqe_fcoe->index); |
3360 | rc = lpfc_sli4_read_fcf_rec(phba, acqe_fcoe->index); | 3386 | rc = lpfc_sli4_read_fcf_rec(phba, acqe_fcoe->index); |
3361 | } | 3387 | } |
3362 | 3388 | /* If the FCF has been in discovered state, do nothing. */ | |
3389 | spin_lock_irq(&phba->hbalock); | ||
3390 | if (phba->fcf.fcf_flag & FCF_SCAN_DONE) { | ||
3391 | spin_unlock_irq(&phba->hbalock); | ||
3392 | break; | ||
3393 | } | ||
3394 | spin_unlock_irq(&phba->hbalock); | ||
3363 | /* Otherwise, scan the entire FCF table and re-discover SAN */ | 3395 | /* Otherwise, scan the entire FCF table and re-discover SAN */ |
3364 | lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_DISCOVERY, | 3396 | lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_DISCOVERY, |
3365 | "2770 Start FCF table scan due to new FCF " | 3397 | "2770 Start FCF table scan due to new FCF " |
@@ -4885,6 +4917,7 @@ lpfc_create_shost(struct lpfc_hba *phba) | |||
4885 | phba->fc_altov = FF_DEF_ALTOV; | 4917 | phba->fc_altov = FF_DEF_ALTOV; |
4886 | phba->fc_arbtov = FF_DEF_ARBTOV; | 4918 | phba->fc_arbtov = FF_DEF_ARBTOV; |
4887 | 4919 | ||
4920 | atomic_set(&phba->sdev_cnt, 0); | ||
4888 | vport = lpfc_create_port(phba, phba->brd_no, &phba->pcidev->dev); | 4921 | vport = lpfc_create_port(phba, phba->brd_no, &phba->pcidev->dev); |
4889 | if (!vport) | 4922 | if (!vport) |
4890 | return -ENODEV; | 4923 | return -ENODEV; |
@@ -5533,9 +5566,12 @@ lpfc_sli4_read_config(struct lpfc_hba *phba) | |||
5533 | mempool_free(pmb, phba->mbox_mem_pool); | 5566 | mempool_free(pmb, phba->mbox_mem_pool); |
5534 | 5567 | ||
5535 | /* Reset the DFT_HBA_Q_DEPTH to the max xri */ | 5568 | /* Reset the DFT_HBA_Q_DEPTH to the max xri */ |
5536 | if (phba->cfg_hba_queue_depth > (phba->sli4_hba.max_cfg_param.max_xri)) | 5569 | if (phba->cfg_hba_queue_depth > |
5570 | (phba->sli4_hba.max_cfg_param.max_xri - | ||
5571 | lpfc_sli4_get_els_iocb_cnt(phba))) | ||
5537 | phba->cfg_hba_queue_depth = | 5572 | phba->cfg_hba_queue_depth = |
5538 | phba->sli4_hba.max_cfg_param.max_xri; | 5573 | phba->sli4_hba.max_cfg_param.max_xri - |
5574 | lpfc_sli4_get_els_iocb_cnt(phba); | ||
5539 | return rc; | 5575 | return rc; |
5540 | } | 5576 | } |
5541 | 5577 | ||
@@ -6993,22 +7029,28 @@ lpfc_sli_disable_intr(struct lpfc_hba *phba) | |||
6993 | static int | 7029 | static int |
6994 | lpfc_sli4_enable_msix(struct lpfc_hba *phba) | 7030 | lpfc_sli4_enable_msix(struct lpfc_hba *phba) |
6995 | { | 7031 | { |
6996 | int rc, index; | 7032 | int vectors, rc, index; |
6997 | 7033 | ||
6998 | /* Set up MSI-X multi-message vectors */ | 7034 | /* Set up MSI-X multi-message vectors */ |
6999 | for (index = 0; index < phba->sli4_hba.cfg_eqn; index++) | 7035 | for (index = 0; index < phba->sli4_hba.cfg_eqn; index++) |
7000 | phba->sli4_hba.msix_entries[index].entry = index; | 7036 | phba->sli4_hba.msix_entries[index].entry = index; |
7001 | 7037 | ||
7002 | /* Configure MSI-X capability structure */ | 7038 | /* Configure MSI-X capability structure */ |
7039 | vectors = phba->sli4_hba.cfg_eqn; | ||
7040 | enable_msix_vectors: | ||
7003 | rc = pci_enable_msix(phba->pcidev, phba->sli4_hba.msix_entries, | 7041 | rc = pci_enable_msix(phba->pcidev, phba->sli4_hba.msix_entries, |
7004 | phba->sli4_hba.cfg_eqn); | 7042 | vectors); |
7005 | if (rc) { | 7043 | if (rc > 1) { |
7044 | vectors = rc; | ||
7045 | goto enable_msix_vectors; | ||
7046 | } else if (rc) { | ||
7006 | lpfc_printf_log(phba, KERN_INFO, LOG_INIT, | 7047 | lpfc_printf_log(phba, KERN_INFO, LOG_INIT, |
7007 | "0484 PCI enable MSI-X failed (%d)\n", rc); | 7048 | "0484 PCI enable MSI-X failed (%d)\n", rc); |
7008 | goto msi_fail_out; | 7049 | goto msi_fail_out; |
7009 | } | 7050 | } |
7051 | |||
7010 | /* Log MSI-X vector assignment */ | 7052 | /* Log MSI-X vector assignment */ |
7011 | for (index = 0; index < phba->sli4_hba.cfg_eqn; index++) | 7053 | for (index = 0; index < vectors; index++) |
7012 | lpfc_printf_log(phba, KERN_INFO, LOG_INIT, | 7054 | lpfc_printf_log(phba, KERN_INFO, LOG_INIT, |
7013 | "0489 MSI-X entry[%d]: vector=x%x " | 7055 | "0489 MSI-X entry[%d]: vector=x%x " |
7014 | "message=%d\n", index, | 7056 | "message=%d\n", index, |
@@ -7030,7 +7072,7 @@ lpfc_sli4_enable_msix(struct lpfc_hba *phba) | |||
7030 | } | 7072 | } |
7031 | 7073 | ||
7032 | /* The rest of the vector(s) are associated to fast-path handler(s) */ | 7074 | /* The rest of the vector(s) are associated to fast-path handler(s) */ |
7033 | for (index = 1; index < phba->sli4_hba.cfg_eqn; index++) { | 7075 | for (index = 1; index < vectors; index++) { |
7034 | phba->sli4_hba.fcp_eq_hdl[index - 1].idx = index - 1; | 7076 | phba->sli4_hba.fcp_eq_hdl[index - 1].idx = index - 1; |
7035 | phba->sli4_hba.fcp_eq_hdl[index - 1].phba = phba; | 7077 | phba->sli4_hba.fcp_eq_hdl[index - 1].phba = phba; |
7036 | rc = request_irq(phba->sli4_hba.msix_entries[index].vector, | 7078 | rc = request_irq(phba->sli4_hba.msix_entries[index].vector, |
@@ -7044,6 +7086,7 @@ lpfc_sli4_enable_msix(struct lpfc_hba *phba) | |||
7044 | goto cfg_fail_out; | 7086 | goto cfg_fail_out; |
7045 | } | 7087 | } |
7046 | } | 7088 | } |
7089 | phba->sli4_hba.msix_vec_nr = vectors; | ||
7047 | 7090 | ||
7048 | return rc; | 7091 | return rc; |
7049 | 7092 | ||
@@ -7077,9 +7120,10 @@ lpfc_sli4_disable_msix(struct lpfc_hba *phba) | |||
7077 | /* Free up MSI-X multi-message vectors */ | 7120 | /* Free up MSI-X multi-message vectors */ |
7078 | free_irq(phba->sli4_hba.msix_entries[0].vector, phba); | 7121 | free_irq(phba->sli4_hba.msix_entries[0].vector, phba); |
7079 | 7122 | ||
7080 | for (index = 1; index < phba->sli4_hba.cfg_eqn; index++) | 7123 | for (index = 1; index < phba->sli4_hba.msix_vec_nr; index++) |
7081 | free_irq(phba->sli4_hba.msix_entries[index].vector, | 7124 | free_irq(phba->sli4_hba.msix_entries[index].vector, |
7082 | &phba->sli4_hba.fcp_eq_hdl[index - 1]); | 7125 | &phba->sli4_hba.fcp_eq_hdl[index - 1]); |
7126 | |||
7083 | /* Disable MSI-X */ | 7127 | /* Disable MSI-X */ |
7084 | pci_disable_msix(phba->pcidev); | 7128 | pci_disable_msix(phba->pcidev); |
7085 | 7129 | ||
@@ -7121,6 +7165,7 @@ lpfc_sli4_enable_msi(struct lpfc_hba *phba) | |||
7121 | pci_disable_msi(phba->pcidev); | 7165 | pci_disable_msi(phba->pcidev); |
7122 | lpfc_printf_log(phba, KERN_WARNING, LOG_INIT, | 7166 | lpfc_printf_log(phba, KERN_WARNING, LOG_INIT, |
7123 | "0490 MSI request_irq failed (%d)\n", rc); | 7167 | "0490 MSI request_irq failed (%d)\n", rc); |
7168 | return rc; | ||
7124 | } | 7169 | } |
7125 | 7170 | ||
7126 | for (index = 0; index < phba->cfg_fcp_eq_count; index++) { | 7171 | for (index = 0; index < phba->cfg_fcp_eq_count; index++) { |
@@ -7128,7 +7173,7 @@ lpfc_sli4_enable_msi(struct lpfc_hba *phba) | |||
7128 | phba->sli4_hba.fcp_eq_hdl[index].phba = phba; | 7173 | phba->sli4_hba.fcp_eq_hdl[index].phba = phba; |
7129 | } | 7174 | } |
7130 | 7175 | ||
7131 | return rc; | 7176 | return 0; |
7132 | } | 7177 | } |
7133 | 7178 | ||
7134 | /** | 7179 | /** |
@@ -7839,6 +7884,9 @@ lpfc_sli_prep_dev_for_reset(struct lpfc_hba *phba) | |||
7839 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 7884 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
7840 | "2710 PCI channel disable preparing for reset\n"); | 7885 | "2710 PCI channel disable preparing for reset\n"); |
7841 | 7886 | ||
7887 | /* Block any management I/Os to the device */ | ||
7888 | lpfc_block_mgmt_io(phba); | ||
7889 | |||
7842 | /* Block all SCSI devices' I/Os on the host */ | 7890 | /* Block all SCSI devices' I/Os on the host */ |
7843 | lpfc_scsi_dev_block(phba); | 7891 | lpfc_scsi_dev_block(phba); |
7844 | 7892 | ||
@@ -7848,6 +7896,7 @@ lpfc_sli_prep_dev_for_reset(struct lpfc_hba *phba) | |||
7848 | /* Disable interrupt and pci device */ | 7896 | /* Disable interrupt and pci device */ |
7849 | lpfc_sli_disable_intr(phba); | 7897 | lpfc_sli_disable_intr(phba); |
7850 | pci_disable_device(phba->pcidev); | 7898 | pci_disable_device(phba->pcidev); |
7899 | |||
7851 | /* Flush all driver's outstanding SCSI I/Os as we are to reset */ | 7900 | /* Flush all driver's outstanding SCSI I/Os as we are to reset */ |
7852 | lpfc_sli_flush_fcp_rings(phba); | 7901 | lpfc_sli_flush_fcp_rings(phba); |
7853 | } | 7902 | } |
@@ -7861,7 +7910,7 @@ lpfc_sli_prep_dev_for_reset(struct lpfc_hba *phba) | |||
7861 | * pending I/Os. | 7910 | * pending I/Os. |
7862 | **/ | 7911 | **/ |
7863 | static void | 7912 | static void |
7864 | lpfc_prep_dev_for_perm_failure(struct lpfc_hba *phba) | 7913 | lpfc_sli_prep_dev_for_perm_failure(struct lpfc_hba *phba) |
7865 | { | 7914 | { |
7866 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 7915 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
7867 | "2711 PCI channel permanent disable for failure\n"); | 7916 | "2711 PCI channel permanent disable for failure\n"); |
@@ -7910,7 +7959,7 @@ lpfc_io_error_detected_s3(struct pci_dev *pdev, pci_channel_state_t state) | |||
7910 | return PCI_ERS_RESULT_NEED_RESET; | 7959 | return PCI_ERS_RESULT_NEED_RESET; |
7911 | case pci_channel_io_perm_failure: | 7960 | case pci_channel_io_perm_failure: |
7912 | /* Permanent failure, prepare for device down */ | 7961 | /* Permanent failure, prepare for device down */ |
7913 | lpfc_prep_dev_for_perm_failure(phba); | 7962 | lpfc_sli_prep_dev_for_perm_failure(phba); |
7914 | return PCI_ERS_RESULT_DISCONNECT; | 7963 | return PCI_ERS_RESULT_DISCONNECT; |
7915 | default: | 7964 | default: |
7916 | /* Unknown state, prepare and request slot reset */ | 7965 | /* Unknown state, prepare and request slot reset */ |
@@ -7979,7 +8028,8 @@ lpfc_io_slot_reset_s3(struct pci_dev *pdev) | |||
7979 | } else | 8028 | } else |
7980 | phba->intr_mode = intr_mode; | 8029 | phba->intr_mode = intr_mode; |
7981 | 8030 | ||
7982 | /* Take device offline; this will perform cleanup */ | 8031 | /* Take device offline, it will perform cleanup */ |
8032 | lpfc_offline_prep(phba); | ||
7983 | lpfc_offline(phba); | 8033 | lpfc_offline(phba); |
7984 | lpfc_sli_brdrestart(phba); | 8034 | lpfc_sli_brdrestart(phba); |
7985 | 8035 | ||
@@ -8110,8 +8160,12 @@ lpfc_pci_probe_one_s4(struct pci_dev *pdev, const struct pci_device_id *pid) | |||
8110 | } | 8160 | } |
8111 | 8161 | ||
8112 | /* Initialize and populate the iocb list per host */ | 8162 | /* Initialize and populate the iocb list per host */ |
8113 | error = lpfc_init_iocb_list(phba, | 8163 | |
8114 | phba->sli4_hba.max_cfg_param.max_xri); | 8164 | lpfc_printf_log(phba, KERN_INFO, LOG_INIT, |
8165 | "2821 initialize iocb list %d.\n", | ||
8166 | phba->cfg_iocb_cnt*1024); | ||
8167 | error = lpfc_init_iocb_list(phba, phba->cfg_iocb_cnt*1024); | ||
8168 | |||
8115 | if (error) { | 8169 | if (error) { |
8116 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 8170 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
8117 | "1413 Failed to initialize iocb list.\n"); | 8171 | "1413 Failed to initialize iocb list.\n"); |
@@ -8160,6 +8214,8 @@ lpfc_pci_probe_one_s4(struct pci_dev *pdev, const struct pci_device_id *pid) | |||
8160 | /* Default to single FCP EQ for non-MSI-X */ | 8214 | /* Default to single FCP EQ for non-MSI-X */ |
8161 | if (phba->intr_type != MSIX) | 8215 | if (phba->intr_type != MSIX) |
8162 | phba->cfg_fcp_eq_count = 1; | 8216 | phba->cfg_fcp_eq_count = 1; |
8217 | else if (phba->sli4_hba.msix_vec_nr < phba->cfg_fcp_eq_count) | ||
8218 | phba->cfg_fcp_eq_count = phba->sli4_hba.msix_vec_nr - 1; | ||
8163 | /* Set up SLI-4 HBA */ | 8219 | /* Set up SLI-4 HBA */ |
8164 | if (lpfc_sli4_hba_setup(phba)) { | 8220 | if (lpfc_sli4_hba_setup(phba)) { |
8165 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 8221 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
@@ -8321,7 +8377,7 @@ lpfc_pci_suspend_one_s4(struct pci_dev *pdev, pm_message_t msg) | |||
8321 | struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba; | 8377 | struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba; |
8322 | 8378 | ||
8323 | lpfc_printf_log(phba, KERN_INFO, LOG_INIT, | 8379 | lpfc_printf_log(phba, KERN_INFO, LOG_INIT, |
8324 | "0298 PCI device Power Management suspend.\n"); | 8380 | "2843 PCI device Power Management suspend.\n"); |
8325 | 8381 | ||
8326 | /* Bring down the device */ | 8382 | /* Bring down the device */ |
8327 | lpfc_offline_prep(phba); | 8383 | lpfc_offline_prep(phba); |
@@ -8412,6 +8468,84 @@ lpfc_pci_resume_one_s4(struct pci_dev *pdev) | |||
8412 | } | 8468 | } |
8413 | 8469 | ||
8414 | /** | 8470 | /** |
8471 | * lpfc_sli4_prep_dev_for_recover - Prepare SLI4 device for pci slot recover | ||
8472 | * @phba: pointer to lpfc hba data structure. | ||
8473 | * | ||
8474 | * This routine is called to prepare the SLI4 device for PCI slot recover. It | ||
8475 | * aborts all the outstanding SCSI I/Os to the pci device. | ||
8476 | **/ | ||
8477 | static void | ||
8478 | lpfc_sli4_prep_dev_for_recover(struct lpfc_hba *phba) | ||
8479 | { | ||
8480 | struct lpfc_sli *psli = &phba->sli; | ||
8481 | struct lpfc_sli_ring *pring; | ||
8482 | |||
8483 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
8484 | "2828 PCI channel I/O abort preparing for recovery\n"); | ||
8485 | /* | ||
8486 | * There may be errored I/Os through HBA, abort all I/Os on txcmplq | ||
8487 | * and let the SCSI mid-layer to retry them to recover. | ||
8488 | */ | ||
8489 | pring = &psli->ring[psli->fcp_ring]; | ||
8490 | lpfc_sli_abort_iocb_ring(phba, pring); | ||
8491 | } | ||
8492 | |||
8493 | /** | ||
8494 | * lpfc_sli4_prep_dev_for_reset - Prepare SLI4 device for pci slot reset | ||
8495 | * @phba: pointer to lpfc hba data structure. | ||
8496 | * | ||
8497 | * This routine is called to prepare the SLI4 device for PCI slot reset. It | ||
8498 | * disables the device interrupt and pci device, and aborts the internal FCP | ||
8499 | * pending I/Os. | ||
8500 | **/ | ||
8501 | static void | ||
8502 | lpfc_sli4_prep_dev_for_reset(struct lpfc_hba *phba) | ||
8503 | { | ||
8504 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
8505 | "2826 PCI channel disable preparing for reset\n"); | ||
8506 | |||
8507 | /* Block any management I/Os to the device */ | ||
8508 | lpfc_block_mgmt_io(phba); | ||
8509 | |||
8510 | /* Block all SCSI devices' I/Os on the host */ | ||
8511 | lpfc_scsi_dev_block(phba); | ||
8512 | |||
8513 | /* stop all timers */ | ||
8514 | lpfc_stop_hba_timers(phba); | ||
8515 | |||
8516 | /* Disable interrupt and pci device */ | ||
8517 | lpfc_sli4_disable_intr(phba); | ||
8518 | pci_disable_device(phba->pcidev); | ||
8519 | |||
8520 | /* Flush all driver's outstanding SCSI I/Os as we are to reset */ | ||
8521 | lpfc_sli_flush_fcp_rings(phba); | ||
8522 | } | ||
8523 | |||
8524 | /** | ||
8525 | * lpfc_sli4_prep_dev_for_perm_failure - Prepare SLI4 dev for pci slot disable | ||
8526 | * @phba: pointer to lpfc hba data structure. | ||
8527 | * | ||
8528 | * This routine is called to prepare the SLI4 device for PCI slot permanently | ||
8529 | * disabling. It blocks the SCSI transport layer traffic and flushes the FCP | ||
8530 | * pending I/Os. | ||
8531 | **/ | ||
8532 | static void | ||
8533 | lpfc_sli4_prep_dev_for_perm_failure(struct lpfc_hba *phba) | ||
8534 | { | ||
8535 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
8536 | "2827 PCI channel permanent disable for failure\n"); | ||
8537 | |||
8538 | /* Block all SCSI devices' I/Os on the host */ | ||
8539 | lpfc_scsi_dev_block(phba); | ||
8540 | |||
8541 | /* stop all timers */ | ||
8542 | lpfc_stop_hba_timers(phba); | ||
8543 | |||
8544 | /* Clean up all driver's outstanding SCSI I/Os */ | ||
8545 | lpfc_sli_flush_fcp_rings(phba); | ||
8546 | } | ||
8547 | |||
8548 | /** | ||
8415 | * lpfc_io_error_detected_s4 - Method for handling PCI I/O error to SLI-4 device | 8549 | * lpfc_io_error_detected_s4 - Method for handling PCI I/O error to SLI-4 device |
8416 | * @pdev: pointer to PCI device. | 8550 | * @pdev: pointer to PCI device. |
8417 | * @state: the current PCI connection state. | 8551 | * @state: the current PCI connection state. |
@@ -8430,7 +8564,29 @@ lpfc_pci_resume_one_s4(struct pci_dev *pdev) | |||
8430 | static pci_ers_result_t | 8564 | static pci_ers_result_t |
8431 | lpfc_io_error_detected_s4(struct pci_dev *pdev, pci_channel_state_t state) | 8565 | lpfc_io_error_detected_s4(struct pci_dev *pdev, pci_channel_state_t state) |
8432 | { | 8566 | { |
8433 | return PCI_ERS_RESULT_NEED_RESET; | 8567 | struct Scsi_Host *shost = pci_get_drvdata(pdev); |
8568 | struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba; | ||
8569 | |||
8570 | switch (state) { | ||
8571 | case pci_channel_io_normal: | ||
8572 | /* Non-fatal error, prepare for recovery */ | ||
8573 | lpfc_sli4_prep_dev_for_recover(phba); | ||
8574 | return PCI_ERS_RESULT_CAN_RECOVER; | ||
8575 | case pci_channel_io_frozen: | ||
8576 | /* Fatal error, prepare for slot reset */ | ||
8577 | lpfc_sli4_prep_dev_for_reset(phba); | ||
8578 | return PCI_ERS_RESULT_NEED_RESET; | ||
8579 | case pci_channel_io_perm_failure: | ||
8580 | /* Permanent failure, prepare for device down */ | ||
8581 | lpfc_sli4_prep_dev_for_perm_failure(phba); | ||
8582 | return PCI_ERS_RESULT_DISCONNECT; | ||
8583 | default: | ||
8584 | /* Unknown state, prepare and request slot reset */ | ||
8585 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
8586 | "2825 Unknown PCI error state: x%x\n", state); | ||
8587 | lpfc_sli4_prep_dev_for_reset(phba); | ||
8588 | return PCI_ERS_RESULT_NEED_RESET; | ||
8589 | } | ||
8434 | } | 8590 | } |
8435 | 8591 | ||
8436 | /** | 8592 | /** |
@@ -8454,6 +8610,39 @@ lpfc_io_error_detected_s4(struct pci_dev *pdev, pci_channel_state_t state) | |||
8454 | static pci_ers_result_t | 8610 | static pci_ers_result_t |
8455 | lpfc_io_slot_reset_s4(struct pci_dev *pdev) | 8611 | lpfc_io_slot_reset_s4(struct pci_dev *pdev) |
8456 | { | 8612 | { |
8613 | struct Scsi_Host *shost = pci_get_drvdata(pdev); | ||
8614 | struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba; | ||
8615 | struct lpfc_sli *psli = &phba->sli; | ||
8616 | uint32_t intr_mode; | ||
8617 | |||
8618 | dev_printk(KERN_INFO, &pdev->dev, "recovering from a slot reset.\n"); | ||
8619 | if (pci_enable_device_mem(pdev)) { | ||
8620 | printk(KERN_ERR "lpfc: Cannot re-enable " | ||
8621 | "PCI device after reset.\n"); | ||
8622 | return PCI_ERS_RESULT_DISCONNECT; | ||
8623 | } | ||
8624 | |||
8625 | pci_restore_state(pdev); | ||
8626 | if (pdev->is_busmaster) | ||
8627 | pci_set_master(pdev); | ||
8628 | |||
8629 | spin_lock_irq(&phba->hbalock); | ||
8630 | psli->sli_flag &= ~LPFC_SLI_ACTIVE; | ||
8631 | spin_unlock_irq(&phba->hbalock); | ||
8632 | |||
8633 | /* Configure and enable interrupt */ | ||
8634 | intr_mode = lpfc_sli4_enable_intr(phba, phba->intr_mode); | ||
8635 | if (intr_mode == LPFC_INTR_ERROR) { | ||
8636 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
8637 | "2824 Cannot re-enable interrupt after " | ||
8638 | "slot reset.\n"); | ||
8639 | return PCI_ERS_RESULT_DISCONNECT; | ||
8640 | } else | ||
8641 | phba->intr_mode = intr_mode; | ||
8642 | |||
8643 | /* Log the current active interrupt mode */ | ||
8644 | lpfc_log_intr_mode(phba, phba->intr_mode); | ||
8645 | |||
8457 | return PCI_ERS_RESULT_RECOVERED; | 8646 | return PCI_ERS_RESULT_RECOVERED; |
8458 | } | 8647 | } |
8459 | 8648 | ||
@@ -8470,7 +8659,27 @@ lpfc_io_slot_reset_s4(struct pci_dev *pdev) | |||
8470 | static void | 8659 | static void |
8471 | lpfc_io_resume_s4(struct pci_dev *pdev) | 8660 | lpfc_io_resume_s4(struct pci_dev *pdev) |
8472 | { | 8661 | { |
8473 | return; | 8662 | struct Scsi_Host *shost = pci_get_drvdata(pdev); |
8663 | struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba; | ||
8664 | |||
8665 | /* | ||
8666 | * In case of slot reset, as function reset is performed through | ||
8667 | * mailbox command which needs DMA to be enabled, this operation | ||
8668 | * has to be moved to the io resume phase. Taking device offline | ||
8669 | * will perform the necessary cleanup. | ||
8670 | */ | ||
8671 | if (!(phba->sli.sli_flag & LPFC_SLI_ACTIVE)) { | ||
8672 | /* Perform device reset */ | ||
8673 | lpfc_offline_prep(phba); | ||
8674 | lpfc_offline(phba); | ||
8675 | lpfc_sli_brdrestart(phba); | ||
8676 | /* Bring the device back online */ | ||
8677 | lpfc_online(phba); | ||
8678 | } | ||
8679 | |||
8680 | /* Clean up Advanced Error Reporting (AER) if needed */ | ||
8681 | if (phba->hba_flag & HBA_AER_ENABLED) | ||
8682 | pci_cleanup_aer_uncorrect_error_status(pdev); | ||
8474 | } | 8683 | } |
8475 | 8684 | ||
8476 | /** | 8685 | /** |
@@ -8802,6 +9011,8 @@ static struct pci_device_id lpfc_id_table[] = { | |||
8802 | PCI_ANY_ID, PCI_ANY_ID, }, | 9011 | PCI_ANY_ID, PCI_ANY_ID, }, |
8803 | {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_FALCON, | 9012 | {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_FALCON, |
8804 | PCI_ANY_ID, PCI_ANY_ID, }, | 9013 | PCI_ANY_ID, PCI_ANY_ID, }, |
9014 | {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_BALIUS, | ||
9015 | PCI_ANY_ID, PCI_ANY_ID, }, | ||
8805 | { 0 } | 9016 | { 0 } |
8806 | }; | 9017 | }; |
8807 | 9018 | ||