diff options
Diffstat (limited to 'linux-core/drm_bufs.c')
-rw-r--r-- | linux-core/drm_bufs.c | 89 |
1 files changed, 63 insertions, 26 deletions
diff --git a/linux-core/drm_bufs.c b/linux-core/drm_bufs.c index 50182160..b54aaeb8 100644 --- a/linux-core/drm_bufs.c +++ b/linux-core/drm_bufs.c @@ -122,27 +122,23 @@ EXPORT_SYMBOL(drm_initmap); * type. Adds the map to the map list drm_device::maplist. Adds MTRR's where * applicable and if supported by the kernel. */ -int drm_addmap(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) +int drm_addmap(drm_device_t * dev, unsigned int offset, + unsigned int size, drm_map_type_t type, + drm_map_flags_t flags, drm_map_t ** map_ptr) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->head->dev; drm_map_t *map; - drm_map_t __user *argp = (void __user *)arg; drm_map_list_t *list; drm_dma_handle_t *dmah; - if (!(filp->f_mode & 3)) - return -EACCES; /* Require read/write */ map = drm_alloc(sizeof(*map), DRM_MEM_MAPS); if (!map) return -ENOMEM; - if (copy_from_user(map, argp, sizeof(*map))) { - drm_free(map, sizeof(*map), DRM_MEM_MAPS); - return -EFAULT; - } + map->offset = offset; + map->size = size; + map->flags = flags; + map->type = type; /* Only allow shared memory to be removable since we only keep enough * book keeping information about shared memory to allow for removal @@ -289,11 +285,40 @@ int drm_addmap(struct inode *inode, struct file *filp, list_add(&list->head, &dev->maplist->head); up(&dev->struct_sem); found_it: - if (copy_to_user(argp, map, sizeof(*map))) + *map_ptr = map; + return 0; +} +EXPORT_SYMBOL(drm_addmap); + +int drm_addmap_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->head->dev; + drm_map_t map; + drm_map_t *map_ptr; + drm_map_t __user *argp = (void __user *)arg; + int err; + + if (!(filp->f_mode & 3)) + return -EACCES; /* Require read/write */ + + if (copy_from_user(& map, argp, sizeof(map))) { return -EFAULT; - if (map->type != _DRM_SHM) { + } + + err = drm_addmap( dev, map.offset, map.size, map.type, map.flags, + & map_ptr ); + + if (err) { + return err; + } + + if (copy_to_user(argp, map_ptr, sizeof(*map_ptr))) + return -EFAULT; + if (map_ptr->type != _DRM_SHM) { if (copy_to_user(&argp->handle, - &map->offset, sizeof(map->offset))) + &map_ptr->offset, sizeof(map_ptr->offset))) return -EFAULT; } return 0; @@ -313,23 +338,16 @@ int drm_addmap(struct inode *inode, struct file *filp, * its being used, and free any associate resource (such as MTRR's) if it's not * being on use. * - * \sa addmap(). + * \sa drm_addmap */ -int drm_rmmap(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) +int drm_rmmap(drm_device_t *dev, void *handle) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->head->dev; struct list_head *list; drm_map_list_t *r_list = NULL; drm_vma_entry_t *pt, *prev; drm_map_t *map; - drm_map_t request; int found_maps = 0; - if (copy_from_user(&request, (drm_map_t __user *) arg, sizeof(request))) { - return -EFAULT; - } down(&dev->struct_sem); list = &dev->maplist->head; @@ -337,7 +355,7 @@ int drm_rmmap(struct inode *inode, struct file *filp, r_list = list_entry(list, drm_map_list_t, head); if (r_list->map && - r_list->map->handle == request.handle && + r_list->map->handle == handle && r_list->map->flags & _DRM_REMOVABLE) break; } @@ -389,6 +407,22 @@ int drm_rmmap(struct inode *inode, struct file *filp, up(&dev->struct_sem); return 0; } +EXPORT_SYMBOL(drm_rmmap); + +int drm_rmmap_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->head->dev; + drm_map_t request; + + + if (copy_from_user(&request, (drm_map_t __user *) arg, sizeof(request))) { + return -EFAULT; + } + + return drm_rmmap(dev, request.handle); +} /** * Cleanup after an error on one of the addbufs() functions. @@ -444,7 +478,7 @@ static void drm_cleanup_buf_error(drm_device_t * dev, drm_buf_entry_t * entry) * reallocates the buffer list of the same size order to accommodate the new * buffers. */ -static int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request) +int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request) { drm_device_dma_t *dma = dev->dma; drm_buf_entry_t *entry; @@ -596,9 +630,10 @@ static int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request) atomic_dec(&dev->buf_alloc); return 0; } +EXPORT_SYMBOL(drm_addbufs_agp); #endif /* __OS_HAS_AGP */ -static int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request) +int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request) { drm_device_dma_t *dma = dev->dma; int count; @@ -814,6 +849,7 @@ static int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request) return 0; } +EXPORT_SYMBOL(drm_addbufs_pci); static int drm_addbufs_sg(drm_device_t * dev, drm_buf_desc_t * request) { @@ -1127,6 +1163,7 @@ int drm_addbufs_fb(drm_device_t * dev, drm_buf_desc_t * request) atomic_dec(&dev->buf_alloc); return 0; } +EXPORT_SYMBOL(drm_addbufs_fb); /** |