Commit eb31aae8cb5eb54e234ed2d857ddac868195d911

Authored by Bjorn Helgaas
Committed by Jesse Barnes
1 parent 24d25dbfa6

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>

Showing 1 changed file with 42 additions and 0 deletions Side-by-side Diff

drivers/pnp/quirks.c
... ... @@ -295,6 +295,45 @@
295 295 }
296 296 }
297 297  
  298 +#ifdef CONFIG_AMD_NB
  299 +
  300 +#include <asm/amd_nb.h>
  301 +
  302 +static 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 338 * PnP Quirks
300 339 * Cards or devices that need some tweaking due to incomplete resource info
... ... @@ -322,6 +361,9 @@
322 361 /* PnP resources that might overlap PCI BARs */
323 362 {"PNP0c01", quirk_system_pci_resources},
324 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