diff options
Diffstat (limited to 'linux-core')
-rw-r--r-- | linux-core/drm_bo.c | 63 | ||||
-rw-r--r-- | linux-core/drm_ttm.c | 2 | ||||
-rw-r--r-- | linux-core/drm_ttm.h | 3 |
3 files changed, 59 insertions, 9 deletions
diff --git a/linux-core/drm_bo.c b/linux-core/drm_bo.c index 6a677578..847b0406 100644 --- a/linux-core/drm_bo.c +++ b/linux-core/drm_bo.c @@ -31,6 +31,30 @@ #include "drmP.h" +/* + * Buffer object locking policy: + * Lock dev->struct_mutex; + * Increase usage + * Unlock dev->struct_mutex; + * Lock buffer->mutex; + * Do whatever you want; + * Unlock buffer->mutex; + * Decrease usage. Call destruction if zero. + * + * User object visibility ups usage just once, since it has its own + * refcounting. + * + * Destruction: + * lock dev->struct_mutex; + * Verify that usage is zero. Otherwise unlock and continue. + * Destroy object. + * unlock dev->struct_mutex; + * + * Mutex and spinlock locking orders: + * 1.) Buffer mutex + * 2.) Refer to ttm locking orders. + */ + int drm_fence_buffer_objects(drm_file_t *priv) { drm_device_t *dev = priv->head->dev; @@ -277,11 +301,35 @@ 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, void __user *data) +static int drm_do_bo_ioctl(drm_file_t *priv, int num_requests, + drm_bo_arg_data_t __user *data) { - return 0; + 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) { DRM_DEVICE; @@ -299,13 +347,16 @@ int drm_bo_ioctl(DRM_IOCTL_ARGS) switch(arg.op) { case drm_op_bo: - return drm_do_bo_ioctl(priv, arg.num_requests, - (void __user *) data_ptr); + 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, arg.num_requests, - (drm_ttm_arg_t __user *) data_ptr); + 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_ttm.c b/linux-core/drm_ttm.c index 46878a7d..05bae7de 100644 --- a/linux-core/drm_ttm.c +++ b/linux-core/drm_ttm.c @@ -799,7 +799,7 @@ int drm_add_ttm(drm_device_t * dev, unsigned size, drm_map_list_t ** maplist) return 0; } -int drm_ttm_ioctl(drm_file_t *priv, int num_requests, drm_ttm_arg_t __user *data) +int drm_ttm_ioctl(drm_file_t *priv, drm_ttm_arg_t __user *data) { return 0; } diff --git a/linux-core/drm_ttm.h b/linux-core/drm_ttm.h index 81006c3c..5a7569ff 100644 --- a/linux-core/drm_ttm.h +++ b/linux-core/drm_ttm.h @@ -148,8 +148,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, int num_requests, - drm_ttm_arg_t __user *data); +extern int drm_ttm_ioctl(drm_file_t *priv, drm_ttm_arg_t __user *data); #define DRM_MASK_VAL(dest, mask, val) \ (dest) = ((dest) & ~(mask)) | ((val) & (mask)); |