#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
*/
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)
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, ®32);
if ((reg32 & 0x000000F0) != 0x20 ||
((reg32 >> 16) & 0x000000FF) != 0x06 ||
*/
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).
}
}
- /* 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, ®8);
- 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, ®8);
+ 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;
}
#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