diff --git a/ChangeLog b/ChangeLog index a2972a0a1..b865ec109 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2006-05-18 Adam Jackson + + * hw/xfree86/os-support/linux/lnx_pci.c: + Bug #6377: Ignore disabled BARs, and allow matching BARs + aligned to less than 16 bytes. (Felix Kühling, ATI) + 2006-05-18 Adam Jackson * hw/xfree86/os-support/linux/lnx_acpi.c: diff --git a/hw/xfree86/os-support/linux/lnx_pci.c b/hw/xfree86/os-support/linux/lnx_pci.c index cec9226c8..3505887bc 100644 --- a/hw/xfree86/os-support/linux/lnx_pci.c +++ b/hw/xfree86/os-support/linux/lnx_pci.c @@ -202,22 +202,26 @@ xf86GetOSOffsetFromPCI(PCITAG tag, int space, unsigned long base) if (tag == pciTag(bus,dev,fn)) { /* ok now look through all the BAR values of this device */ for (ndx=0; ndx<7; ndx++) { - unsigned long savePtr; - /* - * remember to lop of the last 4bits of the BAR values as they are - * memory attributes - */ + unsigned long savePtr, flagMask; if (ndx == 6) - savePtr = (0xFFFFFFF0) & - pciReadLong(tag, PCI_CMD_BIOS_REG); + savePtr = pciReadLong(tag, PCI_CMD_BIOS_REG); else /* this the ROM bar */ - savePtr = (0xFFFFFFF0) & - pciReadLong(tag, PCI_CMD_BASE_REG + (0x4 * ndx)); + savePtr = pciReadLong(tag, PCI_CMD_BASE_REG + (0x4 * ndx)); + /* Ignore unset base addresses. The kernel may + * have reported non-zero size and address even + * if they are disabled (e.g. disabled ROM BAR). + */ + if (savePtr == 0) + continue; + /* Remove memory attribute bits, different for IO + * and memory ranges. */ + flagMask = (savePtr & 0x1) ? ~0x3UL : ~0xFUL; + savePtr &= flagMask; /* find the index of the incoming base */ - if (base >= savePtr && base <= (savePtr + size[ndx])) { + if (base >= savePtr && base < (savePtr + size[ndx])) { fclose(file); - return (offset[ndx] & ~(0xFUL)) + (base - savePtr); + return (offset[ndx] & flagMask) + (base - savePtr); } } }