diff options
-rw-r--r-- | libdrm/xf86drm.c | 96 | ||||
-rw-r--r-- | libdrm/xf86drm.h | 7 | ||||
-rw-r--r-- | linux-core/drm_bo.c | 43 | ||||
-rw-r--r-- | linux-core/drm_drv.c | 16 | ||||
-rw-r--r-- | linux-core/drm_ttm.c | 4 | ||||
-rw-r--r-- | linux-core/drm_ttm.h | 2 | ||||
-rw-r--r-- | shared-core/drm.h | 3 |
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 |