Bugzilla – Attachment 58912 Details for
Bug 132308
X server crashes
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
IDP Log In
|
Forgot Password
[patch]
Final patch
pci-domain.diff (text/plain), 16.25 KB, created by
Andreas Schwab
on 2005-11-29 10:32:13 UTC
(
hide
)
Description:
Final patch
Filename:
MIME Type:
Creator:
Andreas Schwab
Created:
2005-11-29 10:32:13 UTC
Size:
16.25 KB
patch
obsolete
>? 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 <dirent.h> > > /* > * 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;
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