scsi: pmcraid: switch to pci_alloc_irq_vectors
authorChristoph Hellwig <hch@lst.de>
Fri, 18 Nov 2016 06:28:16 +0000 (07:28 +0100)
committerMartin K. Petersen <martin.petersen@oracle.com>
Tue, 10 Jan 2017 04:47:00 +0000 (23:47 -0500)
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/pmcraid.c
drivers/scsi/pmcraid.h

index 337982cf3d638198c1d674ab974d696b582ab160..49e70a383afaedf0c56024249b10bd67540169e7 100644 (file)
@@ -4587,16 +4587,14 @@ static void pmcraid_tasklet_function(unsigned long instance)
 static
 void pmcraid_unregister_interrupt_handler(struct pmcraid_instance *pinstance)
 {
+       struct pci_dev *pdev = pinstance->pdev;
        int i;
 
        for (i = 0; i < pinstance->num_hrrq; i++)
-               free_irq(pinstance->hrrq_vector[i].vector,
-                        &(pinstance->hrrq_vector[i]));
+               free_irq(pci_irq_vector(pdev, i), &pinstance->hrrq_vector[i]);
 
-       if (pinstance->interrupt_mode) {
-               pci_disable_msix(pinstance->pdev);
-               pinstance->interrupt_mode = 0;
-       }
+       pinstance->interrupt_mode = 0;
+       pci_free_irq_vectors(pdev);
 }
 
 /**
@@ -4609,60 +4607,52 @@ void pmcraid_unregister_interrupt_handler(struct pmcraid_instance *pinstance)
 static int
 pmcraid_register_interrupt_handler(struct pmcraid_instance *pinstance)
 {
-       int rc;
        struct pci_dev *pdev = pinstance->pdev;
+       unsigned int irq_flag = PCI_IRQ_LEGACY, flag;
+       int num_hrrq, rc, i;
+       irq_handler_t isr;
 
-       if ((pmcraid_enable_msix) &&
-               (pci_find_capability(pdev, PCI_CAP_ID_MSIX))) {
-               int num_hrrq = PMCRAID_NUM_MSIX_VECTORS;
-               struct msix_entry entries[PMCRAID_NUM_MSIX_VECTORS];
-               int i;
-               for (i = 0; i < PMCRAID_NUM_MSIX_VECTORS; i++)
-                       entries[i].entry = i;
-
-               num_hrrq = pci_enable_msix_range(pdev, entries, 1, num_hrrq);
-               if (num_hrrq < 0)
-                       goto pmcraid_isr_legacy;
-
-               for (i = 0; i < num_hrrq; i++) {
-                       pinstance->hrrq_vector[i].hrrq_id = i;
-                       pinstance->hrrq_vector[i].drv_inst = pinstance;
-                       pinstance->hrrq_vector[i].vector = entries[i].vector;
-                       rc = request_irq(pinstance->hrrq_vector[i].vector,
-                                       pmcraid_isr_msix, 0,
-                                       PMCRAID_DRIVER_NAME,
-                                       &(pinstance->hrrq_vector[i]));
-
-                       if (rc) {
-                               int j;
-                               for (j = 0; j < i; j++)
-                                       free_irq(entries[j].vector,
-                                                &(pinstance->hrrq_vector[j]));
-                               pci_disable_msix(pdev);
-                               goto pmcraid_isr_legacy;
-                       }
-               }
+       if (pmcraid_enable_msix)
+               irq_flag |= PCI_IRQ_MSIX;
 
-               pinstance->num_hrrq = num_hrrq;
+       num_hrrq = pci_alloc_irq_vectors(pdev, 1, PMCRAID_NUM_MSIX_VECTORS,
+                       irq_flag);
+       if (num_hrrq < 0)
+               return num_hrrq;
+
+       if (pdev->msix_enabled) {
+               flag = 0;
+               isr = pmcraid_isr_msix;
+       } else {
+               flag = IRQF_SHARED;
+               isr = pmcraid_isr;
+       }
+
+       for (i = 0; i < num_hrrq; i++) {
+               struct pmcraid_isr_param *vec = &pinstance->hrrq_vector[i];
+
+               vec->hrrq_id = i;
+               vec->drv_inst = pinstance;
+               rc = request_irq(pci_irq_vector(pdev, i), isr, flag,
+                               PMCRAID_DRIVER_NAME, vec);
+               if (rc)
+                       goto out_unwind;
+       }
+
+       pinstance->num_hrrq = num_hrrq;
+       if (pdev->msix_enabled) {
                pinstance->interrupt_mode = 1;
                iowrite32(DOORBELL_INTR_MODE_MSIX,
                          pinstance->int_regs.host_ioa_interrupt_reg);
                ioread32(pinstance->int_regs.host_ioa_interrupt_reg);
-               goto pmcraid_isr_out;
        }
 
-pmcraid_isr_legacy:
-       /* If MSI-X registration failed fallback to legacy mode, where
-        * only one hrrq entry will be used
-        */
-       pinstance->hrrq_vector[0].hrrq_id = 0;
-       pinstance->hrrq_vector[0].drv_inst = pinstance;
-       pinstance->hrrq_vector[0].vector = pdev->irq;
-       pinstance->num_hrrq = 1;
-
-       rc = request_irq(pdev->irq, pmcraid_isr, IRQF_SHARED,
-                        PMCRAID_DRIVER_NAME, &pinstance->hrrq_vector[0]);
-pmcraid_isr_out:
+       return 0;
+
+out_unwind:
+       while (--i > 0)
+               free_irq(pci_irq_vector(pdev, i), &pinstance->hrrq_vector[i]);
+       pci_free_irq_vectors(pdev);
        return rc;
 }
 
index e1d150f3fd4d4912c2cdc9f972550874f0fd63f7..568b18a2f47dd69d5347b103bd5ce27ef9af89c7 100644 (file)
@@ -628,7 +628,6 @@ struct pmcraid_interrupts {
 /* ISR parameters LLD allocates (one for each MSI-X if enabled) vectors */
 struct pmcraid_isr_param {
        struct pmcraid_instance *drv_inst;
-       u16 vector;                     /* allocated msi-x vector */
        u8 hrrq_id;                     /* hrrq entry index */
 };