OSDN Git Service

IB/qib: Update QIB to use the latest PCI API
authorMichael J. Ruhl <michael.j.ruhl@intel.com>
Tue, 26 Sep 2017 14:00:24 +0000 (07:00 -0700)
committerDoug Ledford <dledford@redhat.com>
Wed, 27 Sep 2017 15:34:13 +0000 (11:34 -0400)
The QIB PCI IRQ code uses an obsolete PCI API.  Updating the code to use
the new PCI IRQ API and any necessary changes because of the new API.

Reviewed-by: Sebastian Sanchez <sebastian.sanchez@intel.com>
Signed-off-by: Michael J. Ruhl <michael.j.ruhl@intel.com>
Signed-off-by: Dennis Dalessandro <dennis.dalessandro@intel.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
drivers/infiniband/hw/qib/qib.h
drivers/infiniband/hw/qib/qib_7220.h
drivers/infiniband/hw/qib/qib_iba6120.c
drivers/infiniband/hw/qib/qib_iba7220.c
drivers/infiniband/hw/qib/qib_iba7322.c
drivers/infiniband/hw/qib/qib_pcie.c

index f9e1c69..1167a9c 100644 (file)
@@ -443,14 +443,12 @@ struct qib_irq_notify;
 #endif
 
 struct qib_msix_entry {
-       int irq;
        void *arg;
 #ifdef CONFIG_INFINIBAND_QIB_DCA
        int dca;
        int rcv;
        struct qib_irq_notify *notifier;
 #endif
-       char name[MAX_NAME_SIZE];
        cpumask_var_t mask;
 };
 
@@ -1434,10 +1432,8 @@ int qib_pcie_ddinit(struct qib_devdata *, struct pci_dev *,
                    const struct pci_device_id *);
 void qib_pcie_ddcleanup(struct qib_devdata *);
 int qib_pcie_params(struct qib_devdata *dd, u32 minw, u32 *nent);
-int qib_reinit_intr(struct qib_devdata *);
-void qib_enable_intx(struct qib_devdata *dd);
-void qib_nomsi(struct qib_devdata *);
-void qib_nomsix(struct qib_devdata *);
+void qib_free_irq(struct qib_devdata *dd);
+int qib_reinit_intr(struct qib_devdata *dd);
 void qib_pcie_getcmd(struct qib_devdata *, u16 *, u8 *, u8 *);
 void qib_pcie_reenable(struct qib_devdata *, u16, u8, u8);
 /* interrupts for device */
index a5356cb..4ec3dc1 100644 (file)
@@ -67,7 +67,6 @@ struct qib_chip_specific {
        u32 lastbuf_for_pio;
        u32 updthresh; /* current AvailUpdThld */
        u32 updthresh_dflt; /* default AvailUpdThld */
-       int irq;
        u8 presets_needed;
        u8 relock_timer_active;
        char emsgbuf[128];
index 3259a60..c4a4c57 100644 (file)
@@ -245,7 +245,6 @@ struct qib_chip_specific {
        u64 iblnkerrsnap;
        u64 ibcctrl; /* shadow for kr_ibcctrl */
        u32 lastlinkrecov; /* link recovery issue */
-       int irq;
        u32 cntrnamelen;
        u32 portcntrnamelen;
        u32 ncntrs;
@@ -1485,15 +1484,6 @@ static void qib_6120_setup_setextled(struct qib_pportdata *ppd, u32 on)
        spin_unlock_irqrestore(&dd->cspec->gpio_lock, flags);
 }
 
-static void qib_6120_free_irq(struct qib_devdata *dd)
-{
-       if (dd->cspec->irq) {
-               free_irq(dd->cspec->irq, dd);
-               dd->cspec->irq = 0;
-       }
-       qib_nomsi(dd);
-}
-
 /**
  * qib_6120_setup_cleanup - clean up any per-chip chip-specific stuff
  * @dd: the qlogic_ib device
@@ -1502,7 +1492,7 @@ static void qib_6120_free_irq(struct qib_devdata *dd)
 */
 static void qib_6120_setup_cleanup(struct qib_devdata *dd)
 {
-       qib_6120_free_irq(dd);
+       qib_free_irq(dd);
        kfree(dd->cspec->cntrs);
        kfree(dd->cspec->portcntrs);
        if (dd->cspec->dummy_hdrq) {
@@ -1706,6 +1696,8 @@ bail:
  */
 static void qib_setup_6120_interrupt(struct qib_devdata *dd)
 {
+       int ret;
+
        /*
         * If the chip supports added error indication via GPIO pins,
         * enable interrupts on those bits so the interrupt routine
@@ -1719,19 +1711,12 @@ static void qib_setup_6120_interrupt(struct qib_devdata *dd)
                qib_write_kreg(dd, kr_gpio_mask, dd->cspec->gpio_mask);
        }
 
-       if (!dd->cspec->irq)
+       ret = pci_request_irq(dd->pcidev, 0, qib_6120intr, NULL, dd,
+                             QIB_DRV_NAME);
+       if (ret)
                qib_dev_err(dd,
-                       "irq is 0, BIOS error?  Interrupts won't work\n");
-       else {
-               int ret;
-
-               ret = request_irq(dd->cspec->irq, qib_6120intr, 0,
-                                 QIB_DRV_NAME, dd);
-               if (ret)
-                       qib_dev_err(dd,
-                               "Couldn't setup interrupt (irq=%d): %d\n",
-                               dd->cspec->irq, ret);
-       }
+                           "Couldn't setup interrupt (irq=%d): %d\n",
+                           pci_irq_vector(dd->pcidev, 0), ret);
 }
 
 /**
@@ -3490,7 +3475,7 @@ struct qib_devdata *qib_init_iba6120_funcs(struct pci_dev *pdev,
        dd->f_bringup_serdes    = qib_6120_bringup_serdes;
        dd->f_cleanup           = qib_6120_setup_cleanup;
        dd->f_clear_tids        = qib_6120_clear_tids;
-       dd->f_free_irq          = qib_6120_free_irq;
+       dd->f_free_irq          = qib_free_irq;
        dd->f_get_base_info     = qib_6120_get_base_info;
        dd->f_get_msgheader     = qib_6120_get_msgheader;
        dd->f_getsendbuf        = qib_6120_getsendbuf;
@@ -3559,8 +3544,6 @@ struct qib_devdata *qib_init_iba6120_funcs(struct pci_dev *pdev,
        if (qib_pcie_params(dd, 8, NULL))
                qib_dev_err(dd,
                        "Failed to setup PCIe or interrupts; continuing anyway\n");
-       dd->cspec->irq = pdev->irq; /* save IRQ */
-
        /* clear diagctrl register, in case diags were running and crashed */
        qib_write_kreg(dd, kr_hwdiagctrl, 0);
 
index 04bdd3d..78ce79b 100644 (file)
@@ -1780,15 +1780,6 @@ static void qib_setup_7220_setextled(struct qib_pportdata *ppd, u32 on)
                qib_write_kreg(dd, kr_rcvpktledcnt, ledblink);
 }
 
-static void qib_7220_free_irq(struct qib_devdata *dd)
-{
-       if (dd->cspec->irq) {
-               free_irq(dd->cspec->irq, dd);
-               dd->cspec->irq = 0;
-       }
-       qib_nomsi(dd);
-}
-
 /*
  * qib_setup_7220_cleanup - clean up any per-chip chip-specific stuff
  * @dd: the qlogic_ib device
@@ -1798,7 +1789,7 @@ static void qib_7220_free_irq(struct qib_devdata *dd)
  */
 static void qib_setup_7220_cleanup(struct qib_devdata *dd)
 {
-       qib_7220_free_irq(dd);
+       qib_free_irq(dd);
        kfree(dd->cspec->cntrs);
        kfree(dd->cspec->portcntrs);
 }
@@ -2026,20 +2017,14 @@ bail:
  */
 static void qib_setup_7220_interrupt(struct qib_devdata *dd)
 {
-       if (!dd->cspec->irq)
-               qib_dev_err(dd,
-                       "irq is 0, BIOS error?  Interrupts won't work\n");
-       else {
-               int ret = request_irq(dd->cspec->irq, qib_7220intr,
-                       dd->msi_lo ? 0 : IRQF_SHARED,
-                       QIB_DRV_NAME, dd);
+       int ret;
 
-               if (ret)
-                       qib_dev_err(dd,
-                               "Couldn't setup %s interrupt (irq=%d): %d\n",
-                               dd->msi_lo ?  "MSI" : "INTx",
-                               dd->cspec->irq, ret);
-       }
+       ret = pci_request_irq(dd->pcidev, 0, qib_7220intr, NULL, dd,
+                             QIB_DRV_NAME);
+       if (ret)
+               qib_dev_err(dd, "Couldn't setup %s interrupt (irq=%d): %d\n",
+                           dd->pcidev->msi_enabled ?  "MSI" : "INTx",
+                           pci_irq_vector(dd->pcidev, 0), ret);
 }
 
 /**
@@ -3302,16 +3287,12 @@ static int qib_7220_intr_fallback(struct qib_devdata *dd)
                return 0;
 
        qib_devinfo(dd->pcidev,
-               "MSI interrupt not detected, trying INTx interrupts\n");
-       qib_7220_free_irq(dd);
-       qib_enable_intx(dd);
-       /*
-        * Some newer kernels require free_irq before disable_msi,
-        * and irq can be changed during disable and INTx enable
-        * and we need to therefore use the pcidev->irq value,
-        * not our saved MSI value.
-        */
-       dd->cspec->irq = dd->pcidev->irq;
+                   "MSI interrupt not detected, trying INTx interrupts\n");
+
+       qib_free_irq(dd);
+       dd->msi_lo = 0;
+       if (pci_alloc_irq_vectors(dd->pcidev, 1, 1, PCI_IRQ_LEGACY) < 0)
+               qib_dev_err(dd, "Failed to enable INTx\n");
        qib_setup_7220_interrupt(dd);
        return 1;
 }
@@ -4535,7 +4516,7 @@ struct qib_devdata *qib_init_iba7220_funcs(struct pci_dev *pdev,
        dd->f_bringup_serdes    = qib_7220_bringup_serdes;
        dd->f_cleanup           = qib_setup_7220_cleanup;
        dd->f_clear_tids        = qib_7220_clear_tids;
-       dd->f_free_irq          = qib_7220_free_irq;
+       dd->f_free_irq          = qib_free_irq;
        dd->f_get_base_info     = qib_7220_get_base_info;
        dd->f_get_msgheader     = qib_7220_get_msgheader;
        dd->f_getsendbuf        = qib_7220_getsendbuf;
@@ -4618,9 +4599,6 @@ struct qib_devdata *qib_init_iba7220_funcs(struct pci_dev *pdev,
                qib_dev_err(dd,
                        "Failed to setup PCIe or interrupts; continuing anyway\n");
 
-       /* save IRQ for possible later use */
-       dd->cspec->irq = pdev->irq;
-
        if (qib_read_kreg64(dd, kr_hwerrstatus) &
            QLOGIC_IB_HWE_SERDESPLLFAILED)
                qib_write_kreg(dd, kr_hwerrclear,
index 14cadf6..4d02cff 100644 (file)
@@ -553,7 +553,6 @@ struct qib_chip_specific {
        u32 updthresh; /* current AvailUpdThld */
        u32 updthresh_dflt; /* default AvailUpdThld */
        u32 r1;
-       int irq;
        u32 num_msix_entries;
        u32 sdmabufcnt;
        u32 lastbuf_for_pio;
@@ -756,10 +755,8 @@ static void check_7322_rxe_status(struct qib_pportdata *);
 static u32 __iomem *qib_7322_getsendbuf(struct qib_pportdata *, u64, u32 *);
 #ifdef CONFIG_INFINIBAND_QIB_DCA
 static void qib_setup_dca(struct qib_devdata *dd);
-static void setup_dca_notifier(struct qib_devdata *dd,
-                              struct qib_msix_entry *m);
-static void reset_dca_notifier(struct qib_devdata *dd,
-                              struct qib_msix_entry *m);
+static void setup_dca_notifier(struct qib_devdata *dd, int msixnum);
+static void reset_dca_notifier(struct qib_devdata *dd, int msixnum);
 #endif
 
 /**
@@ -2778,7 +2775,7 @@ static void qib_setup_dca(struct qib_devdata *dd)
                qib_write_kreg(dd, KREG_IDX(DCACtrlB) + i,
                               cspec->dca_rcvhdr_ctrl[i]);
        for (i = 0; i < cspec->num_msix_entries; i++)
-               setup_dca_notifier(dd, &cspec->msix_entries[i]);
+               setup_dca_notifier(dd, i);
 }
 
 static void qib_irq_notifier_notify(struct irq_affinity_notify *notify,
@@ -2820,49 +2817,41 @@ static void qib_irq_notifier_release(struct kref *ref)
 }
 #endif
 
-/*
- * Disable MSIx interrupt if enabled, call generic MSIx code
- * to cleanup, and clear pending MSIx interrupts.
- * Used for fallback to INTx, after reset, and when MSIx setup fails.
- */
-static void qib_7322_nomsix(struct qib_devdata *dd)
+static void qib_7322_free_irq(struct qib_devdata *dd)
 {
        u64 intgranted;
-       int n;
+       int i;
 
        dd->cspec->main_int_mask = ~0ULL;
-       n = dd->cspec->num_msix_entries;
-       if (n) {
-               int i;
 
-               dd->cspec->num_msix_entries = 0;
-               for (i = 0; i < n; i++) {
+       for (i = 0; i < dd->cspec->num_msix_entries; i++) {
+               /* only free IRQs that were allocated */
+               if (dd->cspec->msix_entries[i].arg) {
 #ifdef CONFIG_INFINIBAND_QIB_DCA
-                       reset_dca_notifier(dd, &dd->cspec->msix_entries[i]);
+                       reset_dca_notifier(dd, i);
 #endif
-                       irq_set_affinity_hint(
-                               dd->cspec->msix_entries[i].irq, NULL);
+                       irq_set_affinity_hint(pci_irq_vector(dd->pcidev, i),
+                                             NULL);
                        free_cpumask_var(dd->cspec->msix_entries[i].mask);
-                       free_irq(dd->cspec->msix_entries[i].irq,
-                                dd->cspec->msix_entries[i].arg);
+                       pci_free_irq(dd->pcidev, i,
+                                    dd->cspec->msix_entries[i].arg);
                }
-               qib_nomsix(dd);
        }
+
+       /* If num_msix_entries was 0, disable the INTx IRQ */
+       if (!dd->cspec->num_msix_entries)
+               pci_free_irq(dd->pcidev, 0, dd);
+       else
+               dd->cspec->num_msix_entries = 0;
+
+       pci_free_irq_vectors(dd->pcidev);
+
        /* make sure no MSIx interrupts are left pending */
        intgranted = qib_read_kreg64(dd, kr_intgranted);
        if (intgranted)
                qib_write_kreg(dd, kr_intgranted, intgranted);
 }
 
-static void qib_7322_free_irq(struct qib_devdata *dd)
-{
-       if (dd->cspec->irq) {
-               free_irq(dd->cspec->irq, dd);
-               dd->cspec->irq = 0;
-       }
-       qib_7322_nomsix(dd);
-}
-
 static void qib_setup_7322_cleanup(struct qib_devdata *dd)
 {
        int i;
@@ -3329,22 +3318,20 @@ static irqreturn_t sdma_cleanup_intr(int irq, void *data)
 
 #ifdef CONFIG_INFINIBAND_QIB_DCA
 
-static void reset_dca_notifier(struct qib_devdata *dd, struct qib_msix_entry *m)
+static void reset_dca_notifier(struct qib_devdata *dd, int msixnum)
 {
-       if (!m->dca)
+       if (!dd->cspec->msix_entries[msixnum].dca)
                return;
-       qib_devinfo(dd->pcidev,
-               "Disabling notifier on HCA %d irq %d\n",
-               dd->unit,
-               m->irq);
-       irq_set_affinity_notifier(
-               m->irq,
-               NULL);
-       m->notifier = NULL;
+
+       qib_devinfo(dd->pcidev, "Disabling notifier on HCA %d irq %d\n",
+                   dd->unit, pci_irq_vector(dd->pcidev, msixnum));
+       irq_set_affinity_notifier(pci_irq_vector(dd->pcidev, msixnum), NULL);
+       dd->cspec->msix_entries[msixnum].notifier = NULL;
 }
 
-static void setup_dca_notifier(struct qib_devdata *dd, struct qib_msix_entry *m)
+static void setup_dca_notifier(struct qib_devdata *dd, int msixnum)
 {
+       struct qib_msix_entry *m = &dd->cspec->msix_entries[msixnum];
        struct qib_irq_notify *n;
 
        if (!m->dca)
@@ -3354,7 +3341,7 @@ static void setup_dca_notifier(struct qib_devdata *dd, struct qib_msix_entry *m)
                int ret;
 
                m->notifier = n;
-               n->notify.irq = m->irq;
+               n->notify.irq = pci_irq_vector(dd->pcidev, msixnum);
                n->notify.notify = qib_irq_notifier_notify;
                n->notify.release = qib_irq_notifier_release;
                n->arg = m->arg;
@@ -3415,22 +3402,17 @@ static void qib_setup_7322_interrupt(struct qib_devdata *dd, int clearpend)
        if (!dd->cspec->num_msix_entries) {
                /* Try to get INTx interrupt */
 try_intx:
-               if (!dd->pcidev->irq) {
-                       qib_dev_err(dd,
-                               "irq is 0, BIOS error?  Interrupts won't work\n");
-                       goto bail;
-               }
-               ret = request_irq(dd->pcidev->irq, qib_7322intr,
-                                 IRQF_SHARED, QIB_DRV_NAME, dd);
+               ret = pci_request_irq(dd->pcidev, 0, qib_7322intr, NULL, dd,
+                                     QIB_DRV_NAME);
                if (ret) {
-                       qib_dev_err(dd,
+                       qib_dev_err(
+                               dd,
                                "Couldn't setup INTx interrupt (irq=%d): %d\n",
-                               dd->pcidev->irq, ret);
-                       goto bail;
+                               pci_irq_vector(dd->pcidev, 0), ret);
+                       return;
                }
-               dd->cspec->irq = dd->pcidev->irq;
                dd->cspec->main_int_mask = ~0ULL;
-               goto bail;
+               return;
        }
 
        /* Try to get MSIx interrupts */
@@ -3458,10 +3440,6 @@ try_intx:
 #ifdef CONFIG_INFINIBAND_QIB_DCA
                int dca = 0;
 #endif
-
-               dd->cspec->msix_entries[msixnum].
-                       name[sizeof(dd->cspec->msix_entries[msixnum].name) - 1]
-                       = '\0';
                if (i < ARRAY_SIZE(irq_table)) {
                        if (irq_table[i].port) {
                                /* skip if for a non-configured port */
@@ -3475,11 +3453,10 @@ try_intx:
 #endif
                        lsb = irq_table[i].lsb;
                        handler = irq_table[i].handler;
-                       snprintf(dd->cspec->msix_entries[msixnum].name,
-                               sizeof(dd->cspec->msix_entries[msixnum].name)
-                                - 1,
-                               QIB_DRV_NAME "%d%s", dd->unit,
-                               irq_table[i].name);
+                       ret = pci_request_irq(dd->pcidev, msixnum, handler,
+                                             NULL, arg, QIB_DRV_NAME "%d%s",
+                                             dd->unit,
+                                             irq_table[i].name);
                } else {
                        unsigned ctxt;
 
@@ -3495,37 +3472,25 @@ try_intx:
 #endif
                        lsb = QIB_I_RCVAVAIL_LSB + ctxt;
                        handler = qib_7322pintr;
-                       snprintf(dd->cspec->msix_entries[msixnum].name,
-                               sizeof(dd->cspec->msix_entries[msixnum].name)
-                                - 1,
-                               QIB_DRV_NAME "%d (kctx)", dd->unit);
+                       ret = pci_request_irq(dd->pcidev, msixnum, handler,
+                                             NULL, arg,
+                                             QIB_DRV_NAME "%d (kctx)",
+                                             dd->unit);
                }
 
-               dd->cspec->msix_entries[msixnum].irq = pci_irq_vector(
-                       dd->pcidev, msixnum);
-               if (dd->cspec->msix_entries[msixnum].irq < 0) {
-                       qib_dev_err(dd,
-                                   "Couldn't get MSIx irq (vec=%d): %d\n",
-                                   msixnum,
-                                   dd->cspec->msix_entries[msixnum].irq);
-                       qib_7322_nomsix(dd);
-                       goto try_intx;
-               }
-               ret = request_irq(dd->cspec->msix_entries[msixnum].irq,
-                                 handler, 0,
-                                 dd->cspec->msix_entries[msixnum].name,
-                                 arg);
                if (ret) {
                        /*
                         * Shouldn't happen since the enable said we could
                         * have as many as we are trying to setup here.
                         */
                        qib_dev_err(dd,
-                               "Couldn't setup MSIx interrupt (vec=%d, irq=%d): %d\n",
-                               msixnum,
-                               dd->cspec->msix_entries[msixnum].irq,
-                               ret);
-                       qib_7322_nomsix(dd);
+                                   "Couldn't setup MSIx interrupt (vec=%d, irq=%d): %d\n",
+                                   msixnum,
+                                   pci_irq_vector(dd->pcidev, msixnum),
+                                   ret);
+                       qib_7322_free_irq(dd);
+                       pci_alloc_irq_vectors(dd->pcidev, 1, 1,
+                                             PCI_IRQ_LEGACY);
                        goto try_intx;
                }
                dd->cspec->msix_entries[msixnum].arg = arg;
@@ -3559,7 +3524,7 @@ try_intx:
                                        dd->cspec->msix_entries[msixnum].mask);
                        }
                        irq_set_affinity_hint(
-                               dd->cspec->msix_entries[msixnum].irq,
+                               pci_irq_vector(dd->pcidev, msixnum),
                                dd->cspec->msix_entries[msixnum].mask);
                }
                msixnum++;
@@ -3570,7 +3535,6 @@ try_intx:
        dd->cspec->main_int_mask = mask;
        tasklet_init(&dd->error_tasklet, qib_error_tasklet,
                (unsigned long)dd);
-bail:;
 }
 
 /**
@@ -3674,8 +3638,9 @@ static int qib_do_7322_reset(struct qib_devdata *dd)
        /* no interrupts till re-initted */
        qib_7322_set_intr_state(dd, 0);
 
+       qib_7322_free_irq(dd);
+
        if (msix_entries) {
-               qib_7322_nomsix(dd);
                /* can be up to 512 bytes, too big for stack */
                msix_vecsave = kmalloc(2 * dd->cspec->num_msix_entries *
                        sizeof(u64), GFP_KERNEL);
@@ -3765,11 +3730,11 @@ static int qib_do_7322_reset(struct qib_devdata *dd)
                write_7322_init_portregs(&dd->pport[i]);
        write_7322_initregs(dd);
 
-       if (qib_pcie_params(dd, dd->lbus_width,
-                           &dd->cspec->num_msix_entries))
+       if (qib_pcie_params(dd, dd->lbus_width, &msix_entries))
                qib_dev_err(dd,
                        "Reset failed to setup PCIe or interrupts; continuing anyway\n");
 
+       dd->cspec->num_msix_entries = msix_entries;
        qib_setup_7322_interrupt(dd, 1);
 
        for (i = 0; i < dd->num_pports; ++i) {
@@ -5197,8 +5162,9 @@ static int qib_7322_intr_fallback(struct qib_devdata *dd)
 
        qib_devinfo(dd->pcidev,
                "MSIx interrupt not detected, trying INTx interrupts\n");
-       qib_7322_nomsix(dd);
-       qib_enable_intx(dd);
+       qib_7322_free_irq(dd);
+       if (pci_alloc_irq_vectors(dd->pcidev, 1, 1, PCI_IRQ_LEGACY) < 0)
+               qib_dev_err(dd, "Failed to enable INTx\n");
        qib_setup_7322_interrupt(dd, 0);
        return 1;
 }
index d90403e..6f4cc26 100644 (file)
@@ -193,7 +193,7 @@ void qib_pcie_ddcleanup(struct qib_devdata *dd)
  * chip reset (the kernel PCI infrastructure doesn't yet handle that
  * correctly.
  */
-static void qib_msi_setup(struct qib_devdata *dd, int pos)
+static void qib_cache_msi_info(struct qib_devdata *dd, int pos)
 {
        struct pci_dev *pdev = dd->pcidev;
        u16 control;
@@ -208,64 +208,39 @@ static void qib_msi_setup(struct qib_devdata *dd, int pos)
                             &dd->msi_data);
 }
 
-static int qib_allocate_irqs(struct qib_devdata *dd, u32 maxvec)
-{
-       unsigned int flags = PCI_IRQ_LEGACY;
-
-       /* Check our capabilities */
-       if (dd->pcidev->msix_cap) {
-               flags |= PCI_IRQ_MSIX;
-       } else {
-               if (dd->pcidev->msi_cap) {
-                       flags |= PCI_IRQ_MSI;
-                       /* Get msi_lo and msi_hi */
-                       qib_msi_setup(dd, dd->pcidev->msi_cap);
-               }
-       }
-
-       if (!(flags & (PCI_IRQ_MSIX | PCI_IRQ_MSI)))
-               qib_dev_err(dd, "No PCI MSI or MSIx capability!\n");
-
-       return pci_alloc_irq_vectors(dd->pcidev, 1, maxvec, flags);
-}
-
 int qib_pcie_params(struct qib_devdata *dd, u32 minw, u32 *nent)
 {
        u16 linkstat, speed;
        int nvec;
        int maxvec;
-       int ret = 0;
+       unsigned int flags = PCI_IRQ_MSIX | PCI_IRQ_MSI;
 
        if (!pci_is_pcie(dd->pcidev)) {
                qib_dev_err(dd, "Can't find PCI Express capability!\n");
                /* set up something... */
                dd->lbus_width = 1;
                dd->lbus_speed = 2500; /* Gen1, 2.5GHz */
-               ret = -1;
+               nvec = -1;
                goto bail;
        }
 
+       if (dd->flags & QIB_HAS_INTX)
+               flags |= PCI_IRQ_LEGACY;
        maxvec = (nent && *nent) ? *nent : 1;
-       nvec = qib_allocate_irqs(dd, maxvec);
-       if (nvec < 0) {
-               ret = nvec;
+       nvec = pci_alloc_irq_vectors(dd->pcidev, 1, maxvec, flags);
+       if (nvec < 0)
                goto bail;
-       }
 
        /*
-        * If nent exists, make sure to record how many vectors were allocated
+        * If nent exists, make sure to record how many vectors were allocated.
+        * If msix_enabled is false, return 0 so the fallback code works
+        * correctly.
         */
-       if (nent) {
-               *nent = nvec;
+       if (nent)
+               *nent = !dd->pcidev->msix_enabled ? 0 : nvec;
 
-               /*
-                * If we requested (nent) MSIX, but msix_enabled is not set,
-                * pci_alloc_irq_vectors() enabled INTx.
-                */
-               if (!dd->pcidev->msix_enabled)
-                       qib_dev_err(dd,
-                                   "no msix vectors allocated, using INTx\n");
-       }
+       if (dd->pcidev->msi_enabled)
+               qib_cache_msi_info(dd, dd->pcidev->msi_cap);
 
        pcie_capability_read_word(dd->pcidev, PCI_EXP_LNKSTA, &linkstat);
        /*
@@ -306,7 +281,21 @@ bail:
        /* fill in string, even on errors */
        snprintf(dd->lbus_info, sizeof(dd->lbus_info),
                 "PCIe,%uMHz,x%u\n", dd->lbus_speed, dd->lbus_width);
-       return ret;
+       return nvec < 0 ? nvec : 0;
+}
+
+/**
+ * qib_free_irq - Cleanup INTx and MSI interrupts
+ * @dd: valid pointer to qib dev data
+ *
+ * Since cleanup for INTx and MSI interrupts is trivial, have a common
+ * routine.
+ *
+ */
+void qib_free_irq(struct qib_devdata *dd)
+{
+       pci_free_irq(dd->pcidev, 0, dd);
+       pci_free_irq_vectors(dd->pcidev);
 }
 
 /*
@@ -351,10 +340,10 @@ int qib_reinit_intr(struct qib_devdata *dd)
                              dd->msi_data);
        ret = 1;
 bail:
-       if (!ret && (dd->flags & QIB_HAS_INTX)) {
-               qib_enable_intx(dd);
+       qib_free_irq(dd);
+
+       if (!ret && (dd->flags & QIB_HAS_INTX))
                ret = 1;
-       }
 
        /* and now set the pci master bit again */
        pci_set_master(dd->pcidev);
@@ -363,56 +352,6 @@ bail:
 }
 
 /*
- * Disable msi interrupt if enabled, and clear msi_lo.
- * This is used primarily for the fallback to INTx, but
- * is also used in reinit after reset, and during cleanup.
- */
-void qib_nomsi(struct qib_devdata *dd)
-{
-       dd->msi_lo = 0;
-       pci_free_irq_vectors(dd->pcidev);
-}
-
-/*
- * Same as qib_nosmi, but for MSIx.
- */
-void qib_nomsix(struct qib_devdata *dd)
-{
-       pci_free_irq_vectors(dd->pcidev);
-}
-
-/*
- * Similar to pci_intx(pdev, 1), except that we make sure
- * msi(x) is off.
- */
-void qib_enable_intx(struct qib_devdata *dd)
-{
-       u16 cw, new;
-       int pos;
-       struct pci_dev *pdev = dd->pcidev;
-
-       if (pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_LEGACY) < 0)
-               qib_dev_err(dd, "Failed to enable INTx\n");
-
-       pos = pdev->msi_cap;
-       if (pos) {
-               /* then turn off MSI */
-               pci_read_config_word(pdev, pos + PCI_MSI_FLAGS, &cw);
-               new = cw & ~PCI_MSI_FLAGS_ENABLE;
-               if (new != cw)
-                       pci_write_config_word(pdev, pos + PCI_MSI_FLAGS, new);
-       }
-       pos = pdev->msix_cap;
-       if (pos) {
-               /* then turn off MSIx */
-               pci_read_config_word(pdev, pos + PCI_MSIX_FLAGS, &cw);
-               new = cw & ~PCI_MSIX_FLAGS_ENABLE;
-               if (new != cw)
-                       pci_write_config_word(pdev, pos + PCI_MSIX_FLAGS, new);
-       }
-}
-
-/*
  * These two routines are helper routines for the device reset code
  * to move all the pcie code out of the chip-specific driver code.
  */