packaging: set pc file name for devel package explicitly
[platform/upstream/libdrm.git] / xf86drm.c
index 08e5caf..dbb7c14 100644 (file)
--- a/xf86drm.c
+++ b/xf86drm.c
@@ -122,6 +122,23 @@ struct drm_pciinfo {
 static drmServerInfoPtr drm_server_info;
 
 static bool drmNodeIsDRM(int maj, int min);
+static char *drmGetMinorNameForFD(int fd, int type);
+
+static unsigned log2_int(unsigned x)
+{
+    unsigned l;
+
+    if (x < 2) {
+        return 0;
+    }
+    for (l = 2; ; l++) {
+        if ((unsigned)(1 << l) > x) {
+            return l - 1;
+        }
+    }
+    return 0;
+}
+
 
 drm_public void drmSetServerInfo(drmServerInfoPtr info)
 {
@@ -695,7 +712,7 @@ static int drmOpenByName(const char *name, int type)
         int  retcode;
 
         sprintf(proc_name, "/proc/dri/%d/name", i);
-        if ((fd = open(proc_name, 0, 0)) >= 0) {
+        if ((fd = open(proc_name, O_RDONLY, 0)) >= 0) {
             retcode = read(fd, buf, sizeof(buf)-1);
             close(fd);
             if (retcode) {
@@ -2776,24 +2793,16 @@ drm_public char *drmGetDeviceNameFromFd(int fd)
 {
 #ifdef __FreeBSD__
     struct stat sbuf;
-    char dname[SPECNAMELEN];
-    char name[SPECNAMELEN];
     int maj, min;
+    int nodetype;
 
     if (fstat(fd, &sbuf))
         return NULL;
 
     maj = major(sbuf.st_rdev);
     min = minor(sbuf.st_rdev);
-
-    if (!drmNodeIsDRM(maj, min) || !S_ISCHR(sbuf.st_mode))
-        return NULL;
-
-    if (!devname_r(sbuf.st_rdev, S_IFCHR, dname, sizeof(dname)))
-        return NULL;
-
-    snprintf(name, sizeof(name), "/dev/%s", dname);
-    return strdup(name);
+    nodetype = drmGetMinorType(maj, min);
+    return drmGetMinorNameForFD(fd, nodetype);
 #else
     char name[128];
     struct stat sbuf;
@@ -2829,7 +2838,7 @@ static bool drmNodeIsDRM(int maj, int min)
     snprintf(path, sizeof(path), "/sys/dev/char/%d:%d/device/drm",
              maj, min);
     return stat(path, &sbuf) == 0;
-#elif __FreeBSD__
+#elif defined(__FreeBSD__)
     char name[SPECNAMELEN];
 
     if (!devname_r(makedev(maj, min), S_IFCHR, name, sizeof(name)))
@@ -2942,12 +2951,12 @@ static char *drmGetMinorNameForFD(int fd, int type)
 
     closedir(sysdir);
     return NULL;
-#elif __FreeBSD__
+#elif defined(__FreeBSD__)
     struct stat sbuf;
     char dname[SPECNAMELEN];
     const char *mname;
     char name[SPECNAMELEN];
-    int id, maj, min;
+    int id, maj, min, nodetype, i;
 
     if (fstat(fd, &sbuf))
         return NULL;
@@ -2965,14 +2974,25 @@ static char *drmGetMinorNameForFD(int fd, int type)
      * FreeBSD on amd64/i386/powerpc external kernel modules create node in
      * in /dev/drm/ and links in /dev/dri while a WIP in kernel driver creates
      * only device nodes in /dev/dri/ */
+
+    /* Get the node type represented by fd so we can deduce the target name */
+    nodetype = drmGetMinorType(maj, min);
+    if (nodetype == -1)
+        return (NULL);
     mname = drmGetMinorName(type);
-    if (sscanf(dname, "drm/%d", &id) != 1) {
-        snprintf(name, sizeof(name), "dri/%s", mname);
-        if (strncmp(name, dname, strlen(name)) != 0)
-            return NULL;
-        snprintf(name, sizeof(name), "/dev/%s", dname);
-    } else
-        snprintf(name, sizeof(name), DRM_DIR_NAME "/%s%d", mname, id);
+
+    for (i = 0; i < SPECNAMELEN; i++) {
+        if (isalpha(dname[i]) == 0 && dname[i] != '/')
+           break;
+    }
+    if (dname[i] == '\0')
+        return (NULL);
+
+    id = (int)strtol(&dname[i], NULL, 10);
+    id -= drmGetMinorBase(nodetype);
+    snprintf(name, sizeof(name), DRM_DIR_NAME "/%s%d", mname,
+         id + drmGetMinorBase(type));
+
     return strdup(name);
 #else
     struct stat sbuf;
@@ -3251,7 +3271,7 @@ static int drmParsePciBusInfo(int maj, int min, drmPciBusInfoPtr info)
     info->func = pinfo.func;
 
     return 0;
-#elif __FreeBSD__
+#elif defined(__FreeBSD__)
     return get_sysctl_pci_bus_info(maj, min, info);
 #else
 #warning "Missing implementation of drmParsePciBusInfo"
@@ -3420,7 +3440,7 @@ static int drmParsePciDeviceInfo(int maj, int min,
     device->subdevice_id = pinfo.subdevice_id;
 
     return 0;
-#elif __FreeBSD__
+#elif defined(__FreeBSD__)
     drmPciBusInfo info;
     struct pci_conf_io pc;
     struct pci_match_conf patterns[1];
@@ -3997,7 +4017,7 @@ static void drmFoldDuplicatedDevices(drmDevicePtr local_devices[], int count)
         for (j = i + 1; j < count; j++) {
             if (drmDevicesEqual(local_devices[i], local_devices[j])) {
                 local_devices[i]->available_nodes |= local_devices[j]->available_nodes;
-                node_type = log2(local_devices[j]->available_nodes);
+                node_type = log2_int(local_devices[j]->available_nodes);
                 memcpy(local_devices[i]->nodes[node_type],
                        local_devices[j]->nodes[node_type], drmGetMaxNodeName());
                 drmFreeDevice(&local_devices[j]);
@@ -4298,7 +4318,7 @@ drm_public char *drmGetDeviceNameFromFd2(int fd)
     free(value);
 
     return strdup(path);
-#elif __FreeBSD__
+#elif defined(__FreeBSD__)
     return drmGetDeviceNameFromFd(fd);
 #else
     struct stat      sbuf;