summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHuacai Chen <chenhc@lemote.com>2020-07-05 05:59:58 -0400
committerMatt Turner <mattst88@gmail.com>2020-08-18 17:20:09 +0000
commit249a12c54a9316b089bd22683c011519348496df (patch)
tree457d4c8424d59a84edf2d12f21580daa18b4bd28
parent5c96eb5f44e62a4cfe835023cde304eb5795b8fd (diff)
linux: Fix platform device probe for DT-based PCI
On a DT-base PCI platform, the sysfs path of vga device is like this: /sys/devices/platform/bus@10000000/1a000000.pci/pci0000:00/0000:00:11.0/0000:04:00.0. Then the ID_PATH from udev is platform-1a000000.pci-pci-0000:04:00.0 and the BusID will be pci-0000:04:00.0, which causes Xorg start fail. This is because config_udev_odev_setup_attribs() use strstr() to search the first "pci-" in ID_PATH. To fix this, we implement a strrstr() function and use it to search the last "pci-" in ID_PATH, which can get a correct BusID. (backported from commit 9fbd3e43dd9e13700df96b508c3d97f77e2b9f7e) Reviewed-by: Dave Airlie <airlied@redhat.com> Signed-off-by: Huacai Chen <chenhc@lemote.com>
-rw-r--r--config/udev.c27
1 files changed, 26 insertions, 1 deletions
diff --git a/config/udev.c b/config/udev.c
index 14409549b..b00d90237 100644
--- a/config/udev.c
+++ b/config/udev.c
@@ -464,6 +464,31 @@ config_udev_fini(void)
#ifdef CONFIG_UDEV_KMS
+/* Find the last occurrence of the needle in haystack */
+static char *strrstr(const char *haystack, const char *needle)
+{
+ char *prev, *last, *tmp;
+
+ prev = strstr(haystack, needle);
+ if (!prev)
+ return NULL;
+
+ last = prev;
+ tmp = prev + 1;
+
+ while (tmp) {
+ last = strstr(tmp, needle);
+ if (!last)
+ return prev;
+ else {
+ prev = last;
+ tmp = prev + 1;
+ }
+ }
+
+ return last;
+}
+
static void
config_udev_odev_setup_attribs(struct udev_device *udev_device, const char *path, const char *syspath,
int major, int minor,
@@ -478,7 +503,7 @@ config_udev_odev_setup_attribs(struct udev_device *udev_device, const char *path
attribs->minor = minor;
value = udev_device_get_property_value(udev_device, "ID_PATH");
- if (value && (str = strstr(value, "pci-"))) {
+ if (value && (str = strrstr(value, "pci-"))) {
attribs->busid = XNFstrdup(str);
attribs->busid[3] = ':';
}