Imported Debian patch 2:1.15.1-0ubuntu2.6
[deb_xorg-server.git] / debian / patches / drm_device_keep_trying.patch
CommitLineData
7217e0ca
ML
1From: Maarten Lankhorst <maarten.lankhorst@canonical.com>
2Subject: [PATCH] do not use drmGetBusid to grab the pci-id name
3
4The kernel returns EACCES or EAGAIN on drm open when the drm device is
5currently unavailable, such as if it is in use by another process
6(e.g. plymouth), or hasn't finished initializing (e.g. on a really fast
7SSD). Because the probing is done before a vt switch is completed,
8we have no way to ensure that we can own DRM master. This results
9in failing to boot.
10
11Also attrib->unowned is not initialized, always initialize it to fix
12a valgrind warning, and to prevent adding the same device a second time
13after a vt switch.
14
15Fixes: https://bugs.launchpad.net/ubuntu/+source/xorg-server/+bug/982889
16
17Signed-off-by: Bryce Harrington <bryce@canonical.com>
18---
19 hw/xfree86/os-support/linux/lnx_platform.c | 29 +++++++++++++++++++++++++---
20 1 file changed, 26 insertions(+), 3 deletions(-)
21
22--- a/config/udev.c
23+++ b/config/udev.c
24@@ -98,7 +98,7 @@
25 if (strncmp(sysname, "card", 4) != 0)
26 return;
27
28- LogMessage(X_INFO, "config/udev: Adding drm device (%s)\n", path);
29+ LogMessage(X_INFO, "config/udev: Adding drm device (%s) %s %s\n", path, sysname, syspath);
30
31 config_udev_odev_setup_attribs(path, syspath, NewGPUDeviceRequest);
32 return;
33@@ -430,11 +430,23 @@
34 #ifdef CONFIG_UDEV_KMS
35
36 static Bool
37+get_pci_busid(const char *in, char *pci_str)
38+{
39+ int ret, domain, bus, dev, func;
40+ ret = sscanf(in, "/%04x:%02x:%02x.%d/drm/card%*d", &domain, &bus, &dev, &func);
41+ if (ret != 4)
42+ return FALSE;
43+ sprintf(pci_str, "pci:%04x:%02x:%02x.%d", domain, bus, dev, func);
44+ return TRUE;
45+}
46+
47+static Bool
48 config_udev_odev_setup_attribs(const char *path, const char *syspath,
49 config_odev_probe_proc_ptr probe_callback)
50 {
51 struct OdevAttributes *attribs = config_odev_allocate_attribute_list();
52 int ret;
53+ const char *platform;
54
55 if (!attribs)
56 return FALSE;
57@@ -447,6 +459,33 @@
58 if (ret == FALSE)
59 goto fail;
60
61+ if (strstr(syspath, "/devices/pci")) {
62+ char pci_str[17];
63+ const char *end = strstr(syspath, "/drm/card");
64+ if (strstr(syspath, "/usb"))
65+ ret = config_odev_add_attribute(attribs, ODEV_ATTRIB_BUSID, "");
66+ else if (get_pci_busid(end - 13, pci_str))
67+ ret = config_odev_add_attribute(attribs, ODEV_ATTRIB_BUSID, pci_str);
68+ } else if ((platform = strstr(syspath, "/devices/platform/"))) {
69+ /* OMAP relies on this, modesetting doesn't use it */
70+ const char *end;
71+ platform += 18;
72+ end = strchr(platform, '.');
73+ if (end) {
74+ char *busid;
75+ ret = asprintf(&busid, "platform:%.*s:%02li",
76+ (int)(end - platform), platform, strtol(end + 1, NULL, 10));
77+ if (ret >= 0) {
78+ ret = config_odev_add_attribute(attribs, ODEV_ATTRIB_BUSID, busid);
79+ free(busid);
80+ }
81+ else
82+ ret = TRUE;
83+ }
84+ }
85+ if (ret == FALSE)
86+ goto fail;
87+
88 /* ownership of attribs is passed to probe layer */
89 probe_callback(attribs);
90 return TRUE;
91--- a/hw/xfree86/os-support/linux/lnx_platform.c
92+++ b/hw/xfree86/os-support/linux/lnx_platform.c
93@@ -19,44 +19,6 @@
94
95 #include "hotplug.h"
96
97-static Bool
98-get_drm_info(struct OdevAttributes *attribs, char *path, int delayed_index)
99-{
100- drmSetVersion sv;
101- char *buf;
102- int fd;
103- int err = 0;
104-
105- fd = open(path, O_RDWR, O_CLOEXEC);
106- if (fd == -1)
107- return FALSE;
108-
109- sv.drm_di_major = 1;
110- sv.drm_di_minor = 4;
111- sv.drm_dd_major = -1; /* Don't care */
112- sv.drm_dd_minor = -1; /* Don't care */
113-
114- err = drmSetInterfaceVersion(fd, &sv);
115- if (err) {
116- ErrorF("setversion 1.4 failed: %s\n", strerror(-err));
117- goto out;
118- }
119-
120- /* for a delayed probe we've already added the device */
121- if (delayed_index == -1) {
122- xf86_add_platform_device(attribs);
123- delayed_index = xf86_num_platform_devices - 1;
124- }
125-
126- buf = drmGetBusid(fd);
127- xf86_add_platform_device_attrib(delayed_index,
128- ODEV_ATTRIB_BUSID, buf);
129- drmFreeBusid(buf);
130-out:
131- close(fd);
132- return (err == 0);
133-}
134-
135 Bool
136 xf86PlatformDeviceCheckBusID(struct xf86_platform_device *device, const char *busid)
137 {
138@@ -105,11 +67,6 @@
139 char *dpath;
140 dpath = xf86_get_platform_attrib(index, ODEV_ATTRIB_PATH);
141
142- ret = get_drm_info(attribs, dpath, index);
143- if (ret == FALSE) {
144- xf86_remove_platform_device(index);
145- return;
146- }
147 ret = xf86platformAddDevice(index);
148 if (ret == -1)
149 xf86_remove_platform_device(index);
150@@ -145,18 +102,10 @@
151
152 LogMessage(X_INFO, "xfree86: Adding drm device (%s)\n", path);
153
154- if (!xf86VTOwner()) {
155- /* if we don't currently own the VT then don't probe the device,
156- just mark it as unowned for later use */
157- attribs->unowned = TRUE;
158- xf86_add_platform_device(attribs);
159- return;
160- }
161-
162- ret = get_drm_info(attribs, path, -1);
163- if (ret == FALSE)
164- goto out_free;
165-
166+ /* if we don't currently own the VT then don't probe the device,
167+ just mark it as unowned for later use */
168+ attribs->unowned = !xf86VTOwner();
169+ xf86_add_platform_device(attribs);
170 return;
171
172 out_free: