? doc/Xserver.1x Index: hw/xfree86/os-support/bus/Pci.c =================================================================== RCS file: /cvs/xorg/xserver/xorg/hw/xfree86/os-support/bus/Pci.c,v retrieving revision 1.13 diff -u -u -r1.13 Pci.c --- hw/xfree86/os-support/bus/Pci.c 25 Mar 2006 19:52:04 -0000 1.13 +++ hw/xfree86/os-support/bus/Pci.c 26 Apr 2006 09:42:29 -0000 @@ -236,6 +236,8 @@ 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 @@ #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 @@ 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; Index: hw/xfree86/os-support/bus/Pci.h =================================================================== RCS file: /cvs/xorg/xserver/xorg/hw/xfree86/os-support/bus/Pci.h,v retrieving revision 1.11 diff -u -u -r1.11 Pci.h --- hw/xfree86/os-support/bus/Pci.h 29 Dec 2005 08:42:49 -0000 1.11 +++ hw/xfree86/os-support/bus/Pci.h 26 Apr 2006 09:42:29 -0000 @@ -425,6 +425,7 @@ 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); Index: hw/xfree86/os-support/bus/linuxPci.c =================================================================== RCS file: /cvs/xorg/xserver/xorg/hw/xfree86/os-support/bus/linuxPci.c,v retrieving revision 1.12 diff -u -u -r1.12 linuxPci.c --- hw/xfree86/os-support/bus/linuxPci.c 25 Mar 2006 19:52:04 -0000 1.12 +++ hw/xfree86/os-support/bus/linuxPci.c 26 Apr 2006 09:42:29 -0000 @@ -73,6 +73,7 @@ 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 @@ pciBusInfo[0] = &linuxPci0; pciFindFirstFP = pciGenFindFirst; pciFindNextFP = pciGenFindNext; + pciSetOSBIOSPtr(linuxPciHandleBIOS); } static int @@ -888,3 +890,44 @@ } #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; +}