Commit 1307ef66 authored by Ivan Kokshaysky's avatar Ivan Kokshaysky Committed by Linus Torvalds

[PATCH] PCI: probing read-only BARs

Some pci devices may have base address registers locked with non-zero values.
Examples:
- AGP aperture BAR of AMD-7xx host bridges: if the AGP window disabled,
  this BAR is read-only and read as 0x00000008;
- BAR0-4 of ALi IDE controllers can be non-zero and read-only.

Obviously, we can't calculate correct size of the respective region in
this case (for AMD AGP window we'll get 4 GB resource - ouch).
So I think that we should ignore r/o BARs (let the device specific
fixups deal with them if needed).

Patch appended (note that extra write(0)/read-back pair is required,
as the BAR might be programmed with all 1s).
parent fda0b1ed
...@@ -46,7 +46,7 @@ static u32 pci_size(u32 base, unsigned long mask) ...@@ -46,7 +46,7 @@ static u32 pci_size(u32 base, unsigned long mask)
static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom) static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom)
{ {
unsigned int pos, reg, next; unsigned int pos, reg, next;
u32 l, sz; u32 l, l0, sz;
struct resource *res; struct resource *res;
for(pos=0; pos<howmany; pos = next) { for(pos=0; pos<howmany; pos = next) {
...@@ -55,10 +55,12 @@ static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom) ...@@ -55,10 +55,12 @@ static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom)
res->name = dev->name; res->name = dev->name;
reg = PCI_BASE_ADDRESS_0 + (pos << 2); reg = PCI_BASE_ADDRESS_0 + (pos << 2);
pci_read_config_dword(dev, reg, &l); pci_read_config_dword(dev, reg, &l);
pci_write_config_dword(dev, reg, 0);
pci_read_config_dword(dev, reg, &l0);
pci_write_config_dword(dev, reg, ~0); pci_write_config_dword(dev, reg, ~0);
pci_read_config_dword(dev, reg, &sz); pci_read_config_dword(dev, reg, &sz);
pci_write_config_dword(dev, reg, l); pci_write_config_dword(dev, reg, l);
if (!sz || sz == 0xffffffff) if (!sz || sz == 0xffffffff || sz == l0)
continue; continue;
if (l == 0xffffffff) if (l == 0xffffffff)
l = 0; l = 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment