diff options
Diffstat (limited to 'linux-core/drm_scatter.c')
-rw-r--r-- | linux-core/drm_scatter.c | 49 |
1 files changed, 31 insertions, 18 deletions
diff --git a/linux-core/drm_scatter.c b/linux-core/drm_scatter.c index e5c9f877..c0d6db24 100644 --- a/linux-core/drm_scatter.c +++ b/linux-core/drm_scatter.c @@ -55,6 +55,7 @@ void drm_sg_cleanup(drm_sg_mem_t * entry) entry->pages * sizeof(*entry->pagelist), DRM_MEM_PAGES); drm_free(entry, sizeof(*entry), DRM_MEM_SGLISTS); } +EXPORT_SYMBOL(drm_sg_cleanup); #ifdef _LP64 # define ScatterHandle(x) (unsigned int)((x >> 32) + (x & ((1L << 32) - 1))) @@ -62,13 +63,8 @@ void drm_sg_cleanup(drm_sg_mem_t * entry) # define ScatterHandle(x) (unsigned int)(x) #endif -int drm_sg_alloc(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) +int drm_sg_alloc(drm_device_t * dev, drm_scatter_gather_t * request) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->head->dev; - drm_scatter_gather_t __user *argp = (void __user *)arg; - drm_scatter_gather_t request; drm_sg_mem_t *entry; unsigned long pages, i, j; @@ -80,17 +76,13 @@ int drm_sg_alloc(struct inode *inode, struct file *filp, if (dev->sg) return -EINVAL; - if (copy_from_user(&request, argp, sizeof(request))) - return -EFAULT; - entry = drm_alloc(sizeof(*entry), DRM_MEM_SGLISTS); if (!entry) return -ENOMEM; memset(entry, 0, sizeof(*entry)); - - pages = (request.size + PAGE_SIZE - 1) / PAGE_SIZE; - DRM_DEBUG("sg size=%ld pages=%ld\n", request.size, pages); + pages = (request->size + PAGE_SIZE - 1) / PAGE_SIZE; + DRM_DEBUG("sg size=%ld pages=%ld\n", request->size, pages); entry->pages = pages; entry->pagelist = drm_alloc(pages * sizeof(*entry->pagelist), @@ -142,12 +134,7 @@ int drm_sg_alloc(struct inode *inode, struct file *filp, SetPageReserved(entry->pagelist[j]); } - request.handle = entry->handle; - - if (copy_to_user(argp, &request, sizeof(request))) { - drm_sg_cleanup(entry); - return -EFAULT; - } + request->handle = entry->handle; dev->sg = entry; @@ -196,6 +183,32 @@ int drm_sg_alloc(struct inode *inode, struct file *filp, failed: drm_sg_cleanup(entry); return -ENOMEM; + +} +EXPORT_SYMBOL(drm_sg_alloc); + +int drm_sg_alloc_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_scatter_gather_t __user *argp = (void __user *)arg; + drm_scatter_gather_t request; + int ret; + + if (copy_from_user(&request, argp, sizeof(request))) + return -EFAULT; + + ret = drm_sg_alloc(priv->head->dev, &request); + if ( ret ) return ret; + + if (copy_to_user(argp, &request, sizeof(request))) { + drm_sg_cleanup(priv->head->dev->sg); + return -EFAULT; + } + + + return 0; + } int drm_sg_free(struct inode *inode, struct file *filp, |