Bugzilla – Attachment 58825 Details for
Bug 132308
X server crashes
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
IDP Log In
|
Forgot Password
[patch]
better domain support detection
diff.xorg_pcinew (text/plain), 16.22 KB, created by
Egbert Eich
on 2005-11-28 12:57:39 UTC
(
hide
)
Description:
better domain support detection
Filename:
MIME Type:
Creator:
Egbert Eich
Created:
2005-11-28 12:57:39 UTC
Size:
16.22 KB
patch
obsolete
>? diff.fontfix >Index: programs/Xserver/hw/xfree86/int10/helper_exec.c >=================================================================== >RCS file: /home/eich/cvs/xc/programs/Xserver/hw/xfree86/int10/helper_exec.c,v >retrieving revision 1.1.1.29 >diff -u -r1.1.1.29 helper_exec.c >--- programs/Xserver/hw/xfree86/int10/helper_exec.c 13 Sep 2005 10:30:49 -0000 1.1.1.29 >+++ programs/Xserver/hw/xfree86/int10/helper_exec.c 28 Nov 2005 12:47:57 -0000 >@@ -478,7 +478,7 @@ > 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 @@ > 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 >=================================================================== >RCS file: /home/eich/cvs/xc/programs/Xserver/hw/xfree86/os-support/bus/Pci.c,v >retrieving revision 1.1.1.60 >diff -u -r1.1.1.60 Pci.c >--- programs/Xserver/hw/xfree86/os-support/bus/Pci.c 25 Nov 2005 10:05:28 -0000 1.1.1.60 >+++ programs/Xserver/hw/xfree86/os-support/bus/Pci.c 28 Nov 2005 12:47:57 -0000 >@@ -597,6 +597,16 @@ > 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 >=================================================================== >RCS file: /home/eich/cvs/xc/programs/Xserver/hw/xfree86/os-support/bus/Pci.h,v >retrieving revision 1.1.1.37 >diff -u -r1.1.1.37 Pci.h >--- programs/Xserver/hw/xfree86/os-support/bus/Pci.h 25 Nov 2005 10:05:28 -0000 1.1.1.37 >+++ programs/Xserver/hw/xfree86/os-support/bus/Pci.h 28 Nov 2005 12:47:57 -0000 >@@ -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 >=================================================================== >RCS file: /home/eich/cvs/xc/programs/Xserver/hw/xfree86/os-support/bus/altixPCI.c,v >retrieving revision 1.1.1.2 >diff -u -r1.1.1.2 altixPCI.c >--- programs/Xserver/hw/xfree86/os-support/bus/altixPCI.c 13 Sep 2005 10:31:29 -0000 1.1.1.2 >+++ programs/Xserver/hw/xfree86/os-support/bus/altixPCI.c 28 Nov 2005 12:47:57 -0000 >@@ -41,13 +41,14 @@ > 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 @@ > } > > 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 >=================================================================== >RCS file: /home/eich/cvs/xc/programs/Xserver/hw/xfree86/os-support/bus/linuxPci.c,v >retrieving revision 1.1.1.12 >diff -u -r1.1.1.12 linuxPci.c >--- programs/Xserver/hw/xfree86/os-support/bus/linuxPci.c 25 Nov 2005 10:05:28 -0000 1.1.1.12 >+++ programs/Xserver/hw/xfree86/os-support/bus/linuxPci.c 28 Nov 2005 12:47:57 -0000 >@@ -55,6 +55,7 @@ > #include "xf86Priv.h" > #include "xf86_OSlib.h" > #include "Pci.h" >+#include <dirent.h> > > /* > * 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 Bool linuxDomainSupport(void); > > static pciBusFuncs_t linuxFuncs0 = { > /* pciReadLong */ linuxPciCfgRead, >@@ -111,6 +113,8 @@ > /* bridge */ NULL > }; > >+static Bool domain_support = FALSE; >+ > void > linuxPciInit() > { >@@ -121,43 +125,60 @@ > we'll need a fallback for 2.0 kernels here */ > return; > } >+ >+ domain_support = linuxDomainSupport(); >+ > 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:%02x", 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:%02x/%02x.%1x", >+ domain, bus, dev, func); > } > if (write) { > fd = open(file,O_RDWR); >@@ -171,7 +192,8 @@ > fd = open(file,O_RDONLY); > is_write = FALSE; > } >- >+ bail: >+ ldomain = domain; > lbus = bus; > ldev = dev; > lfunc = func; >@@ -482,6 +504,32 @@ > } > } > >+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) > { >@@ -724,7 +772,7 @@ > 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 +940,105 @@ > } > > #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 >=================================================================== >RCS file: /home/eich/cvs/xc/programs/Xserver/hw/xfree86/os-support/bus/xf86Pci.h,v >retrieving revision 1.1.1.33 >diff -u -r1.1.1.33 xf86Pci.h >--- programs/Xserver/hw/xfree86/os-support/bus/xf86Pci.h 27 Apr 2005 16:00:07 -0000 1.1.1.33 >+++ programs/Xserver/hw/xfree86/os-support/bus/xf86Pci.h 28 Nov 2005 12:47:57 -0000 >@@ -768,6 +768,8 @@ > 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 >=================================================================== >RCS file: /home/eich/cvs/xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_pci.c,v >retrieving revision 1.1.1.10 >diff -u -r1.1.1.10 lnx_pci.c >--- programs/Xserver/hw/xfree86/os-support/linux/lnx_pci.c 25 Nov 2005 10:05:30 -0000 1.1.1.10 >+++ programs/Xserver/hw/xfree86/os-support/linux/lnx_pci.c 28 Nov 2005 12:47:57 -0000 >@@ -28,16 +28,41 @@ > 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 @@ > 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 @@ > 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;
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
Actions:
View
|
Diff
Attachments on
bug 132308
:
56480
|
56955
|
58767
|
58769
|
58776
|
58825
|
58912
|
63024