summaryrefslogtreecommitdiff
path: root/libdrm/xf86drm.c
diff options
context:
space:
mode:
Diffstat (limited to 'libdrm/xf86drm.c')
-rw-r--r--libdrm/xf86drm.c444
1 files changed, 117 insertions, 327 deletions
diff --git a/libdrm/xf86drm.c b/libdrm/xf86drm.c
index 50b421af..a5aef4c6 100644
--- a/libdrm/xf86drm.c
+++ b/libdrm/xf86drm.c
@@ -1,6 +1,6 @@
/* xf86drm.c -- User-level interface to DRM device
* Created: Tue Jan 5 08:16:21 1999 by faith@precisioninsight.com
- * Revised: Fri Jun 18 09:52:23 1999 by faith@precisioninsight.com
+ * Revised: Wed Aug 4 07:54:23 1999 by faith@precisioninsight.com
*
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
* All Rights Reserved.
@@ -24,8 +24,8 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
- * $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c,v 1.41 1999/06/21 14:31:20 faith Exp $
- * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c,v 1.3 1999/06/27 14:08:19 dawes Exp $
+ * $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c,v 1.43 1999/08/04 18:14:43 faith Exp $
+ * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c,v 1.4 1999/09/25 14:37:49 dawes Exp $
*
*/
@@ -101,63 +101,6 @@ static char *drmStrdup(const char *s)
}
-/* drm_lookup searches file for a line tagged with name, and returns the
- value for that tag. If busid is NULL, the file format is that used for
- /proc/devices and /proc/misc, or the first part of /proc/drm/devices:
-
- <value> <whitespace> <tag>
-
- If the busid is non-NULL, the file format is the extended format used
- for /proc/drm/devices:
-
- <value> <whitespace> <name> <whitespace> <busid>
-
- If both name and busid are non-NULL, both must match. If either is
- NULL, then the other is matched.
-*/
-
-static int drm_lookup(const char *file, const char *name, const char *busid)
-{
- FILE *str;
- char buf[128];
- char *pt;
- int name_match;
- int busid_match;
- char *namept = NULL;
- char *busidpt = NULL;
-
- if (!(str = fopen(file, "r"))) return DRM_ERR_NO_DEVICE;
- while (fgets(buf, sizeof(buf)-1, str)) {
- buf[sizeof(buf)-1] = '\0';
- for (pt = buf; *pt && isspace(*pt); ++pt); /* skip whitespace */
- for (; *pt && !isspace(*pt); ++pt); /* next space or null */
- if (isspace(pt[0]) && pt[1]) {
- pt++;
- for (; *pt && isspace(*pt); ++pt); /* skip whitespace */
- namept = pt;
- for (; *pt && !isspace(*pt); ++pt); /* next space or null */
- if (isspace(pt[0]) && pt[1]) { /* busid present */
- *pt = '\0'; /* proper termination */
- pt++;
- for (; *pt && isspace(*pt); ++pt); /* skip whitespace */
- busidpt = pt;
- for (; *pt && !isspace(*pt); ++pt); /* next space or null */
- }
- *pt = '\0'; /* proper termination */
- name_match = name ? 0 : 1; /* match if we don't care */
- busid_match = busid ? 0 : 1; /* match if we don't care */
- if (name && namept && !strcmp(name, namept)) ++name_match;
- if (busid && busidpt && !strcmp(busid, busidpt)) ++busid_match;
- if (name_match && busid_match) {
- fclose(str);
- return atoi(buf); /* stops at whitespace */
- }
- }
- }
- fclose(str);
- return DRM_ERR_NO_DEVICE;
-}
-
static unsigned long drmGetKeyFromFd(int fd)
{
#ifdef XFree86LOADER
@@ -205,123 +148,128 @@ static int drm_open(const char *file)
int drmAvailable(void)
{
- if (!access(DRM_PROC_DRM, R_OK)) return 1;
+ if (!access("/proc/graphics/0", R_OK)) return 1;
return 0;
}
-/* drmGetMajor tries to find the major device number for /dev/drm by
- searching /proc/devices. A negative value is returned on error. */
-
-static int drmGetMajor(void)
-{
- int major;
-
- if (!drmAvailable()) return DRM_ERR_NO_DEVICE;
-
- if ((major = drm_lookup(DRM_PROC_DEVICES, DRM_NAME, NULL)) >= 0)
- return major;
-
- return DRM_ERR_NO_DEVICE;
-}
-
-/* drmGetMinor tries to find the minor device number for name by looking in
- /proc/drm/devices. A negative value is retruned on error. */
-
-static int drmGetMinor(const char *name, const char *busid)
-{
- int minor;
- char buf[128];
-
- if (!drmAvailable()) return DRM_ERR_NO_DEVICE;
-
- sprintf(buf, "/proc/%s/%s", DRM_NAME, DRM_DEVICES);
-
- if ((minor = drm_lookup(buf, name, busid))) return minor;
- return 0;
-}
-
-
-/* drmOpen looks up the specified name and/or busid in /proc/drm/devices,
- and opens the device found. The entry in /dev is created if necessary
- (and if root). A file descriptor is returned. On error, the return
- value is negative. */
-
-static int drmOpen(const char *name, const char *busid)
+static int drmOpenDevice(const char *path, long dev,
+ mode_t mode, uid_t user, gid_t group)
{
#ifdef XFree86LOADER
struct xf86stat st;
#else
struct stat st;
#endif
- char path[128];
- int major;
- int minor;
- dev_t dev;
-
- if (!drmAvailable()) return DRM_ERR_NO_DEVICE;
- if ((major = drmGetMajor()) < 0) return major;
- if ((minor = drmGetMinor(name,busid)) < 0) return minor;
- dev = makedev(major, minor);
- if (!minor) {
- sprintf(path, "/dev/%s", DRM_NAME );
- } else {
- sprintf(path, "/dev/%s%d", DRM_NAME, minor-1 );
- }
+ if (!stat(path, &st) && st.st_rdev == dev) return drm_open(path);
- /* Check device major/minor for match */
- if (!access(path, F_OK)) {
- if (stat(path, &st)) return DRM_ERR_NO_ACCESS;
- if (st.st_rdev == dev) {
-#if defined(XFree86Server)
- chmod(path,
- xf86ConfigDRI.mode ? xf86ConfigDRI.mode : DRM_DEV_MODE);
- chown(path, DRM_DEV_UID,
- xf86ConfigDRI.group ? xf86ConfigDRI.group : DRM_DEV_GID);
-#endif
-#if defined(DRM_USE_MALLOC)
- chmod(path, DRM_DEV_MODE);
- chown(path, DRM_DEV_UID, DRM_DEV_GID);
-#endif
- return drm_open(path);
- }
- }
-
- /* Doesn't exist or match failed, so we
- have to be root to create it. */
if (geteuid()) return DRM_ERR_NOT_ROOT;
remove(path);
- if (mknod(path, S_IFCHR | DRM_DEV_MODE, dev)) {
+ if (mknod(path, S_IFCHR, dev)) {
remove(path);
return DRM_ERR_NOT_ROOT;
}
-#if defined(XFree86Server)
- chmod(path, xf86ConfigDRI.mode ? xf86ConfigDRI.mode : DRM_DEV_MODE);
- chown(path, DRM_DEV_UID,
- xf86ConfigDRI.group ? xf86ConfigDRI.group : DRM_DEV_GID);
-#endif
-#if defined(DRM_USE_MALLOC)
- chmod(path, DRM_DEV_MODE);
- chown(path, DRM_DEV_UID, DRM_DEV_GID);
-#endif
+ chown(path, user, group);
+ chmod(path, mode);
return drm_open(path);
}
-/* drmOpenDRM returns a file descriptor for the main /dev/drm control
- device. The entry in /dev is created if necessary (and if root). A
- file descriptor is returned. On error, the return value is negative. */
+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 ? xf86ConfigDRI.group : DRM_DEV_GID;
+#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/graphics", 0);
+ chown("/dev/graphics", user, group);
+ chmod("/dev/graphics", dirmode);
+ }
+
+ for (i = 0; i < 8; i++) {
+ sprintf(proc_name, "/proc/graphics/%d/name", i);
+ sprintf(dev_name, "/dev/graphics/card%d", i);
+ if ((fd = open(proc_name, 0, 0)) >= 0) {
+ retcode = read(fd, buf, sizeof(buf)-1);
+ close(fd);
+ if (retcode) {
+ buf[retcode-1] = '\0';
+ for (driver = pt = buf; *pt && *pt != ' '; ++pt)
+ ;
+ if (*pt) { /* Device is next */
+ *pt = '\0';
+ if (!strcmp(driver, name)) { /* Match */
+ for (devstring = ++pt; *pt && *pt != ' '; ++pt)
+ ;
+ if (*pt) { /* Found busid */
+ return drmOpenByBusid(++pt);
+ } else { /* No busid */
+ dev = strtol(devstring, NULL, 0);
+ return drmOpenDevice(dev_name, dev,
+ mode, user, group);
+ }
+ }
+ }
+ }
+ } else remove(dev_name);
+ }
+ return -1;
+}
-int drmOpenDRM(void)
+static int drmOpenByBusid(const char *busid)
{
- return drmOpen(DRM_NAME, NULL);
+ int i;
+ char dev_name[64];
+ char *buf;
+ int fd;
+
+ for (i = 0; i < 8; i++) {
+ sprintf(dev_name, "/dev/graphics/card%d", i);
+ if ((fd = drm_open(dev_name)) >= 0) {
+ buf = drmGetBusid(fd);
+ if (buf && !strcmp(buf, busid)) {
+ drmFreeBusid(buf);
+ return fd;
+ }
+ if (buf) drmFreeBusid(buf);
+ close(fd);
+ }
+ }
+ return -1;
}
-/* drmClose closes the file descriptor returned from drmOpen. */
-
-int drmCloseDRM(int fd)
+/* drmOpen looks up the specified name and busid, and opens the device
+ found. The entry in /dev/graphics is created if necessary (and if root).
+ A file descriptor is returned. On error, the return value is
+ negative. */
+
+int drmOpen(const char *name, const char *busid)
{
- return close(fd);
+
+ if (busid) return drmOpenByBusid(busid);
+ return drmOpenByName(name);
}
void drmFreeVersion(drmVersionPtr v)
@@ -404,137 +352,33 @@ drmVersionPtr drmGetVersion(int fd)
return retval;
}
-void drmFreeVersionList(drmListPtr list)
+void drmFreeBusid(const char *busid)
{
- int i;
-
- if (!list) return;
- if (list->version) {
- for (i = 0; i < list->count; i++) {
- if (list->version[i].name) drmFree(list->version[i].name);
- if (list->version[i].date) drmFree(list->version[i].date);
- if (list->version[i].desc) drmFree(list->version[i].desc);
-
- }
- drmFree(list->version);
- }
- if (list->capability) drmFree(list->capability);
- drmFree(list);
+ drmFree((void *)busid);
}
-static void drmFreeKernelVersionList(drm_list_t *list)
+char *drmGetBusid(int fd)
{
- int i;
-
- if (!list) return;
- if (list->version) {
- for (i = 0; i < list->count; i++) {
- if (list->version[i].name) drmFree(list->version[i].name);
- if (list->version[i].date) drmFree(list->version[i].date);
- if (list->version[i].desc) drmFree(list->version[i].desc);
-
- }
- drmFree(list->version);
- }
- drmFree(list);
-}
-
-/* drmList obtains a list of all drivers and capabilities via an ioctl. */
-
-drmListPtr drmGetVersionList(int fd)
-{
- drmListPtr retval;
- drm_list_t *list = drmMalloc(sizeof(*list));
- int i;
-
- list->count = 0;
-
- /* First, get the count */
-
- if (ioctl(fd, DRM_IOCTL_LIST, list)) {
- drmFreeKernelVersionList(list);
- return NULL;
- }
-
- /* Next, get the version sizes */
- for (i = 0; i < list->count; i++) {
- list->version
- = drmMalloc(list->count * sizeof(*list->version));
- list->version[i].name_len = 0;
- list->version[i].name = NULL;
- list->version[i].date_len = 0;
- list->version[i].date = NULL;
- list->version[i].desc_len = 0;
- list->version[i].desc = NULL;
- }
+ drm_unique_t u;
- if (ioctl(fd, DRM_IOCTL_LIST, list)) {
- drmFreeKernelVersionList(list);
- return NULL;
- }
-
- /* Now, allocate space and get the data */
- for (i = 0; i < list->count; i++) {
- if (list->version[i].name_len)
- list->version[i].name = drmMalloc(list->version[i].name_len + 1);
- if (list->version[i].date_len)
- list->version[i].date = drmMalloc(list->version[i].date_len + 1);
- if (list->version[i].desc_len)
- list->version[i].desc = drmMalloc(list->version[i].desc_len + 1);
- }
-
- if (ioctl(fd, DRM_IOCTL_LIST, list)) {
- drmFreeKernelVersionList(list);
- return NULL;
- }
-
- /* The results might not be null-terminated
- strings, so terminate them. */
+ u.unique_len = 0;
+ u.unique = NULL;
- for (i = 0; i < list->count; i++) {
- if (list->version[i].name_len)
- list->version[i].name[list->version[i].name_len] = '\0';
- if (list->version[i].date_len)
- list->version[i].date[list->version[i].date_len] = '\0';
- if (list->version[i].desc_len)
- list->version[i].desc[list->version[i].desc_len] = '\0';
- }
-
- /* Now, copy it all back into the
- client-visible data structure... */
- retval = drmMalloc(sizeof(*retval));
- retval->count = list->count;
- retval->version = drmMalloc(list->count * sizeof(*retval->version));
- retval->capability = drmMalloc(list->count * sizeof(*retval->capability));
- for (i = 0; i < list->count; i++) {
- drmCopyVersion(&retval->version[i], &list->version[i]);
- }
- drmFreeKernelVersionList(list);
- return retval;
+ if (ioctl(fd, DRM_IOCTL_GET_UNIQUE, &u)) return NULL;
+ u.unique = drmMalloc(u.unique_len + 1);
+ if (ioctl(fd, DRM_IOCTL_GET_UNIQUE, &u)) return NULL;
+ u.unique[u.unique_len] = '\0';
+ return u.unique;
}
-int drmCreateSub(int fd, const char *name, const char *busid)
+int drmSetBusid(int fd, const char *busid)
{
- drm_request_t request;
+ drm_unique_t u;
- request.device_name = name;
- request.device_busid = busid;
- if (ioctl(fd, DRM_IOCTL_CREATE, &request)) {
- return -errno;
- }
- return 0;
-}
+ u.unique = (char *)busid;
+ u.unique_len = strlen(busid);
-int drmDestroySub(int fd, const char *busid)
-{
- drm_request_t request;
-
- request.device_busid = busid;
- request.device_major = drmGetMajor();
- request.device_minor = drmGetMinor(NULL, busid);
- if (ioctl(fd, DRM_IOCTL_DESTROY, &request)) {
- return -errno;
- }
+ if (ioctl(fd, DRM_IOCTL_SET_UNIQUE, &u)) return -errno;
return 0;
}
@@ -634,12 +478,7 @@ int drmFreeBufs(int fd, int count, int *list)
return 0;
}
-int drmOpenSub(const char *busid)
-{
- return drmOpen(NULL, busid);
-}
-
-int drmCloseSub(int fd)
+int drmClose(int fd)
{
unsigned long key = drmGetKeyFromFd(fd);
drmHashEntry *entry = drmGetEntry(fd);
@@ -923,58 +762,12 @@ int drmError(int err, const char *label)
return 1;
}
-int drmCtlAddCommand(int fd, drmCtlDesc desc, int count, int *inst)
-{
- drm_control_t ctl;
-
- ctl.func = DRM_ADD_COMMAND;
- ctl.irq = 0;
- ctl.count = count;
- ctl.inst = inst;
-
- switch (desc) {
- case DRM_IH_PRE_INST: ctl.desc = _DRM_IH_PRE_INST; break;
- case DRM_IH_POST_INST: ctl.desc = _DRM_IH_POST_INST; break;
- case DRM_IH_SERVICE: ctl.desc = _DRM_IH_SERVICE; break;
- case DRM_IH_PRE_UNINST: ctl.desc = _DRM_IH_PRE_UNINST; break;
- case DRM_IH_POST_UNINST: ctl.desc = _DRM_IH_POST_UNINST; break;
- case DRM_DMA_DISPATCH: ctl.desc = _DRM_DMA_DISPATCH; break;
- case DRM_DMA_READY: ctl.desc = _DRM_DMA_READY; break;
- case DRM_DMA_IS_READY: ctl.desc = _DRM_DMA_IS_READY; break;
- case DRM_DMA_QUIESCENT: ctl.desc = _DRM_DMA_QUIESCENT; break;
- default:
- return -EINVAL;
- }
-
- if (ioctl(fd, DRM_IOCTL_CONTROL, &ctl)) return -errno;
- return 0;
-}
-
-int drmCtlRemoveCommands(int fd)
-{
- drm_control_t ctl;
- drm_desc_t i;
-
- for (i = 0; i < DRM_DESC_MAX; i++) {
- ctl.func = DRM_RM_COMMAND;
- ctl.desc = i;
- ctl.irq = 0;
- ctl.count = 0;
- ctl.inst = NULL;
- ioctl(fd, DRM_IOCTL_CONTROL, &ctl);
- }
- return 0;
-}
-
int drmCtlInstHandler(int fd, int irq)
{
drm_control_t ctl;
ctl.func = DRM_INST_HANDLER;
- ctl.desc = 0; /* unused */
ctl.irq = irq;
- ctl.count = 0;
- ctl.inst = NULL;
if (ioctl(fd, DRM_IOCTL_CONTROL, &ctl)) return -errno;
return 0;
}
@@ -984,10 +777,7 @@ int drmCtlUninstHandler(int fd)
drm_control_t ctl;
ctl.func = DRM_UNINST_HANDLER;
- ctl.desc = 0; /* unused */
ctl.irq = 0;
- ctl.count = 0;
- ctl.inst = NULL;
if (ioctl(fd, DRM_IOCTL_CONTROL, &ctl)) return -errno;
return 0;
}