mpt(4): Use MSI on SAS adapters that support it.
authorSascha Wildner <saw@online.de>
Sat, 21 Jul 2012 18:43:31 +0000 (20:43 +0200)
committerSascha Wildner <saw@online.de>
Sat, 21 Jul 2012 18:43:31 +0000 (20:43 +0200)
The hw.mpt.msi.enable tunable can be used to override this behavior.

Tested-by: ftigeot
share/man/man4/mpt.4
sys/dev/disk/mpt/mpt.h
sys/dev/disk/mpt/mpt_pci.c

index 3e8a052..d7b420b 100644 (file)
@@ -35,7 +35,7 @@
 .\"
 .\" $FreeBSD: src/share/man/man4/mpt.4,v 1.22 2011/07/23 22:55:32 gjb Exp $
 .\"
 .\"
 .\" $FreeBSD: src/share/man/man4/mpt.4,v 1.22 2011/07/23 22:55:32 gjb Exp $
 .\"
-.Dd November 28, 2011
+.Dd July 21, 2012
 .Dt MPT 4
 .Os
 .Sh NAME
 .Dt MPT 4
 .Os
 .Sh NAME
@@ -66,6 +66,12 @@ for the LSI Logic Fusion-MPT family of
 and
 .Tn SAS
 controllers.
 and
 .Tn SAS
 controllers.
+.Sh LOADER TUNABLES
+.Bl -tag -width indent
+.It Va hw.mpt.msi.enable
+This tunable specifies whether MSI will be used or not, provided the
+controller supports it.
+By default, the driver will use MSI for SAS adapters.
 .Sh HARDWARE
 The following controllers are supported by the
 .Nm
 .Sh HARDWARE
 The following controllers are supported by the
 .Nm
index f8bff27..3f27ca5 100644 (file)
@@ -644,7 +644,10 @@ struct mpt_softc {
        /*
         * PCI Hardware info
         */
        /*
         * PCI Hardware info
         */
+#ifdef OLD_MSI
        int                     pci_msi_count;
        int                     pci_msi_count;
+#endif
+       int                     irq_type;       /* Interrupt type */
        struct resource *       pci_irq;        /* Interrupt map for chip */
        void *                  ih;             /* Interrupt handle */
 #if 0
        struct resource *       pci_irq;        /* Interrupt map for chip */
        void *                  ih;             /* Interrupt handle */
 #if 0
index cec8dc0..ae8f8ca 100644 (file)
@@ -256,6 +256,7 @@ static void
 mpt_set_options(struct mpt_softc *mpt)
 {
        int bitmap;
 mpt_set_options(struct mpt_softc *mpt)
 {
        int bitmap;
+       int tval;
 
        bitmap = 0;
        if (kgetenv_int("mpt_disable", &bitmap)) {
 
        bitmap = 0;
        if (kgetenv_int("mpt_disable", &bitmap)) {
@@ -310,7 +311,12 @@ mpt_set_options(struct mpt_softc *mpt)
                }
                mpt->do_cfg_role = 1;
        }
                }
                mpt->do_cfg_role = 1;
        }
+       tval = 0;
        mpt->msi_enable = 0;
        mpt->msi_enable = 0;
+       if (mpt->is_sas)
+               mpt->msi_enable = 1;
+       if (kgetenv_int("hw.mpt.msi.enable", &tval))
+               mpt->msi_enable = tval;
 }
 
 static void
 }
 
 static void
@@ -359,6 +365,7 @@ mpt_pci_attach(device_t dev)
        int               iqd;
        uint32_t          data, cmd;
        int               mpt_io_bar, mpt_mem_bar;
        int               iqd;
        uint32_t          data, cmd;
        int               mpt_io_bar, mpt_mem_bar;
+       u_int             irq_flags;
 
        mpt  = (struct mpt_softc*)device_get_softc(dev);
 
 
        mpt  = (struct mpt_softc*)device_get_softc(dev);
 
@@ -519,18 +526,12 @@ mpt_pci_attach(device_t dev)
                                mpt->pci_msi_count = 0;
                        }
                }
                                mpt->pci_msi_count = 0;
                        }
                }
-               if (iqd == 0 && pci_msi_count(dev) == 1) {
-                       mpt->pci_msi_count = 1;
-                       if (pci_alloc_msi(dev, &mpt->pci_msi_count) == 0) {
-                               iqd = 1;
-                       } else {
-                               mpt->pci_msi_count = 0;
-                       }
-               }
        }
 #endif
        }
 #endif
+       mpt->irq_type = pci_alloc_1intr(dev, mpt->msi_enable, &iqd,
+           &irq_flags);
        mpt->pci_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &iqd,
        mpt->pci_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &iqd,
-           RF_ACTIVE | (mpt->pci_msi_count ? 0 : RF_SHAREABLE));
+           irq_flags);
        if (mpt->pci_irq == NULL) {
                device_printf(dev, "could not allocate interrupt\n");
                goto bad;
        if (mpt->pci_irq == NULL) {
                device_printf(dev, "could not allocate interrupt\n");
                goto bad;
@@ -626,10 +627,8 @@ mpt_free_bus_resources(struct mpt_softc *mpt)
                mpt->pci_irq = NULL;
        }
 
                mpt->pci_irq = NULL;
        }
 
-       if (mpt->pci_msi_count) {
+       if (mpt->irq_type == PCI_INTR_TYPE_MSI)
                pci_release_msi(mpt->dev);
                pci_release_msi(mpt->dev);
-               mpt->pci_msi_count = 0;
-       }
 
        if (mpt->pci_pio_reg) {
                bus_release_resource(mpt->dev, SYS_RES_IOPORT,
 
        if (mpt->pci_pio_reg) {
                bus_release_resource(mpt->dev, SYS_RES_IOPORT,