aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pnp
diff options
context:
space:
mode:
authorBjorn Helgaas <bhelgaas@google.com>2012-01-05 16:27:24 -0500
committerJesse Barnes <jbarnes@virtuousgeek.org>2012-01-06 15:11:20 -0500
commiteb31aae8cb5eb54e234ed2d857ddac868195d911 (patch)
tree2026abae47901bfcd4b334f6086158fc5cbc93b3 /drivers/pnp
parent24d25dbfa63c376323096660bfa9ad45a08870ce (diff)
PNP: work around Dell 1536/1546 BIOS MMCONFIG bug that breaks USB
Some Dell BIOSes have MCFG tables that don't report the entire MMCONFIG area claimed by the chipset. If we move PCI devices into that claimed-but-unreported area, they don't work. This quirk reads the AMD MMCONFIG MSRs and adds PNP0C01 resources as needed to cover the entire area. Example problem scenario: BIOS-e820: 00000000cfec5400 - 00000000d4000000 (reserved) Fam 10h mmconf [d0000000, dfffffff] PCI: MMCONFIG for domain 0000 [bus 00-3f] at [mem 0xd0000000-0xd3ffffff] (base 0xd0000000) pnp 00:0c: [mem 0xd0000000-0xd3ffffff] pci 0000:00:12.0: reg 10: [mem 0xffb00000-0xffb00fff] pci 0000:00:12.0: no compatible bridge window for [mem 0xffb00000-0xffb00fff] pci 0000:00:12.0: BAR 0: assigned [mem 0xd4000000-0xd40000ff] Reported-by: Lisa Salimbas <lisa.salimbas@canonical.com> Reported-by: <thuban@singularity.fr> Tested-by: dann frazier <dann.frazier@canonical.com> References: https://bugzilla.kernel.org/show_bug.cgi?id=31602 References: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/647043 References: https://bugzilla.redhat.com/show_bug.cgi?id=770308 Cc: stable@kernel.org # 2.6.34+ Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'drivers/pnp')
-rw-r--r--drivers/pnp/quirks.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/drivers/pnp/quirks.c b/drivers/pnp/quirks.c
index dfbd5a6cc58b..258fef272ea7 100644
--- a/drivers/pnp/quirks.c
+++ b/drivers/pnp/quirks.c
@@ -295,6 +295,45 @@ static void quirk_system_pci_resources(struct pnp_dev *dev)
295 } 295 }
296} 296}
297 297
298#ifdef CONFIG_AMD_NB
299
300#include <asm/amd_nb.h>
301
302static void quirk_amd_mmconfig_area(struct pnp_dev *dev)
303{
304 resource_size_t start, end;
305 struct pnp_resource *pnp_res;
306 struct resource *res;
307 struct resource mmconfig_res, *mmconfig;
308
309 mmconfig = amd_get_mmconfig_range(&mmconfig_res);
310 if (!mmconfig)
311 return;
312
313 list_for_each_entry(pnp_res, &dev->resources, list) {
314 res = &pnp_res->res;
315 if (res->end < mmconfig->start || res->start > mmconfig->end ||
316 (res->start == mmconfig->start && res->end == mmconfig->end))
317 continue;
318
319 dev_info(&dev->dev, FW_BUG
320 "%pR covers only part of AMD MMCONFIG area %pR; adding more reservations\n",
321 res, mmconfig);
322 if (mmconfig->start < res->start) {
323 start = mmconfig->start;
324 end = res->start - 1;
325 pnp_add_mem_resource(dev, start, end, 0);
326 }
327 if (mmconfig->end > res->end) {
328 start = res->end + 1;
329 end = mmconfig->end;
330 pnp_add_mem_resource(dev, start, end, 0);
331 }
332 break;
333 }
334}
335#endif
336
298/* 337/*
299 * PnP Quirks 338 * PnP Quirks
300 * Cards or devices that need some tweaking due to incomplete resource info 339 * Cards or devices that need some tweaking due to incomplete resource info
@@ -322,6 +361,9 @@ static struct pnp_fixup pnp_fixups[] = {
322 /* PnP resources that might overlap PCI BARs */ 361 /* PnP resources that might overlap PCI BARs */
323 {"PNP0c01", quirk_system_pci_resources}, 362 {"PNP0c01", quirk_system_pci_resources},
324 {"PNP0c02", quirk_system_pci_resources}, 363 {"PNP0c02", quirk_system_pci_resources},
364#ifdef CONFIG_AMD_NB
365 {"PNP0c01", quirk_amd_mmconfig_area},
366#endif
325 {""} 367 {""}
326}; 368};
327 369