diff options
author | Shaohua Li <shaohua.li@intel.com> | 2008-10-13 19:39:25 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2008-10-22 14:13:25 -0700 |
commit | 7a69c701bd95e1dc0eaf7e4008e5fd409ac7e042 (patch) | |
tree | d0b959f0e1c3b02111a1b54ec16d6dcdd3996e82 | |
parent | 7a17866e8cc637a5ffb91266e3b551ae3c95b40a (diff) |
PCI: disable ASPM on pre-1.1 PCIe devices
commit 149e16372a2066c5474d8a8db9b252afd57eb427 upstream
Disable ASPM on pre-1.1 PCIe devices, as many of them don't implement it
correctly.
Tested-by: Jack Howarth <howarth@bromo.msbb.uc.edu>
Signed-off-by: Shaohua Li <shaohua.li@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Cc: Chuck Ebbert <cebbert@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r-- | drivers/pci/pcie/aspm.c | 13 | ||||
-rw-r--r-- | drivers/pci/probe.c | 3 | ||||
-rw-r--r-- | include/linux/pci_regs.h | 1 |
3 files changed, 16 insertions, 1 deletions
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index 759c51a4e399..704605298c5e 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c @@ -510,6 +510,7 @@ static int pcie_aspm_sanity_check(struct pci_dev *pdev) { struct pci_dev *child_dev; int child_pos; + u32 reg32; /* * Some functions in a slot might not all be PCIE functions, very @@ -519,6 +520,18 @@ static int pcie_aspm_sanity_check(struct pci_dev *pdev) child_pos = pci_find_capability(child_dev, PCI_CAP_ID_EXP); if (!child_pos) return -EINVAL; + + /* + * Disable ASPM for pre-1.1 PCIe device, we follow MS to use + * RBER bit to determine if a function is 1.1 version device + */ + pci_read_config_dword(child_dev, child_pos + PCI_EXP_DEVCAP, + ®32); + if (!(reg32 & PCI_EXP_DEVCAP_RBER)) { + printk("Pre-1.1 PCIe device detected, " + "disable ASPM for %s\n", pci_name(pdev)); + return -EINVAL; + } } return 0; } diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 3706ce7972dd..4f90250a5d31 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -1047,7 +1047,8 @@ int pci_scan_slot(struct pci_bus *bus, int devfn) } } - if (bus->self) + /* only one slot has pcie device */ + if (bus->self && nr) pcie_aspm_init_link_state(bus->self); return nr; diff --git a/include/linux/pci_regs.h b/include/linux/pci_regs.h index c0c1223c9194..81045aa504e3 100644 --- a/include/linux/pci_regs.h +++ b/include/linux/pci_regs.h @@ -373,6 +373,7 @@ #define PCI_EXP_DEVCAP_ATN_BUT 0x1000 /* Attention Button Present */ #define PCI_EXP_DEVCAP_ATN_IND 0x2000 /* Attention Indicator Present */ #define PCI_EXP_DEVCAP_PWR_IND 0x4000 /* Power Indicator Present */ +#define PCI_EXP_DEVCAP_RBER 0x8000 /* Role-Based Error Reporting */ #define PCI_EXP_DEVCAP_PWR_VAL 0x3fc0000 /* Slot Power Limit Value */ #define PCI_EXP_DEVCAP_PWR_SCL 0xc000000 /* Slot Power Limit Scale */ #define PCI_EXP_DEVCTL 8 /* Device Control */ |