#include <string.h>
#include <strings.h>
#include <ctype.h>
+#include <dirent.h>
+#include <stddef.h>
#include <fcntl.h>
#include <errno.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <stdarg.h>
+#ifdef HAVE_SYS_MKDEV_H
+# include <sys/mkdev.h> /* defines major(), minor(), and makedev() on Solaris */
+#endif
/* Not all systems have MAP_FAILED defined */
#ifndef MAP_FAILED
return vfprintf(stderr, format, ap);
}
-typedef int DRM_PRINTFLIKE(1, 0) (*debug_msg_func_t)(const char *format,
- va_list ap);
-
-static debug_msg_func_t drm_debug_print = drmDebugPrint;
-
void
drmMsg(const char *format, ...)
{
if (drm_server_info) {
drm_server_info->debug_print(format,ap);
} else {
- drm_debug_print(format, ap);
+ drmDebugPrint(format, ap);
}
va_end(ap);
}
}
-void
-drmSetDebugMsgFunction(debug_msg_func_t debug_msg_ptr)
-{
- drm_debug_print = debug_msg_ptr;
-}
-
static void *drmHashTable = NULL; /* Context switch callbacks */
void *drmGetHashTable(void)
* If any other failure happened then it will output error mesage using
* drmMsg() call.
*/
+#if !defined(UDEV)
static int chown_check_return(const char *path, uid_t owner, gid_t group)
{
int rv;
path, errno, strerror(errno));
return -1;
}
+#endif
/**
* Open the DRM device, creating it if necessary.
char buf[64];
int fd;
mode_t devmode = DRM_DEV_MODE, serv_mode;
+ gid_t serv_group;
+#if !defined(UDEV)
int isroot = !geteuid();
uid_t user = DRM_DEV_UID;
- gid_t group = DRM_DEV_GID, serv_group;
-
+ gid_t group = DRM_DEV_GID;
+#endif
+
switch (type) {
case DRM_NODE_PRIMARY:
dev_name = DRM_DEV_NAME;
drm_server_info->get_perms(&serv_group, &serv_mode);
devmode = serv_mode ? serv_mode : DRM_DEV_MODE;
devmode &= ~(S_IXUSR|S_IXGRP|S_IXOTH);
- group = (serv_group >= 0) ? serv_group : DRM_DEV_GID;
}
#if !defined(UDEV)
}
if (drm_server_info) {
+ group = (serv_group >= 0) ? serv_group : DRM_DEV_GID;
chown_check_return(buf, user, group);
chmod(buf, devmode);
}
};
}
+static int drmGetMinorType(int minor)
+{
+ int type = minor >> 6;
+
+ if (minor < 0)
+ return -1;
+
+ switch (type) {
+ case DRM_NODE_PRIMARY:
+ case DRM_NODE_CONTROL:
+ case DRM_NODE_RENDER:
+ return type;
+ default:
+ return -1;
+ }
+}
+
+static const char *drmGetMinorName(int type)
+{
+ switch (type) {
+ case DRM_NODE_PRIMARY:
+ return "card";
+ case DRM_NODE_CONTROL:
+ return "controlD";
+ case DRM_NODE_RENDER:
+ return "renderD";
+ default:
+ return NULL;
+ }
+}
+
/**
* Open the device by bus ID.
*
{
drm_agp_mode_t m;
- memclear(mode);
+ memclear(m);
m.mode = mode;
if (drmIoctl(fd, DRM_IOCTL_AGP_ENABLE, &m))
return -errno;
return strdup(name);
}
+int drmGetNodeTypeFromFd(int fd)
+{
+ struct stat sbuf;
+ int maj, min, type;
+
+ if (fstat(fd, &sbuf))
+ return -1;
+
+ maj = major(sbuf.st_rdev);
+ min = minor(sbuf.st_rdev);
+
+ if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode)) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ type = drmGetMinorType(min);
+ if (type == -1)
+ errno = ENODEV;
+ return type;
+}
+
int drmPrimeHandleToFD(int fd, uint32_t handle, uint32_t flags, int *prime_fd)
{
struct drm_prime_handle args;
return 0;
}
+static char *drmGetMinorNameForFD(int fd, int type)
+{
+#ifdef __linux__
+ DIR *sysdir;
+ struct dirent *pent, *ent;
+ struct stat sbuf;
+ const char *name = drmGetMinorName(type);
+ int len;
+ char dev_name[64], buf[64];
+ long name_max;
+ int maj, min;
+
+ if (!name)
+ return NULL;
+
+ len = strlen(name);
+
+ if (fstat(fd, &sbuf))
+ return NULL;
+
+ maj = major(sbuf.st_rdev);
+ min = minor(sbuf.st_rdev);
+
+ if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode))
+ return NULL;
+
+ snprintf(buf, sizeof(buf), "/sys/dev/char/%d:%d/device/drm", maj, min);
+
+ sysdir = opendir(buf);
+ if (!sysdir)
+ return NULL;
+
+ name_max = fpathconf(dirfd(sysdir), _PC_NAME_MAX);
+ if (name_max == -1)
+ goto out_close_dir;
+
+ pent = malloc(offsetof(struct dirent, d_name) + name_max + 1);
+ if (pent == NULL)
+ goto out_close_dir;
+
+ while (readdir_r(sysdir, pent, &ent) == 0 && ent != NULL) {
+ if (strncmp(ent->d_name, name, len) == 0) {
+ free(pent);
+ closedir(sysdir);
+
+ snprintf(dev_name, sizeof(dev_name), DRM_DIR_NAME "/%s",
+ ent->d_name);
+ return strdup(dev_name);
+ }
+ }
+
+ free(pent);
+
+out_close_dir:
+ closedir(sysdir);
+#endif
+ return NULL;
+}
+
+char *drmGetPrimaryDeviceNameFromFd(int fd)
+{
+ return drmGetMinorNameForFD(fd, DRM_NODE_PRIMARY);
+}
+
+char *drmGetRenderDeviceNameFromFd(int fd)
+{
+ return drmGetMinorNameForFD(fd, DRM_NODE_RENDER);
+}