diff options
author | Dave Airlie <airlied@starflyer.(none)> | 2005-07-10 02:56:52 -0400 |
---|---|---|
committer | Dave Airlie <airlied@linux.ie> | 2005-07-10 02:56:52 -0400 |
commit | 7ab984012a879a53abb56abfe03b0c686f42b281 (patch) | |
tree | 53738f82e57b2aa91c5706f6c463831ddf19164d /drivers/char/drm/drm_bufs.c | |
parent | 9c8da5ebbf6f87293cf8555182da271449889a69 (diff) |
drm: update some function so a driver can call them
This patch splits some ioctl functions so that they can be called
in-kernel by a DRM driver. The driver will use them later.
From: Ian Romanick <idr@us.ibm.com>
Signed-off-by: Dave Airlie <airlied@linux.ie>
Diffstat (limited to 'drivers/char/drm/drm_bufs.c')
-rw-r--r-- | drivers/char/drm/drm_bufs.c | 84 |
1 files changed, 59 insertions, 25 deletions
diff --git a/drivers/char/drm/drm_bufs.c b/drivers/char/drm/drm_bufs.c index be54efbefe84..cd4636f7f187 100644 --- a/drivers/char/drm/drm_bufs.c +++ b/drivers/char/drm/drm_bufs.c | |||
@@ -82,26 +82,22 @@ static unsigned int map32_handle = 0x10000000; | |||
82 | * type. Adds the map to the map list drm_device::maplist. Adds MTRR's where | 82 | * type. Adds the map to the map list drm_device::maplist. Adds MTRR's where |
83 | * applicable and if supported by the kernel. | 83 | * applicable and if supported by the kernel. |
84 | */ | 84 | */ |
85 | int drm_addmap( struct inode *inode, struct file *filp, | 85 | int drm_addmap(drm_device_t * dev, unsigned int offset, |
86 | unsigned int cmd, unsigned long arg ) | 86 | unsigned int size, drm_map_type_t type, |
87 | drm_map_flags_t flags, drm_local_map_t ** map_ptr) | ||
87 | { | 88 | { |
88 | drm_file_t *priv = filp->private_data; | ||
89 | drm_device_t *dev = priv->head->dev; | ||
90 | drm_map_t *map; | 89 | drm_map_t *map; |
91 | drm_map_t __user *argp = (void __user *)arg; | ||
92 | drm_map_list_t *list; | 90 | drm_map_list_t *list; |
93 | drm_dma_handle_t *dmah; | 91 | drm_dma_handle_t *dmah; |
94 | 92 | ||
95 | if ( !(filp->f_mode & 3) ) return -EACCES; /* Require read/write */ | ||
96 | |||
97 | map = drm_alloc( sizeof(*map), DRM_MEM_MAPS ); | 93 | map = drm_alloc( sizeof(*map), DRM_MEM_MAPS ); |
98 | if ( !map ) | 94 | if ( !map ) |
99 | return -ENOMEM; | 95 | return -ENOMEM; |
100 | 96 | ||
101 | if ( copy_from_user( map, argp, sizeof(*map) ) ) { | 97 | map->offset = offset; |
102 | drm_free( map, sizeof(*map), DRM_MEM_MAPS ); | 98 | map->size = size; |
103 | return -EFAULT; | 99 | map->flags = flags; |
104 | } | 100 | map->type = type; |
105 | 101 | ||
106 | /* Only allow shared memory to be removable since we only keep enough | 102 | /* Only allow shared memory to be removable since we only keep enough |
107 | * book keeping information about shared memory to allow for removal | 103 | * book keeping information about shared memory to allow for removal |
@@ -218,10 +214,42 @@ int drm_addmap( struct inode *inode, struct file *filp, | |||
218 | #endif | 214 | #endif |
219 | up(&dev->struct_sem); | 215 | up(&dev->struct_sem); |
220 | 216 | ||
221 | if ( copy_to_user( argp, map, sizeof(*map) ) ) | 217 | *map_ptr = map; |
218 | return 0; | ||
219 | } | ||
220 | EXPORT_SYMBOL(drm_addmap); | ||
221 | |||
222 | int drm_addmap_ioctl(struct inode *inode, struct file *filp, | ||
223 | unsigned int cmd, unsigned long arg) | ||
224 | { | ||
225 | drm_file_t *priv = filp->private_data; | ||
226 | drm_device_t *dev = priv->head->dev; | ||
227 | drm_map_t map; | ||
228 | drm_map_t *map_ptr; | ||
229 | drm_map_t __user *argp = (void __user *)arg; | ||
230 | int err; | ||
231 | |||
232 | if (!(filp->f_mode & 3)) | ||
233 | return -EACCES; /* Require read/write */ | ||
234 | |||
235 | if (copy_from_user(& map, argp, sizeof(map))) { | ||
222 | return -EFAULT; | 236 | return -EFAULT; |
223 | if (copy_to_user(&argp->handle, &map->offset, sizeof(map->offset))) | 237 | } |
238 | |||
239 | err = drm_addmap( dev, map.offset, map.size, map.type, map.flags, | ||
240 | &map_ptr ); | ||
241 | |||
242 | if (err) { | ||
243 | return err; | ||
244 | } | ||
245 | |||
246 | if (copy_to_user(argp, map_ptr, sizeof(*map_ptr))) | ||
224 | return -EFAULT; | 247 | return -EFAULT; |
248 | if (map_ptr->type != _DRM_SHM) { | ||
249 | if (copy_to_user(&argp->handle, &map_ptr->offset, | ||
250 | sizeof(map_ptr->offset))) | ||
251 | return -EFAULT; | ||
252 | } | ||
225 | return 0; | 253 | return 0; |
226 | } | 254 | } |
227 | 255 | ||
@@ -240,32 +268,23 @@ int drm_addmap( struct inode *inode, struct file *filp, | |||
240 | * its being used, and free any associate resource (such as MTRR's) if it's not | 268 | * its being used, and free any associate resource (such as MTRR's) if it's not |
241 | * being on use. | 269 | * being on use. |
242 | * | 270 | * |
243 | * \sa addmap(). | 271 | * \sa drm_addmap |
244 | */ | 272 | */ |
245 | int drm_rmmap(struct inode *inode, struct file *filp, | 273 | int drm_rmmap(drm_device_t *dev, void *handle) |
246 | unsigned int cmd, unsigned long arg) | ||
247 | { | 274 | { |
248 | drm_file_t *priv = filp->private_data; | ||
249 | drm_device_t *dev = priv->head->dev; | ||
250 | struct list_head *list; | 275 | struct list_head *list; |
251 | drm_map_list_t *r_list = NULL; | 276 | drm_map_list_t *r_list = NULL; |
252 | drm_vma_entry_t *pt, *prev; | 277 | drm_vma_entry_t *pt, *prev; |
253 | drm_map_t *map; | 278 | drm_map_t *map; |
254 | drm_map_t request; | ||
255 | int found_maps = 0; | 279 | int found_maps = 0; |
256 | 280 | ||
257 | if (copy_from_user(&request, (drm_map_t __user *)arg, | ||
258 | sizeof(request))) { | ||
259 | return -EFAULT; | ||
260 | } | ||
261 | |||
262 | down(&dev->struct_sem); | 281 | down(&dev->struct_sem); |
263 | list = &dev->maplist->head; | 282 | list = &dev->maplist->head; |
264 | list_for_each(list, &dev->maplist->head) { | 283 | list_for_each(list, &dev->maplist->head) { |
265 | r_list = list_entry(list, drm_map_list_t, head); | 284 | r_list = list_entry(list, drm_map_list_t, head); |
266 | 285 | ||
267 | if(r_list->map && | 286 | if(r_list->map && |
268 | r_list->map->offset == (unsigned long) request.handle && | 287 | r_list->map->handle == handle && |
269 | r_list->map->flags & _DRM_REMOVABLE) break; | 288 | r_list->map->flags & _DRM_REMOVABLE) break; |
270 | } | 289 | } |
271 | 290 | ||
@@ -319,6 +338,21 @@ int drm_rmmap(struct inode *inode, struct file *filp, | |||
319 | up(&dev->struct_sem); | 338 | up(&dev->struct_sem); |
320 | return 0; | 339 | return 0; |
321 | } | 340 | } |
341 | EXPORT_SYMBOL(drm_rmmap); | ||
342 | |||
343 | int drm_rmmap_ioctl(struct inode *inode, struct file *filp, | ||
344 | unsigned int cmd, unsigned long arg) | ||
345 | { | ||
346 | drm_file_t *priv = filp->private_data; | ||
347 | drm_device_t *dev = priv->head->dev; | ||
348 | drm_map_t request; | ||
349 | |||
350 | if (copy_from_user(&request, (drm_map_t __user *)arg, sizeof(request))) { | ||
351 | return -EFAULT; | ||
352 | } | ||
353 | |||
354 | return drm_rmmap(dev, request.handle); | ||
355 | } | ||
322 | 356 | ||
323 | /** | 357 | /** |
324 | * Cleanup after an error on one of the addbufs() functions. | 358 | * Cleanup after an error on one of the addbufs() functions. |