mirror of
https://github.com/X11Libre/xserver.git
synced 2026-11-01 03:03:58 +00:00
Bug #4139: Fix a BAR remapping bug that could lead to IERR and system hang.
(Egbert Eich)
This commit is contained in:
parent
91239d83f4
commit
deebf6bd51
8 changed files with 181 additions and 73 deletions
|
|
@ -1068,6 +1068,20 @@ xf86scanpci(int flags)
|
|||
return pci_devp;
|
||||
}
|
||||
|
||||
pciConfigPtr
|
||||
xf86GetPciConfigFromTag(PCITAG Tag)
|
||||
{
|
||||
pciConfigPtr pDev;
|
||||
int i = 0;
|
||||
|
||||
for (i = 0 ; (pDev = pci_devp[i]) && i <= MAX_PCI_DEVICES; i++) {
|
||||
if (Tag == pDev->tag)
|
||||
return pDev;
|
||||
}
|
||||
|
||||
return NULL; /* Bad data */
|
||||
}
|
||||
|
||||
CARD32
|
||||
pciCheckForBrokenBase(PCITAG Tag,int basereg)
|
||||
{
|
||||
|
|
@ -1158,13 +1172,18 @@ handlePciBIOS( PCITAG Tag, int basereg, unsigned char * buf, int len )
|
|||
|
||||
/* if we use a mem base save it and move it out of the way */
|
||||
if (b_reg >= 0 && b_reg <= 5) {
|
||||
memType emptybase;
|
||||
savebase = pciReadLong(Tag, PCI_MAP_REG_START+(b_reg<<2));
|
||||
xf86MsgVerb(X_INFO,5,"xf86ReadPciBios: modifying membase[%i]"
|
||||
" for device %i:%i:%i\n", basereg,
|
||||
(int)PCI_BUS_FROM_TAG(Tag), (int)PCI_DEV_FROM_TAG(Tag),
|
||||
(int)PCI_FUNC_FROM_TAG(Tag));
|
||||
if (!(emptybase = getEmptyPciRange(Tag,b_reg))) {
|
||||
xf86Msg(X_ERROR,"Cannot find empty range to map base to\n");
|
||||
return 0;
|
||||
}
|
||||
pciWriteLong(Tag, PCI_MAP_REG_START + (b_reg << 2),
|
||||
(CARD32)~0);
|
||||
emptybase);
|
||||
}
|
||||
/* Set ROM base address and enable ROM address decoding */
|
||||
pciWriteLong(Tag, PCI_MAP_ROM_REG, romaddr
|
||||
|
|
|
|||
|
|
@ -774,6 +774,7 @@ pointer xf86MapPciMem(int ScreenNum, int Flags, PCITAG Tag,
|
|||
int xf86ReadPciBIOS(unsigned long Offset, PCITAG Tag, int basereg,
|
||||
unsigned char *Buf, int Len);
|
||||
pciConfigPtr *xf86scanpci(int flags);
|
||||
pciConfigPtr xf86GetPciConfigFromTag(PCITAG Tag);
|
||||
|
||||
extern int pciNumBuses;
|
||||
|
||||
|
|
|
|||
|
|
@ -201,12 +201,14 @@ xf86GetOSOffsetFromPCI(PCITAG tag, int space, unsigned long base)
|
|||
fn = devfn & 0x7;
|
||||
if (tag == pciTag(bus,dev,fn)) {
|
||||
/* ok now look through all the BAR values of this device */
|
||||
pciConfigPtr pDev = xf86GetPciConfigFromTag(tag);
|
||||
|
||||
for (ndx=0; ndx<7; ndx++) {
|
||||
unsigned long savePtr, flagMask;
|
||||
if (ndx == 6)
|
||||
savePtr = pciReadLong(tag, PCI_CMD_BIOS_REG);
|
||||
savePtr = pDev->pci_baserom;
|
||||
else /* this the ROM bar */
|
||||
savePtr = pciReadLong(tag, PCI_CMD_BASE_REG + (0x4 * ndx));
|
||||
savePtr = (&pDev->pci_base0)[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).
|
||||
|
|
|
|||
Loading…
Reference in a new issue