Implement drmOpen* without /proc dependence (Fallback to /proc is included
for backward compatibility.) Move statistic-gathering drm* calls from dristat.c to xf86drm.cmain
parent
c4a247d262
commit
88dbee54ed
354
libdrm/xf86drm.c
354
libdrm/xf86drm.c
|
@ -81,7 +81,18 @@ extern unsigned long _bus_base(void);
|
||||||
#include "xf86drm.h"
|
#include "xf86drm.h"
|
||||||
#include "drm.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__
|
#ifdef __linux__
|
||||||
#include <sys/sysmacros.h> /* for makedev() */
|
#include <sys/sysmacros.h> /* for makedev() */
|
||||||
|
@ -161,75 +172,92 @@ static drmHashEntry *drmGetEntry(int fd)
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* drm_open is used to open the /dev/dri device */
|
static int drmOpenDevice(long dev, int minor)
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
#ifdef XFree86LOADER
|
#ifdef XFree86LOADER
|
||||||
struct xf86stat st;
|
struct xf86stat st;
|
||||||
#else
|
#else
|
||||||
struct stat st;
|
struct stat st;
|
||||||
#endif
|
#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 */
|
#if defined(XFree86Server)
|
||||||
mode &= ~(S_IXUSR|S_IXGRP|S_IXOTH);
|
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 (stat(DRM_DIR_NAME, &st)) {
|
||||||
if (!geteuid()) {
|
if (!isroot) return DRM_ERR_NOT_ROOT;
|
||||||
chown(path, user, group);
|
remove(DRM_DIR_NAME);
|
||||||
chmod(path, mode);
|
mkdir(DRM_DIR_NAME, dirmode);
|
||||||
}
|
}
|
||||||
return drm_open(path);
|
#if defined(XFree86Server)
|
||||||
|
chown(DRM_DIR_NAME, user, group);
|
||||||
|
chmod(DRM_DIR_NAME, dirmode);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
#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;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (geteuid()) return DRM_ERR_NOT_ROOT;
|
int drmOpenMinor(int minor, int create)
|
||||||
remove(path);
|
{
|
||||||
if (mknod(path, S_IFCHR, dev)) {
|
int fd;
|
||||||
remove(path);
|
char buf[64];
|
||||||
return DRM_ERR_NOT_ROOT;
|
|
||||||
}
|
if (create) return drmOpenDevice(makedev(DRM_MAJOR, minor), minor);
|
||||||
chown(path, user, group);
|
|
||||||
chmod(path, mode);
|
sprintf(buf, DRM_DEV_NAME, DRM_DIR_NAME, minor);
|
||||||
return drm_open(path);
|
if ((fd = open(buf, O_RDWR, 0)) >= 0) return fd;
|
||||||
|
return -errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* drmAvailable looks for /proc/dri, and returns 1 if it is present. On
|
/* drmAvailable looks for (DRM_MAJOR, 0) and returns 1 if it returns
|
||||||
OSs that do not have a Linux-like /proc, this information will not be
|
information for DRM_IOCTL_VERSION. For backward compatibility with
|
||||||
available, and we'll have to create a device and check if the driver is
|
older Linux implementations, /proc/dri is also checked. */
|
||||||
loaded that way. */
|
|
||||||
|
|
||||||
int drmAvailable(void)
|
int drmAvailable(void)
|
||||||
{
|
{
|
||||||
char dev_name[64];
|
|
||||||
drmVersionPtr version;
|
drmVersionPtr version;
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
|
if ((fd = drmOpenMinor(0, 1)) < 0) {
|
||||||
|
/* Try proc for backward Linux compatibility */
|
||||||
if (!access("/proc/dri/0", R_OK)) return 1;
|
if (!access("/proc/dri/0", R_OK)) return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
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))) {
|
if ((version = drmGetVersion(fd))) {
|
||||||
retval = 1;
|
retval = 1;
|
||||||
drmFreeVersion(version);
|
drmFreeVersion(version);
|
||||||
}
|
}
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
|
||||||
remove(dev_name);
|
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
@ -237,13 +265,11 @@ int drmAvailable(void)
|
||||||
static int drmOpenByBusid(const char *busid)
|
static int drmOpenByBusid(const char *busid)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
char dev_name[64];
|
|
||||||
char *buf;
|
|
||||||
int fd;
|
int fd;
|
||||||
|
const char *buf;
|
||||||
|
|
||||||
for (i = 0; i < 8; i++) {
|
for (i = 0; i < DRM_MAX_MINOR; i++) {
|
||||||
sprintf(dev_name, "/dev/dri/card%d", i);
|
if ((fd = drmOpenMinor(i, 0)) >= 0) {
|
||||||
if ((fd = drm_open(dev_name)) >= 0) {
|
|
||||||
buf = drmGetBusid(fd);
|
buf = drmGetBusid(fd);
|
||||||
if (buf && !strcmp(buf, busid)) {
|
if (buf && !strcmp(buf, busid)) {
|
||||||
drmFreeBusid(buf);
|
drmFreeBusid(buf);
|
||||||
|
@ -259,53 +285,42 @@ static int drmOpenByBusid(const char *busid)
|
||||||
static int drmOpenByName(const char *name)
|
static int drmOpenByName(const char *name)
|
||||||
{
|
{
|
||||||
int i;
|
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;
|
int fd;
|
||||||
char *pt;
|
drmVersionPtr version;
|
||||||
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)
|
|
||||||
if (!drmAvailable()) {
|
if (!drmAvailable()) {
|
||||||
|
#if !defined(XFree86Server)
|
||||||
|
return -1;
|
||||||
|
#else
|
||||||
/* try to load the kernel module now */
|
/* try to load the kernel module now */
|
||||||
if (!xf86LoadKernelModule(name)) {
|
if (!xf86LoadKernelModule(name)) {
|
||||||
ErrorF("[drm] failed to load kernel module \"%s\"\n",
|
ErrorF("[drm] failed to load kernel module \"%s\"\n",
|
||||||
name);
|
name);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#else
|
|
||||||
if (!drmAvailable())
|
|
||||||
return -1;
|
|
||||||
#endif
|
#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++) {
|
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(proc_name, "/proc/dri/%d/name", i);
|
||||||
sprintf(dev_name, "/dev/dri/card%d", i);
|
|
||||||
if ((fd = open(proc_name, 0, 0)) >= 0) {
|
if ((fd = open(proc_name, 0, 0)) >= 0) {
|
||||||
retcode = read(fd, buf, sizeof(buf)-1);
|
retcode = read(fd, buf, sizeof(buf)-1);
|
||||||
close(fd);
|
close(fd);
|
||||||
|
@ -321,32 +336,15 @@ static int drmOpenByName(const char *name)
|
||||||
if (*pt) { /* Found busid */
|
if (*pt) { /* Found busid */
|
||||||
return drmOpenByBusid(++pt);
|
return drmOpenByBusid(++pt);
|
||||||
} else { /* No busid */
|
} else { /* No busid */
|
||||||
dev = strtol(devstring, NULL, 0);
|
return drmOpenDevice(strtol(devstring, NULL, 0),i);
|
||||||
return drmOpenDevice(dev_name, dev,
|
|
||||||
mode, user, group);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} 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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1090,6 +1088,160 @@ void *drmGetContextTag(int fd, drmContext context)
|
||||||
return value;
|
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)
|
#if defined(XFree86Server) || defined(DRM_USE_MALLOC)
|
||||||
static void drmSIGIOHandler(int interrupt, void *closure)
|
static void drmSIGIOHandler(int interrupt, void *closure)
|
||||||
{
|
{
|
||||||
|
|
|
@ -174,7 +174,7 @@ all::;@echo === SMP=${SMP} MODULES=${MODULES} MODVERSIONS=${MODVERSIONS} AGP=${A
|
||||||
all::;@echo === kill_fasync has $(PARAMS) parameters
|
all::;@echo === kill_fasync has $(PARAMS) parameters
|
||||||
all::;@echo === Compiling for machine $(MACHINE)
|
all::;@echo === Compiling for machine $(MACHINE)
|
||||||
all::;@echo === WARNING
|
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
|
all::;@echo === WARNING
|
||||||
|
|
||||||
ifeq ($(MODULES),0)
|
ifeq ($(MODULES),0)
|
||||||
|
|
|
@ -44,11 +44,8 @@
|
||||||
#define DRM_IOCTL_NR(n) ((n) & 0xff)
|
#define DRM_IOCTL_NR(n) ((n) & 0xff)
|
||||||
#endif
|
#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_MAJOR 226
|
||||||
|
#define DRM_MAX_MINOR 15
|
||||||
#define DRM_NAME "drm" /* Name in kernel, /dev, and /proc */
|
#define DRM_NAME "drm" /* Name in kernel, /dev, and /proc */
|
||||||
#define DRM_MIN_ORDER 5 /* At least 2^5 bytes = 32 bytes */
|
#define DRM_MIN_ORDER 5 /* At least 2^5 bytes = 32 bytes */
|
||||||
#define DRM_MAX_ORDER 22 /* Up to 2^22 bytes = 4MB */
|
#define DRM_MAX_ORDER 22 /* Up to 2^22 bytes = 4MB */
|
||||||
|
|
|
@ -44,11 +44,8 @@
|
||||||
#define DRM_IOCTL_NR(n) ((n) & 0xff)
|
#define DRM_IOCTL_NR(n) ((n) & 0xff)
|
||||||
#endif
|
#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_MAJOR 226
|
||||||
|
#define DRM_MAX_MINOR 15
|
||||||
#define DRM_NAME "drm" /* Name in kernel, /dev, and /proc */
|
#define DRM_NAME "drm" /* Name in kernel, /dev, and /proc */
|
||||||
#define DRM_MIN_ORDER 5 /* At least 2^5 bytes = 32 bytes */
|
#define DRM_MIN_ORDER 5 /* At least 2^5 bytes = 32 bytes */
|
||||||
#define DRM_MAX_ORDER 22 /* Up to 2^22 bytes = 4MB */
|
#define DRM_MAX_ORDER 22 /* Up to 2^22 bytes = 4MB */
|
||||||
|
|
|
@ -44,11 +44,8 @@
|
||||||
#define DRM_IOCTL_NR(n) ((n) & 0xff)
|
#define DRM_IOCTL_NR(n) ((n) & 0xff)
|
||||||
#endif
|
#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_MAJOR 226
|
||||||
|
#define DRM_MAX_MINOR 15
|
||||||
#define DRM_NAME "drm" /* Name in kernel, /dev, and /proc */
|
#define DRM_NAME "drm" /* Name in kernel, /dev, and /proc */
|
||||||
#define DRM_MIN_ORDER 5 /* At least 2^5 bytes = 32 bytes */
|
#define DRM_MIN_ORDER 5 /* At least 2^5 bytes = 32 bytes */
|
||||||
#define DRM_MAX_ORDER 22 /* Up to 2^22 bytes = 4MB */
|
#define DRM_MAX_ORDER 22 /* Up to 2^22 bytes = 4MB */
|
||||||
|
|
237
tests/dristat.c
237
tests/dristat.c
|
@ -35,28 +35,11 @@
|
||||||
#include "../xf86drmHash.c"
|
#include "../xf86drmHash.c"
|
||||||
#include "../xf86drm.c"
|
#include "../xf86drm.c"
|
||||||
|
|
||||||
#define DRM_DIR_NAME "/dev/dri"
|
|
||||||
#define DRM_DEV_NAME "%s/card%d"
|
|
||||||
|
|
||||||
#define DRM_VERSION 0x00000001
|
#define DRM_VERSION 0x00000001
|
||||||
#define DRM_MEMORY 0x00000002
|
#define DRM_MEMORY 0x00000002
|
||||||
#define DRM_CLIENTS 0x00000004
|
#define DRM_CLIENTS 0x00000004
|
||||||
#define DRM_STATS 0x00000008
|
#define DRM_STATS 0x00000008
|
||||||
|
#define DRM_BUSID 0x00000010
|
||||||
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;
|
|
||||||
|
|
||||||
static void getversion(int fd)
|
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 {
|
typedef struct {
|
||||||
unsigned long offset; /* Requested physical address (0 for SAREA)*/
|
unsigned long offset; /* Requested physical address (0 for SAREA)*/
|
||||||
unsigned long size; /* Requested physical size (bytes) */
|
unsigned long size; /* Requested physical size (bytes) */
|
||||||
|
@ -88,160 +80,7 @@ typedef struct {
|
||||||
int mtrr; /* MTRR slot used */
|
int mtrr; /* MTRR slot used */
|
||||||
/* Private data */
|
/* Private data */
|
||||||
} drmVmRec, *drmVmPtr;
|
} drmVmRec, *drmVmPtr;
|
||||||
|
#endif
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void getvm(int fd)
|
static void getvm(int fd)
|
||||||
{
|
{
|
||||||
|
@ -255,7 +94,7 @@ static void getvm(int fd)
|
||||||
drmHandle handle;
|
drmHandle handle;
|
||||||
int mtrr;
|
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");
|
printf(" slot offset size type flags address mtrr\n");
|
||||||
|
|
||||||
for (i = 0;
|
for (i = 0;
|
||||||
|
@ -307,14 +146,18 @@ static void getclients(int fd)
|
||||||
read(procfd, cmd, sizeof(cmd)-1);
|
read(procfd, cmd, sizeof(cmd)-1);
|
||||||
close(procfd);
|
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",
|
printf(" %c %5d %5d %10lu %10lu %s\n",
|
||||||
auth ? 'y' : 'n', pid, uid, magic, iocs, cmd);
|
auth ? 'y' : 'n', pid, uid, magic, iocs, cmd);
|
||||||
else
|
} else {
|
||||||
printf(" %c %5d %5d %10lu %10lu\n",
|
printf(" %c %5d %5d %10lu %10lu\n",
|
||||||
auth ? 'y' : 'n', pid, uid, magic, iocs);
|
auth ? 'y' : 'n', pid, uid, magic, iocs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void printhuman(unsigned long value, const char *name, int mult)
|
static void printhuman(unsigned long value, const char *name, int mult)
|
||||||
{
|
{
|
||||||
|
@ -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 main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
|
@ -442,13 +247,14 @@ int main(int argc, char **argv)
|
||||||
char buf[64];
|
char buf[64];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
while ((c = getopt(argc, argv, "avmcsM:i:")) != EOF)
|
while ((c = getopt(argc, argv, "avmcsbM:i:")) != EOF)
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'a': mask = ~0; break;
|
case 'a': mask = ~0; break;
|
||||||
case 'v': mask |= DRM_VERSION; break;
|
case 'v': mask |= DRM_VERSION; break;
|
||||||
case 'm': mask |= DRM_MEMORY; break;
|
case 'm': mask |= DRM_MEMORY; break;
|
||||||
case 'c': mask |= DRM_CLIENTS; break;
|
case 'c': mask |= DRM_CLIENTS; break;
|
||||||
case 's': mask |= DRM_STATS; break;
|
case 's': mask |= DRM_STATS; break;
|
||||||
|
case 'b': mask |= DRM_BUSID; break;
|
||||||
case 'i': interval = strtol(optarg, NULL, 0); break;
|
case 'i': interval = strtol(optarg, NULL, 0); break;
|
||||||
case 'M': minor = strtol(optarg, NULL, 0); break;
|
case 'M': minor = strtol(optarg, NULL, 0); break;
|
||||||
default:
|
default:
|
||||||
|
@ -458,9 +264,10 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
for (i = 0; i < 16; i++) if (!minor || i == minor) {
|
for (i = 0; i < 16; i++) if (!minor || i == minor) {
|
||||||
sprintf(buf, DRM_DEV_NAME, DRM_DIR_NAME, i);
|
sprintf(buf, DRM_DEV_NAME, DRM_DIR_NAME, i);
|
||||||
fd = drmOpenMinor(i, 0, 0, 0700, 0600, 0);
|
fd = drmOpenMinor(i, 1);
|
||||||
if (fd >= 0) {
|
if (fd >= 0) {
|
||||||
printf("%s\n", buf);
|
printf("%s\n", buf);
|
||||||
|
if (mask & DRM_BUSID) getbusid(fd);
|
||||||
if (mask & DRM_VERSION) getversion(fd);
|
if (mask & DRM_VERSION) getversion(fd);
|
||||||
if (mask & DRM_MEMORY) getvm(fd);
|
if (mask & DRM_MEMORY) getvm(fd);
|
||||||
if (mask & DRM_CLIENTS) getclients(fd);
|
if (mask & DRM_CLIENTS) getclients(fd);
|
||||||
|
|
Loading…
Reference in New Issue