summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Hellstrom <thomas-at-tungstengraphics-dot-com>2006-08-27 21:16:13 +0200
committerThomas Hellstrom <thomas-at-tungstengraphics-dot-com>2006-08-27 21:16:13 +0200
commitb4b7b997605f88f3ffdcb0cc7cd1271e0cb24073 (patch)
tree4b9d29ba4ced4638dc9ff07df4fb2d84105506cc
parentac26b51503dfedf422d6ae49518adcf41dff1af3 (diff)
Remove the ioctl multiplexing, and instead allow for generic
drm ioctls 0x80 - 0xFF.
-rw-r--r--libdrm/xf86drm.c96
-rw-r--r--libdrm/xf86drm.h7
-rw-r--r--linux-core/drm_bo.c43
-rw-r--r--linux-core/drm_drv.c16
-rw-r--r--linux-core/drm_ttm.c4
-rw-r--r--linux-core/drm_ttm.h2
-rw-r--r--shared-core/drm.h3
7 files changed, 119 insertions, 52 deletions
diff --git a/libdrm/xf86drm.c b/libdrm/xf86drm.c
index a2a2e28c..e666df3c 100644
--- a/libdrm/xf86drm.c
+++ b/libdrm/xf86drm.c
@@ -2362,4 +2362,100 @@ int drmFenceWait(int fd, drmFence *fence, unsigned flush_type,
return 0;
}
+static unsigned long combine64(unsigned lo, unsigned hi)
+{
+ unsigned long ret = lo;
+ if (sizeof(ret) == 8) {
+ int shift = 32;
+ ret |= (hi << shift);
+ }
+ return ret;
+}
+
+static void split32(unsigned long val, unsigned *lo, unsigned *hi)
+{
+ *lo = val & 0xFFFFFFFFUL;
+ if (sizeof(val) == 8) {
+ int shift = 32;
+ *hi = val >> shift;
+ } else {
+ *hi = 0;
+ }
+}
+
+int drmTTMCreate(int fd, drmTTM *ttm, unsigned long size, unsigned flags)
+{
+ drm_ttm_arg_t argTTM;
+ drm_bo_arg_t arg;
+
+ arg.num_requests = 1;
+ arg.op = drm_op_ttm;
+ split32((unsigned long) &argTTM, &arg.data_lo, &arg.data_hi);
+
+ argTTM.op = drm_ttm_create;
+ argTTM.flags = flags;
+ split32((unsigned long) &size, &argTTM.size_lo, &argTTM.size_hi);
+
+ if (ioctl(fd, DRM_IOCTL_TTM, &arg))
+ return -errno;
+
+ ttm->handle = argTTM.handle;
+ ttm->user_token = (drm_handle_t) argTTM.user_token;
+ ttm->flags = argTTM.flags;
+ ttm->size = combine64(argTTM.size_lo, argTTM.size_hi);
+ return 0;
+}
+
+int drmTTMDestroy(int fd, const drmTTM *ttm)
+{
+ drm_ttm_arg_t argTTM;
+ drm_bo_arg_t arg;
+ arg.num_requests = 1;
+ arg.op = drm_op_ttm;
+ split32((unsigned long) &argTTM, &arg.data_lo, &arg.data_hi);
+ argTTM.op = drm_ttm_destroy;
+ argTTM.handle = ttm->handle;
+ if (ioctl(fd, DRM_IOCTL_TTM, &arg))
+ return -errno;
+ return 0;
+}
+
+
+int drmTTMReference(int fd, unsigned handle, drmTTM *ttm)
+{
+ drm_ttm_arg_t argTTM;
+ drm_bo_arg_t arg;
+
+ arg.num_requests = 1;
+ arg.op = drm_op_ttm;
+ split32((unsigned long) &argTTM, &arg.data_lo, &arg.data_hi);
+
+ argTTM.handle = handle;
+ argTTM.op = drm_ttm_reference;
+ if (ioctl(fd, DRM_IOCTL_TTM, &arg))
+ return -errno;
+ ttm->handle = argTTM.handle;
+ ttm->user_token = (drm_handle_t) argTTM.user_token;
+ ttm->flags = argTTM.flags;
+ ttm->size = combine64(argTTM.size_lo, argTTM.size_hi);
+ return 0;
+}
+
+int drmTTMUnreference(int fd, const drmTTM *ttm)
+{
+ drm_ttm_arg_t argTTM;
+ drm_bo_arg_t arg;
+
+ argTTM.op = drm_ttm_destroy;
+ argTTM.handle = ttm->handle;
+ if (ioctl(fd, DRM_IOCTL_TTM, &arg))
+ return -errno;
+ return 0;
+}
+
+drm_handle_t drmTTMMapHandle(int fd, const drmTTM *ttm)
+{
+ (void) fd;
+ return ttm->user_token;
+}
diff --git a/libdrm/xf86drm.h b/libdrm/xf86drm.h
index 78730785..92cef4c0 100644
--- a/libdrm/xf86drm.h
+++ b/libdrm/xf86drm.h
@@ -287,6 +287,13 @@ typedef struct _drmFence{
unsigned signaled;
} drmFence;
+typedef struct _drmTTM{
+ unsigned handle;
+ drm_handle_t user_token;
+ unsigned flags;
+ unsigned long size;
+} drmTTM;
+
#define __drm_dummy_lock(lock) (*(__volatile__ unsigned int *)lock)
#define DRM_LOCK_HELD 0x80000000U /**< Hardware lock is held */
diff --git a/linux-core/drm_bo.c b/linux-core/drm_bo.c
index 35d4aba7..5eb09839 100644
--- a/linux-core/drm_bo.c
+++ b/linux-core/drm_bo.c
@@ -301,34 +301,6 @@ int drm_bo_alloc_space(drm_device_t *dev, int tt, drm_buffer_object_t *buf)
}
#endif
-static int drm_do_bo_ioctl(drm_file_t *priv, int num_requests,
- drm_bo_arg_data_t __user *data)
-{
- drm_bo_arg_data_t arg;
- drm_bo_arg_request_t *req = &arg.req;
- drm_bo_arg_reply_t rep;
- int i, ret;
-
- for (i=0; i<num_requests; ++i) {
- rep.ret = 0;
- ret = copy_from_user(&arg, (void __user *) data, sizeof(arg));
- if (ret) {
- rep.ret = -EFAULT;
- goto out_loop;
- }
-
- arg.rep = rep;
- data++;
- out_loop:
- arg.rep = rep;
- ret = copy_to_user((void __user *) data, &arg, sizeof(arg));
- if (!ret)
- ++i;
- break;
- }
- return i;
-}
-
int drm_bo_ioctl(DRM_IOCTL_ARGS)
{
@@ -336,21 +308,6 @@ int drm_bo_ioctl(DRM_IOCTL_ARGS)
drm_bo_arg_t arg;
unsigned long data_ptr;
(void) dev;
-
- DRM_COPY_FROM_USER_IOCTL(arg, (void __user *)data, sizeof(arg));
- data_ptr = combine_64(arg.data_lo, arg.data_hi);
- switch(arg.op) {
- case drm_op_bo:
- arg.num_requests = drm_do_bo_ioctl(priv, arg.num_requests,
- (drm_bo_arg_data_t __user *)
- data_ptr);
- break;
- case drm_op_ttm:
- return drm_ttm_ioctl(priv, (drm_ttm_arg_t __user *)
- data_ptr);
- }
-
- DRM_COPY_TO_USER_IOCTL((void __user *) data, arg, sizeof(arg));
return 0;
}
diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c
index e6ae690a..b33d1f14 100644
--- a/linux-core/drm_drv.c
+++ b/linux-core/drm_drv.c
@@ -120,6 +120,7 @@ static drm_ioctl_desc_t drm_ioctls[] = {
[DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK)] = {drm_wait_vblank, 0},
[DRM_IOCTL_NR(DRM_IOCTL_FENCE)] = {drm_fence_ioctl, DRM_AUTH},
+ [DRM_IOCTL_NR(DRM_IOCTL_TTM)] = {drm_ttm_ioctl, DRM_AUTH},
};
#define DRIVER_IOCTL_COUNT DRM_ARRAY_SIZE( drm_ioctls )
@@ -539,14 +540,19 @@ int drm_ioctl(struct inode *inode, struct file *filp,
current->pid, cmd, nr, (long)old_encode_dev(priv->head->device),
priv->authenticated);
- if (nr < DRIVER_IOCTL_COUNT)
+ if (nr >= DRIVER_IOCTL_COUNT &&
+ (nr < DRM_COMMAND_BASE || nr >= DRM_COMMAND_END))
+ goto err_i1;
+ if ((nr >= DRM_COMMAND_BASE) && (nr < DRM_COMMAND_END)
+ && (nr < DRM_COMMAND_BASE + dev->driver->num_ioctls))
+ ioctl = &dev->driver->ioctls[nr - DRM_COMMAND_BASE];
+ else if (nr >= DRM_COMMAND_END || nr < DRM_COMMAND_BASE)
ioctl = &drm_ioctls[nr];
- else if ((nr >= DRM_COMMAND_BASE)
- && (nr < DRM_COMMAND_BASE + dev->driver->num_ioctls))
- ioctl = &dev->driver->ioctls[nr - DRM_COMMAND_BASE];
- else
+ else
goto err_i1;
+
+
func = ioctl->func;
if ((nr == DRM_IOCTL_NR(DRM_IOCTL_DMA)) && dev->driver->dma_ioctl) /* Local override? */
func = dev->driver->dma_ioctl;
diff --git a/linux-core/drm_ttm.c b/linux-core/drm_ttm.c
index ecf3e0ac..950b0d4d 100644
--- a/linux-core/drm_ttm.c
+++ b/linux-core/drm_ttm.c
@@ -850,10 +850,10 @@ int drm_ttm_object_create(drm_device_t *dev, unsigned long size,
}
-int drm_ttm_ioctl(drm_file_t *priv, drm_ttm_arg_t __user *data)
+int drm_ttm_ioctl(DRM_IOCTL_ARGS)
{
+ DRM_DEVICE;
drm_ttm_arg_t arg;
- drm_device_t *dev = priv->head->dev;
drm_ttm_object_t *entry;
drm_user_object_t *uo;
unsigned long size;
diff --git a/linux-core/drm_ttm.h b/linux-core/drm_ttm.h
index bad21c97..6ebb1aa2 100644
--- a/linux-core/drm_ttm.h
+++ b/linux-core/drm_ttm.h
@@ -156,7 +156,7 @@ extern int drm_destroy_ttm(drm_ttm_t * ttm);
extern void drm_user_destroy_region(drm_ttm_backend_list_t * entry);
extern int drm_ttm_add_mm_to_list(drm_ttm_t * ttm, struct mm_struct *mm);
extern void drm_ttm_delete_mm(drm_ttm_t * ttm, struct mm_struct *mm);
-extern int drm_ttm_ioctl(drm_file_t *priv, drm_ttm_arg_t __user *data);
+extern int drm_ttm_ioctl(DRM_IOCTL_ARGS);
#define DRM_MASK_VAL(dest, mask, val) \
(dest) = ((dest) & ~(mask)) | ((val) & (mask));
diff --git a/shared-core/drm.h b/shared-core/drm.h
index 450864bc..726a5140 100644
--- a/shared-core/drm.h
+++ b/shared-core/drm.h
@@ -816,7 +816,7 @@ typedef union drm_bo_arg_data {
#define DRM_IOCTL_WAIT_VBLANK DRM_IOWR(0x3a, drm_wait_vblank_t)
#define DRM_IOCTL_FENCE DRM_IOWR(0x3b, drm_fence_arg_t)
-#define DRM_IOCTL_BUFFER_OBJECT DRM_IOWR(0x3c, drm_buffer_arg_t)
+#define DRM_IOCTL_TTM DRM_IOWR(0x3c, drm_ttm_arg_t)
/*@}*/
@@ -828,5 +828,6 @@ typedef union drm_bo_arg_data {
* drmCommandReadWrite().
*/
#define DRM_COMMAND_BASE 0x40
+#define DRM_COMMAND_END 0x80
#endif