Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7ab98401 authored by Dave Airlie's avatar Dave Airlie Committed by Dave Airlie
Browse files

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: default avatarDave Airlie <airlied@linux.ie>
parent 9c8da5eb
Loading
Loading
Loading
Loading
+21 −13
Original line number Diff line number Diff line
@@ -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_order( unsigned long size );
extern int	     drm_addmap( struct inode *inode, struct file *filp,
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( struct inode *inode, struct file *filp,
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_addbufs( struct inode *inode, struct file *filp,
				   unsigned int cmd, unsigned long arg );
extern int	     drm_infobufs( struct inode *inode, struct file *filp,
@@ -927,14 +932,17 @@ 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,
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 void           drm_agp_do_release(drm_device_t *dev);
extern int            drm_agp_release(struct inode *inode, struct file *filp,
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(struct inode *inode, struct file *filp,
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(struct inode *inode, struct file *filp,
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);
+79 −56
Original line number Diff line number Diff line
@@ -37,7 +37,7 @@
#if __OS_HAS_AGP

/**
 * AGP information ioctl.
 * Get AGP information.
 *
 * \param inode device inode.
 * \param filp file pointer.
@@ -48,27 +48,39 @@
 * 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;
	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;
@@ -76,23 +88,16 @@ int drm_agp_info(struct inode *inode, struct file *filp,
}

/**
 * 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,62 +118,79 @@ 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,
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;

	if (!dev->agp || !dev->agp->acquired)
		return -EINVAL;
	agp_backend_release(dev->agp->bridge);
	dev->agp->acquired = 0;
	return 0;
	
	return drm_agp_acquire( (drm_device_t *) priv->head->dev );
}

/**
 * Release the AGP device.
 *
 * Calls agp_backend_release().
 * \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.
 */
void drm_agp_do_release(drm_device_t *dev)
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);

int drm_agp_release_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;
	
	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,
int drm_agp_enable(drm_device_t *dev, drm_agp_mode_t mode)
{
	if (!dev->agp || !dev->agp->acquired)
		return -EINVAL;

	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 (!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;
	return drm_agp_enable(dev, mode);
}

/**
+59 −25
Original line number Diff line number Diff line
@@ -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;
	}

	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 (copy_to_user(&argp->handle, &map->offset, sizeof(map->offset)))
	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.
+8 −7
Original line number Diff line number Diff line
@@ -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;