aboutsummaryrefslogtreecommitdiff
path: root/drivers/pci/pcie
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2008-07-03 15:03:02 +0200
committerIngo Molnar <mingo@elte.hu>2008-07-03 15:03:02 +0200
commita8cac817764a494705aebd99fd51bdf6cdc28ec9 (patch)
tree202847337f42b188755a53a7b57b502a7cdc0ad3 /drivers/pci/pcie
parentb4b3bd96f26586e53ab5482f1869221dd1b5ac36 (diff)
parent543cf4cb3fe6f6cae3651ba918b9c56200b257d0 (diff)
Merge commit 'v2.6.26-rc8' into x86/mce
Diffstat (limited to 'drivers/pci/pcie')
-rw-r--r--drivers/pci/pcie/aspm.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
index 61fedb2448b..f82495583e6 100644
--- a/drivers/pci/pcie/aspm.c
+++ b/drivers/pci/pcie/aspm.c
@@ -506,6 +506,23 @@ static void free_link_state(struct pci_dev *pdev)
pdev->link_state = NULL;
}
+static int pcie_aspm_sanity_check(struct pci_dev *pdev)
+{
+ struct pci_dev *child_dev;
+ int child_pos;
+
+ /*
+ * Some functions in a slot might not all be PCIE functions, very
+ * strange. Disable ASPM for the whole slot
+ */
+ list_for_each_entry(child_dev, &pdev->subordinate->devices, bus_list) {
+ child_pos = pci_find_capability(child_dev, PCI_CAP_ID_EXP);
+ if (!child_pos)
+ return -EINVAL;
+ }
+ return 0;
+}
+
/*
* pcie_aspm_init_link_state: Initiate PCI express link state.
* It is called after the pcie and its children devices are scaned.
@@ -526,6 +543,9 @@ void pcie_aspm_init_link_state(struct pci_dev *pdev)
if (list_empty(&pdev->subordinate->devices))
goto out;
+ if (pcie_aspm_sanity_check(pdev))
+ goto out;
+
mutex_lock(&aspm_lock);
link_state = kzalloc(sizeof(*link_state), GFP_KERNEL);