Merge 'drm-3264' branch of rsync://rsync.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6
This commit is contained in:
commit
8678887e7f
8 changed files with 1501 additions and 10 deletions
|
@ -19,6 +19,11 @@ radeon-objs := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o
|
|||
ffb-objs := ffb_drv.o ffb_context.o
|
||||
sis-objs := sis_drv.o sis_ds.o sis_mm.o
|
||||
|
||||
ifeq ($(CONFIG_COMPAT),y)
|
||||
drm-objs += drm_ioc32.o
|
||||
radeon-objs += radeon_ioc32.o
|
||||
endif
|
||||
|
||||
obj-$(CONFIG_DRM) += drm.o
|
||||
obj-$(CONFIG_DRM_GAMMA) += gamma.o
|
||||
obj-$(CONFIG_DRM_TDFX) += tdfx.o
|
||||
|
|
|
@ -316,6 +316,9 @@ do { \
|
|||
typedef int drm_ioctl_t( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg );
|
||||
|
||||
typedef int drm_ioctl_compat_t(struct file *filp, unsigned int cmd,
|
||||
unsigned long arg);
|
||||
|
||||
typedef struct drm_ioctl_desc {
|
||||
drm_ioctl_t *func;
|
||||
int auth_needed;
|
||||
|
@ -775,6 +778,8 @@ extern int drm_version(struct inode *inode, struct file *filp,
|
|||
unsigned int cmd, unsigned long arg);
|
||||
extern int drm_ioctl(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
extern long drm_compat_ioctl(struct file *filp,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
extern int drm_takedown(drm_device_t * dev);
|
||||
|
||||
/* Device support (drm_fops.h) */
|
||||
|
|
|
@ -60,6 +60,15 @@ int drm_order( unsigned long size )
|
|||
}
|
||||
EXPORT_SYMBOL(drm_order);
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
/*
|
||||
* Used to allocate 32-bit handles for _DRM_SHM regions
|
||||
* The 0x10000000 value is chosen to be out of the way of
|
||||
* FB/register and GART physical addresses.
|
||||
*/
|
||||
static unsigned int map32_handle = 0x10000000;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Ioctl to specify a range of memory that is available for mapping by a non-root process.
|
||||
*
|
||||
|
@ -187,16 +196,18 @@ int drm_addmap( struct inode *inode, struct file *filp,
|
|||
|
||||
down(&dev->struct_sem);
|
||||
list_add(&list->head, &dev->maplist->head);
|
||||
#ifdef CONFIG_COMPAT
|
||||
/* Assign a 32-bit handle for _DRM_SHM mappings */
|
||||
/* We do it here so that dev->struct_sem protects the increment */
|
||||
if (map->type == _DRM_SHM)
|
||||
map->offset = map32_handle += PAGE_SIZE;
|
||||
#endif
|
||||
up(&dev->struct_sem);
|
||||
|
||||
if ( copy_to_user( argp, map, sizeof(*map) ) )
|
||||
return -EFAULT;
|
||||
if ( map->type != _DRM_SHM ) {
|
||||
if ( copy_to_user( &argp->handle,
|
||||
&map->offset,
|
||||
sizeof(map->offset) ) )
|
||||
if (copy_to_user(&argp->handle, &map->offset, sizeof(map->offset)))
|
||||
return -EFAULT;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -240,7 +251,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->offset == (unsigned long) request.handle &&
|
||||
r_list->map->flags & _DRM_REMOVABLE) break;
|
||||
}
|
||||
|
||||
|
|
|
@ -225,7 +225,7 @@ int drm_getsareactx(struct inode *inode, struct file *filp,
|
|||
map = dev->context_sareas[request.ctx_id];
|
||||
up(&dev->struct_sem);
|
||||
|
||||
request.handle = map->handle;
|
||||
request.handle = (void *) map->offset;
|
||||
if (copy_to_user(argp, &request, sizeof(request)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
|
@ -261,8 +261,8 @@ int drm_setsareactx(struct inode *inode, struct file *filp,
|
|||
down(&dev->struct_sem);
|
||||
list_for_each(list, &dev->maplist->head) {
|
||||
r_list = list_entry(list, drm_map_list_t, head);
|
||||
if(r_list->map &&
|
||||
r_list->map->handle == request.handle)
|
||||
if (r_list->map
|
||||
&& r_list->map->offset == (unsigned long) request.handle)
|
||||
goto found;
|
||||
}
|
||||
bad:
|
||||
|
|
1069
drivers/char/drm/drm_ioc32.c
Normal file
1069
drivers/char/drm/drm_ioc32.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -101,6 +101,9 @@ static struct drm_driver driver = {
|
|||
.mmap = drm_mmap,
|
||||
.poll = drm_poll,
|
||||
.fasync = drm_fasync,
|
||||
#ifdef CONFIG_COMPAT
|
||||
.compat_ioctl = radeon_compat_ioctl,
|
||||
#endif
|
||||
},
|
||||
.pci_driver = {
|
||||
.name = DRIVER_NAME,
|
||||
|
|
|
@ -317,6 +317,9 @@ extern int radeon_preinit( struct drm_device *dev, unsigned long flags );
|
|||
extern int radeon_postinit( struct drm_device *dev, unsigned long flags );
|
||||
extern int radeon_postcleanup( struct drm_device *dev );
|
||||
|
||||
extern long radeon_compat_ioctl(struct file *filp, unsigned int cmd,
|
||||
unsigned long arg);
|
||||
|
||||
/* Flags for stats.boxes
|
||||
*/
|
||||
#define RADEON_BOX_DMA_IDLE 0x1
|
||||
|
|
395
drivers/char/drm/radeon_ioc32.c
Normal file
395
drivers/char/drm/radeon_ioc32.c
Normal file
|
@ -0,0 +1,395 @@
|
|||
/**
|
||||
* \file radeon_ioc32.c
|
||||
*
|
||||
* 32-bit ioctl compatibility routines for the Radeon DRM.
|
||||
*
|
||||
* \author Paul Mackerras <paulus@samba.org>
|
||||
*
|
||||
* Copyright (C) Paul Mackerras 2005
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
#include <linux/compat.h>
|
||||
#include <linux/ioctl32.h>
|
||||
|
||||
#include "drmP.h"
|
||||
#include "drm.h"
|
||||
#include "radeon_drm.h"
|
||||
#include "radeon_drv.h"
|
||||
|
||||
typedef struct drm_radeon_init32 {
|
||||
int func;
|
||||
u32 sarea_priv_offset;
|
||||
int is_pci;
|
||||
int cp_mode;
|
||||
int gart_size;
|
||||
int ring_size;
|
||||
int usec_timeout;
|
||||
|
||||
unsigned int fb_bpp;
|
||||
unsigned int front_offset, front_pitch;
|
||||
unsigned int back_offset, back_pitch;
|
||||
unsigned int depth_bpp;
|
||||
unsigned int depth_offset, depth_pitch;
|
||||
|
||||
u32 fb_offset;
|
||||
u32 mmio_offset;
|
||||
u32 ring_offset;
|
||||
u32 ring_rptr_offset;
|
||||
u32 buffers_offset;
|
||||
u32 gart_textures_offset;
|
||||
} drm_radeon_init32_t;
|
||||
|
||||
static int compat_radeon_cp_init(struct file *file, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
drm_radeon_init32_t init32;
|
||||
drm_radeon_init_t __user *init;
|
||||
|
||||
if (copy_from_user(&init32, (void __user *)arg, sizeof(init32)))
|
||||
return -EFAULT;
|
||||
|
||||
init = compat_alloc_user_space(sizeof(*init));
|
||||
if (!access_ok(VERIFY_WRITE, init, sizeof(*init))
|
||||
|| __put_user(init32.func, &init->func)
|
||||
|| __put_user(init32.sarea_priv_offset, &init->sarea_priv_offset)
|
||||
|| __put_user(init32.is_pci, &init->is_pci)
|
||||
|| __put_user(init32.cp_mode, &init->cp_mode)
|
||||
|| __put_user(init32.gart_size, &init->gart_size)
|
||||
|| __put_user(init32.ring_size, &init->ring_size)
|
||||
|| __put_user(init32.usec_timeout, &init->usec_timeout)
|
||||
|| __put_user(init32.fb_bpp, &init->fb_bpp)
|
||||
|| __put_user(init32.front_offset, &init->front_offset)
|
||||
|| __put_user(init32.front_pitch, &init->front_pitch)
|
||||
|| __put_user(init32.back_offset, &init->back_offset)
|
||||
|| __put_user(init32.back_pitch, &init->back_pitch)
|
||||
|| __put_user(init32.depth_bpp, &init->depth_bpp)
|
||||
|| __put_user(init32.depth_offset, &init->depth_offset)
|
||||
|| __put_user(init32.depth_pitch, &init->depth_pitch)
|
||||
|| __put_user(init32.fb_offset, &init->fb_offset)
|
||||
|| __put_user(init32.mmio_offset, &init->mmio_offset)
|
||||
|| __put_user(init32.ring_offset, &init->ring_offset)
|
||||
|| __put_user(init32.ring_rptr_offset, &init->ring_rptr_offset)
|
||||
|| __put_user(init32.buffers_offset, &init->buffers_offset)
|
||||
|| __put_user(init32.gart_textures_offset,
|
||||
&init->gart_textures_offset))
|
||||
return -EFAULT;
|
||||
|
||||
return drm_ioctl(file->f_dentry->d_inode, file,
|
||||
DRM_IOCTL_RADEON_CP_INIT, (unsigned long) init);
|
||||
}
|
||||
|
||||
typedef struct drm_radeon_clear32 {
|
||||
unsigned int flags;
|
||||
unsigned int clear_color;
|
||||
unsigned int clear_depth;
|
||||
unsigned int color_mask;
|
||||
unsigned int depth_mask; /* misnamed field: should be stencil */
|
||||
u32 depth_boxes;
|
||||
} drm_radeon_clear32_t;
|
||||
|
||||
static int compat_radeon_cp_clear(struct file *file, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
drm_radeon_clear32_t clr32;
|
||||
drm_radeon_clear_t __user *clr;
|
||||
|
||||
if (copy_from_user(&clr32, (void __user *)arg, sizeof(clr32)))
|
||||
return -EFAULT;
|
||||
|
||||
clr = compat_alloc_user_space(sizeof(*clr));
|
||||
if (!access_ok(VERIFY_WRITE, clr, sizeof(*clr))
|
||||
|| __put_user(clr32.flags, &clr->flags)
|
||||
|| __put_user(clr32.clear_color, &clr->clear_color)
|
||||
|| __put_user(clr32.clear_depth, &clr->clear_depth)
|
||||
|| __put_user(clr32.color_mask, &clr->color_mask)
|
||||
|| __put_user(clr32.depth_mask, &clr->depth_mask)
|
||||
|| __put_user((void __user *)(unsigned long)clr32.depth_boxes,
|
||||
&clr->depth_boxes))
|
||||
return -EFAULT;
|
||||
|
||||
return drm_ioctl(file->f_dentry->d_inode, file,
|
||||
DRM_IOCTL_RADEON_CLEAR, (unsigned long) clr);
|
||||
}
|
||||
|
||||
typedef struct drm_radeon_stipple32 {
|
||||
u32 mask;
|
||||
} drm_radeon_stipple32_t;
|
||||
|
||||
static int compat_radeon_cp_stipple(struct file *file, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
drm_radeon_stipple32_t __user *argp = (void __user *) arg;
|
||||
drm_radeon_stipple_t __user *request;
|
||||
u32 mask;
|
||||
|
||||
if (get_user(mask, &argp->mask))
|
||||
return -EFAULT;
|
||||
|
||||
request = compat_alloc_user_space(sizeof(*request));
|
||||
if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
|
||||
|| __put_user((unsigned int __user *)(unsigned long) mask,
|
||||
&request->mask))
|
||||
return -EFAULT;
|
||||
|
||||
return drm_ioctl(file->f_dentry->d_inode, file,
|
||||
DRM_IOCTL_RADEON_STIPPLE, (unsigned long) request);
|
||||
}
|
||||
|
||||
typedef struct drm_radeon_tex_image32 {
|
||||
unsigned int x, y; /* Blit coordinates */
|
||||
unsigned int width, height;
|
||||
u32 data;
|
||||
} drm_radeon_tex_image32_t;
|
||||
|
||||
typedef struct drm_radeon_texture32 {
|
||||
unsigned int offset;
|
||||
int pitch;
|
||||
int format;
|
||||
int width; /* Texture image coordinates */
|
||||
int height;
|
||||
u32 image;
|
||||
} drm_radeon_texture32_t;
|
||||
|
||||
static int compat_radeon_cp_texture(struct file *file, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
drm_radeon_texture32_t req32;
|
||||
drm_radeon_texture_t __user *request;
|
||||
drm_radeon_tex_image32_t img32;
|
||||
drm_radeon_tex_image_t __user *image;
|
||||
|
||||
if (copy_from_user(&req32, (void __user *) arg, sizeof(req32)))
|
||||
return -EFAULT;
|
||||
if (req32.image == 0)
|
||||
return -EINVAL;
|
||||
if (copy_from_user(&img32, (void __user *)(unsigned long)req32.image,
|
||||
sizeof(img32)))
|
||||
return -EFAULT;
|
||||
|
||||
request = compat_alloc_user_space(sizeof(*request) + sizeof(*image));
|
||||
if (!access_ok(VERIFY_WRITE, request,
|
||||
sizeof(*request) + sizeof(*image)))
|
||||
return -EFAULT;
|
||||
image = (drm_radeon_tex_image_t __user *) (request + 1);
|
||||
|
||||
if (__put_user(req32.offset, &request->offset)
|
||||
|| __put_user(req32.pitch, &request->pitch)
|
||||
|| __put_user(req32.format, &request->format)
|
||||
|| __put_user(req32.width, &request->width)
|
||||
|| __put_user(req32.height, &request->height)
|
||||
|| __put_user(image, &request->image)
|
||||
|| __put_user(img32.x, &image->x)
|
||||
|| __put_user(img32.y, &image->y)
|
||||
|| __put_user(img32.width, &image->width)
|
||||
|| __put_user(img32.height, &image->height)
|
||||
|| __put_user((const void __user *)(unsigned long)img32.data,
|
||||
&image->data))
|
||||
return -EFAULT;
|
||||
|
||||
return drm_ioctl(file->f_dentry->d_inode, file,
|
||||
DRM_IOCTL_RADEON_TEXTURE, (unsigned long) request);
|
||||
}
|
||||
|
||||
typedef struct drm_radeon_vertex2_32 {
|
||||
int idx; /* Index of vertex buffer */
|
||||
int discard; /* Client finished with buffer? */
|
||||
int nr_states;
|
||||
u32 state;
|
||||
int nr_prims;
|
||||
u32 prim;
|
||||
} drm_radeon_vertex2_32_t;
|
||||
|
||||
static int compat_radeon_cp_vertex2(struct file *file, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
drm_radeon_vertex2_32_t req32;
|
||||
drm_radeon_vertex2_t __user *request;
|
||||
|
||||
if (copy_from_user(&req32, (void __user *) arg, sizeof(req32)))
|
||||
return -EFAULT;
|
||||
|
||||
request = compat_alloc_user_space(sizeof(*request));
|
||||
if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
|
||||
|| __put_user(req32.idx, &request->idx)
|
||||
|| __put_user(req32.discard, &request->discard)
|
||||
|| __put_user(req32.nr_states, &request->nr_states)
|
||||
|| __put_user((void __user *)(unsigned long)req32.state,
|
||||
&request->state)
|
||||
|| __put_user(req32.nr_prims, &request->nr_prims)
|
||||
|| __put_user((void __user *)(unsigned long)req32.prim,
|
||||
&request->prim))
|
||||
return -EFAULT;
|
||||
|
||||
return drm_ioctl(file->f_dentry->d_inode, file,
|
||||
DRM_IOCTL_RADEON_VERTEX2, (unsigned long) request);
|
||||
}
|
||||
|
||||
typedef struct drm_radeon_cmd_buffer32 {
|
||||
int bufsz;
|
||||
u32 buf;
|
||||
int nbox;
|
||||
u32 boxes;
|
||||
} drm_radeon_cmd_buffer32_t;
|
||||
|
||||
static int compat_radeon_cp_cmdbuf(struct file *file, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
drm_radeon_cmd_buffer32_t req32;
|
||||
drm_radeon_cmd_buffer_t __user *request;
|
||||
|
||||
if (copy_from_user(&req32, (void __user *) arg, sizeof(req32)))
|
||||
return -EFAULT;
|
||||
|
||||
request = compat_alloc_user_space(sizeof(*request));
|
||||
if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
|
||||
|| __put_user(req32.bufsz, &request->bufsz)
|
||||
|| __put_user((void __user *)(unsigned long)req32.buf,
|
||||
&request->buf)
|
||||
|| __put_user(req32.nbox, &request->nbox)
|
||||
|| __put_user((void __user *)(unsigned long)req32.boxes,
|
||||
&request->boxes))
|
||||
return -EFAULT;
|
||||
|
||||
return drm_ioctl(file->f_dentry->d_inode, file,
|
||||
DRM_IOCTL_RADEON_CMDBUF, (unsigned long) request);
|
||||
}
|
||||
|
||||
typedef struct drm_radeon_getparam32 {
|
||||
int param;
|
||||
u32 value;
|
||||
} drm_radeon_getparam32_t;
|
||||
|
||||
static int compat_radeon_cp_getparam(struct file *file, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
drm_radeon_getparam32_t req32;
|
||||
drm_radeon_getparam_t __user *request;
|
||||
|
||||
if (copy_from_user(&req32, (void __user *) arg, sizeof(req32)))
|
||||
return -EFAULT;
|
||||
|
||||
request = compat_alloc_user_space(sizeof(*request));
|
||||
if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
|
||||
|| __put_user(req32.param, &request->param)
|
||||
|| __put_user((void __user *)(unsigned long)req32.value,
|
||||
&request->value))
|
||||
return -EFAULT;
|
||||
|
||||
return drm_ioctl(file->f_dentry->d_inode, file,
|
||||
DRM_IOCTL_RADEON_GETPARAM, (unsigned long) request);
|
||||
}
|
||||
|
||||
typedef struct drm_radeon_mem_alloc32 {
|
||||
int region;
|
||||
int alignment;
|
||||
int size;
|
||||
u32 region_offset; /* offset from start of fb or GART */
|
||||
} drm_radeon_mem_alloc32_t;
|
||||
|
||||
static int compat_radeon_mem_alloc(struct file *file, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
drm_radeon_mem_alloc32_t req32;
|
||||
drm_radeon_mem_alloc_t __user *request;
|
||||
|
||||
if (copy_from_user(&req32, (void __user *) arg, sizeof(req32)))
|
||||
return -EFAULT;
|
||||
|
||||
request = compat_alloc_user_space(sizeof(*request));
|
||||
if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
|
||||
|| __put_user(req32.region, &request->region)
|
||||
|| __put_user(req32.alignment, &request->alignment)
|
||||
|| __put_user(req32.size, &request->size)
|
||||
|| __put_user((int __user *)(unsigned long)req32.region_offset,
|
||||
&request->region_offset))
|
||||
return -EFAULT;
|
||||
|
||||
return drm_ioctl(file->f_dentry->d_inode, file,
|
||||
DRM_IOCTL_RADEON_ALLOC, (unsigned long) request);
|
||||
}
|
||||
|
||||
typedef struct drm_radeon_irq_emit32 {
|
||||
u32 irq_seq;
|
||||
} drm_radeon_irq_emit32_t;
|
||||
|
||||
static int compat_radeon_irq_emit(struct file *file, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
drm_radeon_irq_emit32_t req32;
|
||||
drm_radeon_irq_emit_t __user *request;
|
||||
|
||||
if (copy_from_user(&req32, (void __user *) arg, sizeof(req32)))
|
||||
return -EFAULT;
|
||||
|
||||
request = compat_alloc_user_space(sizeof(*request));
|
||||
if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
|
||||
|| __put_user((int __user *)(unsigned long)req32.irq_seq,
|
||||
&request->irq_seq))
|
||||
return -EFAULT;
|
||||
|
||||
return drm_ioctl(file->f_dentry->d_inode, file,
|
||||
DRM_IOCTL_RADEON_IRQ_EMIT, (unsigned long) request);
|
||||
}
|
||||
|
||||
drm_ioctl_compat_t *radeon_compat_ioctls[] = {
|
||||
[DRM_RADEON_CP_INIT] = compat_radeon_cp_init,
|
||||
[DRM_RADEON_CLEAR] = compat_radeon_cp_clear,
|
||||
[DRM_RADEON_STIPPLE] = compat_radeon_cp_stipple,
|
||||
[DRM_RADEON_TEXTURE] = compat_radeon_cp_texture,
|
||||
[DRM_RADEON_VERTEX2] = compat_radeon_cp_vertex2,
|
||||
[DRM_RADEON_CMDBUF] = compat_radeon_cp_cmdbuf,
|
||||
[DRM_RADEON_GETPARAM] = compat_radeon_cp_getparam,
|
||||
[DRM_RADEON_ALLOC] = compat_radeon_mem_alloc,
|
||||
[DRM_RADEON_IRQ_EMIT] = compat_radeon_irq_emit,
|
||||
};
|
||||
|
||||
/**
|
||||
* Called whenever a 32-bit process running under a 64-bit kernel
|
||||
* performs an ioctl on /dev/dri/card<n>.
|
||||
*
|
||||
* \param filp file pointer.
|
||||
* \param cmd command.
|
||||
* \param arg user argument.
|
||||
* \return zero on success or negative number on failure.
|
||||
*/
|
||||
long radeon_compat_ioctl(struct file *filp, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
unsigned int nr = DRM_IOCTL_NR(cmd);
|
||||
drm_ioctl_compat_t *fn = NULL;
|
||||
int ret;
|
||||
|
||||
if (nr < DRM_COMMAND_BASE)
|
||||
return drm_compat_ioctl(filp, cmd, arg);
|
||||
|
||||
if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(radeon_compat_ioctls))
|
||||
fn = radeon_compat_ioctls[nr - DRM_COMMAND_BASE];
|
||||
|
||||
lock_kernel(); /* XXX for now */
|
||||
if (fn != NULL)
|
||||
ret = (*fn)(filp, cmd, arg);
|
||||
else
|
||||
ret = drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
|
||||
unlock_kernel();
|
||||
|
||||
return ret;
|
||||
}
|
Reference in a new issue