[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#279436: xserver-xfree86: fix for bug #246782 breaks X server on machines with no PCI bus #0



Package: xserver-xfree86
Version: 4.3.0.dfsg.1-8
Severity: normal
Tags: patch


It appears this change:

 xfree86 (4.3.0.dfsg.1-5) unstable; urgency=low

  Changes by Branden Robinson:

  * Fix XFree86 X server's PCI bus support code to be able to cope with both
    Linux 2.4 and Linux 2.6 styles of organization for /proc/bus/pci, checking
    for the 2.6 style first (thanks, Daniel Seyffer and Ciaran McCreesh).
    (Closes: #225526)

is keeping X from working on my machine.  That machine is a bit
unusual in the sense that it has no PCI bus numbered 0:

 $ ls /proc/bus/pci/
 40/  60/  80/  81/  devices

Due to this, the workaround for bug #225526 actually ends up breaking
X on my machine:

> -             if (bus < 256)
> -                     sprintf(file, "/proc/bus/pci/%02x/%02x.%1x",
> -                             bus, dev, func);
> -             else
> -                     sprintf(file, "/proc/bus/pci/%04x/%02x.%1x",
> -                             bus, dev, func);
> +             if (bus < 256) {
> +                     if (stat("/proc/bus/pci/00", &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);
> +             } else {
> +                     if (stat("/proc/bus/pci/00", &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);
> +             }

So, on my machine (bus is < 256), the stat("/proc/bus/pci/00", &ignored)
call fails and then X attempts to use PCI-domain numbers,
which is wrong for my machine.

As far as I know, it is bogus to assume every machine has a PCI bus
numbered 0.  My proposal is to avoid that assumption by using a patch
along these lines:

--- orig/xfree86-4.3.0.dfsg.1/build-tree/xc/programs/Xserver/hw/xfree86/os-support/bus/linuxPci.c	2004-11-02 17:46:20.629996688 -0800
+++ xfree86-4.3.0.dfsg.1/build-tree/xc/programs/Xserver/hw/xfree86/os-support/bus/linuxPci.c	2004-11-02 13:52:36.465824860 -0800
@@ -101,10 +101,21 @@
 static int
 linuxPciOpenFile(PCITAG tag)
 {
-	static int	lbus,ldev,lfunc,fd = -1;
+	static int	lbus,ldev,lfunc,fd = -1,with_domain = 0;
+	static const char *format_string[2][2] = {
+	    /* without PCI domain #: */
+	    {
+		"/proc/bus/pci/%02x/%02x.%1x",	/* bus # < 256 */
+		"/proc/bus/pci/%04x/%02x.%1x"	/* bus # >= 256 */
+	    },
+	    /* with PCI domain #: */
+	    {
+		"/proc/bus/pci/0000:%02x/%02x.%1x",	/* bus # < 256 */
+		"/proc/bus/pci/0000:%04x/%02x.%1x"	/* bus # >= 256 */
+	    }
+	};
 	int		bus, dev, func;
 	char		file[32];
-	struct stat	ignored;
 
 	bus  = PCI_BUS_FROM_TAG(tag);
 	dev  = PCI_DEV_FROM_TAG(tag);
@@ -112,22 +123,20 @@
 	if (fd == -1 || bus != lbus || dev != ldev || func != lfunc) {
 		if (fd != -1)
 			close(fd);
-		if (bus < 256) {
-			if (stat("/proc/bus/pci/00", &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);
-		} else {
-			if (stat("/proc/bus/pci/00", &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);
-		}
+	  retry:
+		sprintf(file, format_string[with_domain][bus >= 256],
+			bus, dev, func);
 		fd = open(file,O_RDWR);
+
+		if (fd < 0) {
+			if (!with_domain) {
+				/* try again, this time with domains */
+				with_domain = 1;
+				goto retry;
+			}
+			/* failed even with domains; fall back again */
+			with_domain = 0;
+		}
 		lbus  = bus;
 		ldev  = dev;
 		lfunc = func;

This fixes the problem on my machine and should still do the right thing
on PCI-domain-enabled SPARC kernels, though I cannot test that myself.

If it looks OK, please merge this patch.  It would be really nice to
have X work out-of-the-box again.

Thanks,

	--david

-- Package-specific info:
Contents of /var/lib/xfree86/X.roster:
xserver-xfree86

X server symlink status:
lrwxr-xr-x  1 root root 20 Aug 25  2003 /etc/X11/X -> /usr/bin/X11/XFree86
-rwxr-xr-x  3 root root 26364440 Nov  2 13:53 /usr/bin/X11/XFree86

Contents of /var/lib/xfree86/XF86Config-4.roster:
xserver-xfree86

VGA-compatible devices on PCI bus:
0000:81:00.0 VGA compatible controller: ATI Technologies Inc R300 AG [FireGL Z1/X1] (rev 80)

/var/lib/xfree86/XF86Config-4.md5sum does not exist.

XFree86 X server configuration file status:
-rw-r--r--  1 root root 6239 Nov  1 13:48 /etc/X11/XF86Config-4

-- System Information:
Debian Release: 3.1
  APT prefers unstable
  APT policy: (990, 'unstable'), (500, 'testing')
Architecture: ia64
Kernel: Linux 2.6.7
Locale: LANG=C, LC_CTYPE=C (charmap=ANSI_X3.4-1968)

Versions of packages xserver-xfree86 depends on:
ii  debconf [debconf-2.0]     1.4.39         Debian configuration management sy
ii  libc6.1                   2.3.2.ds1-18   GNU C Library: Shared libraries an
ii  libgcc1                   1:3.4.2-3      GCC support library
ii  xserver-common            4.3.0.dfsg.1-8 files and utilities common to all 
ii  zlib1g                    1:1.2.2-1      compression library - runtime

-- debconf information excluded



Reply to: