diff options
author | Dave Airlie <airlied@starflyer.(none)> | 2005-07-10 08:56:52 +0200 |
---|---|---|
committer | Dave Airlie <airlied@linux.ie> | 2005-07-10 08:56:52 +0200 |
commit | 7ab984012a879a53abb56abfe03b0c686f42b281 (patch) | |
tree | 53738f82e57b2aa91c5706f6c463831ddf19164d /drivers/char | |
parent | drm: update support for drm pci buffers (diff) | |
download | linux-7ab984012a879a53abb56abfe03b0c686f42b281.tar.xz linux-7ab984012a879a53abb56abfe03b0c686f42b281.zip |
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')
-rw-r--r-- | drivers/char/drm/drmP.h | 34 | ||||
-rw-r--r-- | drivers/char/drm/drm_agpsupport.c | 135 | ||||
-rw-r--r-- | drivers/char/drm/drm_bufs.c | 84 | ||||
-rw-r--r-- | drivers/char/drm/drm_drv.c | 15 |
4 files changed, 167 insertions, 101 deletions
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h index 7e633a9ce933..d16d07e28b4c 100644 --- a/drivers/char/drm/drmP.h +++ b/drivers/char/drm/drmP.h @@ -889,11 +889,16 @@ extern int drm_lock_free(drm_device_t *dev, unsigned int context); /* Buffer management support (drm_bufs.h) */ +extern 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); +extern int drm_addmap_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int drm_rmmap(drm_device_t *dev, void *handle); +extern int drm_rmmap_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); + extern int drm_order( unsigned long size ); -extern int drm_addmap( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); -extern int drm_rmmap( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); extern int drm_addbufs( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg ); extern int drm_infobufs( struct inode *inode, struct file *filp, @@ -927,15 +932,18 @@ extern void drm_vbl_send_signals( drm_device_t *dev ); /* AGP/GART support (drm_agpsupport.h) */ extern drm_agp_head_t *drm_agp_init(drm_device_t *dev); -extern int drm_agp_acquire(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg); -extern void drm_agp_do_release(drm_device_t *dev); -extern int drm_agp_release(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg); -extern int drm_agp_enable(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg); -extern int drm_agp_info(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg); +extern int drm_agp_acquire(drm_device_t * dev); +extern int drm_agp_acquire_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int drm_agp_release(drm_device_t *dev); +extern int drm_agp_release_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int drm_agp_enable(drm_device_t *dev, drm_agp_mode_t mode); +extern int drm_agp_enable_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int drm_agp_info(drm_device_t * dev, drm_agp_info_t *info); +extern int drm_agp_info_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); extern int drm_agp_alloc(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); extern int drm_agp_free(struct inode *inode, struct file *filp, diff --git a/drivers/char/drm/drm_agpsupport.c b/drivers/char/drm/drm_agpsupport.c index 8d94c0b5fa44..10c8b4daec51 100644 --- a/drivers/char/drm/drm_agpsupport.c +++ b/drivers/char/drm/drm_agpsupport.c @@ -37,7 +37,7 @@ #if __OS_HAS_AGP /** - * AGP information ioctl. + * Get AGP information. * * \param inode device inode. * \param filp file pointer. @@ -48,51 +48,56 @@ * Verifies the AGP device has been initialized and acquired and fills in the * drm_agp_info structure with the information in drm_agp_head::agp_info. */ -int drm_agp_info(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) +int drm_agp_info(drm_device_t *dev, drm_agp_info_t *info) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->head->dev; DRM_AGP_KERN *kern; - drm_agp_info_t info; if (!dev->agp || !dev->agp->acquired) return -EINVAL; kern = &dev->agp->agp_info; - info.agp_version_major = kern->version.major; - info.agp_version_minor = kern->version.minor; - info.mode = kern->mode; - info.aperture_base = kern->aper_base; - info.aperture_size = kern->aper_size * 1024 * 1024; - info.memory_allowed = kern->max_memory << PAGE_SHIFT; - info.memory_used = kern->current_memory << PAGE_SHIFT; - info.id_vendor = kern->device->vendor; - info.id_device = kern->device->device; - - if (copy_to_user((drm_agp_info_t __user *)arg, &info, sizeof(info))) + info->agp_version_major = kern->version.major; + info->agp_version_minor = kern->version.minor; + info->mode = kern->mode; + info->aperture_base = kern->aper_base; + info->aperture_size = kern->aper_size * 1024 * 1024; + info->memory_allowed = kern->max_memory << PAGE_SHIFT; + info->memory_used = kern->current_memory << PAGE_SHIFT; + info->id_vendor = kern->device->vendor; + info->id_device = kern->device->device; + + return 0; +} +EXPORT_SYMBOL(drm_agp_info); + +int drm_agp_info_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_agp_info_t info; + int err; + + err = drm_agp_info(dev, &info); + if (err) + return err; + + if (copy_to_user((drm_agp_info_t __user *) arg, &info, sizeof(info))) return -EFAULT; return 0; } /** - * Acquire the AGP device (ioctl). + * Acquire the AGP device. * - * \param inode device inode. - * \param filp file pointer. - * \param cmd command. - * \param arg user argument. + * \param dev DRM device that is to acquire AGP * \return zero on success or a negative number on failure. * * Verifies the AGP device hasn't been acquired before and calls - * agp_acquire(). + * \c agp_backend_acquire. */ -int drm_agp_acquire(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) +int drm_agp_acquire(drm_device_t *dev) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->head->dev; - if (!dev->agp) return -ENODEV; if (dev->agp->acquired) @@ -102,9 +107,10 @@ int drm_agp_acquire(struct inode *inode, struct file *filp, dev->agp->acquired = 1; return 0; } +EXPORT_SYMBOL(drm_agp_acquire); /** - * Release the AGP device (ioctl). + * Acquire the AGP device (ioctl). * * \param inode device inode. * \param filp file pointer. @@ -112,63 +118,80 @@ int drm_agp_acquire(struct inode *inode, struct file *filp, * \param arg user argument. * \return zero on success or a negative number on failure. * - * Verifies the AGP device has been acquired and calls agp_backend_release(). + * Verifies the AGP device hasn't been acquired before and calls + * \c agp_backend_acquire. */ -int drm_agp_release(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) +int drm_agp_acquire_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_file_t *priv = filp->private_data; + + return drm_agp_acquire( (drm_device_t *) priv->head->dev ); +} +/** + * Release the AGP device. + * + * \param dev DRM device that is to release AGP + * \return zero on success or a negative number on failure. + * + * Verifies the AGP device has been acquired and calls \c agp_backend_release. + */ +int drm_agp_release(drm_device_t *dev) +{ if (!dev->agp || !dev->agp->acquired) return -EINVAL; agp_backend_release(dev->agp->bridge); dev->agp->acquired = 0; return 0; - } +EXPORT_SYMBOL(drm_agp_release); -/** - * Release the AGP device. - * - * Calls agp_backend_release(). - */ -void drm_agp_do_release(drm_device_t *dev) +int drm_agp_release_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) { - agp_backend_release(dev->agp->bridge); + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->head->dev; + + return drm_agp_release(dev); } /** * Enable the AGP bus. * - * \param inode device inode. - * \param filp file pointer. - * \param cmd command. - * \param arg pointer to a drm_agp_mode structure. + * \param dev DRM device that has previously acquired AGP. + * \param mode Requested AGP mode. * \return zero on success or a negative number on failure. * * Verifies the AGP device has been acquired but not enabled, and calls - * agp_enable(). + * \c agp_enable. */ -int drm_agp_enable(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) +int drm_agp_enable(drm_device_t *dev, drm_agp_mode_t mode) { - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->head->dev; - drm_agp_mode_t mode; - if (!dev->agp || !dev->agp->acquired) return -EINVAL; - if (copy_from_user(&mode, (drm_agp_mode_t __user *)arg, sizeof(mode))) - return -EFAULT; - dev->agp->mode = mode.mode; agp_enable(dev->agp->bridge, mode.mode); dev->agp->base = dev->agp->agp_info.aper_base; dev->agp->enabled = 1; return 0; } +EXPORT_SYMBOL(drm_agp_enable); + +int drm_agp_enable_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_agp_mode_t mode; + + + if (copy_from_user(&mode, (drm_agp_mode_t __user *) arg, sizeof(mode))) + return -EFAULT; + + return drm_agp_enable(dev, mode); +} /** * Allocate AGP memory. 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; * 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_local_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 @@ -218,10 +214,42 @@ int drm_addmap( struct inode *inode, struct file *filp, #endif up(&dev->struct_sem); - 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 (copy_to_user(&argp->handle, &map->offset, sizeof(map->offset))) + } + + 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_ptr->offset, + sizeof(map_ptr->offset))) + return -EFAULT; + } return 0; } @@ -240,32 +268,23 @@ 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; list_for_each(list, &dev->maplist->head) { r_list = list_entry(list, drm_map_list_t, head); if(r_list->map && - r_list->map->offset == (unsigned long) request.handle && + r_list->map->handle == handle && r_list->map->flags & _DRM_REMOVABLE) break; } @@ -319,6 +338,21 @@ 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. diff --git a/drivers/char/drm/drm_drv.c b/drivers/char/drm/drm_drv.c index ab172ea8e98a..9b09b105e1d6 100644 --- a/drivers/char/drm/drm_drv.c +++ b/drivers/char/drm/drm_drv.c @@ -70,8 +70,8 @@ static drm_ioctl_desc_t drm_ioctls[] = { [DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)] = { drm_noop, 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = { drm_authmagic, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = { drm_addmap, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_RM_MAP)] = { drm_rmmap, 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = { drm_addmap_ioctl,1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_RM_MAP)] = { drm_rmmap_ioctl, 1, 0 }, [DRM_IOCTL_NR(DRM_IOCTL_SET_SAREA_CTX)] = { drm_setsareactx, 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_GET_SAREA_CTX)] = { drm_getsareactx, 1, 0 }, @@ -102,10 +102,10 @@ static drm_ioctl_desc_t drm_ioctls[] = { [DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = { drm_control, 1, 1 }, #if __OS_HAS_AGP - [DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = { drm_agp_acquire, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = { drm_agp_release, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = { drm_agp_enable, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)] = { drm_agp_info, 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = { drm_agp_acquire_ioctl, 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = { drm_agp_release_ioctl, 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = { drm_agp_enable_ioctl, 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)] = { drm_agp_info_ioctl, 1, 0 }, [DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)] = { drm_agp_alloc, 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = { drm_agp_free, 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = { drm_agp_bind, 1, 1 }, @@ -178,7 +178,8 @@ int drm_takedown( drm_device_t *dev ) } dev->agp->memory = NULL; - if ( dev->agp->acquired ) drm_agp_do_release(dev); + if (dev->agp->acquired) + drm_agp_release(dev); dev->agp->acquired = 0; dev->agp->enabled = 0; |