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)); | 
