Loading drivers/scsi/lpfc/lpfc.h +9 −1 Original line number Diff line number Diff line Loading @@ -392,6 +392,13 @@ enum hba_temp_state { HBA_OVER_TEMP }; enum intr_type_t { NONE = 0, INTx, MSI, MSIX, }; struct lpfc_hba { struct lpfc_sli sli; uint32_t sli_rev; /* SLI2 or SLI3 */ Loading Loading @@ -555,7 +562,8 @@ struct lpfc_hba { mempool_t *nlp_mem_pool; struct fc_host_statistics link_stats; uint8_t using_msi; enum intr_type_t intr_type; struct msix_entry msix_entries[1]; struct list_head port_list; struct lpfc_vport *pport; /* physical lpfc_vport pointer */ Loading drivers/scsi/lpfc/lpfc_attr.c +4 −2 Original line number Diff line number Diff line Loading @@ -1592,9 +1592,11 @@ LPFC_ATTR_RW(poll_tmo, 10, 1, 255, # support this feature # 0 = MSI disabled (default) # 1 = MSI enabled # Value range is [0,1]. Default value is 0. # 2 = MSI-X enabled # Value range is [0,2]. Default value is 0. */ LPFC_ATTR_R(use_msi, 0, 0, 1, "Use Message Signaled Interrupts, if possible"); LPFC_ATTR_R(use_msi, 0, 0, 2, "Use Message Signaled Interrupts (1) or " "MSI-X (2), if possible"); /* # lpfc_enable_hba_reset: Allow or prevent HBA resets to the hardware. Loading drivers/scsi/lpfc/lpfc_init.c +78 −19 Original line number Diff line number Diff line Loading @@ -1924,6 +1924,42 @@ void lpfc_host_attrib_init(struct Scsi_Host *shost) spin_unlock_irq(shost->host_lock); } static int lpfc_enable_msix(struct lpfc_hba *phba) { int error; phba->msix_entries[0].entry = 0; phba->msix_entries[0].vector = 0; error = pci_enable_msix(phba->pcidev, phba->msix_entries, ARRAY_SIZE(phba->msix_entries)); if (error) { lpfc_printf_log(phba, KERN_INFO, LOG_INIT, "0420 Enable MSI-X failed (%d), continuing " "with MSI\n", error); pci_disable_msix(phba->pcidev); return error; } error = request_irq(phba->msix_entries[0].vector, lpfc_intr_handler, 0, LPFC_DRIVER_NAME, phba); if (error) { lpfc_printf_log(phba, KERN_ERR, LOG_INIT, "0421 MSI-X request_irq failed (%d), " "continuing with MSI\n", error); pci_disable_msix(phba->pcidev); } return error; } static void lpfc_disable_msix(struct lpfc_hba *phba) { free_irq(phba->msix_entries[0].vector, phba); pci_disable_msix(phba->pcidev); } static int __devinit lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) { Loading Loading @@ -2125,24 +2161,36 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) lpfc_debugfs_initialize(vport); pci_set_drvdata(pdev, shost); phba->intr_type = NONE; if (phba->cfg_use_msi) { if (phba->cfg_use_msi == 2) { error = lpfc_enable_msix(phba); if (!error) phba->intr_type = MSIX; } /* Fallback to MSI if MSI-X initialization failed */ if (phba->cfg_use_msi >= 1 && phba->intr_type == NONE) { retval = pci_enable_msi(phba->pcidev); if (!retval) phba->using_msi = 1; phba->intr_type = MSI; else lpfc_printf_log(phba, KERN_INFO, LOG_INIT, "0452 Enable MSI failed, continuing " "with IRQ\n"); } retval = request_irq(phba->pcidev->irq, lpfc_intr_handler, IRQF_SHARED, LPFC_DRIVER_NAME, phba); /* MSI-X is the only case the doesn't need to call request_irq */ if (phba->intr_type != MSIX) { retval = request_irq(phba->pcidev->irq, lpfc_intr_handler, IRQF_SHARED, LPFC_DRIVER_NAME, phba); if (retval) { lpfc_printf_log(phba, KERN_ERR, LOG_INIT, "0451 Enable interrupt handler failed\n"); lpfc_printf_log(phba, KERN_ERR, LOG_INIT, "0451 Enable " "interrupt handler failed\n"); error = retval; goto out_disable_msi; } else if (phba->intr_type != MSI) phba->intr_type = INTx; } phba->MBslimaddr = phba->slim_memmap_p; Loading Loading @@ -2187,9 +2235,14 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) out_free_irq: lpfc_stop_phba_timers(phba); phba->pport->work_port_events = 0; if (phba->intr_type == MSIX) lpfc_disable_msix(phba); else free_irq(phba->pcidev->irq, phba); out_disable_msi: if (phba->using_msi) if (phba->intr_type == MSI) pci_disable_msi(phba->pcidev); destroy_port(vport); out_kthread_stop: Loading Loading @@ -2262,10 +2315,13 @@ lpfc_pci_remove_one(struct pci_dev *pdev) lpfc_debugfs_terminate(vport); /* Release the irq reservation */ if (phba->intr_type == MSIX) lpfc_disable_msix(phba); else { free_irq(phba->pcidev->irq, phba); if (phba->using_msi) if (phba->intr_type == MSI) pci_disable_msi(phba->pcidev); } pci_set_drvdata(pdev, NULL); scsi_host_put(shost); Loading Loading @@ -2324,10 +2380,13 @@ static pci_ers_result_t lpfc_io_error_detected(struct pci_dev *pdev, pring = &psli->ring[psli->fcp_ring]; lpfc_sli_abort_iocb_ring(phba, pring); /* Release the irq reservation */ if (phba->intr_type == MSIX) lpfc_disable_msix(phba); else { free_irq(phba->pcidev->irq, phba); if (phba->using_msi) if (phba->intr_type == MSI) pci_disable_msi(phba->pcidev); } /* Request a slot reset. */ return PCI_ERS_RESULT_NEED_RESET; Loading Loading
drivers/scsi/lpfc/lpfc.h +9 −1 Original line number Diff line number Diff line Loading @@ -392,6 +392,13 @@ enum hba_temp_state { HBA_OVER_TEMP }; enum intr_type_t { NONE = 0, INTx, MSI, MSIX, }; struct lpfc_hba { struct lpfc_sli sli; uint32_t sli_rev; /* SLI2 or SLI3 */ Loading Loading @@ -555,7 +562,8 @@ struct lpfc_hba { mempool_t *nlp_mem_pool; struct fc_host_statistics link_stats; uint8_t using_msi; enum intr_type_t intr_type; struct msix_entry msix_entries[1]; struct list_head port_list; struct lpfc_vport *pport; /* physical lpfc_vport pointer */ Loading
drivers/scsi/lpfc/lpfc_attr.c +4 −2 Original line number Diff line number Diff line Loading @@ -1592,9 +1592,11 @@ LPFC_ATTR_RW(poll_tmo, 10, 1, 255, # support this feature # 0 = MSI disabled (default) # 1 = MSI enabled # Value range is [0,1]. Default value is 0. # 2 = MSI-X enabled # Value range is [0,2]. Default value is 0. */ LPFC_ATTR_R(use_msi, 0, 0, 1, "Use Message Signaled Interrupts, if possible"); LPFC_ATTR_R(use_msi, 0, 0, 2, "Use Message Signaled Interrupts (1) or " "MSI-X (2), if possible"); /* # lpfc_enable_hba_reset: Allow or prevent HBA resets to the hardware. Loading
drivers/scsi/lpfc/lpfc_init.c +78 −19 Original line number Diff line number Diff line Loading @@ -1924,6 +1924,42 @@ void lpfc_host_attrib_init(struct Scsi_Host *shost) spin_unlock_irq(shost->host_lock); } static int lpfc_enable_msix(struct lpfc_hba *phba) { int error; phba->msix_entries[0].entry = 0; phba->msix_entries[0].vector = 0; error = pci_enable_msix(phba->pcidev, phba->msix_entries, ARRAY_SIZE(phba->msix_entries)); if (error) { lpfc_printf_log(phba, KERN_INFO, LOG_INIT, "0420 Enable MSI-X failed (%d), continuing " "with MSI\n", error); pci_disable_msix(phba->pcidev); return error; } error = request_irq(phba->msix_entries[0].vector, lpfc_intr_handler, 0, LPFC_DRIVER_NAME, phba); if (error) { lpfc_printf_log(phba, KERN_ERR, LOG_INIT, "0421 MSI-X request_irq failed (%d), " "continuing with MSI\n", error); pci_disable_msix(phba->pcidev); } return error; } static void lpfc_disable_msix(struct lpfc_hba *phba) { free_irq(phba->msix_entries[0].vector, phba); pci_disable_msix(phba->pcidev); } static int __devinit lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) { Loading Loading @@ -2125,24 +2161,36 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) lpfc_debugfs_initialize(vport); pci_set_drvdata(pdev, shost); phba->intr_type = NONE; if (phba->cfg_use_msi) { if (phba->cfg_use_msi == 2) { error = lpfc_enable_msix(phba); if (!error) phba->intr_type = MSIX; } /* Fallback to MSI if MSI-X initialization failed */ if (phba->cfg_use_msi >= 1 && phba->intr_type == NONE) { retval = pci_enable_msi(phba->pcidev); if (!retval) phba->using_msi = 1; phba->intr_type = MSI; else lpfc_printf_log(phba, KERN_INFO, LOG_INIT, "0452 Enable MSI failed, continuing " "with IRQ\n"); } retval = request_irq(phba->pcidev->irq, lpfc_intr_handler, IRQF_SHARED, LPFC_DRIVER_NAME, phba); /* MSI-X is the only case the doesn't need to call request_irq */ if (phba->intr_type != MSIX) { retval = request_irq(phba->pcidev->irq, lpfc_intr_handler, IRQF_SHARED, LPFC_DRIVER_NAME, phba); if (retval) { lpfc_printf_log(phba, KERN_ERR, LOG_INIT, "0451 Enable interrupt handler failed\n"); lpfc_printf_log(phba, KERN_ERR, LOG_INIT, "0451 Enable " "interrupt handler failed\n"); error = retval; goto out_disable_msi; } else if (phba->intr_type != MSI) phba->intr_type = INTx; } phba->MBslimaddr = phba->slim_memmap_p; Loading Loading @@ -2187,9 +2235,14 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) out_free_irq: lpfc_stop_phba_timers(phba); phba->pport->work_port_events = 0; if (phba->intr_type == MSIX) lpfc_disable_msix(phba); else free_irq(phba->pcidev->irq, phba); out_disable_msi: if (phba->using_msi) if (phba->intr_type == MSI) pci_disable_msi(phba->pcidev); destroy_port(vport); out_kthread_stop: Loading Loading @@ -2262,10 +2315,13 @@ lpfc_pci_remove_one(struct pci_dev *pdev) lpfc_debugfs_terminate(vport); /* Release the irq reservation */ if (phba->intr_type == MSIX) lpfc_disable_msix(phba); else { free_irq(phba->pcidev->irq, phba); if (phba->using_msi) if (phba->intr_type == MSI) pci_disable_msi(phba->pcidev); } pci_set_drvdata(pdev, NULL); scsi_host_put(shost); Loading Loading @@ -2324,10 +2380,13 @@ static pci_ers_result_t lpfc_io_error_detected(struct pci_dev *pdev, pring = &psli->ring[psli->fcp_ring]; lpfc_sli_abort_iocb_ring(phba, pring); /* Release the irq reservation */ if (phba->intr_type == MSIX) lpfc_disable_msix(phba); else { free_irq(phba->pcidev->irq, phba); if (phba->using_msi) if (phba->intr_type == MSI) pci_disable_msi(phba->pcidev); } /* Request a slot reset. */ return PCI_ERS_RESULT_NEED_RESET; Loading