Added linux 2.6 compatible domain aware device scanning code.
Additional scanning code uses the /sys interface of 2.6 kernels. Cleaned up the use of tags and already split domain/bus/dev/fn.
This commit is contained in:
parent
6319f7d713
commit
5afc6c1a14
|
@ -20,6 +20,8 @@
|
|||
* pciSetBitsByte() - Write an 8 bit value against a mask
|
||||
* pciTag() - Return tag for a given PCI bus, device, &
|
||||
* function
|
||||
* pciDomTag() - Return tag for a given PCI domain, bus,
|
||||
* device & function
|
||||
* pciBusAddrToHostAddr() - Convert a PCI address to a host address
|
||||
* pciHostAddrToBusAddr() - Convert a host address to a PCI address
|
||||
* pciGetBaseSize() - Returns the number of bits in a PCI base
|
||||
|
@ -614,6 +616,12 @@ pciTag(int busnum, int devnum, int funcnum)
|
|||
return(PCI_MAKE_TAG(busnum,devnum,funcnum));
|
||||
}
|
||||
|
||||
_X_EXPORT PCITAG
|
||||
pciDomTag(int domnum, int busnum, int devnum, int funcnum)
|
||||
{
|
||||
return(PCI_MAKE_TAG(PCI_MAKE_BUS(domnum,busnum),devnum,funcnum));
|
||||
}
|
||||
|
||||
#if defined(PCI_MFDEV_SUPPORT)
|
||||
|
||||
Bool
|
||||
|
|
|
@ -766,6 +766,7 @@ void pciSetBitsByte(PCITAG tag, int offset, CARD8 mask, CARD8 val);
|
|||
ADDRESS pciBusAddrToHostAddr(PCITAG tag, PciAddrType type, ADDRESS addr);
|
||||
ADDRESS pciHostAddrToBusAddr(PCITAG tag, PciAddrType type, ADDRESS addr);
|
||||
PCITAG pciTag(int busnum, int devnum, int funcnum);
|
||||
PCITAG pciDomTag(int domnum, int busnum, int devnum, int funcnum);
|
||||
int pciGetBaseSize(PCITAG tag, int indx, Bool destructive, Bool *min);
|
||||
CARD32 pciCheckForBrokenBase(PCITAG tag,int basereg);
|
||||
pointer xf86MapPciMem(int ScreenNum, int Flags, PCITAG Tag,
|
||||
|
|
|
@ -3,7 +3,9 @@
|
|||
#include <xorg-config.h>
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <dirent.h>
|
||||
#include <X11/X.h>
|
||||
#include "os.h"
|
||||
#include "xf86.h"
|
||||
|
@ -25,8 +27,10 @@
|
|||
int lnxPciInit(void);
|
||||
|
||||
struct pci_dev {
|
||||
unsigned int domain;
|
||||
unsigned int bus;
|
||||
unsigned int devfn;
|
||||
unsigned int dev;
|
||||
unsigned int fn;
|
||||
PCIADDR_TYPE offset[7];
|
||||
PCIADDR_TYPE size[7];
|
||||
struct pci_dev *next;
|
||||
|
@ -38,10 +42,53 @@ int xf86OSLinuxNumPciDevs = 0;
|
|||
static struct pci_dev *xf86OSLinuxGetPciDevs(void) {
|
||||
char c[0x200];
|
||||
FILE *file = NULL;
|
||||
DIR *dir;
|
||||
struct dirent *dirent;
|
||||
struct pci_dev *tmp, *ret = NULL;
|
||||
unsigned int num;
|
||||
unsigned int i, num, devfn;
|
||||
unsigned PCIADDR_TYPE begin, end;
|
||||
char *res;
|
||||
|
||||
/* Try 2.6 devices first, with domain support */
|
||||
if ( (dir = opendir ("/sys/bus/pci/devices")) ) {
|
||||
xf86OSLinuxNumPciDevs = 0;
|
||||
while ( (dirent = readdir (dir)) ) {
|
||||
unsigned int domain, bus, dev, fn;
|
||||
if (sscanf (dirent->d_name, "%04x:%02x:%02x.%01x",
|
||||
&domain, &bus, &dev, &fn) == 4) {
|
||||
tmp = xcalloc (sizeof(struct pci_dev), 1);
|
||||
tmp->domain = domain;
|
||||
tmp->bus = bus;
|
||||
tmp->dev = dev;
|
||||
tmp->fn = fn;
|
||||
sprintf (c, "/sys/bus/pci/devices/%12s/resource",
|
||||
dirent->d_name);
|
||||
i = 0;
|
||||
if ( (file = fopen (c, "r")) ) {
|
||||
while (i < 7 && fgets (c, 0x200, file)) {
|
||||
if (sscanf (c, PCIADDR_FMT " " PCIADDR_FMT " "
|
||||
PCIADDR_IGNORE_FMT, &begin, &end) == 2) {
|
||||
tmp->offset[i] = begin;
|
||||
tmp->size[i] = begin ? end-begin+1 : 0;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
fclose (file);
|
||||
}
|
||||
if (i > 0) {
|
||||
tmp->next = ret;
|
||||
ret = tmp;
|
||||
xf86OSLinuxNumPciDevs++;
|
||||
} else
|
||||
xfree (tmp);
|
||||
}
|
||||
}
|
||||
closedir (dir);
|
||||
}
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
file = fopen("/proc/bus/pci/devices", "r");
|
||||
if (!file) return NULL;
|
||||
|
||||
|
@ -70,9 +117,11 @@ static struct pci_dev *xf86OSLinuxGetPciDevs(void) {
|
|||
"\t" PCIADDR_FMT
|
||||
"\t" PCIADDR_FMT
|
||||
"\t" PCIADDR_FMT,
|
||||
&tmp->bus,&tmp->devfn,&tmp->offset[0],&tmp->offset[1],&tmp->offset[2],&tmp->offset[3],
|
||||
&tmp->bus,&devfn,&tmp->offset[0],&tmp->offset[1],&tmp->offset[2],&tmp->offset[3],
|
||||
&tmp->offset[4],&tmp->offset[5],&tmp->offset[6], &tmp->size[0], &tmp->size[1], &tmp->size[2],
|
||||
&tmp->size[3], &tmp->size[4], &tmp->size[5], &tmp->size[6]);
|
||||
tmp->dev = devfn >> 3;
|
||||
tmp->fn = devfn & 0x7;
|
||||
if (num != 16) { /* apparantly not 2.3 style */
|
||||
xfree(tmp);
|
||||
fclose(file);
|
||||
|
@ -114,10 +163,8 @@ xf86GetPciSizeFromOS(PCITAG tag, int index, int* bits)
|
|||
return FALSE;
|
||||
|
||||
for (device = xf86OSLinuxPCIDevs; device; device = device->next) {
|
||||
dev = device->devfn >> 3;
|
||||
fn = device->devfn & 0x7;
|
||||
if (tag == pciTag(device->bus,dev,fn)) {
|
||||
*bits = 0;
|
||||
if (tag == pciDomTag (device->domain, device->bus,
|
||||
device->dev, device->fn)) {
|
||||
if (device->size[index] != 0) {
|
||||
Size = device->size[index] - ((PCIADDR_TYPE) 1);
|
||||
while (Size & ((PCIADDR_TYPE) 0x01)) {
|
||||
|
@ -151,9 +198,8 @@ xf86GetPciOffsetFromOS(PCITAG tag, int index, unsigned long* bases)
|
|||
return FALSE;
|
||||
|
||||
for (device = xf86OSLinuxPCIDevs; device; device = device->next) {
|
||||
dev = device->devfn >> 3;
|
||||
fn = device->devfn & 0x7;
|
||||
if (tag == pciTag(device->bus,dev,fn)) {
|
||||
if (tag == pciDomTag (device->domain, device->bus,
|
||||
device->dev, device->fn)) {
|
||||
/* return the offset for the index requested */
|
||||
*bases = device->offset[index];
|
||||
return TRUE;
|
||||
|
@ -179,9 +225,8 @@ xf86GetOSOffsetFromPCI(PCITAG tag, int space, unsigned long base)
|
|||
}
|
||||
|
||||
for (device = xf86OSLinuxPCIDevs; device; device = device->next) {
|
||||
dev = device->devfn >> 3;
|
||||
fn = device->devfn & 0x7;
|
||||
if (tag == pciTag(device->bus, dev, fn)) {
|
||||
if (tag == pciDomTag (device->domain, device->bus,
|
||||
device->dev, device->fn)) {
|
||||
/* ok now look through all the BAR values of this device */
|
||||
pciConfigPtr pDev = xf86GetPciConfigFromTag(tag);
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user