#include <linux/vmalloc.h>
#include "drmP.h"
-unsigned long drm_get_resource_start(drm_device_t *dev, unsigned int resource)
+unsigned long drm_get_resource_start(struct drm_device *dev, unsigned int resource)
{
return pci_resource_start(dev->pdev, resource);
}
EXPORT_SYMBOL(drm_get_resource_start);
-unsigned long drm_get_resource_len(drm_device_t *dev, unsigned int resource)
+unsigned long drm_get_resource_len(struct drm_device *dev, unsigned int resource)
{
return pci_resource_len(dev->pdev, resource);
}
EXPORT_SYMBOL(drm_get_resource_len);
-static drm_map_list_t *drm_find_matching_map(drm_device_t *dev,
+static struct drm_map_list *drm_find_matching_map(struct drm_device *dev,
drm_local_map_t *map)
{
- struct list_head *list;
-
- list_for_each(list, &dev->maplist->head) {
- drm_map_list_t *entry = list_entry(list, drm_map_list_t, head);
+ struct drm_map_list *entry;
+ list_for_each_entry(entry, &dev->maplist, head) {
if (entry->map && map->type == entry->map->type &&
- entry->map->offset == map->offset) {
+ ((entry->map->offset == map->offset) ||
+ (map->type == _DRM_SHM && map->flags==_DRM_CONTAINS_LOCK))) {
return entry;
}
}
return NULL;
}
-static int drm_map_handle(drm_device_t *dev, drm_hash_item_t *hash,
+static int drm_map_handle(struct drm_device *dev, struct drm_hash_item *hash,
unsigned long user_token, int hashed_handle)
{
int use_hashed_handle;
* Ioctl to specify a range of memory that is available for mapping by a non-root process.
*
* \param inode device inode.
- * \param filp file pointer.
+ * \param file_priv DRM file private.
* \param cmd command.
* \param arg pointer to a drm_map structure.
* \return zero on success or a negative value on error.
* type. Adds the map to the map list drm_device::maplist. Adds MTRR's where
* applicable and if supported by the kernel.
*/
-static int drm_addmap_core(drm_device_t * dev, unsigned int offset,
- unsigned int size, drm_map_type_t type,
- drm_map_flags_t flags, drm_map_list_t ** maplist)
+static int drm_addmap_core(struct drm_device * dev, unsigned int offset,
+ unsigned int size, enum drm_map_type type,
+ enum drm_map_flags flags,
+ struct drm_map_list ** maplist)
{
- drm_map_t *map;
- drm_map_list_t *list;
+ struct drm_map *map;
+ struct drm_map_list *list;
drm_dma_handle_t *dmah;
unsigned long user_token;
int ret;
MTRR_TYPE_WRCOMB, 1);
}
}
- if (map->type == _DRM_REGISTERS)
+ if (map->type == _DRM_REGISTERS) {
map->handle = ioremap(map->offset, map->size);
+ if (!map->handle) {
+ drm_free(map, sizeof(*map), DRM_MEM_MAPS);
+ return -ENOMEM;
+ }
+ }
+
break;
-
case _DRM_SHM:
+ list = drm_find_matching_map(dev, map);
+ if (list != NULL) {
+ if(list->map->size != map->size) {
+ DRM_DEBUG("Matching maps of type %d with "
+ "mismatched sizes, (%ld vs %ld)\n",
+ map->type, map->size, list->map->size);
+ list->map->size = map->size;
+ }
+
+ drm_free(map, sizeof(*map), DRM_MEM_MAPS);
+ *maplist = list;
+ return 0;
+ }
map->handle = vmalloc_user(map->size);
DRM_DEBUG("%lu %d %p\n",
map->size, drm_order(map->size), map->handle);
dev->sigdata.lock = dev->lock.hw_lock = map->handle; /* Pointer to lock */
}
break;
- case _DRM_AGP:
- if (drm_core_has_AGP(dev)) {
+ case _DRM_AGP: {
+ struct drm_agp_mem *entry;
+ int valid = 0;
+
+ if (!drm_core_has_AGP(dev)) {
+ drm_free(map, sizeof(*map), DRM_MEM_MAPS);
+ return -EINVAL;
+ }
#ifdef __alpha__
- map->offset += dev->hose->mem_space->start;
+ map->offset += dev->hose->mem_space->start;
#endif
- map->offset += dev->agp->base;
- map->mtrr = dev->agp->agp_mtrr; /* for getmap */
+ /* Note: dev->agp->base may actually be 0 when the DRM
+ * is not in control of AGP space. But if user space is
+ * it should already have added the AGP base itself.
+ */
+ map->offset += dev->agp->base;
+ map->mtrr = dev->agp->agp_mtrr; /* for getmap */
+
+ /* This assumes the DRM is in total control of AGP space.
+ * It's not always the case as AGP can be in the control
+ * of user space (i.e. i810 driver). So this loop will get
+ * skipped and we double check that dev->agp->memory is
+ * actually set as well as being invalid before EPERM'ing
+ */
+ list_for_each_entry(entry, &dev->agp->memory, head) {
+ if ((map->offset >= entry->bound) &&
+ (map->offset + map->size <= entry->bound + entry->pages * PAGE_SIZE)) {
+ valid = 1;
+ break;
+ }
+ }
+ if (!list_empty(&dev->agp->memory) && !valid) {
+ drm_free(map, sizeof(*map), DRM_MEM_MAPS);
+ return -EPERM;
}
+ DRM_DEBUG("AGP offset = 0x%08lx, size = 0x%08lx\n", map->offset, map->size);
+
break;
+ }
case _DRM_SCATTER_GATHER:
if (!dev->sg) {
drm_free(map, sizeof(*map), DRM_MEM_MAPS);
list->map = map;
mutex_lock(&dev->struct_mutex);
- list_add(&list->head, &dev->maplist->head);
+ list_add(&list->head, &dev->maplist);
/* Assign a 32-bit handle */
/* We do it here so that dev->struct_mutex protects the increment */
*maplist = list;
return 0;
-}
+ }
-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)
+int drm_addmap(struct drm_device * dev, unsigned int offset,
+ unsigned int size, enum drm_map_type type,
+ enum drm_map_flags flags, drm_local_map_t ** map_ptr)
{
- drm_map_list_t *list;
+ struct drm_map_list *list;
int rc;
rc = drm_addmap_core(dev, offset, size, type, flags, &list);
EXPORT_SYMBOL(drm_addmap);
-int drm_addmap_ioctl(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+int drm_addmap_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->head->dev;
- drm_map_t map;
- drm_map_list_t *maplist;
- drm_map_t __user *argp = (void __user *)arg;
+ struct drm_map *map = data;
+ struct drm_map_list *maplist;
int err;
- if (!(filp->f_mode & 3))
- return -EACCES; /* Require read/write */
-
- if (copy_from_user(&map, argp, sizeof(map))) {
- return -EFAULT;
- }
-
- if (!(capable(CAP_SYS_ADMIN) || map.type == _DRM_AGP))
+ if (!(capable(CAP_SYS_ADMIN) || map->type == _DRM_AGP))
return -EPERM;
- err = drm_addmap_core(dev, map.offset, map.size, map.type, map.flags,
- &maplist);
+ err = drm_addmap_core(dev, map->offset, map->size, map->type,
+ map->flags, &maplist);
if (err)
return err;
- if (copy_to_user(argp, maplist->map, sizeof(drm_map_t)))
- return -EFAULT;
-
/* avoid a warning on 64-bit, this casting isn't very nice, but the API is set so too late */
- if (put_user((void *)(unsigned long)maplist->user_token, &argp->handle))
- return -EFAULT;
+ map->handle = (void *)(unsigned long)maplist->user_token;
return 0;
}
* isn't in use.
*
* \param inode device inode.
- * \param filp file pointer.
+ * \param file_priv DRM file private.
* \param cmd command.
- * \param arg pointer to a drm_map_t structure.
+ * \param arg pointer to a struct drm_map structure.
* \return zero on success or a negative value on error.
*
* Searches the map on drm_device::maplist, removes it from the list, see if
*
* \sa drm_addmap
*/
-int drm_rmmap_locked(drm_device_t *dev, drm_local_map_t *map)
+int drm_rmmap_locked(struct drm_device *dev, drm_local_map_t *map)
{
- struct list_head *list;
- drm_map_list_t *r_list = NULL;
+ struct drm_map_list *r_list = NULL, *list_t;
drm_dma_handle_t dmah;
+ int found = 0;
/* Find the list entry for the map and remove it */
- list_for_each(list, &dev->maplist->head) {
- r_list = list_entry(list, drm_map_list_t, head);
-
+ list_for_each_entry_safe(r_list, list_t, &dev->maplist, head) {
if (r_list->map == map) {
- list_del(list);
+ list_del(&r_list->head);
drm_ht_remove_key(&dev->map_hash,
r_list->user_token >> PAGE_SHIFT);
- drm_free(list, sizeof(*list), DRM_MEM_MAPS);
+ drm_free(r_list, sizeof(*r_list), DRM_MEM_MAPS);
+ found = 1;
break;
}
}
- /* List has wrapped around to the head pointer, or it's empty and we
- * didn't find anything.
- */
- if (list == (&dev->maplist->head)) {
+ if (!found)
return -EINVAL;
- }
switch (map->type) {
case _DRM_REGISTERS:
return 0;
}
-int drm_rmmap(drm_device_t *dev, drm_local_map_t *map)
+int drm_rmmap(struct drm_device *dev, drm_local_map_t *map)
{
int ret;
* gets used by drivers that the server doesn't need to care about. This seems
* unlikely.
*/
-int drm_rmmap_ioctl(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+int drm_rmmap_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->head->dev;
- drm_map_t request;
+ struct drm_map *request = data;
drm_local_map_t *map = NULL;
- struct list_head *list;
+ struct drm_map_list *r_list;
int ret;
- if (copy_from_user(&request, (drm_map_t __user *) arg, sizeof(request))) {
- return -EFAULT;
- }
-
mutex_lock(&dev->struct_mutex);
- list_for_each(list, &dev->maplist->head) {
- drm_map_list_t *r_list = list_entry(list, drm_map_list_t, head);
-
+ list_for_each_entry(r_list, &dev->maplist, head) {
if (r_list->map &&
- r_list->user_token == (unsigned long)request.handle &&
+ r_list->user_token == (unsigned long)request->handle &&
r_list->map->flags & _DRM_REMOVABLE) {
map = r_list->map;
break;
/* List has wrapped around to the head pointer, or its empty we didn't
* find anything.
*/
- if (list == (&dev->maplist->head)) {
- mutex_unlock(&dev->struct_mutex);
- return -EINVAL;
- }
-
- if (!map) {
+ if (list_empty(&dev->maplist) || !map) {
mutex_unlock(&dev->struct_mutex);
return -EINVAL;
}
*
* Frees any pages and buffers associated with the given entry.
*/
-static void drm_cleanup_buf_error(drm_device_t * dev, drm_buf_entry_t * entry)
+static void drm_cleanup_buf_error(struct drm_device * dev,
+ struct drm_buf_entry * entry)
{
int i;
/**
* Add AGP buffers for DMA transfers.
*
- * \param dev drm_device_t to which the buffers are to be added.
- * \param request pointer to a drm_buf_desc_t describing the request.
+ * \param dev struct drm_device to which the buffers are to be added.
+ * \param request pointer to a struct drm_buf_desc describing the request.
* \return zero on success or a negative number on failure.
*
* After some sanity checks creates a drm_buf structure for each buffer and
* reallocates the buffer list of the same size order to accommodate the new
* buffers.
*/
-int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request)
+int drm_addbufs_agp(struct drm_device * dev, struct drm_buf_desc * request)
{
- drm_device_dma_t *dma = dev->dma;
- drm_buf_entry_t *entry;
- drm_buf_t *buf;
+ struct drm_device_dma *dma = dev->dma;
+ struct drm_buf_entry *entry;
+ struct drm_agp_mem *agp_entry;
+ struct drm_buf *buf;
unsigned long offset;
unsigned long agp_offset;
int count;
int page_order;
int total;
int byte_count;
- int i;
- drm_buf_t **temp_buflist;
+ int i, valid;
+ struct drm_buf **temp_buflist;
if (!dma)
return -EINVAL;
if (dev->queue_count)
return -EBUSY; /* Not while in use */
+ /* Make sure buffers are located in AGP memory that we own */
+ valid = 0;
+ list_for_each_entry(agp_entry, &dev->agp->memory, head) {
+ if ((agp_offset >= agp_entry->bound) &&
+ (agp_offset + total * count <= agp_entry->bound + agp_entry->pages * PAGE_SIZE)) {
+ valid = 1;
+ break;
+ }
+ }
+ if (!list_empty(&dev->agp->memory) && !valid) {
+ DRM_DEBUG("zone invalid\n");
+ return -EINVAL;
+ }
spin_lock(&dev->count_lock);
if (dev->buf_use) {
spin_unlock(&dev->count_lock);
buf->waiting = 0;
buf->pending = 0;
init_waitqueue_head(&buf->dma_wait);
- buf->filp = NULL;
+ buf->file_priv = NULL;
buf->dev_priv_size = dev->driver->dev_priv_size;
buf->dev_private = drm_alloc(buf->dev_priv_size, DRM_MEM_BUFS);
EXPORT_SYMBOL(drm_addbufs_agp);
#endif /* __OS_HAS_AGP */
-int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request)
+int drm_addbufs_pci(struct drm_device * dev, struct drm_buf_desc * request)
{
- drm_device_dma_t *dma = dev->dma;
+ struct drm_device_dma *dma = dev->dma;
int count;
int order;
int size;
int total;
int page_order;
- drm_buf_entry_t *entry;
+ struct drm_buf_entry *entry;
drm_dma_handle_t *dmah;
- drm_buf_t *buf;
+ struct drm_buf *buf;
int alignment;
unsigned long offset;
int i;
int byte_count;
int page_count;
unsigned long *temp_pagelist;
- drm_buf_t **temp_buflist;
+ struct drm_buf **temp_buflist;
if (!drm_core_check_feature(dev, DRIVER_PCI_DMA))
return -EINVAL;
buf->waiting = 0;
buf->pending = 0;
init_waitqueue_head(&buf->dma_wait);
- buf->filp = NULL;
+ buf->file_priv = NULL;
buf->dev_priv_size = dev->driver->dev_priv_size;
buf->dev_private = drm_alloc(buf->dev_priv_size,
}
EXPORT_SYMBOL(drm_addbufs_pci);
-static int drm_addbufs_sg(drm_device_t * dev, drm_buf_desc_t * request)
+static int drm_addbufs_sg(struct drm_device * dev, struct drm_buf_desc * request)
{
- drm_device_dma_t *dma = dev->dma;
- drm_buf_entry_t *entry;
- drm_buf_t *buf;
+ struct drm_device_dma *dma = dev->dma;
+ struct drm_buf_entry *entry;
+ struct drm_buf *buf;
unsigned long offset;
unsigned long agp_offset;
int count;
int total;
int byte_count;
int i;
- drm_buf_t **temp_buflist;
+ struct drm_buf **temp_buflist;
if (!drm_core_check_feature(dev, DRIVER_SG))
return -EINVAL;
buf->waiting = 0;
buf->pending = 0;
init_waitqueue_head(&buf->dma_wait);
- buf->filp = NULL;
+ buf->file_priv = NULL;
buf->dev_priv_size = dev->driver->dev_priv_size;
buf->dev_private = drm_alloc(buf->dev_priv_size, DRM_MEM_BUFS);
return 0;
}
-static int drm_addbufs_fb(drm_device_t * dev, drm_buf_desc_t * request)
+static int drm_addbufs_fb(struct drm_device * dev, struct drm_buf_desc * request)
{
- drm_device_dma_t *dma = dev->dma;
- drm_buf_entry_t *entry;
- drm_buf_t *buf;
+ struct drm_device_dma *dma = dev->dma;
+ struct drm_buf_entry *entry;
+ struct drm_buf *buf;
unsigned long offset;
unsigned long agp_offset;
int count;
int total;
int byte_count;
int i;
- drm_buf_t **temp_buflist;
+ struct drm_buf **temp_buflist;
if (!drm_core_check_feature(dev, DRIVER_FB_DMA))
return -EINVAL;
buf->waiting = 0;
buf->pending = 0;
init_waitqueue_head(&buf->dma_wait);
- buf->filp = NULL;
+ buf->file_priv = NULL;
buf->dev_priv_size = dev->driver->dev_priv_size;
buf->dev_private = drm_alloc(buf->dev_priv_size, DRM_MEM_BUFS);
* Add buffers for DMA transfers (ioctl).
*
* \param inode device inode.
- * \param filp file pointer.
+ * \param file_priv DRM file private.
* \param cmd command.
- * \param arg pointer to a drm_buf_desc_t request.
+ * \param arg pointer to a struct drm_buf_desc request.
* \return zero on success or a negative number on failure.
*
* According with the memory type specified in drm_buf_desc::flags and the
* addbufs_sg() or addbufs_pci() for AGP, scatter-gather or consistent
* PCI memory respectively.
*/
-int drm_addbufs(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+int drm_addbufs(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
{
- drm_buf_desc_t request;
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->head->dev;
+ struct drm_buf_desc *request = data;
int ret;
if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA))
return -EINVAL;
- if (copy_from_user(&request, (drm_buf_desc_t __user *) arg,
- sizeof(request)))
- return -EFAULT;
-
#if __OS_HAS_AGP
- if (request.flags & _DRM_AGP_BUFFER)
- ret = drm_addbufs_agp(dev, &request);
+ if (request->flags & _DRM_AGP_BUFFER)
+ ret = drm_addbufs_agp(dev, request);
else
#endif
- if (request.flags & _DRM_SG_BUFFER)
- ret = drm_addbufs_sg(dev, &request);
- else if (request.flags & _DRM_FB_BUFFER)
- ret = drm_addbufs_fb(dev, &request);
+ if (request->flags & _DRM_SG_BUFFER)
+ ret = drm_addbufs_sg(dev, request);
+ else if (request->flags & _DRM_FB_BUFFER)
+ ret = drm_addbufs_fb(dev, request);
else
- ret = drm_addbufs_pci(dev, &request);
+ ret = drm_addbufs_pci(dev, request);
- if (ret == 0) {
- if (copy_to_user((void __user *)arg, &request, sizeof(request))) {
- ret = -EFAULT;
- }
- }
return ret;
}
* large buffers can be used for image transfer).
*
* \param inode device inode.
- * \param filp file pointer.
+ * \param file_priv DRM file private.
* \param cmd command.
* \param arg pointer to a drm_buf_info structure.
* \return zero on success or a negative number on failure.
* lock, preventing of allocating more buffers after this call. Information
* about each requested buffer is then copied into user space.
*/
-int drm_infobufs(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+int drm_infobufs(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->head->dev;
- drm_device_dma_t *dma = dev->dma;
- drm_buf_info_t request;
- drm_buf_info_t __user *argp = (void __user *)arg;
+ struct drm_device_dma *dma = dev->dma;
+ struct drm_buf_info *request = data;
int i;
int count;
++dev->buf_use; /* Can't allocate more after this call */
spin_unlock(&dev->count_lock);
- if (copy_from_user(&request, argp, sizeof(request)))
- return -EFAULT;
-
for (i = 0, count = 0; i < DRM_MAX_ORDER + 1; i++) {
if (dma->bufs[i].buf_count)
++count;
DRM_DEBUG("count = %d\n", count);
- if (request.count >= count) {
+ if (request->count >= count) {
for (i = 0, count = 0; i < DRM_MAX_ORDER + 1; i++) {
if (dma->bufs[i].buf_count) {
- drm_buf_desc_t __user *to =
- &request.list[count];
- drm_buf_entry_t *from = &dma->bufs[i];
- drm_freelist_t *list = &dma->bufs[i].freelist;
+ struct drm_buf_desc __user *to =
+ &request->list[count];
+ struct drm_buf_entry *from = &dma->bufs[i];
+ struct drm_freelist *list = &dma->bufs[i].freelist;
if (copy_to_user(&to->count,
&from->buf_count,
sizeof(from->buf_count)) ||
}
}
}
- request.count = count;
-
- if (copy_to_user(argp, &request, sizeof(request)))
- return -EFAULT;
+ request->count = count;
return 0;
}
* Specifies a low and high water mark for buffer allocation
*
* \param inode device inode.
- * \param filp file pointer.
+ * \param file_priv DRM file private.
* \param cmd command.
* \param arg a pointer to a drm_buf_desc structure.
* \return zero on success or a negative number on failure.
*
* \note This ioctl is deprecated and mostly never used.
*/
-int drm_markbufs(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+int drm_markbufs(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->head->dev;
- drm_device_dma_t *dma = dev->dma;
- drm_buf_desc_t request;
+ struct drm_device_dma *dma = dev->dma;
+ struct drm_buf_desc *request = data;
int order;
- drm_buf_entry_t *entry;
+ struct drm_buf_entry *entry;
if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA))
return -EINVAL;
if (!dma)
return -EINVAL;
- if (copy_from_user(&request,
- (drm_buf_desc_t __user *) arg, sizeof(request)))
- return -EFAULT;
-
DRM_DEBUG("%d, %d, %d\n",
- request.size, request.low_mark, request.high_mark);
- order = drm_order(request.size);
+ request->size, request->low_mark, request->high_mark);
+ order = drm_order(request->size);
if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER)
return -EINVAL;
entry = &dma->bufs[order];
- if (request.low_mark < 0 || request.low_mark > entry->buf_count)
+ if (request->low_mark < 0 || request->low_mark > entry->buf_count)
return -EINVAL;
- if (request.high_mark < 0 || request.high_mark > entry->buf_count)
+ if (request->high_mark < 0 || request->high_mark > entry->buf_count)
return -EINVAL;
- entry->freelist.low_mark = request.low_mark;
- entry->freelist.high_mark = request.high_mark;
+ entry->freelist.low_mark = request->low_mark;
+ entry->freelist.high_mark = request->high_mark;
return 0;
}
* Unreserve the buffers in list, previously reserved using drmDMA.
*
* \param inode device inode.
- * \param filp file pointer.
+ * \param file_priv DRM file private.
* \param cmd command.
* \param arg pointer to a drm_buf_free structure.
* \return zero on success or a negative number on failure.
* Calls free_buffer() for each used buffer.
* This function is primarily used for debugging.
*/
-int drm_freebufs(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+int drm_freebufs(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->head->dev;
- drm_device_dma_t *dma = dev->dma;
- drm_buf_free_t request;
+ struct drm_device_dma *dma = dev->dma;
+ struct drm_buf_free *request = data;
int i;
int idx;
- drm_buf_t *buf;
+ struct drm_buf *buf;
if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA))
return -EINVAL;
if (!dma)
return -EINVAL;
- if (copy_from_user(&request,
- (drm_buf_free_t __user *) arg, sizeof(request)))
- return -EFAULT;
-
- DRM_DEBUG("%d\n", request.count);
- for (i = 0; i < request.count; i++) {
- if (copy_from_user(&idx, &request.list[i], sizeof(idx)))
+ DRM_DEBUG("%d\n", request->count);
+ for (i = 0; i < request->count; i++) {
+ if (copy_from_user(&idx, &request->list[i], sizeof(idx)))
return -EFAULT;
if (idx < 0 || idx >= dma->buf_count) {
DRM_ERROR("Index %d (of %d max)\n",
return -EINVAL;
}
buf = dma->buflist[idx];
- if (buf->filp != filp) {
+ if (buf->file_priv != file_priv) {
DRM_ERROR("Process %d freeing buffer not owned\n",
- current->pid);
+ task_pid_nr(current));
return -EINVAL;
}
drm_free_buffer(dev, buf);
* Maps all of the DMA buffers into client-virtual space (ioctl).
*
* \param inode device inode.
- * \param filp file pointer.
+ * \param file_priv DRM file private.
* \param cmd command.
* \param arg pointer to a drm_buf_map structure.
* \return zero on success or a negative number on failure.
* offset equal to 0, which drm_mmap() interpretes as PCI buffers and calls
* drm_mmap_dma().
*/
-int drm_mapbufs(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+int drm_mapbufs(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->head->dev;
- drm_device_dma_t *dma = dev->dma;
- drm_buf_map_t __user *argp = (void __user *)arg;
+ struct drm_device_dma *dma = dev->dma;
int retcode = 0;
const int zero = 0;
unsigned long virtual;
unsigned long address;
- drm_buf_map_t request;
+ struct drm_buf_map *request = data;
int i;
if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA))
dev->buf_use++; /* Can't allocate more after this call */
spin_unlock(&dev->count_lock);
- if (copy_from_user(&request, argp, sizeof(request)))
- return -EFAULT;
-
- if (request.count >= dma->buf_count) {
+ if (request->count >= dma->buf_count) {
if ((drm_core_has_AGP(dev) && (dma->flags & _DRM_DMA_USE_AGP))
|| (drm_core_check_feature(dev, DRIVER_SG)
&& (dma->flags & _DRM_DMA_USE_SG))
|| (drm_core_check_feature(dev, DRIVER_FB_DMA)
&& (dma->flags & _DRM_DMA_USE_FB))) {
- drm_map_t *map = dev->agp_buffer_map;
+ struct drm_map *map = dev->agp_buffer_map;
unsigned long token = dev->agp_buffer_token;
if (!map) {
retcode = -EINVAL;
goto done;
}
-
down_write(¤t->mm->mmap_sem);
- virtual = do_mmap(filp, 0, map->size,
+ virtual = do_mmap(file_priv->filp, 0, map->size,
PROT_READ | PROT_WRITE,
- MAP_SHARED, token);
+ MAP_SHARED,
+ token);
up_write(¤t->mm->mmap_sem);
} else {
down_write(¤t->mm->mmap_sem);
- virtual = do_mmap(filp, 0, dma->byte_count,
+ virtual = do_mmap(file_priv->filp, 0, dma->byte_count,
PROT_READ | PROT_WRITE,
MAP_SHARED, 0);
up_write(¤t->mm->mmap_sem);
retcode = (signed long)virtual;
goto done;
}
- request.virtual = (void __user *)virtual;
+ request->virtual = (void __user *)virtual;
for (i = 0; i < dma->buf_count; i++) {
- if (copy_to_user(&request.list[i].idx,
+ if (copy_to_user(&request->list[i].idx,
&dma->buflist[i]->idx,
- sizeof(request.list[0].idx))) {
+ sizeof(request->list[0].idx))) {
retcode = -EFAULT;
goto done;
}
- if (copy_to_user(&request.list[i].total,
+ if (copy_to_user(&request->list[i].total,
&dma->buflist[i]->total,
- sizeof(request.list[0].total))) {
+ sizeof(request->list[0].total))) {
retcode = -EFAULT;
goto done;
}
- if (copy_to_user(&request.list[i].used,
+ if (copy_to_user(&request->list[i].used,
&zero, sizeof(zero))) {
retcode = -EFAULT;
goto done;
}
address = virtual + dma->buflist[i]->offset; /* *** */
- if (copy_to_user(&request.list[i].address,
+ if (copy_to_user(&request->list[i].address,
&address, sizeof(address))) {
retcode = -EFAULT;
goto done;
}
}
done:
- request.count = dma->buf_count;
- DRM_DEBUG("%d buffers, retcode = %d\n", request.count, retcode);
-
- if (copy_to_user(argp, &request, sizeof(request)))
- return -EFAULT;
+ request->count = dma->buf_count;
+ DRM_DEBUG("%d buffers, retcode = %d\n", request->count, retcode);
return retcode;
}