From 2f53d1cf7304574a516f6868822307648bc35333 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Wed, 7 Apr 2021 18:22:05 +0300 Subject: [PATCH] config: Fix platform busid parsing when there is no ID_PATH prop MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On at least Lenovo Thinkpad E585 udev does not have ID_PATH property for the drm node (see https://gitlab.freedesktop.org/xorg/xserver/-/issues/993). While this is likely udev bug, this causes the device to be not recognized as attribs->busid is NULL, which causes platform_find_pci_info to be not called and corresponding xf86_platform_devices[i]->pdev to be NULL. At this moment pdev being NULL will cause a crash, but this is a different bug. Fixes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/993 Fixes: 0816e8fc linux: Make platform device probe less fragile Reviewed-by: Zoltán Böszörményi Signed-off-by: Povilas Kanapickas --- config/udev.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/config/udev.c b/config/udev.c index 411a459f4..836fc2afa 100644 --- a/config/udev.c +++ b/config/udev.c @@ -502,6 +502,34 @@ static char *strrstr(const char *haystack, const char *needle) return last; } +/* For certain devices udev does not create ID_PATH entry (which is presumably a bug + * in udev). We work around that by implementing a minimal ID_PATH calculator + * ourselves along the same logic that udev uses. This works only for the case of + * a PCI device being directly connected to a PCI bus, but it will cover most end + * users with e.g. a new laptop which only has beta hardware driver support. + * See https://gitlab.freedesktop.org/xorg/xserver/-/issues/993 */ +static char* +config_udev_get_fallback_bus_id(struct udev_device *udev_device) +{ + const char *sysname; + char *busid; + + udev_device = udev_device_get_parent(udev_device); + if (udev_device == NULL) + return NULL; + + if (strcmp(udev_device_get_subsystem(udev_device), "pci") != 0) + return NULL; + + sysname = udev_device_get_sysname(udev_device); + busid = XNFalloc(strlen(sysname) + 5); + busid[0] = '\0'; + strcat(busid, "pci:"); + strcat(busid, sysname); + + return busid; +} + static void config_udev_odev_setup_attribs(struct udev_device *udev_device, const char *path, const char *syspath, int major, int minor, @@ -526,6 +554,9 @@ config_udev_odev_setup_attribs(struct udev_device *udev_device, const char *path attribs->busid[3] = ':'; } + if (!value) + attribs->busid = config_udev_get_fallback_bus_id(udev_device); + /* ownership of attribs is passed to probe layer */ probe_callback(attribs); }