diff options
author | Ingo Molnar <mingo@elte.hu> | 2008-06-16 11:20:28 +0200 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-06-16 11:20:28 +0200 |
commit | faeca31d068090285b77c39574d2bda14b079c50 (patch) | |
tree | 789841a7f0d336b24a74f2191542a2eb8177c8fa /drivers/pci/pcie/aspm.c | |
parent | 499f8f84b8324ba27d756e03f373fa16eeed9ccc (diff) | |
parent | 066519068ad2fbe98c7f45552b1f592903a9c8c8 (diff) |
Merge branch 'linus' into x86/pat
Diffstat (limited to 'drivers/pci/pcie/aspm.c')
-rw-r--r-- | drivers/pci/pcie/aspm.c | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index 61fedb2448b6..f82495583e63 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); |