Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 87181
b: refs/heads/master
c: 0509ad5
h: refs/heads/master
i:
  87179: da9ae69
v: v3
  • Loading branch information
Bjorn Helgaas authored and Linus Torvalds committed Mar 12, 2008
1 parent abdeeaf commit 797903f
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: e0aca2330b59752193877da49c6e6b07df78690a
refs/heads/master: 0509ad5e1a7d9220f09edd5be114bf3bd51a7023
73 changes: 73 additions & 0 deletions trunk/drivers/pnp/quirks.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,77 @@ static void quirk_sb16audio_resources(struct pnp_dev *dev)
"pnp: SB audio device quirk - increasing port range\n");
}


#include <linux/pci.h>

static void quirk_system_pci_resources(struct pnp_dev *dev)
{
struct pci_dev *pdev = NULL;
resource_size_t pnp_start, pnp_end, pci_start, pci_end;
int i, j;

/*
* Some BIOSes have PNP motherboard devices with resources that
* partially overlap PCI BARs. The PNP system driver claims these
* motherboard resources, which prevents the normal PCI driver from
* requesting them later.
*
* This patch disables the PNP resources that conflict with PCI BARs
* so they won't be claimed by the PNP system driver.
*/
for_each_pci_dev(pdev) {
for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
if (!(pci_resource_flags(pdev, i) & IORESOURCE_MEM) ||
pci_resource_len(pdev, i) == 0)
continue;

pci_start = pci_resource_start(pdev, i);
pci_end = pci_resource_end(pdev, i);
for (j = 0; j < PNP_MAX_MEM; j++) {
if (!pnp_mem_valid(dev, j) ||
pnp_mem_len(dev, j) == 0)
continue;

pnp_start = pnp_mem_start(dev, j);
pnp_end = pnp_mem_end(dev, j);

/*
* If the PNP region doesn't overlap the PCI
* region at all, there's no problem.
*/
if (pnp_end < pci_start || pnp_start > pci_end)
continue;

/*
* If the PNP region completely encloses (or is
* at least as large as) the PCI region, that's
* also OK. For example, this happens when the
* PNP device describes a bridge with PCI
* behind it.
*/
if (pnp_start <= pci_start &&
pnp_end >= pci_end)
continue;

/*
* Otherwise, the PNP region overlaps *part* of
* the PCI region, and that might prevent a PCI
* driver from requesting its resources.
*/
dev_warn(&dev->dev, "mem resource "
"(0x%llx-0x%llx) overlaps %s BAR %d "
"(0x%llx-0x%llx), disabling\n",
(unsigned long long) pnp_start,
(unsigned long long) pnp_end,
pci_name(pdev), i,
(unsigned long long) pci_start,
(unsigned long long) pci_end);
pnp_mem_flags(dev, j) = 0;
}
}
}
}

/*
* PnP Quirks
* Cards or devices that need some tweaking due to incomplete resource info
Expand All @@ -128,6 +199,8 @@ static struct pnp_fixup pnp_fixups[] = {
{"CTL0043", quirk_sb16audio_resources},
{"CTL0044", quirk_sb16audio_resources},
{"CTL0045", quirk_sb16audio_resources},
{"PNP0c01", quirk_system_pci_resources},
{"PNP0c02", quirk_system_pci_resources},
{""}
};

Expand Down

0 comments on commit 797903f

Please sign in to comment.