diff options
author | Adam Jackson <ajax@nwnk.net> | 2006-04-28 22:28:56 +0000 |
---|---|---|
committer | Adam Jackson <ajax@nwnk.net> | 2006-04-28 22:28:56 +0000 |
commit | 267133e37732631c74d0f41b9217474188b2bcd4 (patch) | |
tree | d8d6f727378c2fcccfd42acf8c4aa61efc51cd57 /hw | |
parent | c28a0c78502757bad606dee692b8dce3d3a747f0 (diff) |
Bug #6751: Use sysfs to read card ROMs if available. (Dave Airlie)
Diffstat (limited to 'hw')
-rw-r--r-- | hw/xfree86/os-support/bus/Pci.c | 14 | ||||
-rw-r--r-- | hw/xfree86/os-support/bus/Pci.h | 1 | ||||
-rw-r--r-- | hw/xfree86/os-support/bus/linuxPci.c | 43 |
3 files changed, 58 insertions, 0 deletions
diff --git a/hw/xfree86/os-support/bus/Pci.c b/hw/xfree86/os-support/bus/Pci.c index 15cd8f461..007c07a34 100644 --- a/hw/xfree86/os-support/bus/Pci.c +++ b/hw/xfree86/os-support/bus/Pci.c @@ -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; diff --git a/hw/xfree86/os-support/bus/Pci.h b/hw/xfree86/os-support/bus/Pci.h index 833c07af0..32088fe4f 100644 --- a/hw/xfree86/os-support/bus/Pci.h +++ b/hw/xfree86/os-support/bus/Pci.h @@ -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); diff --git a/hw/xfree86/os-support/bus/linuxPci.c b/hw/xfree86/os-support/bus/linuxPci.c index 3dce431a6..092f28f03 100644 --- a/hw/xfree86/os-support/bus/linuxPci.c +++ b/hw/xfree86/os-support/bus/linuxPci.c @@ -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; +} |