Implement drmOpen* without /proc dependence (Fallback to /proc is included
authorRik Faith <faith@alephnull.com>
Wed, 28 Feb 2001 09:27:44 +0000 (09:27 +0000)
committerRik Faith <faith@alephnull.com>
Wed, 28 Feb 2001 09:27:44 +0000 (09:27 +0000)
    for backward compatibility.) Move statistic-gathering drm* calls from
    dristat.c to xf86drm.c

libdrm/xf86drm.c
linux/Makefile.linux
linux/drm.h
shared-core/drm.h
shared/drm.h
tests/dristat.c

index e472aad..73a083e 100644 (file)
@@ -81,7 +81,18 @@ extern unsigned long _bus_base(void);
 #include "xf86drm.h"
 #include "drm.h"
 
-#define DRM_FIXED_DEVICE_MAJOR 145
+#ifndef DRM_MAJOR
+#define DRM_MAJOR 226          /* Linux */
+#endif
+
+#ifndef __linux__
+#undef  DRM_MAJOR
+#define DRM_MAJOR 145          /* Should set in drm.h for *BSD */
+#endif
+
+#ifndef DRM_MAX_MINOR
+#define DRM_MAX_MINOR 16
+#endif
 
 #ifdef __linux__
 #include <sys/sysmacros.h>     /* for makedev() */
@@ -161,93 +172,108 @@ static drmHashEntry *drmGetEntry(int fd)
     return entry;
 }
 
-/* drm_open is used to open the /dev/dri device */
-
-static int drm_open(const char *file)
-{
-    int fd = open(file, O_RDWR, 0);
-
-    if (fd >= 0) return fd;
-    return -errno;
-}
-
-static int drmOpenDevice(const char *path, long dev,
-                        mode_t mode, uid_t user, gid_t group)
+static int drmOpenDevice(long dev, int minor)
 {
 #ifdef XFree86LOADER
     struct xf86stat st;
 #else
     struct stat     st;
 #endif
+    char            buf[64];
+    int             fd;
+    mode_t          dirmode = DRM_DEV_DIRMODE;
+    mode_t          devmode = DRM_DEV_MODE;
+    int             isroot  = !geteuid();
+#if defined(XFree86Server)
+    uid_t           user    = DRM_DEV_UID;
+    gid_t           group   = DRM_DEV_GID;
+#endif
 
-                               /* Fiddle mode to remove execute bits */
-    mode &= ~(S_IXUSR|S_IXGRP|S_IXOTH);
+#if defined(XFree86Server)
+    devmode  = xf86ConfigDRI.mode ? xf86ConfigDRI.mode : DRM_DEV_MODE;
+    dirmode  = (devmode & S_IRUSR) ? S_IXUSR : 0;
+    dirmode |= (devmode & S_IRGRP) ? S_IXGRP : 0;
+    dirmode |= (devmode & S_IROTH) ? S_IXOTH : 0;
+    dirmode |= devmode;
+    devmode &= ~(S_IXUSR|S_IXGRP|S_IXOTH);
+    group = (xf86ConfigDRI.group >= 0) ? xf86ConfigDRI.group : DRM_DEV_GID;
+#endif
 
-    if (!stat(path, &st) && st.st_rdev == dev) {
-       if (!geteuid()) {
-           chown(path, user, group);
-           chmod(path, mode);
-       }
-       return drm_open(path);
+    if (stat(DRM_DIR_NAME, &st)) {
+       if (!isroot) return DRM_ERR_NOT_ROOT;
+       remove(DRM_DIR_NAME);
+       mkdir(DRM_DIR_NAME, dirmode);
     }
+#if defined(XFree86Server)
+    chown(DRM_DIR_NAME, user, group);
+    chmod(DRM_DIR_NAME, dirmode);
+#endif
 
-    if (geteuid()) return DRM_ERR_NOT_ROOT;
-    remove(path);
-    if (mknod(path, S_IFCHR, dev)) {
-       remove(path);
-       return DRM_ERR_NOT_ROOT;
+    sprintf(buf, DRM_DEV_NAME, DRM_DIR_NAME, minor);
+    if (stat(buf, &st) || st.st_rdev != dev) {
+       if (!isroot) return DRM_ERR_NOT_ROOT;
+       remove(buf);
+       mknod(buf, S_IFCHR | devmode, dev);
     }
-    chown(path, user, group);
-    chmod(path, mode);
-    return drm_open(path);
+#if defined(XFree86Server)
+    chown(buf, user, group);
+    chmod(buf, devmode);
+#endif
+
+    if ((fd = open(buf, O_RDWR, 0)) >= 0) return fd;
+    remove(buf);
+    return -errno;
 }
 
-/* drmAvailable looks for /proc/dri, and returns 1 if it is present.  On
-   OSs that do not have a Linux-like /proc, this information will not be
-   available, and we'll have to create a device and check if the driver is
-   loaded that way. */
+int drmOpenMinor(int minor, int create)
+{
+    int  fd;
+    char buf[64];
+    
+    if (create) return drmOpenDevice(makedev(DRM_MAJOR, minor), minor);
+    
+    sprintf(buf, DRM_DEV_NAME, DRM_DIR_NAME, minor);
+    if ((fd = open(buf, O_RDWR, 0)) >= 0) return fd;
+    return -errno;
+}
+
+/* drmAvailable looks for (DRM_MAJOR, 0) and returns 1 if it returns
+   information for DRM_IOCTL_VERSION.  For backward compatibility with
+   older Linux implementations, /proc/dri is also checked. */
 
 int drmAvailable(void)
 {
-    char          dev_name[64];
     drmVersionPtr version;
     int           retval = 0;
     int           fd;
 
-    if (!access("/proc/dri/0", R_OK)) return 1;
-
-    sprintf(dev_name, "/dev/dri-temp-%d", getpid());
-
-    remove(dev_name);
-    if ((fd = drmOpenDevice(dev_name, makedev(DRM_FIXED_DEVICE_MAJOR, 0),
-                           S_IRUSR, geteuid(), getegid())) >= 0) {
-                               /* Read version to make sure this is
-                                   actually a DRI device. */
-       if ((version = drmGetVersion(fd))) {
-           retval = 1;
-           drmFreeVersion(version);
-       }
-       close(fd);
+    if ((fd = drmOpenMinor(0, 1)) < 0) {
+                               /* Try proc for backward Linux compatibility */
+       if (!access("/proc/dri/0", R_OK)) return 1;
+       return 0;
     }
-    remove(dev_name);
+    
+    if ((version = drmGetVersion(fd))) {
+       retval = 1;
+       drmFreeVersion(version);
+    }
+    close(fd);
 
     return retval;
 }
 
 static int drmOpenByBusid(const char *busid)
 {
-    int    i;
-    char   dev_name[64];
-    char   *buf;
-    int    fd;
-
-    for (i = 0; i < 8; i++) {
-       sprintf(dev_name, "/dev/dri/card%d", i);
-       if ((fd = drm_open(dev_name)) >= 0) {
+    int        i;
+    int        fd;
+    const char *buf;
+    
+    for (i = 0; i < DRM_MAX_MINOR; i++) {
+       if ((fd = drmOpenMinor(i, 0)) >= 0) {
            buf = drmGetBusid(fd);
            if (buf && !strcmp(buf, busid)) {
-             drmFreeBusid(buf);
-             return fd;
+               drmFreeBusid(buf);
+               return fd;
            }
            if (buf) drmFreeBusid(buf);
            close(fd);
@@ -258,54 +284,43 @@ static int drmOpenByBusid(const char *busid)
 
 static int drmOpenByName(const char *name)
 {
-    int    i;
-    char   proc_name[64];
-    char   dev_name[64];
-    char   buf[512];
-    mode_t mode   = DRM_DEV_MODE;
-    mode_t dirmode;
-    gid_t  group  = DRM_DEV_GID;
-    uid_t  user   = DRM_DEV_UID;
-    int    fd;
-    char   *pt;
-    char   *driver = NULL;
-    char   *devstring;
-    long   dev     = 0;
-    int    retcode;
-
-#if defined(XFree86Server)
-    mode  = xf86ConfigDRI.mode ? xf86ConfigDRI.mode : DRM_DEV_MODE;
-    group = (xf86ConfigDRI.group >= 0) ? xf86ConfigDRI.group : DRM_DEV_GID;
-#endif
-
-#if defined(XFree86Server)
+    int           i;
+    int           fd;
+    drmVersionPtr version;
+    
     if (!drmAvailable()) {
+#if !defined(XFree86Server)
+       return -1;
+#else
         /* try to load the kernel module now */
         if (!xf86LoadKernelModule(name)) {
             ErrorF("[drm] failed to load kernel module \"%s\"\n",
                   name);
             return -1;
         }
-    }
-#else
-    if (!drmAvailable())
-       return -1;
 #endif
+    }
 
-    if (!geteuid()) {
-       dirmode = mode;
-       if (dirmode & S_IRUSR) dirmode |= S_IXUSR;
-       if (dirmode & S_IRGRP) dirmode |= S_IXGRP;
-       if (dirmode & S_IROTH) dirmode |= S_IXOTH;
-       dirmode &= ~(S_IWGRP | S_IWOTH);
-       mkdir("/dev/dri", 0);
-       chown("/dev/dri", user, group);
-       chmod("/dev/dri", dirmode);
+    for (i = 0; i < DRM_MAX_MINOR; i++) {
+       if ((fd = drmOpenMinor(i, 1)) >= 0) {
+           if ((version = drmGetVersion(fd))) {
+               if (!strcmp(version->name, name)) {
+                   drmFreeVersion(version);
+                   return fd;
+               }
+               drmFreeVersion(version);
+           }
+       }
     }
 
+#ifdef __linux__
+                               /* Backward-compatibility /proc support */
     for (i = 0; i < 8; i++) {
+       char proc_name[64], buf[512];
+       char *driver, *pt, *devstring;
+       int  retcode;
+       
        sprintf(proc_name, "/proc/dri/%d/name", i);
-       sprintf(dev_name, "/dev/dri/card%d", i);
        if ((fd = open(proc_name, 0, 0)) >= 0) {
            retcode = read(fd, buf, sizeof(buf)-1);
            close(fd);
@@ -319,34 +334,17 @@ static int drmOpenByName(const char *name)
                        for (devstring = ++pt; *pt && *pt != ' '; ++pt)
                            ;
                        if (*pt) { /* Found busid */
-                         return drmOpenByBusid(++pt);
+                           return drmOpenByBusid(++pt);
                        } else {        /* No busid */
-                         dev = strtol(devstring, NULL, 0);
-                         return drmOpenDevice(dev_name, dev,
-                                              mode, user, group);
+                           return drmOpenDevice(strtol(devstring, NULL, 0),i);
                        }
                    }
                }
            }
-       } else {
-           drmVersionPtr version;
-                               /* /proc/dri not available, possibly
-                                   because we aren't on a Linux system.
-                                   So, try to create the next device and
-                                   see if it's active. */
-           dev = makedev(DRM_FIXED_DEVICE_MAJOR, i);
-           if ((fd = drmOpenDevice(dev_name, dev, mode, user, group))) {
-               if ((version = drmGetVersion(fd))) {
-                   if (!strcmp(version->name, name)) {
-                       drmFreeVersion(version);
-                       return fd;
-                   }
-                   drmFreeVersion(version);
-               }
-           }
-           remove(dev_name);
        }
     }
+#endif
+
     return -1;
 }
 
@@ -1090,6 +1088,160 @@ void *drmGetContextTag(int fd, drmContext context)
     return value;
 }
 
+int drmGetMap(int fd, int idx, drmHandle *offset, drmSize *size,
+             drmMapType *type, drmMapFlags *flags, drmHandle *handle,
+             int *mtrr)
+{
+    drm_map_t map;
+
+    map.offset = idx;
+    if (ioctl(fd, DRM_IOCTL_GET_MAP, &map)) return -errno;
+    *offset = map.offset;
+    *size   = map.size;
+    *type   = map.type;
+    *flags  = map.flags;
+    *handle = (unsigned long)map.handle;
+    *mtrr   = map.mtrr;
+    return 0;
+}
+
+int drmGetClient(int fd, int idx, int *auth, int *pid, int *uid,
+                unsigned long *magic, unsigned long *iocs)
+{
+    drm_client_t client;
+
+    client.idx = idx;
+    if (ioctl(fd, DRM_IOCTL_GET_CLIENT, &client)) return -errno;
+    *auth      = client.auth;
+    *pid       = client.pid;
+    *uid       = client.uid;
+    *magic     = client.magic;
+    *iocs      = client.iocs;
+    return 0;
+}
+
+int drmGetStats(int fd, drmStatsT *stats)
+{
+    drm_stats_t s;
+    int         i;
+
+    if (ioctl(fd, DRM_IOCTL_GET_STATS, &s)) return -errno;
+
+    stats->count = 0;
+    memset(stats, 0, sizeof(*stats));
+    if (s.count > sizeof(stats->data)/sizeof(stats->data[0]))
+       return -1;
+
+#define SET_VALUE                              \
+    stats->data[i].long_format = "%-20.20s";   \
+    stats->data[i].rate_format = "%8.8s";      \
+    stats->data[i].isvalue     = 1;            \
+    stats->data[i].verbose     = 0
+
+#define SET_COUNT                              \
+    stats->data[i].long_format = "%-20.20s";   \
+    stats->data[i].rate_format = "%5.5s";      \
+    stats->data[i].isvalue     = 0;            \
+    stats->data[i].mult_names  = "kgm";        \
+    stats->data[i].mult        = 1000;         \
+    stats->data[i].verbose     = 0
+
+#define SET_BYTE                               \
+    stats->data[i].long_format = "%-20.20s";   \
+    stats->data[i].rate_format = "%5.5s";      \
+    stats->data[i].isvalue     = 0;            \
+    stats->data[i].mult_names  = "KGM";        \
+    stats->data[i].mult        = 1024;         \
+    stats->data[i].verbose     = 0
+
+
+    stats->count = s.count;
+    for (i = 0; i < s.count; i++) {
+       stats->data[i].value = s.data[i].value;
+       switch (s.data[i].type) {
+       case _DRM_STAT_LOCK:
+           stats->data[i].long_name = "Lock";
+           stats->data[i].rate_name = "Lock";
+           SET_VALUE;
+           break;
+       case _DRM_STAT_OPENS:
+           stats->data[i].long_name = "Opens";
+           stats->data[i].rate_name = "O";
+           SET_COUNT;
+           stats->data[i].verbose   = 1;
+           break;
+       case _DRM_STAT_CLOSES:
+           stats->data[i].long_name = "Closes";
+           stats->data[i].rate_name = "Lock";
+           SET_COUNT;
+           stats->data[i].verbose   = 1;
+           break;
+       case _DRM_STAT_IOCTLS:
+           stats->data[i].long_name = "Ioctls";
+           stats->data[i].rate_name = "Ioc/s";
+           SET_COUNT;
+           break;
+       case _DRM_STAT_LOCKS:
+           stats->data[i].long_name = "Locks";
+           stats->data[i].rate_name = "Lck/s";
+           SET_COUNT;
+           break;
+       case _DRM_STAT_UNLOCKS:
+           stats->data[i].long_name = "Unlocks";
+           stats->data[i].rate_name = "Unl/s";
+           SET_COUNT;
+           break;
+       case _DRM_STAT_IRQ:
+           stats->data[i].long_name = "IRQs";
+           stats->data[i].rate_name = "IRQ/s";
+           SET_COUNT;
+           break;
+       case _DRM_STAT_PRIMARY:
+           stats->data[i].long_name = "Primary Bytes";
+           stats->data[i].rate_name = "PB/s";
+           SET_BYTE;
+           break;
+       case _DRM_STAT_SECONDARY:
+           stats->data[i].long_name = "Secondary Bytes";
+           stats->data[i].rate_name = "SB/s";
+           SET_BYTE;
+           break;
+       case _DRM_STAT_DMA:
+           stats->data[i].long_name = "DMA";
+           stats->data[i].rate_name = "DMA/s";
+           SET_COUNT;
+           break;
+       case _DRM_STAT_SPECIAL:
+           stats->data[i].long_name = "Special DMA";
+           stats->data[i].rate_name = "dma/s";
+           SET_COUNT;
+           break;
+       case _DRM_STAT_MISSED:
+           stats->data[i].long_name = "Miss";
+           stats->data[i].rate_name = "Ms/s";
+           SET_COUNT;
+           break;
+       case _DRM_STAT_VALUE:
+           stats->data[i].long_name = "Value";
+           stats->data[i].rate_name = "Value";
+           SET_VALUE;
+           break;
+       case _DRM_STAT_BYTE:
+           stats->data[i].long_name = "Bytes";
+           stats->data[i].rate_name = "B/s";
+           SET_BYTE;
+           break;
+       case _DRM_STAT_COUNT:
+       default:
+           stats->data[i].long_name = "Count";
+           stats->data[i].rate_name = "Cnt/s";
+           SET_COUNT;
+           break;
+       }
+    }
+    return 0;
+}
+
 #if defined(XFree86Server) || defined(DRM_USE_MALLOC)
 static void drmSIGIOHandler(int interrupt, void *closure)
 {
index 7c1269c..d022557 100644 (file)
@@ -174,7 +174,7 @@ all::;@echo === SMP=${SMP} MODULES=${MODULES} MODVERSIONS=${MODVERSIONS} AGP=${A
 all::;@echo === kill_fasync has $(PARAMS) parameters
 all::;@echo === Compiling for machine $(MACHINE)
 all::;@echo === WARNING
-all::;@echo === WARNING 2.4.0 kernels before test11 DONT WORK
+all::;@echo === WARNING 2.4.0 kernels before 2.4.0-test11 DO NOT WORK
 all::;@echo === WARNING
 
 ifeq ($(MODULES),0)
index 470eb03..40a8587 100644 (file)
 #define DRM_IOCTL_NR(n)             ((n) & 0xff)
 #endif
 
-#define DRM_DEV_MODE    (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP)
-#define DRM_DEV_UID     0
-#define DRM_DEV_GID     0
-
 #define DRM_MAJOR       226
+#define DRM_MAX_MINOR   15
 #define DRM_NAME       "drm"     /* Name in kernel, /dev, and /proc        */
 #define DRM_MIN_ORDER  5         /* At least 2^5 bytes = 32 bytes          */
 #define DRM_MAX_ORDER  22        /* Up to 2^22 bytes = 4MB                 */
index 470eb03..40a8587 100644 (file)
 #define DRM_IOCTL_NR(n)             ((n) & 0xff)
 #endif
 
-#define DRM_DEV_MODE    (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP)
-#define DRM_DEV_UID     0
-#define DRM_DEV_GID     0
-
 #define DRM_MAJOR       226
+#define DRM_MAX_MINOR   15
 #define DRM_NAME       "drm"     /* Name in kernel, /dev, and /proc        */
 #define DRM_MIN_ORDER  5         /* At least 2^5 bytes = 32 bytes          */
 #define DRM_MAX_ORDER  22        /* Up to 2^22 bytes = 4MB                 */
index 470eb03..40a8587 100644 (file)
 #define DRM_IOCTL_NR(n)             ((n) & 0xff)
 #endif
 
-#define DRM_DEV_MODE    (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP)
-#define DRM_DEV_UID     0
-#define DRM_DEV_GID     0
-
 #define DRM_MAJOR       226
+#define DRM_MAX_MINOR   15
 #define DRM_NAME       "drm"     /* Name in kernel, /dev, and /proc        */
 #define DRM_MIN_ORDER  5         /* At least 2^5 bytes = 32 bytes          */
 #define DRM_MAX_ORDER  22        /* Up to 2^22 bytes = 4MB                 */
index f429efd..47193ab 100644 (file)
 #include "../xf86drmHash.c"
 #include "../xf86drm.c"
 
-#define DRM_DIR_NAME "/dev/dri"
-#define DRM_DEV_NAME "%s/card%d"
-
 #define DRM_VERSION 0x00000001
 #define DRM_MEMORY  0x00000002
 #define DRM_CLIENTS 0x00000004
 #define DRM_STATS   0x00000008
-
-typedef struct drmStatsS {
-    unsigned long count;
-    struct {
-       unsigned long value;
-       const char    *long_format;
-       const char    *long_name;
-       const char    *rate_format;
-       const char    *rate_name;
-       int           isvalue;
-       const char    *mult_names;
-       int           mult;
-       int           verbose;
-    } data[15];
-} drmStatsT;
+#define DRM_BUSID   0x00000010
 
 static void getversion(int fd)
 {
@@ -78,6 +61,15 @@ static void getversion(int fd)
     }
 }
 
+static void getbusid(int fd)
+{
+    const char *busid = drmGetBusid(fd);
+    
+    printf("  Busid: %s\n", *busid ? busid : "(not set)");
+    drmFreeBusid(busid);
+}
+
+#if 0
 typedef struct {
     unsigned long      offset;  /* Requested physical address (0 for SAREA)*/
     unsigned long      size;    /* Requested physical size (bytes)         */
@@ -88,160 +80,7 @@ typedef struct {
     int                mtrr;    /* MTRR slot used                          */
                                 /* Private data                            */
 } drmVmRec, *drmVmPtr;
-
-int drmGetMap(int fd, int idx, drmHandle *offset, drmSize *size,
-             drmMapType *type, drmMapFlags *flags, drmHandle *handle,
-             int *mtrr)
-{
-    drm_map_t map;
-
-    map.offset = idx;
-    if (ioctl(fd, DRM_IOCTL_GET_MAP, &map)) return -errno;
-    *offset = map.offset;
-    *size   = map.size;
-    *type   = map.type;
-    *flags  = map.flags;
-    *handle = (unsigned long)map.handle;
-    *mtrr   = map.mtrr;
-    return 0;
-}
-
-int drmGetClient(int fd, int idx, int *auth, int *pid, int *uid,
-                unsigned long *magic, unsigned long *iocs)
-{
-    drm_client_t client;
-
-    client.idx = idx;
-    if (ioctl(fd, DRM_IOCTL_GET_CLIENT, &client)) return -errno;
-    *auth      = client.auth;
-    *pid       = client.pid;
-    *uid       = client.uid;
-    *magic     = client.magic;
-    *iocs      = client.iocs;
-    return 0;
-}
-
-int drmGetStats(int fd, drmStatsT *stats)
-{
-    drm_stats_t s;
-    int         i;
-
-    if (ioctl(fd, DRM_IOCTL_GET_STATS, &s)) return -errno;
-
-    stats->count = 0;
-    memset(stats, 0, sizeof(*stats));
-    if (s.count > sizeof(stats->data)/sizeof(stats->data[0]))
-       return -1;
-
-#define SET_VALUE                              \
-    stats->data[i].long_format = "%-20.20s";   \
-    stats->data[i].rate_format = "%8.8s";      \
-    stats->data[i].isvalue     = 1;            \
-    stats->data[i].verbose     = 0
-
-#define SET_COUNT                              \
-    stats->data[i].long_format = "%-20.20s";     \
-    stats->data[i].rate_format = "%5.5s";      \
-    stats->data[i].isvalue     = 0;            \
-    stats->data[i].mult_names  = "kgm";        \
-    stats->data[i].mult        = 1000;         \
-    stats->data[i].verbose     = 0
-
-#define SET_BYTE                             \
-    stats->data[i].long_format = "%-9.9s";   \
-    stats->data[i].rate_format = "%5.5s";    \
-    stats->data[i].isvalue     = 0;          \
-    stats->data[i].mult_names  = "KGM";      \
-    stats->data[i].mult        = 1024;       \
-    stats->data[i].verbose     = 0
-
-
-    stats->count = s.count;
-    for (i = 0; i < s.count; i++) {
-       stats->data[i].value = s.data[i].value;
-       switch (s.data[i].type) {
-       case _DRM_STAT_LOCK:
-           stats->data[i].long_name = "Lock";
-           stats->data[i].rate_name = "Lock";
-           SET_VALUE;
-           break;
-       case _DRM_STAT_OPENS:
-           stats->data[i].long_name = "Opens";
-           stats->data[i].rate_name = "O";
-           SET_COUNT;
-           stats->data[i].verbose   = 1;
-           break;
-       case _DRM_STAT_CLOSES:
-           stats->data[i].long_name = "Closes";
-           stats->data[i].rate_name = "Lock";
-           SET_COUNT;
-           stats->data[i].verbose   = 1;
-           break;
-       case _DRM_STAT_IOCTLS:
-           stats->data[i].long_name = "Ioctls";
-           stats->data[i].rate_name = "Ioc/s";
-           SET_COUNT;
-           break;
-       case _DRM_STAT_LOCKS:
-           stats->data[i].long_name = "Locks";
-           stats->data[i].rate_name = "Lck/s";
-           SET_COUNT;
-           break;
-       case _DRM_STAT_UNLOCKS:
-           stats->data[i].long_name = "Unlocks";
-           stats->data[i].rate_name = "Unl/s";
-           SET_COUNT;
-           break;
-       case _DRM_STAT_IRQ:
-           stats->data[i].long_name = "IRQs";
-           stats->data[i].rate_name = "IRQ/s";
-           SET_COUNT;
-           break;
-       case _DRM_STAT_PRIMARY:
-           stats->data[i].long_name = "Primary Bytes";
-           stats->data[i].rate_name = "PB/s";
-           SET_BYTE;
-           break;
-       case _DRM_STAT_SECONDARY:
-           stats->data[i].long_name = "Secondary Bytes";
-           stats->data[i].rate_name = "SB/s";
-           SET_BYTE;
-           break;
-       case _DRM_STAT_DMA:
-           stats->data[i].long_name = "DMA";
-           stats->data[i].rate_name = "DMA/s";
-           SET_COUNT;
-           break;
-       case _DRM_STAT_SPECIAL:
-           stats->data[i].long_name = "Special DMA";
-           stats->data[i].rate_name = "dma/s";
-           SET_COUNT;
-           break;
-       case _DRM_STAT_MISSED:
-           stats->data[i].long_name = "Miss";
-           stats->data[i].rate_name = "Ms/s";
-           SET_COUNT;
-           break;
-       case _DRM_STAT_VALUE:
-           stats->data[i].long_name = "Value";
-           stats->data[i].rate_name = "Value";
-           SET_VALUE;
-           break;
-       case _DRM_STAT_BYTE:
-           stats->data[i].long_name = "Bytes";
-           stats->data[i].rate_name = "B/s";
-           SET_BYTE;
-           break;
-       case _DRM_STAT_COUNT:
-       default:
-           stats->data[i].long_name = "Count";
-           stats->data[i].rate_name = "Cnt/s";
-           SET_COUNT;
-           break;
-       }
-    }
-    return 0;
-}
+#endif
 
 static void getvm(int fd)
 {
@@ -255,7 +94,7 @@ static void getvm(int fd)
     drmHandle       handle;
     int             mtrr;
 
-    printf("  VM map information:\n");
+    printf("  VM map information (Restricted locked kernel WC Lock):\n");
     printf("    slot     offset       size type flags    address mtrr\n");
 
     for (i = 0;
@@ -298,7 +137,7 @@ static void getclients(int fd)
     int           procfd;
     
     printf("  DRI client information:\n");
-    printf("    a   pid    uid      magic     ioctls  prog\n");
+    printf("    a   pid   uid      magic     ioctls   prog\n");
 
     for (i = 0; !drmGetClient(fd, i, &auth, &pid, &uid, &magic, &iocs); i++) {
        sprintf(buf, "/proc/%d/cmdline", pid);
@@ -307,12 +146,16 @@ static void getclients(int fd)
            read(procfd, cmd, sizeof(cmd)-1);
            close(procfd);
        }
-       if (*cmd)
+       if (*cmd) {
+           char *pt;
+
+           for (pt = cmd; *pt; pt++) if (!isprint(*pt)) *pt = ' ';
            printf("    %c %5d %5d %10lu %10lu   %s\n",
                   auth ? 'y' : 'n', pid, uid, magic, iocs, cmd);
-       else
+       } else {
            printf("    %c %5d %5d %10lu %10lu\n",
                   auth ? 'y' : 'n', pid, uid, magic, iocs);
+       }
     }
 }
 
@@ -394,44 +237,6 @@ static void getstats(int fd, int i)
     
 }
 
-static int drmOpenMinor(int minor, uid_t user, gid_t group,
-                       mode_t dirmode, mode_t devmode, int force)
-{
-    struct stat st;
-    char        buf[64];
-    long        dev    = makedev(DRM_MAJOR, minor);
-    int         setdir = 0;
-    int         setdev = 0;
-    int         fd;
-
-    if (stat(DRM_DIR_NAME, &st) || !S_ISDIR(st.st_mode)) {
-       remove(DRM_DIR_NAME);
-       mkdir(DRM_DIR_NAME, dirmode);
-       ++setdir;
-    }
-
-    if (force || setdir) {
-       chown(DRM_DIR_NAME, user, group);
-       chmod(DRM_DIR_NAME, dirmode);
-    }
-
-    sprintf(buf, DRM_DEV_NAME, DRM_DIR_NAME, minor);
-    if (stat(buf, &st) || st.st_rdev != dev) {
-       remove(buf);
-       mknod(buf, S_IFCHR, dev);
-       ++setdev;
-    }
-
-    if (force || setdev) {
-       chown(buf, user, group);
-       chmod(buf, devmode);
-    }
-
-    if ((fd = open(buf, O_RDWR, 0)) >= 0) return fd;
-    if (setdev) remove(buf);
-    return -errno;
-}
-       
 int main(int argc, char **argv)
 {
     int  c;
@@ -442,13 +247,14 @@ int main(int argc, char **argv)
     char buf[64];
     int  i;
 
-    while ((c = getopt(argc, argv, "avmcsM:i:")) != EOF)
+    while ((c = getopt(argc, argv, "avmcsbM:i:")) != EOF)
        switch (c) {
        case 'a': mask = ~0;                          break;
        case 'v': mask |= DRM_VERSION;                break;
        case 'm': mask |= DRM_MEMORY;                 break;
        case 'c': mask |= DRM_CLIENTS;                break;
        case 's': mask |= DRM_STATS;                  break;
+       case 'b': mask |= DRM_BUSID;                  break;
        case 'i': interval = strtol(optarg, NULL, 0); break;
        case 'M': minor = strtol(optarg, NULL, 0);    break;
        default:
@@ -458,9 +264,10 @@ int main(int argc, char **argv)
 
     for (i = 0; i < 16; i++) if (!minor || i == minor) {
        sprintf(buf, DRM_DEV_NAME, DRM_DIR_NAME, i);
-       fd = drmOpenMinor(i, 0, 0, 0700, 0600, 0);
+       fd = drmOpenMinor(i, 1);
        if (fd >= 0) {
            printf("%s\n", buf);
+           if (mask & DRM_BUSID)   getbusid(fd);
            if (mask & DRM_VERSION) getversion(fd);
            if (mask & DRM_MEMORY)  getvm(fd);
            if (mask & DRM_CLIENTS) getclients(fd);