diff --git a/hw/xfree86/common/xf86pciBus.c b/hw/xfree86/common/xf86pciBus.c index b763042cc..ae33568b8 100644 --- a/hw/xfree86/common/xf86pciBus.c +++ b/hw/xfree86/common/xf86pciBus.c @@ -1398,7 +1398,7 @@ fixPciResource(int prt, memType alignment, pciVideoPtr pvp, unsigned long type) (*p_base) = H2B(tag,range.rBegin,type); #ifdef DEBUG ErrorF("New PCI res %i base: 0x%lx, size: 0x%lx, type %s\n", - res_n,(*p_base),(1 << (*p_size)), + res_n,(*p_base),(1L << (*p_size)), ((type & ResPhysMask) == ResMem) ? "Mem" : "Io"); #endif if (res_n != 0xff) { @@ -1577,8 +1577,8 @@ findPciRange(PCITAG tag, resPtr m, resPtr avoid, CARD32 size) return 0; } -pciVideoPtr -getPciVideoPtr(tag) +static pciVideoPtr +getPciVideoPtr(PCITAG tag) { int n = 0; diff --git a/hw/xfree86/int10/Makefile.am b/hw/xfree86/int10/Makefile.am index c059070ec..3a18afb8a 100644 --- a/hw/xfree86/int10/Makefile.am +++ b/hw/xfree86/int10/Makefile.am @@ -13,8 +13,12 @@ COMMON_SOURCES = \ xf86int10.c \ xf86int10module.c +if I386_VIDEO +I386_VIDEO_CFLAGS = -D_PC +endif + if INT10_VM86 -AM_CFLAGS = -D_PC -D_VM86_LINUX $(XORG_CFLAGS) $(EXTRA_CFLAGS) +AM_CFLAGS = $(I386_VIDEO_CFLAGS) -D_VM86_LINUX $(XORG_CFLAGS) $(EXTRA_CFLAGS) INCLUDES = $(XORG_INCS) libint10_la_SOURCES = \ $(COMMON_SOURCES) \ @@ -23,7 +27,8 @@ libint10_la_SOURCES = \ endif if INT10_X86EMU -AM_CFLAGS = -D_X86EMU -DNO_SYS_HEADERS -D_PC $(XORG_CFLAGS) $(EXTRA_CFLAGS) +AM_CFLAGS = $(I386_VIDEO_CFLAGS) -D_X86EMU -DNO_SYS_HEADERS \ + $(XORG_CFLAGS) $(EXTRA_CFLAGS) INCLUDES = $(XORG_INCS) -I$(srcdir)/../x86emu libint10_la_SOURCES = \ $(COMMON_SOURCES) \ @@ -33,7 +38,7 @@ libint10_la_SOURCES = \ endif if INT10_STUB -AM_CFLAGS = -D_PC -D_VM86_LINUX $(XORG_CFLAGS) $(EXTRA_CFLAGS) +AM_CFLAGS = $(I386_VIDEO_CFLAGS) -D_VM86_LINUX $(XORG_CFLAGS) $(EXTRA_CFLAGS) libint10_la_SOURCES = stub.c xf86int10module.c endif diff --git a/hw/xfree86/int10/helper_exec.c b/hw/xfree86/int10/helper_exec.c index 734d84720..d80de89cc 100644 --- a/hw/xfree86/int10/helper_exec.c +++ b/hw/xfree86/int10/helper_exec.c @@ -469,7 +469,6 @@ Mem_wl(CARD32 addr, CARD32 val) static CARD32 PciCfg1Addr = 0; -#define TAG(Cfg1Addr) (Cfg1Addr & 0xffff00) #define OFFSET(Cfg1Addr) (Cfg1Addr & 0xff) static int @@ -480,7 +479,7 @@ pciCfg1in(CARD16 addr, CARD32 *val) return 1; } if (addr == 0xCFC) { - *val = pciReadLong(TAG(PciCfg1Addr), OFFSET(PciCfg1Addr)); + *val = pciReadLong(Int10Current->Tag, OFFSET(PciCfg1Addr)); return 1; } return 0; @@ -494,7 +493,7 @@ pciCfg1out(CARD16 addr, CARD32 val) return 1; } if (addr == 0xCFC) { - pciWriteLong(TAG(PciCfg1Addr), OFFSET(PciCfg1Addr), val); + pciWriteLong(Int10Current->Tag, OFFSET(PciCfg1Addr), val); return 1; } return 0; @@ -512,7 +511,7 @@ pciCfg1inw(CARD16 addr, CARD16 *val) } if ((addr >= 0xCFC) && (addr <= 0xCFF)) { offset = addr - 0xCFC; - *val = pciReadWord(TAG(PciCfg1Addr), OFFSET(PciCfg1Addr) + offset); + *val = pciReadWord(Int10Current->Tag, OFFSET(PciCfg1Addr) + offset); return 1; } return 0; @@ -531,7 +530,7 @@ pciCfg1outw(CARD16 addr, CARD16 val) } if ((addr >= 0xCFC) && (addr <= 0xCFF)) { offset = addr - 0xCFC; - pciWriteWord(TAG(PciCfg1Addr), OFFSET(PciCfg1Addr) + offset, val); + pciWriteWord(Int10Current->Tag, OFFSET(PciCfg1Addr) + offset, val); return 1; } return 0; @@ -549,7 +548,7 @@ pciCfg1inb(CARD16 addr, CARD8 *val) } if ((addr >= 0xCFC) && (addr <= 0xCFF)) { offset = addr - 0xCFC; - *val = pciReadByte(TAG(PciCfg1Addr), OFFSET(PciCfg1Addr) + offset); + *val = pciReadByte(Int10Current->Tag, OFFSET(PciCfg1Addr) + offset); return 1; } return 0; @@ -568,7 +567,7 @@ pciCfg1outb(CARD16 addr, CARD8 val) } if ((addr >= 0xCFC) && (addr <= 0xCFF)) { offset = addr - 0xCFC; - pciWriteByte(TAG(PciCfg1Addr), OFFSET(PciCfg1Addr) + offset, val); + pciWriteByte(Int10Current->Tag, OFFSET(PciCfg1Addr) + offset, val); return 1; } return 0; diff --git a/hw/xfree86/os-support/bus/Pci.c b/hw/xfree86/os-support/bus/Pci.c index ea6ac4ec0..b80371d83 100644 --- a/hw/xfree86/os-support/bus/Pci.c +++ b/hw/xfree86/os-support/bus/Pci.c @@ -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 diff --git a/hw/xfree86/os-support/bus/Pci.h b/hw/xfree86/os-support/bus/Pci.h index 0f1af2086..7cc882d36 100644 --- a/hw/xfree86/os-support/bus/Pci.h +++ b/hw/xfree86/os-support/bus/Pci.h @@ -119,7 +119,7 @@ /* by xf86scanpci */ #if defined(sun) && defined(SVR4) && defined(sparc) # define MAX_PCI_BUSES 4096 /* Max number of PCI buses */ -#elif defined(__alpha__) && defined (linux) +#elif (defined(__alpha__) || defined(__ia64__)) && defined (linux) # define MAX_PCI_DOMAINS 512 # define PCI_DOM_MASK 0x01fful # define MAX_PCI_BUSES (MAX_PCI_DOMAINS*256) /* 256 per domain */ @@ -258,7 +258,7 @@ # endif #elif defined(__ia64__) # if defined(linux) -# define ARCH_PCI_INIT linuxPciInit +# define ARCH_PCI_INIT ia64linuxPciInit # define INCLUDE_XF86_MAP_PCI_MEM # elif defined(FreeBSD) # define ARCH_PCI_INIT freebsdPciInit diff --git a/hw/xfree86/os-support/bus/altixPCI.c b/hw/xfree86/os-support/bus/altixPCI.c index 010f6619a..7a72ec6e7 100644 --- a/hw/xfree86/os-support/bus/altixPCI.c +++ b/hw/xfree86/os-support/bus/altixPCI.c @@ -41,13 +41,14 @@ static pciDevice *get_dev_on_bus(unsigned int segnum, unsigned int busnum) static void get_bridge_info(pciBusInfo_t *bus_info, pciDevice *pdev) { unsigned int parent_segnum, segnum = PCI_DOM_FROM_TAG(pdev->tag); - unsigned int parent_busnum, busnum = pdev->busnum; + unsigned int parent_busnum, parent_nodombus, busnum = pdev->busnum; + unsigned int nodombus = PCI_BUS_NO_DOMAIN(PCI_BUS_FROM_TAG(pdev->tag)); char bridge_path[] = "/sys/class/pci_bus/0000:00/bridge"; char bridge_target[] = "../../../devices/pci0000:00"; /* Path to this device's bridge */ sprintf(bridge_path, "/sys/class/pci_bus/%04x:%02x/bridge", segnum, - busnum); + nodombus); if (readlink(bridge_path, bridge_target, strlen(bridge_target)) < 0) { perror("failed to dereference bridge link"); @@ -56,7 +57,9 @@ static void get_bridge_info(pciBusInfo_t *bus_info, pciDevice *pdev) } sscanf(bridge_target, "../../../devices/pci%04x:%02x", &parent_segnum, - &parent_busnum); + &parent_nodombus); + + parent_busnum = PCI_MAKE_BUS(parent_segnum, parent_nodombus); /* * If there's no bridge or the bridge points to the device, use diff --git a/hw/xfree86/os-support/bus/linuxPci.c b/hw/xfree86/os-support/bus/linuxPci.c index 7d220d08a..15fc2b8c7 100644 --- a/hw/xfree86/os-support/bus/linuxPci.c +++ b/hw/xfree86/os-support/bus/linuxPci.c @@ -54,6 +54,7 @@ #include "xf86Priv.h" #include "xf86_OSlib.h" #include "Pci.h" +#include /* * linux platform specific PCI access functions -- using /proc/bus/pci @@ -73,6 +74,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 Bool linuxDomainSupport(void); static pciBusFuncs_t linuxFuncs0 = { /* pciReadLong */ linuxPciCfgRead, @@ -116,6 +118,8 @@ static pciBusInfo_t linuxPci0 = { /* from lnx_pci.c. */ extern int lnxPciInit(void); +static Bool domain_support = FALSE; + void linuxPciInit() { @@ -126,6 +130,9 @@ linuxPciInit() we'll need a fallback for 2.0 kernels here */ return; } +#ifndef INCLUDE_XF86_NO_DOMAIN + domain_support = linuxDomainSupport(); +#endif pciNumBuses = 1; pciBusInfo[0] = &linuxPci0; pciFindFirstFP = pciGenFindFirst; @@ -137,13 +144,14 @@ linuxPciInit() static int linuxPciOpenFile(PCITAG tag, Bool write) { - static int lbus,ldev,lfunc,fd = -1,is_write = 0; - int bus, dev, func; + static int ldomain, lbus,ldev,lfunc,fd = -1,is_write = 0; + int domain, bus, dev, func; char file[64]; struct stat ignored; static int is26 = -1; - bus = PCI_BUS_FROM_TAG(tag); + domain = PCI_DOM_FROM_TAG(tag); + bus = PCI_BUS_NO_DOMAIN(PCI_BUS_FROM_TAG(tag)); dev = PCI_DEV_FROM_TAG(tag); func = PCI_FUNC_FROM_TAG(tag); if (is26 == -1) { @@ -153,30 +161,41 @@ linuxPciOpenFile(PCITAG tag, Bool write) is26 = 1; } - if (fd == -1 || (write && (!is_write)) + if (!domain_support && domain > 0) + return -1; + + if (fd == -1 || (write && (!is_write)) || domain != ldomain || bus != lbus || dev != ldev || func != lfunc) { - if (fd != -1) + if (fd != -1) { close(fd); + fd = -1; + } if (is26) - sprintf(file,"/sys/bus/pci/devices/0000:%02x:%02x.%01x/config", - bus, dev, func); + sprintf(file,"/sys/bus/pci/devices/%04x:%02x:%02x.%01x/config", + domain, bus, dev, func); else { if (bus < 256) { - sprintf(file,"/proc/bus/pci/%02x",bus); - if (stat(file, &ignored) < 0) - sprintf(file, "/proc/bus/pci/0000:%02x/%02x.%1x", - bus, dev, func); - else - sprintf(file, "/proc/bus/pci/%02x/%02x.%1x", - bus, dev, func); + sprintf(file, "/proc/bus/pci/%04x:%02x", domain, bus); + if (stat(file, &ignored) < 0) { + if (domain == 0) + sprintf(file, "/proc/bus/pci/%02x/%02x.%1x", + bus, dev, func); + else + goto bail; + } else + sprintf(file, "/proc/bus/pci/%04x:%02x/%02x.%1x", + domain, bus, dev, func); } else { - sprintf(file,"/proc/bus/pci/%04x",bus); - if (stat(file, &ignored) < 0) - sprintf(file, "/proc/bus/pci/0000:%04x/%02x.%1x", - bus, dev, func); - else - sprintf(file, "/proc/bus/pci/%04x/%02x.%1x", - bus, dev, func); + sprintf(file, "/proc/bus/pci/%04x:%04x", domain, bus); + if (stat(file, &ignored) < 0) { + if (domain == 0) + sprintf(file, "/proc/bus/pci/%04x/%02x.%1x", + bus, dev, func); + else + goto bail; + } else + sprintf(file, "/proc/bus/pci/%04x:%04x/%02x.%1x", + domain, bus, dev, func); } } if (write) { @@ -191,7 +210,8 @@ linuxPciOpenFile(PCITAG tag, Bool write) fd = open(file,O_RDONLY); is_write = FALSE; } - + bail: + ldomain = domain; lbus = bus; ldev = dev; lfunc = func; @@ -489,6 +509,32 @@ linuxGetSizes(PCITAG Tag, unsigned long *io_size, unsigned long *mem_size) *mem_size = sizes->mem_size; } +static Bool +linuxDomainSupport(void) +{ + DIR *dir; + struct dirent *dirent; + char *end; + + if (!(dir = opendir("/proc/bus/pci"))) + return FALSE; + while (1) { + if (!(dirent = readdir(dir))) + return FALSE; + strtol(dirent->d_name,&end,16); + /* entry of the form xx or xxxx : x=[0..f] no domain */ + if (*end == '\0') + return FALSE; + else if (*end == ':') { + /* ':' found immediately after: verify for xxxx:xx or xxxx:xxxx */ + strtol(end + 1,&end,16); + if (*end == '\0') + return TRUE; + } + } + return FALSE; +} + _X_EXPORT int xf86GetPciDomain(PCITAG Tag) { @@ -524,9 +570,7 @@ linuxMapPci(int ScreenNum, int Flags, PCITAG Tag, xf86InitVidMem(); - pPCI = xf86GetPciHostConfigFromTag(Tag); - - if (((fd = linuxPciOpenFile(pPCI ? pPCI->tag : 0,FALSE)) < 0) || + if (((fd = linuxPciOpenFile(Tag ,FALSE)) < 0) || (ioctl(fd, mmap_ioctl, 0) < 0)) break; @@ -583,7 +627,6 @@ linuxMapPci(int ScreenNum, int Flags, PCITAG Tag, #define MAX_DOMAINS 257 static pointer DomainMmappedIO[MAX_DOMAINS]; -static pointer DomainMmappedMem[MAX_DOMAINS]; static int linuxOpenLegacy(PCITAG Tag, char *name) @@ -641,6 +684,7 @@ xf86MapDomainMemory(int ScreenNum, int Flags, PCITAG Tag, { int domain = xf86GetPciDomain(Tag); int fd; + pointer addr; /* * We use /proc/bus/pci on non-legacy addresses or if the Linux sysfs @@ -654,20 +698,14 @@ xf86MapDomainMemory(int ScreenNum, int Flags, PCITAG Tag, return linuxMapPci(ScreenNum, Flags, Tag, Base, Size, PCIIOC_MMAP_IS_MEM); - - /* If we haven't already mapped this legacy space, try to. */ - if (!DomainMmappedMem[domain]) { - DomainMmappedMem[domain] = mmap(NULL, 1024*1024, PROT_READ|PROT_WRITE, - MAP_SHARED, fd, 0); - if (DomainMmappedMem[domain] == MAP_FAILED) { - close(fd); - perror("mmap failure"); - FatalError("xf86MapDomainMem(): mmap() failure\n"); - } + addr = mmap(NULL, Size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, Base); + if (addr == MAP_FAILED) { + close (fd); + perror("mmap failure"); + FatalError("xf86MapDomainMem(): mmap() failure\n"); } - close(fd); - return (pointer)((char *)DomainMmappedMem[domain] + Base); + return addr; } /* @@ -731,7 +769,7 @@ xf86ReadDomainMemory(PCITAG Tag, ADDRESS Base, int Len, unsigned char *Buf) struct stat st; dom = PCI_DOM_FROM_TAG(Tag); - bus = PCI_BUS_FROM_TAG(Tag); + bus = PCI_BUS_NO_DOMAIN(PCI_BUS_FROM_TAG(Tag)); dev = PCI_DEV_FROM_TAG(Tag); func = PCI_FUNC_FROM_TAG(Tag); sprintf(file, "/sys/devices/pci%04x:%02x/%04x:%02x:%02x.%1x/rom", @@ -910,7 +948,7 @@ int linuxPciHandleBIOS(PCITAG Tag, int basereg, unsigned char *buf, int len) int sofar = 0; dom = PCI_DOM_FROM_TAG(Tag); - bus = PCI_BUS_FROM_TAG(Tag); + bus = PCI_BUS_NO_DOMAIN(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", @@ -940,3 +978,106 @@ int linuxPciHandleBIOS(PCITAG Tag, int basereg, unsigned char *buf, int len) } return 0; } + +#ifdef __ia64__ +static PCITAG ia64linuxPciFindFirst(void); +static PCITAG ia64linuxPciFindNext(void); + +void +ia64linuxPciInit() +{ + struct stat st; + + linuxPciInit(); + + if (!stat("/proc/sgi_sn/licenseID", &st) && pciNumBuses) { + /* Be a little paranoid here and only use this code for Altix systems. + * It is generic, so it should work on any system, but depends on + * /proc/bus/pci entries for each domain/bus combination. Altix is + * guaranteed a recent enough kernel to have them. + */ + pciFindFirstFP = ia64linuxPciFindFirst; + pciFindNextFP = ia64linuxPciFindNext; + } +} + +static DIR *busdomdir; +static DIR *devdir; + +static PCITAG +ia64linuxPciFindFirst(void) +{ + busdomdir = opendir("/proc/bus/pci"); + devdir = NULL; + + return ia64linuxPciFindNext(); +} + +static struct dirent *getnextbus(int *domain, int *bus) +{ + struct dirent *entry; + int dombus; + + for (;;) { + entry = readdir(busdomdir); + if (entry == NULL) { + *domain = 0; + *bus = 0; + closedir(busdomdir); + return NULL; + } + if (sscanf(entry->d_name, "%04x:%02x", domain, bus) != 2) + continue; + dombus = PCI_MAKE_BUS(*domain, *bus); + + if (pciNumBuses <= dombus) + pciNumBuses = dombus + 1; + if (!pciBusInfo[dombus]) { + pciBusInfo[dombus] = xnfalloc(sizeof(pciBusInfo_t)); + *pciBusInfo[dombus] = *pciBusInfo[0]; + } + + return entry; + } +} + +static PCITAG +ia64linuxPciFindNext(void) +{ + struct dirent *entry; + char file[40]; + static int bus, dev, func, domain; + PCITAG pciDeviceTag; + CARD32 devid; + + for (;;) { + if (devdir == NULL) { + entry = getnextbus(&domain, &bus); + if (!entry) + return PCI_NOT_FOUND; + snprintf(file, 40, "/proc/bus/pci/%s", entry->d_name); + devdir = opendir(file); + if (!devdir) + return PCI_NOT_FOUND; + + } + + entry = readdir(devdir); + + if (entry == NULL) { + closedir(devdir); + devdir = NULL; + continue; + } + + if (sscanf(entry->d_name, "%02x . %01x", &dev, &func) == 2) { + pciDeviceTag = PCI_MAKE_TAG(PCI_MAKE_BUS(domain, bus), dev, func); + devid = pciReadLong(pciDeviceTag, PCI_ID_REG); + if ((devid & pciDevidMask) == pciDevid) + /* Yes - Return it. Otherwise, next device */ + return pciDeviceTag; + } + } +} +#endif + diff --git a/hw/xfree86/os-support/bus/xf86Pci.h b/hw/xfree86/os-support/bus/xf86Pci.h index fdb88e832..c444a0cd1 100644 --- a/hw/xfree86/os-support/bus/xf86Pci.h +++ b/hw/xfree86/os-support/bus/xf86Pci.h @@ -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, diff --git a/hw/xfree86/os-support/linux/lnx_pci.c b/hw/xfree86/os-support/linux/lnx_pci.c index a1dbc7604..a95703899 100644 --- a/hw/xfree86/os-support/linux/lnx_pci.c +++ b/hw/xfree86/os-support/linux/lnx_pci.c @@ -3,7 +3,9 @@ #include #endif +#include #include +#include #include #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); @@ -100,11 +149,10 @@ int lnxPciInit(void) { Bool xf86GetPciSizeFromOS(PCITAG tag, int index, int* bits) { - unsigned int dev, fn; signed PCIADDR_TYPE Size; struct pci_dev *device; - if (index > 7) + if (index >= 7) return FALSE; if (!xf86OSLinuxPCIDevs) { @@ -114,10 +162,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)) { @@ -134,14 +180,14 @@ xf86GetPciSizeFromOS(PCITAG tag, int index, int* bits) +#if 0 /* Query the kvirt address (64bit) of a BAR range from TAG */ Bool xf86GetPciOffsetFromOS(PCITAG tag, int index, unsigned long* bases) { - unsigned int dev, fn; struct pci_dev *device; - if (index > 7) + if (index >= 7) return FALSE; if (!xf86OSLinuxPCIDevs) { @@ -151,9 +197,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; @@ -162,12 +207,12 @@ xf86GetPciOffsetFromOS(PCITAG tag, int index, unsigned long* bases) return FALSE; } +#endif /* Query the kvirt address (64bit) of a BAR range from size for a given TAG */ unsigned long xf86GetOSOffsetFromPCI(PCITAG tag, int space, unsigned long base) { - unsigned int dev, fn; unsigned int ndx; struct pci_dev *device; @@ -179,9 +224,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);