diff options
Diffstat (limited to 'linux-core')
| -rw-r--r-- | linux-core/drm_bo.c | 46 | 
1 files changed, 43 insertions, 3 deletions
diff --git a/linux-core/drm_bo.c b/linux-core/drm_bo.c index affee135..7f5088fb 100644 --- a/linux-core/drm_bo.c +++ b/linux-core/drm_bo.c @@ -507,11 +507,14 @@ static int drm_buffer_object_unmap(drm_file_t *priv, uint32_t handle)   * Call struct-sem locked.   */ -static void drm_buffer_user_object_unmap(drm_file_t *priv, drm_user_object_t *uo) +static void drm_buffer_user_object_unmap(drm_file_t *priv, drm_user_object_t *uo, +					 drm_ref_t action)  {  	drm_device_t *dev = priv->head->dev;  	drm_buffer_object_t *bo = drm_user_object_entry(uo, drm_buffer_object_t, base); +	BUG_ON(action != _DRM_REF_TYPE1); +  	if (atomic_dec_and_test(&bo->mapped)) {  		mutex_unlock(&dev->struct_mutex);  		mutex_lock(&bo->mutex); @@ -534,7 +537,7 @@ int drm_buffer_object_create(drm_file_t *priv,  			     uint32_t ttm_handle,  			     uint32_t mask,  			     uint32_t hint, -			     void __user *user_pages, +			     unsigned long buffer_start,  			     drm_buffer_object_t **buf_obj)  {  	drm_device_t *dev = priv->head->dev; @@ -569,7 +572,7 @@ int drm_buffer_object_create(drm_file_t *priv,  			goto out_err;  		break;  	case drm_bo_type_user: -		bo->user_pages = user_pages; +		bo->user_pages = (void __user *)buffer_start;  		break;  	default:  		ret = -EINVAL; @@ -592,6 +595,27 @@ int drm_buffer_object_create(drm_file_t *priv,  	drm_free(bo, sizeof(*bo), DRM_MEM_BUFOBJ);  	return  ret;  } + +static int drm_bo_add_user_object(drm_file_t *priv, drm_buffer_object_t *bo,  +				  int shareable) +{ +	drm_device_t *dev = priv->head->dev; +	int ret; + +	mutex_lock(&dev->struct_mutex); +	ret = drm_add_user_object(priv, &bo->base, shareable); +	if (ret) +		goto out; + +	bo->base.remove = drm_bo_base_deref_locked; +	bo->base.type = drm_buffer_type; +	bo->base.ref_struct_locked = NULL; +	bo->base.unref = drm_buffer_user_object_unmap; +	 + out: +	mutex_unlock(&dev->struct_mutex); +	return ret; +} @@ -610,6 +634,22 @@ int drm_bo_ioctl(DRM_IOCTL_ARGS)  		rep.ret = 0;  		rep.handled = 0;  		switch (req->op) { +		case drm_bo_create: { +			unsigned long buffer_start = drm_ul(req->buffer_start); +			rep.ret = drm_buffer_object_create(priv, drm_ul(req->size), +							   req->type, req->arg_handle, +							   req->mask, req->hint, +							   buffer_start, +							   &entry); +			if (rep.ret) +				break; +			 +			rep.ret = drm_bo_add_user_object(priv, entry, req->mask & +							 DRM_BO_FLAG_SHAREABLE); +			if (rep.ret)  +				drm_bo_usage_deref_unlocked(dev, entry); +			break; +		}  		case drm_bo_unmap:  			rep.ret = drm_buffer_object_unmap(priv, req->handle);  			break;  | 
