config: Fix platform busid parsing when there is no ID_PATH prop

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 <zboszor@gmail.com>
Signed-off-by: Povilas Kanapickas <povilas@radix.lt>
This commit is contained in:
Povilas Kanapickas 2021-04-07 18:22:05 +03:00
parent d4b38e1119
commit 2f53d1cf73
1 changed files with 31 additions and 0 deletions

View File

@ -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);
}