mpt(4): Fix an issue that caused the driver to attach to mfi(4) cards.
authorSascha Wildner <saw@online.de>
Tue, 20 Mar 2012 20:19:25 +0000 (21:19 +0100)
committerSascha Wildner <saw@online.de>
Tue, 20 Mar 2012 20:19:36 +0000 (21:19 +0100)
FreeBSD's commit message (r232411) explains it:

Fix a problem that was causing the mpt(4) driver to attach to MegaRAID
cards that should be handled by the mfi(4) driver.

The root of the problem is that the mpt(4) driver was masking off the
bottom bit of the PCI device ID when deciding which cards to attach to.

It appears that a number of the mpt(4) Fibre Channel cards had a LAN
variant whose PCI device ID was just one bit off from the FC card's device
ID.  The FC cards were even and the LAN cards were odd.

The problem was that this pattern wasn't carried over on the SAS and
parallel SCSI mpt(4) cards.  Luckily the SAS and parallel SCSI PCI device
IDs were either even numbers, or they would get masked to a supported
adjacent PCI device ID, and everything worked well.

Now LSI is using some of the odd-numbered PCI device IDs between the 3Gb
SAS device IDs for their new MegaRAID cards.  This is causing the mpt(4)
driver to attach to the RAID cards instead of the mfi(4) driver.

The solution is to stop masking off the bottom bit of the device ID, and
explicitly list the PCI device IDs of all supported cards.

This change should be a no-op for mpt(4) hardware.  The only intended
functional change is that for the 929X, the is_fc variable gets set.  It
wasn't being set previously, but needs to be because the 929X is a Fibre
Channel card.

sys/dev/disk/mpt/mpt_pci.c

index b6d60c4..ec8634e 100644 (file)
 #define        PCI_PRODUCT_LSI_FC919           0x0624
 #endif
 
+#ifndef        PCI_PRODUCT_LSI_FC919_LAN
+#define        PCI_PRODUCT_LSI_FC919_LAN       0x0625
+#endif
+
 #ifndef        PCI_PRODUCT_LSI_FC929
 #define        PCI_PRODUCT_LSI_FC929           0x0622
 #endif
 
+#ifndef        PCI_PRODUCT_LSI_FC929_LAN
+#define        PCI_PRODUCT_LSI_FC929_LAN       0x0623
+#endif
+
 #ifndef        PCI_PRODUCT_LSI_FC929X
 #define        PCI_PRODUCT_LSI_FC929X          0x0626
 #endif
 
+#ifndef        PCI_PRODUCT_LSI_FC929X_LAN
+#define        PCI_PRODUCT_LSI_FC929X_LAN      0x0627
+#endif
+
 #ifndef        PCI_PRODUCT_LSI_FC919X
 #define        PCI_PRODUCT_LSI_FC919X          0x0628
 #endif
 
+#ifndef        PCI_PRODUCT_LSI_FC919X_LAN
+#define        PCI_PRODUCT_LSI_FC919X_LAN      0x0629
+#endif
+
 #ifndef        PCI_PRODUCT_LSI_FC7X04X
 #define        PCI_PRODUCT_LSI_FC7X04X         0x0640
 #endif
 #define        PCI_PRODUCT_LSI_1030            0x0030
 #endif
 
+#ifndef        PCI_PRODUCT_LSI_1030ZC
+#define        PCI_PRODUCT_LSI_1030ZC          0x0031
+#endif
+
 #ifndef        PCI_PRODUCT_LSI_SAS1064
 #define PCI_PRODUCT_LSI_SAS1064                0x0050
 #endif
 #define PCI_PRODUCT_LSI_SAS1068                0x0054
 #endif
 
+#ifndef PCI_PRODUCT_LSI_SAS1068A
+#define PCI_PRODUCT_LSI_SAS1068A       0x0055
+#endif
+
 #ifndef PCI_PRODUCT_LSI_SAS1068E
 #define PCI_PRODUCT_LSI_SAS1068E       0x0058
 #endif
@@ -222,7 +246,7 @@ mpt_pci_probe(device_t dev)
                return (ENXIO);
        }
 
-       switch ((pci_get_device(dev) & ~1)) {
+       switch (pci_get_device(dev)) {
        case PCI_PRODUCT_LSI_FC909:
                desc = "LSILogic FC909 FC Adapter";
                break;
@@ -232,15 +256,27 @@ mpt_pci_probe(device_t dev)
        case PCI_PRODUCT_LSI_FC919:
                desc = "LSILogic FC919 FC Adapter";
                break;
+       case PCI_PRODUCT_LSI_FC919_LAN:
+               desc = "LSILogic FC919 LAN Adapter";
+               break;
        case PCI_PRODUCT_LSI_FC929:
                desc = "Dual LSILogic FC929 FC Adapter";
                break;
+       case PCI_PRODUCT_LSI_FC929_LAN:
+               desc = "Dual LSILogic FC929 LAN Adapter";
+               break;
        case PCI_PRODUCT_LSI_FC919X:
                desc = "LSILogic FC919 FC PCI-X Adapter";
                break;
+       case PCI_PRODUCT_LSI_FC919X_LAN:
+               desc = "LSILogic FC919 LAN PCI-X Adapter";
+               break;
        case PCI_PRODUCT_LSI_FC929X:
                desc = "Dual LSILogic FC929X 2Gb/s FC PCI-X Adapter";
                break;
+       case PCI_PRODUCT_LSI_FC929X_LAN:
+               desc = "Dual LSILogic FC929X LAN PCI-X Adapter";
+               break;
        case PCI_PRODUCT_LSI_FC646:
                desc = "Dual LSILogic FC7X04X 4Gb/s FC PCI-Express Adapter";
                break;
@@ -248,6 +284,7 @@ mpt_pci_probe(device_t dev)
                desc = "Dual LSILogic FC7X04X 4Gb/s FC PCI-X Adapter";
                break;
        case PCI_PRODUCT_LSI_1030:
+       case PCI_PRODUCT_LSI_1030ZC:
                desc = "LSILogic 1030 Ultra4 Adapter";
                break;
        case PCI_PRODUCT_LSI_SAS1064:
@@ -256,6 +293,7 @@ mpt_pci_probe(device_t dev)
        case PCI_PRODUCT_LSI_SAS1066:
        case PCI_PRODUCT_LSI_SAS1066E:
        case PCI_PRODUCT_LSI_SAS1068:
+       case PCI_PRODUCT_LSI_SAS1068A:
        case PCI_PRODUCT_LSI_SAS1068E:
        case PCI_PRODUCT_LSI_SAS1078:
        case PCI_PRODUCT_LSI_SAS1078DE:
@@ -385,12 +423,17 @@ mpt_pci_attach(device_t dev)
                return (ENOMEM);
        }
        memset(mpt, 0, sizeof(struct mpt_softc));
-       switch ((pci_get_device(dev) & ~1)) {
+       switch (pci_get_device(dev)) {
        case PCI_PRODUCT_LSI_FC909:
        case PCI_PRODUCT_LSI_FC909A:
        case PCI_PRODUCT_LSI_FC919:
+       case PCI_PRODUCT_LSI_FC919_LAN:
        case PCI_PRODUCT_LSI_FC929:
+       case PCI_PRODUCT_LSI_FC929_LAN:
+       case PCI_PRODUCT_LSI_FC929X:
+       case PCI_PRODUCT_LSI_FC929X_LAN:
        case PCI_PRODUCT_LSI_FC919X:
+       case PCI_PRODUCT_LSI_FC919X_LAN:
        case PCI_PRODUCT_LSI_FC646:
        case PCI_PRODUCT_LSI_FC7X04X:
                mpt->is_fc = 1;
@@ -401,6 +444,7 @@ mpt_pci_attach(device_t dev)
        case PCI_PRODUCT_LSI_SAS1066:
        case PCI_PRODUCT_LSI_SAS1066E:
        case PCI_PRODUCT_LSI_SAS1068:
+       case PCI_PRODUCT_LSI_SAS1068A:
        case PCI_PRODUCT_LSI_SAS1068E:
        case PCI_PRODUCT_LSI_SAS1078:
        case PCI_PRODUCT_LSI_SAS1078DE:
@@ -450,11 +494,17 @@ mpt_pci_attach(device_t dev)
         * Is this part a dual?
         * If so, link with our partner (around yet)
         */
-       if ((pci_get_device(dev) & ~1) == PCI_PRODUCT_LSI_FC929 ||
-           (pci_get_device(dev) & ~1) == PCI_PRODUCT_LSI_FC646 ||
-           (pci_get_device(dev) & ~1) == PCI_PRODUCT_LSI_FC7X04X ||
-           (pci_get_device(dev) & ~1) == PCI_PRODUCT_LSI_1030) {
+       switch (pci_get_device(dev)) {
+       case PCI_PRODUCT_LSI_FC929:
+       case PCI_PRODUCT_LSI_FC929_LAN:
+       case PCI_PRODUCT_LSI_FC646:
+       case PCI_PRODUCT_LSI_FC7X04X:
+       case PCI_PRODUCT_LSI_1030:
+       case PCI_PRODUCT_LSI_1030ZC:
                mpt_link_peer(mpt);
+               break;
+       default:
+               break;
        }
 
        /*