]> xenbits.xensource.com Git - xenclient/kernel.git/commitdiff
FLR - intermediate checkin 7 3/27 - Added GMCH platform check,
authorRoss Philipson <ross.philipson@citrix.com>
Fri, 27 Mar 2009 13:31:47 +0000 (09:31 -0400)
committerRoss Philipson <ross.philipson@citrix.com>
Fri, 27 Mar 2009 13:31:47 +0000 (09:31 -0400)
fixed and cleaned up some code.

 Changes to be committed:
modified:   drivers/xen/pciback/pciback_ops.c
modified:   include/linux/pci_ids.h

drivers/xen/pciback/pciback_ops.c
include/linux/pci_ids.h

index 94391db699fc57c95e96bbb031d3852c9c12a941..f016ccdcaa8d44ee8fd76a481954d23fa814bfaf 100644 (file)
 #include "pciback.h"
 
 #define PCIBACK_VENDOR_INTEL     0x8086
-#define PCIBACK_DEVICE_IGFX_GM45 0x2a42
-#define PCIBACK_DEVICE_IGFX_Q45  0x2e12
 #define PCIBACK_CLASS_ID_USB     0x0c03
-#define PCIBACK_CLASS_ID_VGA     0x0c00
+#define PCIBACK_CLASS_ID_VGA     0x0300
 #define PCIBACK_USB_FLRCTRL      0x4
 #define PCIBACK_IGFX_FLRCTRL     0x4
 
@@ -131,12 +129,11 @@ static void pciback_do_pci_flr(struct pci_dev *dev, int af_pos)
  */
 static int pciback_do_vendor_specific_reset(struct pci_dev *dev)
 {
+       struct pci_dev *gmch;
        int vendor_pos, i;
-       u16 vendor_id;
-       u16 device_id;
-       u16 class_id;
        u32 reg32;
-       u8  reg8;
+       u16 vendor_id, device_id, class_id;     
+       u8 reg8;
        
        pci_read_config_word(dev, PCI_VENDOR_ID, &vendor_id);
        if (vendor_id != PCIBACK_VENDOR_INTEL)
@@ -144,10 +141,21 @@ static int pciback_do_vendor_specific_reset(struct pci_dev *dev)
 
        pci_read_config_word(dev, PCI_CLASS_DEVICE, &class_id);
        if (class_id == PCIBACK_CLASS_ID_VGA) {
-               pci_read_config_word(dev, PCI_DEVICE_ID, &device_id);
-               if (device_id == PCIBACK_DEVICE_IGFX_GM45) /* TODO sufficient test ?*/
+               if (dev->bus->number != 0 || dev->devfn != PCI_DEVFN(2,0))
                        return -ENXIO;
 
+               /* Locate the GMCH (north bridge) and test for specific Intel devices */
+               gmch = pci_get_bus_and_slot(0, PCI_DEVFN(0,0));
+               if (!gmch)
+                       return -ENXIO;
+
+               pci_read_config_word(gmch, PCI_DEVICE_ID, &device_id);
+               pci_dev_put(gmch);
+
+               if (device_id != PCI_DEVICE_ID_INTEL_GMCHGM45)
+                       return -ENXIO;
+
+               /* Correct device and platform, assume vendor specific offset */
                pci_read_config_dword(dev, PCIBACK_IGFX_CAP09_OFFSET, &reg32);
                if ((reg32 & 0x000000F0) != 0x20 ||
                        ((reg32 >> 16) & 0x000000FF) != 0x06 ||
@@ -397,11 +405,10 @@ static int pciback_find_pcie_flr_caps(struct pci_dev *dev)
  */
 static int pciback_find_pci_flr_caps(struct pci_dev *dev)
 {
+       struct pci_dev *gmch;
        int af_pos;
-       u8  cap;
-       u16 vendor_id;
-       u16 device_id;
-       u8  reg8;
+       u16 vendor_id, device_id, class_id;
+       u8 cap, reg8;
 
        /* First look for the PCI AF capabilities for FLR using the capabilities list. This
         * is only used on the devices on the root/host bus (integrated devices). 
@@ -417,24 +424,44 @@ static int pciback_find_pci_flr_caps(struct pci_dev *dev)
                }
        }
 
-       /* Next look for the unchained AF capabilities for FLR using specific logic */
-       pci_read_config_word(dev, PCI_VENDOR_ID, &vendor_id);
-       if (vendor_id != PCIBACK_VENDOR_INTEL)
-               return -ENXIO;
+       /* Next look for the unchained AF capabilities for FLR using specific 
+        * logic. Currently only the graphics device on the Intel Q45 etc 
+        * systems has special logic for locating the hidden FLR caps.
+     */
+       do {
+               if (dev->bus->number != 0 || dev->devfn != PCI_DEVFN(2,0))
+                       break;
+               pci_read_config_word(dev, PCI_VENDOR_ID, &vendor_id);
+               if (vendor_id != PCIBACK_VENDOR_INTEL)
+                       break;
+               pci_read_config_word(dev, PCI_CLASS_DEVICE, &class_id);
+               if (class_id != PCIBACK_CLASS_ID_VGA)
+                       break;
 
-       pci_read_config_word(dev, PCI_DEVICE_ID, &device_id);
-       if (device_id == PCIBACK_DEVICE_IGFX_Q45) /* TODO need more IDs ?*/
-               return -ENXIO;
-       
-       af_pos = PCIBACK_IGFX_CAP13_OFFSET;
-       pci_read_config_byte(dev, af_pos + PCI_AF_LENFLD, &reg8);
-       if (reg8 == PCI_AF_LENGTH) {
-               pci_read_config_byte(dev, af_pos + PCI_AF_DEVCAP, &cap);
-               if (cap & PCI_AF_CAP_FLR) {
-                       return af_pos;
+               /* Locate the GMCH (north bridge) and test for specific Intel devices */
+               gmch = pci_get_bus_and_slot(0, PCI_DEVFN(0,0));
+               if (!gmch)
+                       break;
+
+               pci_read_config_word(gmch, PCI_DEVICE_ID, &device_id);
+               pci_dev_put(gmch);
+
+               if (device_id != PCI_DEVICE_ID_INTEL_GMCHQ45 ||
+                       device_id != PCI_DEVICE_ID_INTEL_GMCHG45 ||
+                       device_id != PCI_DEVICE_ID_INTEL_GMCHG41)
+                       break;
+               
+               /* Correct device and platform, assume AF offset */
+               af_pos = PCIBACK_IGFX_CAP13_OFFSET;
+               pci_read_config_byte(dev, af_pos + PCI_AF_LENFLD, &reg8);
+               if (reg8 == PCI_AF_LENGTH) {
+                       pci_read_config_byte(dev, af_pos + PCI_AF_DEVCAP, &cap);
+                       if (cap & PCI_AF_CAP_FLR) {
+                               return af_pos;
+                       }
                }
-       }
-       
+       } while (0);
+
        /* Else not found */
        return 0;
 }
index d81bc1325aadedf27c9ddbb7e43e0dfd431b50bb..642eaf20660c865260bc56143ec2d15e37bae5bd 100644 (file)
 #define PCI_DEVICE_ID_INTEL_82454GX    0x84c4
 #define PCI_DEVICE_ID_INTEL_82450GX    0x84c5
 #define PCI_DEVICE_ID_INTEL_82451NX    0x84ca
-#define PCI_DEVICE_ID_INTEL_82454NX     0x84cb
+#define PCI_DEVICE_ID_INTEL_82454NX 0x84cb
 #define PCI_DEVICE_ID_INTEL_84460GX    0x84ea
 #define PCI_DEVICE_ID_INTEL_IXP4XX     0x8500
 #define PCI_DEVICE_ID_INTEL_IXP2800    0x9004
-#define PCI_DEVICE_ID_INTEL_S21152BB   0xb152
+#define PCI_DEVICE_ID_INTEL_S21152BB 0xb152
+
+#define PCI_DEVICE_ID_INTEL_GMCHQ45 0x2e10
+#define PCI_DEVICE_ID_INTEL_GMCHG45 0x2e20
+#define PCI_DEVICE_ID_INTEL_MCHP45  0x2e20
+#define PCI_DEVICE_ID_INTEL_GMCHG41 0x2e30
+#define PCI_DEVICE_ID_INTEL_GMCHGM45 0x2a40
+
+#define PCI_DEVICE_ID_INTEL_GMCHG41 0x2e30
 
 #define PCI_VENDOR_ID_SCALEMP          0x8686
 #define PCI_DEVICE_ID_SCALEMP_VSMP_CTL 0x1010