OSDN Git Service

amdgpu: always add all BOs to handle table
[android-x86/external-libdrm.git] / xf86drm.c
index 02da3e1..336d64d 100644 (file)
--- a/xf86drm.c
+++ b/xf86drm.c
@@ -2954,6 +2954,9 @@ sysfs_uevent_get(const char *path, const char *fmt, ...)
 }
 #endif
 
+/* Little white lie to avoid major rework of the existing code */
+#define DRM_BUS_VIRTIO 0x10
+
 static int drmParseSubsystemType(int maj, int min)
 {
 #ifdef __linux__
@@ -2983,6 +2986,9 @@ static int drmParseSubsystemType(int maj, int min)
     if (strncmp(name, "/host1x", 7) == 0)
         return DRM_BUS_HOST1X;
 
+    if (strncmp(name, "/virtio", 7) == 0)
+        return DRM_BUS_VIRTIO;
+
     return -EINVAL;
 #elif defined(__OpenBSD__)
     return DRM_BUS_PCI;
@@ -2992,16 +2998,33 @@ static int drmParseSubsystemType(int maj, int min)
 #endif
 }
 
+static char *
+get_real_pci_path(int maj, int min, char *real_path)
+{
+    char path[PATH_MAX + 1], *term;
+
+    snprintf(path, sizeof(path), "/sys/dev/char/%d:%d/device", maj, min);
+    if (!realpath(path, real_path))
+        return NULL;
+
+    term = strrchr(real_path, '/');
+    if (term && strncmp(term, "/virtio", 7) == 0)
+        *term = 0;
+
+    return real_path;
+}
+
 static int drmParsePciBusInfo(int maj, int min, drmPciBusInfoPtr info)
 {
 #ifdef __linux__
     unsigned int domain, bus, dev, func;
-    char path[PATH_MAX + 1], *value;
+    char real_path[PATH_MAX + 1], *value;
     int num;
 
-    snprintf(path, sizeof(path), "/sys/dev/char/%d:%d/device", maj, min);
+    if (get_real_pci_path(maj, min, real_path) == NULL)
+        return -ENOENT;
 
-    value = sysfs_uevent_get(path, "PCI_SLOT_NAME");
+    value = sysfs_uevent_get(real_path, "PCI_SLOT_NAME");
     if (!value)
         return -ENOENT;
 
@@ -3114,14 +3137,16 @@ static int parse_separate_sysfs_files(int maj, int min,
       "subsystem_vendor",
       "subsystem_device",
     };
-    char path[PATH_MAX + 1];
+    char path[PATH_MAX + 1], real_path[PATH_MAX + 1];
     unsigned int data[ARRAY_SIZE(attrs)];
     FILE *fp;
     int ret;
 
+    if (get_real_pci_path(maj, min, real_path) == NULL)
+        return -ENOENT;
+
     for (unsigned i = ignore_revision ? 1 : 0; i < ARRAY_SIZE(attrs); i++) {
-        snprintf(path, PATH_MAX, "/sys/dev/char/%d:%d/device/%s", maj, min,
-                 attrs[i]);
+        snprintf(path, PATH_MAX, "%s/%s", real_path, attrs[i]);
         fp = fopen(path, "r");
         if (!fp)
             return -errno;
@@ -3145,11 +3170,14 @@ static int parse_separate_sysfs_files(int maj, int min,
 static int parse_config_sysfs_file(int maj, int min,
                                    drmPciDeviceInfoPtr device)
 {
-    char path[PATH_MAX + 1];
+    char path[PATH_MAX + 1], real_path[PATH_MAX + 1];
     unsigned char config[64];
     int fd, ret;
 
-    snprintf(path, PATH_MAX, "/sys/dev/char/%d:%d/device/config", maj, min);
+    if (get_real_pci_path(maj, min, real_path) == NULL)
+        return -ENOENT;
+
+    snprintf(path, PATH_MAX, "%s/config", real_path);
     fd = open(path, O_RDONLY);
     if (fd < 0)
         return -errno;
@@ -3706,6 +3734,7 @@ process_device(drmDevicePtr *device, const char *d_name,
 
     switch (subsystem_type) {
     case DRM_BUS_PCI:
+    case DRM_BUS_VIRTIO:
         return drmProcessPciDevice(device, node, node_type, maj, min,
                                    fetch_deviceinfo, flags);
     case DRM_BUS_USB:
@@ -3906,6 +3935,8 @@ int drmGetDevice2(int fd, uint32_t flags, drmDevicePtr *device)
 
     drmFoldDuplicatedDevices(local_devices, node_count);
 
+    *device = NULL;
+
     for (i = 0; i < node_count; i++) {
         if (!local_devices[i])
             continue;