Bug #6751: Use the Linux PCI ROM interface on Linux properly. The old

domain code, still modified BARs not a good idea, Just talk to sysfs,
    if 0 read, fallback to old methods.
This commit is contained in:
Dave Airlie 2006-04-26 11:40:58 +00:00
parent c339b221d3
commit 26fa45b642
4 changed files with 69 additions and 0 deletions

View File

@ -1,3 +1,14 @@
2006-04-26 Dave Airlie <airlied@linux.ie>
* hw/xfree86/os-support/bus/Pci.c: (pciSetOSBIOSPtr),
(HandlePciBios):
* hw/xfree86/os-support/bus/Pci.h:
* hw/xfree86/os-support/bus/linuxPci.c: (linuxPciInit),
(linuxPciHandleBIOS):
Bug #6751: Use the Linux PCI ROM interface on Linux properly
The old domain code, still modified BARs not a good idea,
Just talk to sysfs, if 0 read, fallback to old methods.
2006-04-26 Dave Airlie <airlied@linux.ie>
* hw/xfree86/common/xf86pciBus.c:

View File

@ -236,6 +236,8 @@ static pciConfigPtr pci_devp[MAX_PCI_DEVICES + 1] = {NULL, };
static int readPciBios( PCITAG Tag, CARD8* tmp, ADDRESS hostbase,
unsigned char * buf, int len, PciBiosType BiosType );
static int (*pciOSHandleBIOS)(PCITAG Tag, int basereg, unsigned char *buf, int len);
/*
* Platform specific PCI function pointers.
*
@ -269,6 +271,11 @@ pciInit()
#endif
}
void pciSetOSBIOSPtr(int (*bios_fn)(PCITAG Tag, int basereg, unsigned char * buf, int len))
{
pciOSHandleBIOS = bios_fn;
}
_X_EXPORT PCITAG
pciFindFirst(CARD32 id, CARD32 mask)
{
@ -1279,6 +1286,13 @@ HandlePciBios(PCITAG Tag, int basereg, unsigned char * buf, int len)
PCITAG *pTag;
int i;
/* fall back to the old code if the OS code fails */
if (pciOSHandleBIOS) {
n = pciOSHandleBIOS(Tag, basereg, buf, len);
if (n)
return n;
}
n = handlePciBIOS( Tag, basereg, buf, len );
if (n)
return n;

View File

@ -425,6 +425,7 @@ CARD32 pciByteSwap(CARD32);
Bool pciMfDev(int, int);
ADDRESS pciAddrNOOP(PCITAG tag, PciAddrType type, ADDRESS);
extern void pciSetOSBIOSPtr(int (*bios_fn)(PCITAG Tag, int basereg, unsigned char * buf, int len));
extern PCITAG (*pciFindFirstFP)(void);
extern PCITAG (*pciFindNextFP)(void);

View File

@ -73,6 +73,7 @@ static CARD8 linuxPciCfgReadByte(PCITAG tag, int off);
static void linuxPciCfgWriteByte(PCITAG tag, int off, CARD8 val);
static CARD16 linuxPciCfgReadWord(PCITAG tag, int off);
static void linuxPciCfgWriteWord(PCITAG tag, int off, CARD16 val);
static int linuxPciHandleBIOS(PCITAG Tag, int basereg, unsigned char *buf, int len);
static pciBusFuncs_t linuxFuncs0 = {
/* pciReadLong */ linuxPciCfgRead,
@ -121,6 +122,7 @@ linuxPciInit()
pciBusInfo[0] = &linuxPci0;
pciFindFirstFP = pciGenFindFirst;
pciFindNextFP = pciGenFindNext;
pciSetOSBIOSPtr(linuxPciHandleBIOS);
}
static int
@ -888,3 +890,44 @@ xf86AccResFromOS(resPtr pRes)
}
#endif /* !INCLUDE_XF86_NO_DOMAIN */
int linuxPciHandleBIOS(PCITAG Tag, int basereg, unsigned char *buf, int len)
{
unsigned int dom, bus, dev, func;
unsigned int fd;
char file[256];
struct stat st;
int ret;
int sofar = 0;
dom = PCI_DOM_FROM_TAG(Tag);
bus = PCI_BUS_FROM_TAG(Tag);
dev = PCI_DEV_FROM_TAG(Tag);
func = PCI_FUNC_FROM_TAG(Tag);
sprintf(file, "/sys/bus/pci/devices/%04x:%02x:%02x.%1x/rom",
dom, bus, dev, func);
if (stat(file, &st) == 0)
{
if ((fd = open(file, O_RDWR)))
basereg = 0x0;
/* enable the ROM first */
write(fd, "1", 2);
lseek(fd, 0, SEEK_SET);
do {
/* copy the ROM until we hit Len, EOF or read error */
ret = read(fd, buf+sofar, len-sofar);
if (ret <= 0)
break;
sofar += ret;
} while (sofar < len);
write(fd, "0", 2);
close(fd);
if (sofar < len)
xf86MsgVerb(X_INFO, 3, "Attempted to read BIOS %dKB from %s: got %dKB\n", len/1024, file, sofar/1024);
return sofar;
}
return 0;
}