? diff.fontfix Index: programs/Xserver/hw/xfree86/int10/helper_exec.c =================================================================== --- programs/Xserver/hw/xfree86/int10/helper_exec.c.orig 2005-08-23 03:59:12.000000000 +0200 +++ programs/Xserver/hw/xfree86/int10/helper_exec.c 2005-11-29 01:06:29.000000000 +0100 @@ -478,7 +478,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; @@ -492,7 +492,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; Index: programs/Xserver/hw/xfree86/os-support/bus/Pci.c =================================================================== --- programs/Xserver/hw/xfree86/os-support/bus/Pci.c.orig 2005-11-09 10:41:23.000000000 +0100 +++ programs/Xserver/hw/xfree86/os-support/bus/Pci.c 2005-11-29 01:06:29.000000000 +0100 @@ -597,6 +597,16 @@ pciGetBaseSize(PCITAG tag, int index, Bo return bits; } +void +pciInfoFromTag(PCITAG tag, int *domainnum, int *busnum, + int *devnum, int *funcnum) +{ + *domainnum = PCI_DOM_FROM_TAG(tag); + *busnum = PCI_BUS_NO_DOMAIN(PCI_BUS_FROM_TAG(tag)); + *devnum = PCI_DEV_FROM_TAG(tag); + *funcnum = PCI_FUNC_FROM_TAG(tag); +} + PCITAG pciTag(int busnum, int devnum, int funcnum) { Index: programs/Xserver/hw/xfree86/os-support/bus/Pci.h =================================================================== --- programs/Xserver/hw/xfree86/os-support/bus/Pci.h.orig 2005-11-09 10:41:23.000000000 +0100 +++ programs/Xserver/hw/xfree86/os-support/bus/Pci.h 2005-11-29 01:06:30.000000000 +0100 @@ -120,7 +120,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 */ @@ -259,7 +259,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 Index: programs/Xserver/hw/xfree86/os-support/bus/altixPCI.c =================================================================== --- programs/Xserver/hw/xfree86/os-support/bus/altixPCI.c.orig 2005-07-03 12:31:06.000000000 +0200 +++ programs/Xserver/hw/xfree86/os-support/bus/altixPCI.c 2005-11-29 01:06:30.000000000 +0100 @@ -41,13 +41,14 @@ static pciDevice *get_dev_on_bus(unsigne 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 } 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 Index: programs/Xserver/hw/xfree86/os-support/bus/linuxPci.c =================================================================== --- programs/Xserver/hw/xfree86/os-support/bus/linuxPci.c.orig 2005-11-09 10:41:23.000000000 +0100 +++ programs/Xserver/hw/xfree86/os-support/bus/linuxPci.c 2005-11-29 01:08:03.000000000 +0100 @@ -55,6 +55,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 CARD8 linuxPciCfgReadByte(PCITAG 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 Bool linuxDomainSupport(void); static pciBusFuncs_t linuxFuncs0 = { /* pciReadLong */ linuxPciCfgRead, @@ -111,6 +113,8 @@ static pciBusInfo_t linuxPci0 = { /* bridge */ NULL }; +static Bool domain_support = FALSE; + void linuxPciInit() { @@ -121,43 +125,61 @@ 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; pciFindNextFP = pciGenFindNext; + + return; } 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[32]; struct stat ignored; - 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 (fd == -1 || (write && (!is_write)) - || bus != lbus || dev != ldev || func != lfunc) { - if (fd != -1) + + if (!domain_support && domain > 0) + return -1; + + if (fd == -1 || (write && (!is_write)) || bus != lbus + || dev != ldev || func != lfunc || domain != ldomain) { + + if (fd != -1) { close(fd); + fd = -1; + } 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) { fd = open(file,O_RDWR); @@ -171,7 +193,8 @@ linuxPciOpenFile(PCITAG tag, Bool write) fd = open(file,O_RDONLY); is_write = FALSE; } - + bail: + ldomain = domain; lbus = bus; ldev = dev; lfunc = func; @@ -482,6 +505,32 @@ linuxGetSizes(PCITAG Tag, unsigned long } } +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; +} + int xf86GetPciDomain(PCITAG Tag) { @@ -491,7 +540,7 @@ xf86GetPciDomain(PCITAG Tag) pPCI = xf86GetPciHostConfigFromTag(Tag); if (pPCI && (result = PCI_DOM_FROM_BUS(pPCI->busnum))) - return result; + return result + 1; if (!pPCI || pPCI->fakeDevice) return 1; /* Domain 0 is reserved */ @@ -724,7 +773,7 @@ xf86ReadDomainMemory(PCITAG Tag, ADDRESS 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", @@ -892,3 +941,105 @@ xf86AccResFromOS(resPtr pRes) } #endif /* !INCLUDE_XF86_NO_DOMAIN */ + +#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 Index: programs/Xserver/hw/xfree86/os-support/bus/xf86Pci.h =================================================================== --- programs/Xserver/hw/xfree86/os-support/bus/xf86Pci.h.orig 2005-08-27 20:18:17.000000000 +0200 +++ programs/Xserver/hw/xfree86/os-support/bus/xf86Pci.h 2005-11-29 01:06:30.000000000 +0100 @@ -768,6 +768,8 @@ void pciSetBitsByte(PCITAG tag, in ADDRESS pciBusAddrToHostAddr(PCITAG tag, PciAddrType type, ADDRESS addr); ADDRESS pciHostAddrToBusAddr(PCITAG tag, PciAddrType type, ADDRESS addr); PCITAG pciTag(int busnum, int devnum, int funcnum); +void pciInfoFromTag(PCITAG tag, int *domainnum, + 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, Index: programs/Xserver/hw/xfree86/os-support/linux/lnx_pci.c =================================================================== --- programs/Xserver/hw/xfree86/os-support/linux/lnx_pci.c.orig 2005-10-08 17:42:47.000000000 +0200 +++ programs/Xserver/hw/xfree86/os-support/linux/lnx_pci.c 2005-11-29 01:06:30.000000000 +0100 @@ -28,16 +28,41 @@ FILE *xf86OSLinuxPCIFile = NULL; Bool xf86GetPciSizeFromOS(PCITAG tag, int index, int* bits) { + FILE *file; char c[0x200]; char *res; - unsigned int bus, devfn, dev, fn; + unsigned int domain, bus, devfn, dev, fn; unsigned PCIADDR_TYPE size[7]; unsigned int num; signed PCIADDR_TYPE Size; + int resource; + unsigned PCIADDR_TYPE begin, end; if (index > 7) return FALSE; - + + pciInfoFromTag(tag, &domain, &bus, &dev, &fn); + + sprintf(c, "/sys/devices/pci%04x:%02x/%04x:%02x:%02x.%1x/resource", + domain, bus, domain, bus, dev, fn); + if (file = fopen(c, "r")) { + for (resource=0; resource != index; resource++) + fgets(c, 0x1ff, file); + res = fgets(c, 0x1ff, file); + num = sscanf(res, PCIADDR_FMT " " PCIADDR_FMT " " PCIADDR_IGNORE_FMT, + &begin, &end); + if (num == 2) { + Size = end - begin; + while (Size & ((PCIADDR_TYPE) 0x01)) { + Size = Size >> ((PCIADDR_TYPE) 1); + (*bits)++; + } + fclose(file); + return TRUE; + } + fclose(file); + } + if (!xf86OSLinuxPCIFile && \ !(xf86OSLinuxPCIFile = fopen("/proc/bus/pci/devices","r"))) return FALSE; @@ -99,13 +124,32 @@ xf86GetPciOffsetFromOS(PCITAG tag, int i FILE *file; char c[0x200]; char *res; - unsigned int bus, devfn, dev, fn; + unsigned int domain, bus, devfn, dev, fn; unsigned PCIADDR_TYPE offset[7]; unsigned int num; + int resource; if (index > 7) return FALSE; + pciInfoFromTag(tag, &domain, &bus, &dev, &fn); + + sprintf(c, "/sys/devices/pci%04x:%02x/%04x:%02x:%02x.%1x/resource", + domain, bus, domain, bus, dev, fn); + if (file = fopen(c, "r")) { + for (resource=0; resource != index; resource++) + fgets(c, 0x1ff, file); + res = fgets(c, 0x1ff, file); + num = sscanf(res, PCIADDR_FMT " " PCIADDR_IGNORE_FMT " " PCIADDR_IGNORE_FMT, + &offset[0]); + if (num == 1) { + *bases = offset[0]; + fclose(file); + return TRUE; + } + fclose(file); + } + if (!(file = fopen("/proc/bus/pci/devices","r"))) return FALSE; do { @@ -159,11 +203,40 @@ xf86GetOSOffsetFromPCI(PCITAG tag, int s FILE *file; char c[0x200]; char *res; - unsigned int bus, devfn, dev, fn; + unsigned int domain, bus, devfn, dev, fn; unsigned PCIADDR_TYPE offset[7]; unsigned PCIADDR_TYPE size[7]; unsigned int num; unsigned int ndx; + unsigned PCIADDR_TYPE begin,end; + + pciInfoFromTag(tag, &domain, &bus, &dev, &fn); + + sprintf(c, "/sys/devices/pci%04x:%02x/%04x:%02x:%02x.%1x/resource", + domain, bus, domain, bus, dev, fn); + if (file = fopen(c, "r")) { + unsigned long savePtr; + for (ndx=0; ndx < 7; ndx++) { + res = fgets(c, 0x1ff, file); + if (!res) + break; + num = sscanf(res, PCIADDR_FMT " " PCIADDR_FMT " " PCIADDR_IGNORE_FMT, + &begin, &end); + if (num == 2) { + if (ndx == 6) + savePtr = (0xFFFFFFF0) & + pciReadLong(tag, PCI_CMD_BIOS_REG); + else /* this the ROM bar */ + savePtr = (0xFFFFFFF0) & + pciReadLong(tag, PCI_CMD_BASE_REG + (0x4 * ndx)); + if (base >= savePtr && base <= (savePtr + (end - begin))) { + fclose(file); + return ( ~(0xFUL) & (begin + (base - savePtr))); + } + } + } + fclose(file); + } if (!(file = fopen("/proc/bus/pci/devices","r"))) return 0;