Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
8678887e
Commit
8678887e
authored
Jun 26, 2005
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge 'drm-3264' branch of
rsync://rsync.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6
parents
bf82322e
9a186645
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
1501 additions
and
10 deletions
+1501
-10
drivers/char/drm/Makefile
drivers/char/drm/Makefile
+5
-0
drivers/char/drm/drmP.h
drivers/char/drm/drmP.h
+5
-0
drivers/char/drm/drm_bufs.c
drivers/char/drm/drm_bufs.c
+18
-7
drivers/char/drm/drm_context.c
drivers/char/drm/drm_context.c
+3
-3
drivers/char/drm/drm_ioc32.c
drivers/char/drm/drm_ioc32.c
+1069
-0
drivers/char/drm/radeon_drv.c
drivers/char/drm/radeon_drv.c
+3
-0
drivers/char/drm/radeon_drv.h
drivers/char/drm/radeon_drv.h
+3
-0
drivers/char/drm/radeon_ioc32.c
drivers/char/drm/radeon_ioc32.c
+395
-0
No files found.
drivers/char/drm/Makefile
View file @
8678887e
...
...
@@ -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
...
...
drivers/char/drm/drmP.h
View file @
8678887e
...
...
@@ -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) */
...
...
drivers/char/drm/drm_bufs.c
View file @
8678887e
...
...
@@ -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
)
)
)
return
-
EFAULT
;
}
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
;
}
...
...
drivers/char/drm/drm_context.c
View file @
8678887e
...
...
@@ -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:
...
...
drivers/char/drm/drm_ioc32.c
0 → 100644
View file @
8678887e
/**
* \file drm_ioc32.c
*
* 32-bit ioctl compatibility routines for the 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_core.h"
#define DRM_IOCTL_VERSION32 DRM_IOWR(0x00, drm_version32_t)
#define DRM_IOCTL_GET_UNIQUE32 DRM_IOWR(0x01, drm_unique32_t)
#define DRM_IOCTL_GET_MAP32 DRM_IOWR(0x04, drm_map32_t)
#define DRM_IOCTL_GET_CLIENT32 DRM_IOWR(0x05, drm_client32_t)
#define DRM_IOCTL_GET_STATS32 DRM_IOR( 0x06, drm_stats32_t)
#define DRM_IOCTL_SET_UNIQUE32 DRM_IOW( 0x10, drm_unique32_t)
#define DRM_IOCTL_ADD_MAP32 DRM_IOWR(0x15, drm_map32_t)
#define DRM_IOCTL_ADD_BUFS32 DRM_IOWR(0x16, drm_buf_desc32_t)
#define DRM_IOCTL_MARK_BUFS32 DRM_IOW( 0x17, drm_buf_desc32_t)
#define DRM_IOCTL_INFO_BUFS32 DRM_IOWR(0x18, drm_buf_info32_t)
#define DRM_IOCTL_MAP_BUFS32 DRM_IOWR(0x19, drm_buf_map32_t)
#define DRM_IOCTL_FREE_BUFS32 DRM_IOW( 0x1a, drm_buf_free32_t)
#define DRM_IOCTL_RM_MAP32 DRM_IOW( 0x1b, drm_map32_t)
#define DRM_IOCTL_SET_SAREA_CTX32 DRM_IOW( 0x1c, drm_ctx_priv_map32_t)
#define DRM_IOCTL_GET_SAREA_CTX32 DRM_IOWR(0x1d, drm_ctx_priv_map32_t)
#define DRM_IOCTL_RES_CTX32 DRM_IOWR(0x26, drm_ctx_res32_t)
#define DRM_IOCTL_DMA32 DRM_IOWR(0x29, drm_dma32_t)
#define DRM_IOCTL_AGP_ENABLE32 DRM_IOW( 0x32, drm_agp_mode32_t)
#define DRM_IOCTL_AGP_INFO32 DRM_IOR( 0x33, drm_agp_info32_t)
#define DRM_IOCTL_AGP_ALLOC32 DRM_IOWR(0x34, drm_agp_buffer32_t)
#define DRM_IOCTL_AGP_FREE32 DRM_IOW( 0x35, drm_agp_buffer32_t)
#define DRM_IOCTL_AGP_BIND32 DRM_IOW( 0x36, drm_agp_binding32_t)
#define DRM_IOCTL_AGP_UNBIND32 DRM_IOW( 0x37, drm_agp_binding32_t)
#define DRM_IOCTL_SG_ALLOC32 DRM_IOW( 0x38, drm_scatter_gather32_t)
#define DRM_IOCTL_SG_FREE32 DRM_IOW( 0x39, drm_scatter_gather32_t)
#define DRM_IOCTL_WAIT_VBLANK32 DRM_IOWR(0x3a, drm_wait_vblank32_t)
typedef
struct
drm_version_32
{
int
version_major
;
/**< Major version */
int
version_minor
;
/**< Minor version */
int
version_patchlevel
;
/**< Patch level */
u32
name_len
;
/**< Length of name buffer */
u32
name
;
/**< Name of driver */
u32
date_len
;
/**< Length of date buffer */
u32
date
;
/**< User-space buffer to hold date */
u32
desc_len
;
/**< Length of desc buffer */
u32
desc
;
/**< User-space buffer to hold desc */
}
drm_version32_t
;
static
int
compat_drm_version
(
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
drm_version32_t
v32
;
drm_version_t
__user
*
version
;
int
err
;
if
(
copy_from_user
(
&
v32
,
(
void
__user
*
)
arg
,
sizeof
(
v32
)))
return
-
EFAULT
;
version
=
compat_alloc_user_space
(
sizeof
(
*
version
));
if
(
!
access_ok
(
VERIFY_WRITE
,
version
,
sizeof
(
*
version
)))
return
-
EFAULT
;
if
(
__put_user
(
v32
.
name_len
,
&
version
->
name_len
)
||
__put_user
((
void
__user
*
)(
unsigned
long
)
v32
.
name
,
&
version
->
name
)
||
__put_user
(
v32
.
date_len
,
&
version
->
date_len
)
||
__put_user
((
void
__user
*
)(
unsigned
long
)
v32
.
date
,
&
version
->
date
)
||
__put_user
(
v32
.
desc_len
,
&
version
->
desc_len
)
||
__put_user
((
void
__user
*
)(
unsigned
long
)
v32
.
desc
,
&
version
->
desc
))
return
-
EFAULT
;
err
=
drm_ioctl
(
file
->
f_dentry
->
d_inode
,
file
,
DRM_IOCTL_VERSION
,
(
unsigned
long
)
version
);
if
(
err
)
return
err
;
if
(
__get_user
(
v32
.
version_major
,
&
version
->
version_major
)
||
__get_user
(
v32
.
version_minor
,
&
version
->
version_minor
)
||
__get_user
(
v32
.
version_patchlevel
,
&
version
->
version_patchlevel
)
||
__get_user
(
v32
.
name_len
,
&
version
->
name_len
)
||
__get_user
(
v32
.
date_len
,
&
version
->
date_len
)
||
__get_user
(
v32
.
desc_len
,
&
version
->
desc_len
))
return
-
EFAULT
;
if
(
copy_to_user
((
void
__user
*
)
arg
,
&
v32
,
sizeof
(
v32
)))
return
-
EFAULT
;
return
0
;
}
typedef
struct
drm_unique32
{
u32
unique_len
;
/**< Length of unique */
u32
unique
;
/**< Unique name for driver instantiation */
}
drm_unique32_t
;
static
int
compat_drm_getunique
(
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
drm_unique32_t
uq32
;
drm_unique_t
__user
*
u
;
int
err
;
if
(
copy_from_user
(
&
uq32
,
(
void
__user
*
)
arg
,
sizeof
(
uq32
)))
return
-
EFAULT
;
u
=
compat_alloc_user_space
(
sizeof
(
*
u
));
if
(
!
access_ok
(
VERIFY_WRITE
,
u
,
sizeof
(
*
u
)))
return
-
EFAULT
;
if
(
__put_user
(
uq32
.
unique_len
,
&
u
->
unique_len
)
||
__put_user
((
void
__user
*
)(
unsigned
long
)
uq32
.
unique
,
&
u
->
unique
))
return
-
EFAULT
;
err
=
drm_ioctl
(
file
->
f_dentry
->
d_inode
,
file
,
DRM_IOCTL_GET_UNIQUE
,
(
unsigned
long
)
u
);
if
(
err
)
return
err
;
if
(
__get_user
(
uq32
.
unique_len
,
&
u
->
unique_len
))
return
-
EFAULT
;
if
(
copy_to_user
((
void
__user
*
)
arg
,
&
uq32
,
sizeof
(
uq32
)))
return
-
EFAULT
;
return
0
;
}
static
int
compat_drm_setunique
(
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
drm_unique32_t
uq32
;
drm_unique_t
__user
*
u
;
if
(
copy_from_user
(
&
uq32
,
(
void
__user
*
)
arg
,
sizeof
(
uq32
)))
return
-
EFAULT
;
u
=
compat_alloc_user_space
(
sizeof
(
*
u
));
if
(
!
access_ok
(
VERIFY_WRITE
,
u
,
sizeof
(
*
u
)))
return
-
EFAULT
;
if
(
__put_user
(
uq32
.
unique_len
,
&
u
->
unique_len
)
||
__put_user
((
void
__user
*
)(
unsigned
long
)
uq32
.
unique
,
&
u
->
unique
))
return
-
EFAULT
;
return
drm_ioctl
(
file
->
f_dentry
->
d_inode
,
file
,
DRM_IOCTL_SET_UNIQUE
,
(
unsigned
long
)
u
);
}
typedef
struct
drm_map32
{
u32
offset
;
/**< Requested physical address (0 for SAREA)*/
u32
size
;
/**< Requested physical size (bytes) */
drm_map_type_t
type
;
/**< Type of memory to map */
drm_map_flags_t
flags
;
/**< Flags */
u32
handle
;
/**< User-space: "Handle" to pass to mmap() */
int
mtrr
;
/**< MTRR slot used */
}
drm_map32_t
;
static
int
compat_drm_getmap
(
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
drm_map32_t
__user
*
argp
=
(
void
__user
*
)
arg
;
drm_map32_t
m32
;
drm_map_t
__user
*
map
;
int
idx
,
err
;
void
*
handle
;
if
(
get_user
(
idx
,
&
argp
->
offset
))
return
-
EFAULT
;
map
=
compat_alloc_user_space
(
sizeof
(
*
map
));
if
(
!
access_ok
(
VERIFY_WRITE
,
map
,
sizeof
(
*
map
)))
return
-
EFAULT
;
if
(
__put_user
(
idx
,
&
map
->
offset
))
return
-
EFAULT
;
err
=
drm_ioctl
(
file
->
f_dentry
->
d_inode
,
file
,
DRM_IOCTL_GET_MAP
,
(
unsigned
long
)
map
);
if
(
err
)
return
err
;
if
(
__get_user
(
m32
.
offset
,
&
map
->
offset
)
||
__get_user
(
m32
.
size
,
&
map
->
size
)
||
__get_user
(
m32
.
type
,
&
map
->
type
)
||
__get_user
(
m32
.
flags
,
&
map
->
flags
)
||
__get_user
(
handle
,
&
map
->
handle
)
||
__get_user
(
m32
.
mtrr
,
&
map
->
mtrr
))
return
-
EFAULT
;
m32
.
handle
=
(
unsigned
long
)
handle
;
if
(
copy_to_user
(
argp
,
&
m32
,
sizeof
(
m32
)))
return
-
EFAULT
;
return
0
;
}
static
int
compat_drm_addmap
(
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
drm_map32_t
__user
*
argp
=
(
void
__user
*
)
arg
;
drm_map32_t
m32
;
drm_map_t
__user
*
map
;
int
err
;
void
*
handle
;
if
(
copy_from_user
(
&
m32
,
argp
,
sizeof
(
m32
)))
return
-
EFAULT
;
map
=
compat_alloc_user_space
(
sizeof
(
*
map
));
if
(
!
access_ok
(
VERIFY_WRITE
,
map
,
sizeof
(
*
map
)))
return
-
EFAULT
;
if
(
__put_user
(
m32
.
offset
,
&
map
->
offset
)
||
__put_user
(
m32
.
size
,
&
map
->
size
)
||
__put_user
(
m32
.
type
,
&
map
->
type
)
||
__put_user
(
m32
.
flags
,
&
map
->
flags
))
return
-
EFAULT
;
err
=
drm_ioctl
(
file
->
f_dentry
->
d_inode
,
file
,
DRM_IOCTL_ADD_MAP
,
(
unsigned
long
)
map
);
if
(
err
)
return
err
;
if
(
__get_user
(
m32
.
offset
,
&
map
->
offset
)
||
__get_user
(
m32
.
mtrr
,
&
map
->
mtrr
)
||
__get_user
(
handle
,
&
map
->
handle
))
return
-
EFAULT
;
m32
.
handle
=
(
unsigned
long
)
handle
;
if
(
m32
.
handle
!=
(
unsigned
long
)
handle
&&
printk_ratelimit
())
printk
(
KERN_ERR
"compat_drm_addmap truncated handle"
" %p for type %d offset %x
\n
"
,
handle
,
m32
.
type
,
m32
.
offset
);
if
(
copy_to_user
(
argp
,
&
m32
,
sizeof
(
m32
)))
return
-
EFAULT
;
return
0
;
}
static
int
compat_drm_rmmap
(
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
drm_map32_t
__user
*
argp
=
(
void
__user
*
)
arg
;
drm_map_t
__user
*
map
;
u32
handle
;
if
(
get_user
(
handle
,
&
argp
->
handle
))
return
-
EFAULT
;
map
=
compat_alloc_user_space
(
sizeof
(
*
map
));
if
(
!
access_ok
(
VERIFY_WRITE
,
map
,
sizeof
(
*
map
)))
return
-
EFAULT
;
if
(
__put_user
((
void
*
)(
unsigned
long
)
handle
,
&
map
->
handle
))
return
-
EFAULT
;
return
drm_ioctl
(
file
->
f_dentry
->
d_inode
,
file
,
DRM_IOCTL_RM_MAP
,
(
unsigned
long
)
map
);
}
typedef
struct
drm_client32
{
int
idx
;
/**< Which client desired? */
int
auth
;
/**< Is client authenticated? */
u32
pid
;
/**< Process ID */
u32
uid
;
/**< User ID */
u32
magic
;
/**< Magic */
u32
iocs
;
/**< Ioctl count */
}
drm_client32_t
;
static
int
compat_drm_getclient
(
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
drm_client32_t
c32
;
drm_client32_t
__user
*
argp
=
(
void
__user
*
)
arg
;
drm_client_t
__user
*
client
;
int
idx
,
err
;
if
(
get_user
(
idx
,
&
argp
->
idx
))
return
-
EFAULT
;
client
=
compat_alloc_user_space
(
sizeof
(
*
client
));
if
(
!
access_ok
(
VERIFY_WRITE
,
client
,
sizeof
(
*
client
)))
return
-
EFAULT
;
if
(
__put_user
(
idx
,
&
client
->
idx
))
return
-
EFAULT
;
err
=
drm_ioctl
(
file
->
f_dentry
->
d_inode
,
file
,
DRM_IOCTL_GET_CLIENT
,
(
unsigned
long
)
client
);
if
(
err
)
return
err
;
if
(
__get_user
(
c32
.
auth
,
&
client
->
auth
)
||
__get_user
(
c32
.
pid
,
&
client
->
pid
)
||
__get_user
(
c32
.
uid
,
&
client
->
uid
)
||
__get_user
(
c32
.
magic
,
&
client
->
magic
)
||
__get_user
(
c32
.
iocs
,
&
client
->
iocs
))
return
-
EFAULT
;
if
(
copy_to_user
(
argp
,
&
c32
,
sizeof
(
c32
)))
return
-
EFAULT
;
return
0
;
}
typedef
struct
drm_stats32
{
u32
count
;
struct
{
u32
value
;
drm_stat_type_t
type
;
}
data
[
15
];
}
drm_stats32_t
;
static
int
compat_drm_getstats
(
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
drm_stats32_t
s32
;
drm_stats32_t
__user
*
argp
=
(
void
__user
*
)
arg
;
drm_stats_t
__user
*
stats
;
int
i
,
err
;
stats
=
compat_alloc_user_space
(
sizeof
(
*
stats
));
if
(
!
access_ok
(
VERIFY_WRITE
,
stats
,
sizeof
(
*
stats
)))
return
-
EFAULT
;
err
=
drm_ioctl
(
file
->
f_dentry
->
d_inode
,
file
,
DRM_IOCTL_GET_STATS
,
(
unsigned
long
)
stats
);
if
(
err
)
return
err
;
if
(
__get_user
(
s32
.
count
,
&
stats
->
count
))
return
-
EFAULT
;
for
(
i
=
0
;
i
<
15
;
++
i
)
if
(
__get_user
(
s32
.
data
[
i
].
value
,
&
stats
->
data
[
i
].
value
)
||
__get_user
(
s32
.
data
[
i
].
type
,
&
stats
->
data
[
i
].
type
))
return
-
EFAULT
;
if
(
copy_to_user
(
argp
,
&
s32
,
sizeof
(
s32
)))
return
-
EFAULT
;
return
0
;
}
typedef
struct
drm_buf_desc32
{
int
count
;
/**< Number of buffers of this size */
int
size
;
/**< Size in bytes */
int
low_mark
;
/**< Low water mark */
int
high_mark
;
/**< High water mark */
int
flags
;
u32
agp_start
;
/**< Start address in the AGP aperture */
}
drm_buf_desc32_t
;
static
int
compat_drm_addbufs
(
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
drm_buf_desc32_t
__user
*
argp
=
(
void
__user
*
)
arg
;
drm_buf_desc_t
__user
*
buf
;
int
err
;
unsigned
long
agp_start
;
buf
=
compat_alloc_user_space
(
sizeof
(
*
buf
));
if
(
!
access_ok
(
VERIFY_WRITE
,
buf
,
sizeof
(
*
buf
))
||
!
access_ok
(
VERIFY_WRITE
,
argp
,
sizeof
(
*
argp
)))
return
-
EFAULT
;
if
(
__copy_in_user
(
buf
,
argp
,
offsetof
(
drm_buf_desc32_t
,
agp_start
))
||
__get_user
(
agp_start
,
&
argp
->
agp_start
)
||
__put_user
(
agp_start
,
&
buf
->
agp_start
))
return
-
EFAULT
;
err
=
drm_ioctl
(
file
->
f_dentry
->
d_inode
,
file
,
DRM_IOCTL_ADD_BUFS
,
(
unsigned
long
)
buf
);
if
(
err
)
return
err
;
if
(
__copy_in_user
(
argp
,
buf
,
offsetof
(
drm_buf_desc32_t
,
agp_start
))
||
__get_user
(
agp_start
,
&
buf
->
agp_start
)
||
__put_user
(
agp_start
,
&
argp
->
agp_start
))
return
-
EFAULT
;
return
0
;
}
static
int
compat_drm_markbufs
(
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
drm_buf_desc32_t
b32
;
drm_buf_desc32_t
__user
*
argp
=
(
void
__user
*
)
arg
;
drm_buf_desc_t
__user
*
buf
;
if
(
copy_from_user
(
&
b32
,
argp
,
sizeof
(
b32
)))
return
-
EFAULT
;
buf
=
compat_alloc_user_space
(
sizeof
(
*
buf
));
if
(
!
access_ok
(
VERIFY_WRITE
,
buf
,
sizeof
(
*
buf
)))
return
-
EFAULT
;
if
(
__put_user
(
b32
.
size
,
&
buf
->
size
)
||
__put_user
(
b32
.
low_mark
,
&
buf
->
low_mark
)
||
__put_user
(
b32
.
high_mark
,
&
buf
->
high_mark
))
return
-
EFAULT
;
return
drm_ioctl
(
file
->
f_dentry
->
d_inode
,
file
,
DRM_IOCTL_MARK_BUFS
,
(
unsigned
long
)
buf
);
}
typedef
struct
drm_buf_info32
{
int
count
;
/**< Entries in list */
u32
list
;
}
drm_buf_info32_t
;
static
int
compat_drm_infobufs
(
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
drm_buf_info32_t
req32
;
drm_buf_info32_t
__user
*
argp
=
(
void
__user
*
)
arg
;
drm_buf_desc32_t
__user
*
to
;
drm_buf_info_t
__user
*
request
;
drm_buf_desc_t
__user
*
list
;
size_t
nbytes
;
int
i
,
err
;
int
count
,
actual
;
if
(
copy_from_user
(
&
req32
,
argp
,
sizeof
(
req32
)))
return
-
EFAULT
;
count
=
req32
.
count
;
to
=
(
drm_buf_desc32_t
__user
*
)(
unsigned
long
)
req32
.
list
;
if
(
count
<
0
)
count
=
0
;
if
(
count
>
0
&&
!
access_ok
(
VERIFY_WRITE
,
to
,
count
*
sizeof
(
drm_buf_desc32_t
)))
return
-
EFAULT
;
nbytes
=
sizeof
(
*
request
)
+
count
*
sizeof
(
drm_buf_desc_t
);
request
=
compat_alloc_user_space
(
nbytes
);
if
(
!
access_ok
(
VERIFY_WRITE
,
request
,
nbytes
))
return
-
EFAULT
;
list
=
(
drm_buf_desc_t
*
)
(
request
+
1
);
if
(
__put_user
(
count
,
&
request
->
count
)
||
__put_user
(
list
,
&
request
->
list
))
return
-
EFAULT
;
err
=
drm_ioctl
(
file
->
f_dentry
->
d_inode
,
file
,
DRM_IOCTL_INFO_BUFS
,
(
unsigned
long
)
request
);
if
(
err
)
return
err
;
if
(
__get_user
(
actual
,
&
request
->
count
))
return
-
EFAULT
;
if
(
count
>=
actual
)
for
(
i
=
0
;
i
<
actual
;
++
i
)
if
(
__copy_in_user
(
&
to
[
i
],
&
list
[
i
],
offsetof
(
drm_buf_desc_t
,
flags
)))
return
-
EFAULT
;
if
(
__put_user
(
actual
,
&
argp
->
count
))
return
-
EFAULT
;
return
0
;
}
typedef
struct
drm_buf_pub32
{
int
idx
;
/**< Index into the master buffer list */
int
total
;
/**< Buffer size */
int
used
;
/**< Amount of buffer in use (for DMA) */
u32
address
;
/**< Address of buffer */
}
drm_buf_pub32_t
;
typedef
struct
drm_buf_map32
{
int
count
;
/**< Length of the buffer list */
u32
virtual
;
/**< Mmap'd area in user-virtual */
u32
list
;
/**< Buffer information */
}
drm_buf_map32_t
;
static
int
compat_drm_mapbufs
(
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
drm_buf_map32_t
__user
*
argp
=
(
void
__user
*
)
arg
;
drm_buf_map32_t
req32
;
drm_buf_pub32_t
__user
*
list32
;
drm_buf_map_t
__user
*
request
;
drm_buf_pub_t
__user
*
list
;
int
i
,
err
;
int
count
,
actual
;
size_t
nbytes
;
void
__user
*
addr
;
if
(
copy_from_user
(
&
req32
,
argp
,
sizeof
(
req32
)))
return
-
EFAULT
;
count
=
req32
.
count
;
list32
=
(
void
__user
*
)(
unsigned
long
)
req32
.
list
;
if
(
count
<
0
)
return
-
EINVAL
;
nbytes
=
sizeof
(
*
request
)
+
count
*
sizeof
(
drm_buf_pub_t
);
request
=
compat_alloc_user_space
(
nbytes
);
if
(
!
access_ok
(
VERIFY_WRITE
,
request
,
nbytes
))
return
-
EFAULT
;
list
=
(
drm_buf_pub_t
*
)
(
request
+
1
);
if
(
__put_user
(
count
,
&
request
->
count
)
||
__put_user
(
list
,
&
request
->
list
))
return
-
EFAULT
;
err
=
drm_ioctl
(
file
->
f_dentry
->
d_inode
,
file
,
DRM_IOCTL_MAP_BUFS
,
(
unsigned
long
)
request
);
if
(
err
)
return
err
;
if
(
__get_user
(
actual
,
&
request
->
count
))
return
-
EFAULT
;
if
(
count
>=
actual
)
for
(
i
=
0
;
i
<
actual
;
++
i
)
if
(
__copy_in_user
(
&
list32
[
i
],
&
list
[
i
],
offsetof
(
drm_buf_pub_t
,
address
))
||
__get_user
(
addr
,
&
list
[
i
].
address
)
||
__put_user
((
unsigned
long
)
addr
,
&
list32
[
i
].
address
))
return
-
EFAULT
;
if
(
__put_user
(
actual
,
&
argp
->
count
)
||
__get_user
(
addr
,
&
request
->
virtual
)
||
__put_user
((
unsigned
long
)
addr
,
&
argp
->
virtual
))
return
-
EFAULT
;
return
0
;
}
typedef
struct
drm_buf_free32
{
int
count
;
u32
list
;
}
drm_buf_free32_t
;
static
int
compat_drm_freebufs
(
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
drm_buf_free32_t
req32
;
drm_buf_free_t
__user
*
request
;
drm_buf_free32_t
__user
*
argp
=
(
void
__user
*
)
arg
;
if
(
copy_from_user
(
&
req32
,
argp
,
sizeof
(
req32
)))
return
-
EFAULT
;
request
=
compat_alloc_user_space
(
sizeof
(
*
request
));
if
(
!
access_ok
(
VERIFY_WRITE
,
request
,
sizeof
(
*
request
)))
return
-
EFAULT
;
if
(
__put_user
(
req32
.
count
,
&
request
->
count
)
||
__put_user
((
int
__user
*
)(
unsigned
long
)
req32
.
list
,
&
request
->
list
))
return
-
EFAULT
;
return
drm_ioctl
(
file
->
f_dentry
->
d_inode
,
file
,
DRM_IOCTL_FREE_BUFS
,
(
unsigned
long
)
request
);
}
typedef
struct
drm_ctx_priv_map32
{
unsigned
int
ctx_id
;
/**< Context requesting private mapping */
u32
handle
;
/**< Handle of map */
}
drm_ctx_priv_map32_t
;
static
int
compat_drm_setsareactx
(
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
drm_ctx_priv_map32_t
req32
;
drm_ctx_priv_map_t
__user
*
request
;
drm_ctx_priv_map32_t
__user
*
argp
=
(
void
__user
*
)
arg
;
if
(
copy_from_user
(
&
req32
,
argp
,
sizeof
(
req32
)))
return
-
EFAULT
;
request
=
compat_alloc_user_space
(
sizeof
(
*
request
));
if
(
!
access_ok
(
VERIFY_WRITE
,
request
,
sizeof
(
*
request
)))
return
-
EFAULT
;
if
(
__put_user
(
req32
.
ctx_id
,
&
request
->
ctx_id
)
||
__put_user
((
void
*
)(
unsigned
long
)
req32
.
handle
,
&
request
->
handle
))
return
-
EFAULT
;
return
drm_ioctl
(
file
->
f_dentry
->
d_inode
,
file
,
DRM_IOCTL_SET_SAREA_CTX
,
(
unsigned
long
)
request
);
}
static
int
compat_drm_getsareactx
(
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
drm_ctx_priv_map_t
__user
*
request
;
drm_ctx_priv_map32_t
__user
*
argp
=
(
void
__user
*
)
arg
;
int
err
;
unsigned
int
ctx_id
;
void
*
handle
;
if
(
!
access_ok
(
VERIFY_WRITE
,
argp
,
sizeof
(
*
argp
))
||
__get_user
(
ctx_id
,
&
argp
->
ctx_id
))
return
-
EFAULT
;
request
=
compat_alloc_user_space
(
sizeof
(
*
request
));
if
(
!
access_ok
(
VERIFY_WRITE
,
request
,
sizeof
(
*
request
)))
return
-
EFAULT
;
if
(
__put_user
(
ctx_id
,
&
request
->
ctx_id
))
return
-
EFAULT
;
err
=
drm_ioctl
(
file
->
f_dentry
->
d_inode
,
file
,
DRM_IOCTL_GET_SAREA_CTX
,
(
unsigned
long
)
request
);
if
(
err
)
return
err
;
if
(
__get_user
(
handle
,
&
request
->
handle
)
||
__put_user
((
unsigned
long
)
handle
,
&
argp
->
handle
))
return
-
EFAULT
;
return
0
;
}
typedef
struct
drm_ctx_res32
{
int
count
;
u32
contexts
;
}
drm_ctx_res32_t
;
static
int
compat_drm_resctx
(
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
drm_ctx_res32_t
__user
*
argp
=
(
void
__user
*
)
arg
;
drm_ctx_res32_t
res32
;
drm_ctx_res_t
__user
*
res
;
int
err
;
if
(
copy_from_user
(
&
res32
,
argp
,
sizeof
(
res32
)))
return
-
EFAULT
;
res
=
compat_alloc_user_space
(
sizeof
(
*
res
));
if
(
!
access_ok
(
VERIFY_WRITE
,
res
,
sizeof
(
*
res
)))
return
-
EFAULT
;
if
(
__put_user
(
res32
.
count
,
&
res
->
count
)
||
__put_user
((
drm_ctx_t
__user
*
)(
unsigned
long
)
res32
.
contexts
,
&
res
->
contexts
))
return
-
EFAULT
;
err
=
drm_ioctl
(
file
->
f_dentry
->
d_inode
,
file
,
DRM_IOCTL_RES_CTX
,
(
unsigned
long
)
res
);
if
(
err
)
return
err
;
if
(
__get_user
(
res32
.
count
,
&
res
->
count
)
||
__put_user
(
res32
.
count
,
&
argp
->
count
))
return
-
EFAULT
;
return
0
;
}
typedef
struct
drm_dma32
{
int
context
;
/**< Context handle */
int
send_count
;
/**< Number of buffers to send */
u32
send_indices
;
/**< List of handles to buffers */
u32
send_sizes
;
/**< Lengths of data to send */
drm_dma_flags_t
flags
;
/**< Flags */
int
request_count
;
/**< Number of buffers requested */
int
request_size
;
/**< Desired size for buffers */
u32
request_indices
;
/**< Buffer information */
u32
request_sizes
;
int
granted_count
;
/**< Number of buffers granted */
}
drm_dma32_t
;
static
int
compat_drm_dma
(
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
drm_dma32_t
d32
;
drm_dma32_t
__user
*
argp
=
(
void
__user
*
)
arg
;
drm_dma_t
__user
*
d
;
int
err
;
if
(
copy_from_user
(
&
d32
,
argp
,
sizeof
(
d32
)))
return
-
EFAULT
;
d
=
compat_alloc_user_space
(
sizeof
(
*
d
));
if
(
!
access_ok
(
VERIFY_WRITE
,
d
,
sizeof
(
*
d
)))
return
-
EFAULT
;
if
(
__put_user
(
d32
.
context
,
&
d
->
context
)
||
__put_user
(
d32
.
send_count
,
&
d
->
send_count
)
||
__put_user
((
int
__user
*
)(
unsigned
long
)
d32
.
send_indices
,
&
d
->
send_indices
)
||
__put_user
((
int
__user
*
)(
unsigned
long
)
d32
.
send_sizes
,
&
d
->
send_sizes
)
||
__put_user
(
d32
.
flags
,
&
d
->
flags
)
||
__put_user
(
d32
.
request_count
,
&
d
->
request_count
)
||
__put_user
((
int
__user
*
)(
unsigned
long
)
d32
.
request_indices
,
&
d
->
request_indices
)
||
__put_user
((
int
__user
*
)(
unsigned
long
)
d32
.
request_sizes
,
&
d
->
request_sizes
))
return
-
EFAULT
;
err
=
drm_ioctl
(
file
->
f_dentry
->
d_inode
,
file
,
DRM_IOCTL_DMA
,
(
unsigned
long
)
d
);
if
(
err
)
return
err
;
if
(
__get_user
(
d32
.
request_size
,
&
d
->
request_size
)
||
__get_user
(
d32
.
granted_count
,
&
d
->
granted_count
)
||
__put_user
(
d32
.
request_size
,
&
argp
->
request_size
)
||
__put_user
(
d32
.
granted_count
,
&
argp
->
granted_count
))
return
-
EFAULT
;
return
0
;
}
#if __OS_HAS_AGP
typedef
struct
drm_agp_mode32
{
u32
mode
;
/**< AGP mode */
}
drm_agp_mode32_t
;
static
int
compat_drm_agp_enable
(
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
drm_agp_mode32_t
__user
*
argp
=
(
void
__user
*
)
arg
;
drm_agp_mode32_t
m32
;
drm_agp_mode_t
__user
*
mode
;
if
(
get_user
(
m32
.
mode
,
&
argp
->
mode
))
return
-
EFAULT
;
mode
=
compat_alloc_user_space
(
sizeof
(
*
mode
));
if
(
put_user
(
m32
.
mode
,
&
mode
->
mode
))
return
-
EFAULT
;
return
drm_ioctl
(
file
->
f_dentry
->
d_inode
,
file
,
DRM_IOCTL_AGP_ENABLE
,
(
unsigned
long
)
mode
);
}
typedef
struct
drm_agp_info32
{
int
agp_version_major
;
int
agp_version_minor
;
u32
mode
;
u32
aperture_base
;
/* physical address */
u32
aperture_size
;
/* bytes */
u32
memory_allowed
;
/* bytes */
u32
memory_used
;
/* PCI information */
unsigned
short
id_vendor
;
unsigned
short
id_device
;
}
drm_agp_info32_t
;
static
int
compat_drm_agp_info
(
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
drm_agp_info32_t
__user
*
argp
=
(
void
__user
*
)
arg
;
drm_agp_info32_t
i32
;
drm_agp_info_t
__user
*
info
;
int
err
;
info
=
compat_alloc_user_space
(
sizeof
(
*
info
));
if
(
!
access_ok
(
VERIFY_WRITE
,
info
,
sizeof
(
*
info
)))
return
-
EFAULT
;
err
=
drm_ioctl
(
file
->
f_dentry
->
d_inode
,
file
,
DRM_IOCTL_AGP_INFO
,
(
unsigned
long
)
info
);
if
(
err
)
return
err
;
if
(
__get_user
(
i32
.
agp_version_major
,
&
info
->
agp_version_major
)
||
__get_user
(
i32
.
agp_version_minor
,
&
info
->
agp_version_minor
)
||
__get_user
(
i32
.
mode
,
&
info
->
mode
)
||
__get_user
(
i32
.
aperture_base
,
&
info
->
aperture_base
)
||
__get_user
(
i32
.
aperture_size
,
&
info
->
aperture_size
)
||
__get_user
(
i32
.
memory_allowed
,
&
info
->
memory_allowed
)
||
__get_user
(
i32
.
memory_used
,
&
info
->
memory_used
)
||
__get_user
(
i32
.
id_vendor
,
&
info
->
id_vendor
)
||
__get_user
(
i32
.
id_device
,
&
info
->
id_device
))
return
-
EFAULT
;
if
(
copy_to_user
(
argp
,
&
i32
,
sizeof
(
i32
)))
return
-
EFAULT
;
return
0
;
}
typedef
struct
drm_agp_buffer32
{
u32
size
;
/**< In bytes -- will round to page boundary */
u32
handle
;
/**< Used for binding / unbinding */
u32
type
;
/**< Type of memory to allocate */
u32
physical
;
/**< Physical used by i810 */
}
drm_agp_buffer32_t
;
static
int
compat_drm_agp_alloc
(
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
drm_agp_buffer32_t
__user
*
argp
=
(
void
__user
*
)
arg
;
drm_agp_buffer32_t
req32
;
drm_agp_buffer_t
__user
*
request
;
int
err
;
if
(
copy_from_user
(
&
req32
,
argp
,
sizeof
(
req32
)))
return
-
EFAULT
;
request
=
compat_alloc_user_space
(
sizeof
(
*
request
));
if
(
!
access_ok
(
VERIFY_WRITE
,
request
,
sizeof
(
*
request
))
||
__put_user
(
req32
.
size
,
&
request
->
size
)
||
__put_user
(
req32
.
type
,
&
request
->
type
))
return
-
EFAULT
;
err
=
drm_ioctl
(
file
->
f_dentry
->
d_inode
,
file
,
DRM_IOCTL_AGP_ALLOC
,
(
unsigned
long
)
request
);
if
(
err
)
return
err
;
if
(
__get_user
(
req32
.
handle
,
&
request
->
handle
)
||
__get_user
(
req32
.
physical
,
&
request
->
physical
)
||
copy_to_user
(
argp
,
&
req32
,
sizeof
(
req32
)))
{
drm_ioctl
(
file
->
f_dentry
->
d_inode
,
file
,
DRM_IOCTL_AGP_FREE
,
(
unsigned
long
)
request
);
return
-
EFAULT
;
}
return
0
;
}
static
int
compat_drm_agp_free
(
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
drm_agp_buffer32_t
__user
*
argp
=
(
void
__user
*
)
arg
;
drm_agp_buffer_t
__user
*
request
;
u32
handle
;
request
=
compat_alloc_user_space
(
sizeof
(
*
request
));
if
(
!
access_ok
(
VERIFY_WRITE
,
request
,
sizeof
(
*
request
))
||
get_user
(
handle
,
&
argp
->
handle
)
||
__put_user
(
handle
,
&
request
->
handle
))
return
-
EFAULT
;
return
drm_ioctl
(
file
->
f_dentry
->
d_inode
,
file
,
DRM_IOCTL_AGP_FREE
,
(
unsigned
long
)
request
);
}
typedef
struct
drm_agp_binding32
{
u32
handle
;
/**< From drm_agp_buffer */
u32
offset
;
/**< In bytes -- will round to page boundary */
}
drm_agp_binding32_t
;
static
int
compat_drm_agp_bind
(
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
drm_agp_binding32_t
__user
*
argp
=
(
void
__user
*
)
arg
;
drm_agp_binding32_t
req32
;
drm_agp_binding_t
__user
*
request
;
if
(
copy_from_user
(
&
req32
,
argp
,
sizeof
(
req32
)))
return
-
EFAULT
;
request
=
compat_alloc_user_space
(
sizeof
(
*
request
));
if
(
!
access_ok
(
VERIFY_WRITE
,
request
,
sizeof
(
*
request
))
||
__put_user
(
req32
.
handle
,
&
request
->
handle
)
||
__put_user
(
req32
.
offset
,
&
request
->
offset
))
return
-
EFAULT
;
return
drm_ioctl
(
file
->
f_dentry
->
d_inode
,
file
,
DRM_IOCTL_AGP_BIND
,
(
unsigned
long
)
request
);
}
static
int
compat_drm_agp_unbind
(
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
drm_agp_binding32_t
__user
*
argp
=
(
void
__user
*
)
arg
;
drm_agp_binding_t
__user
*
request
;
u32
handle
;
request
=
compat_alloc_user_space
(
sizeof
(
*
request
));
if
(
!
access_ok
(
VERIFY_WRITE
,
request
,
sizeof
(
*
request
))
||
get_user
(
handle
,
&
argp
->
handle
)
||
__put_user
(
handle
,
&
request
->
handle
))
return
-
EFAULT
;
return
drm_ioctl
(
file
->
f_dentry
->
d_inode
,
file
,
DRM_IOCTL_AGP_UNBIND
,
(
unsigned
long
)
request
);
}
#endif
/* __OS_HAS_AGP */
typedef
struct
drm_scatter_gather32
{
u32
size
;
/**< In bytes -- will round to page boundary */
u32
handle
;
/**< Used for mapping / unmapping */
}
drm_scatter_gather32_t
;
static
int
compat_drm_sg_alloc
(
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
drm_scatter_gather32_t
__user
*
argp
=
(
void
__user
*
)
arg
;
drm_scatter_gather_t
__user
*
request
;
int
err
;
unsigned
long
x
;
request
=
compat_alloc_user_space
(
sizeof
(
*
request
));
if
(
!
access_ok
(
VERIFY_WRITE
,
request
,
sizeof
(
*
request
))
||
!
access_ok
(
VERIFY_WRITE
,
argp
,
sizeof
(
*
argp
))
||
__get_user
(
x
,
&
argp
->
size
)
||
__put_user
(
x
,
&
request
->
size
))
return
-
EFAULT
;
err
=
drm_ioctl
(
file
->
f_dentry
->
d_inode
,
file
,
DRM_IOCTL_SG_ALLOC
,
(
unsigned
long
)
request
);
if
(
err
)
return
err
;
/* XXX not sure about the handle conversion here... */
if
(
__get_user
(
x
,
&
request
->
handle
)
||
__put_user
(
x
>>
PAGE_SHIFT
,
&
argp
->
handle
))
return
-
EFAULT
;
return
0
;
}
static
int
compat_drm_sg_free
(
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
drm_scatter_gather32_t
__user
*
argp
=
(
void
__user
*
)
arg
;
drm_scatter_gather_t
__user
*
request
;
unsigned
long
x
;
request
=
compat_alloc_user_space
(
sizeof
(
*
request
));
if
(
!
access_ok
(
VERIFY_WRITE
,
request
,
sizeof
(
*
request
))
||
!
access_ok
(
VERIFY_WRITE
,
argp
,
sizeof
(
*
argp
))
||
__get_user
(
x
,
&
argp
->
handle
)
||
__put_user
(
x
<<
PAGE_SHIFT
,
&
request
->
handle
))
return
-
EFAULT
;
return
drm_ioctl
(
file
->
f_dentry
->
d_inode
,
file
,
DRM_IOCTL_SG_FREE
,
(
unsigned
long
)
request
);
}
struct
drm_wait_vblank_request32
{
drm_vblank_seq_type_t
type
;
unsigned
int
sequence
;
u32
signal
;
};
struct
drm_wait_vblank_reply32
{
drm_vblank_seq_type_t
type
;
unsigned
int
sequence
;
s32
tval_sec
;
s32
tval_usec
;
};
typedef
union
drm_wait_vblank32
{
struct
drm_wait_vblank_request32
request
;
struct
drm_wait_vblank_reply32
reply
;
}
drm_wait_vblank32_t
;
static
int
compat_drm_wait_vblank
(
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
drm_wait_vblank32_t
__user
*
argp
=
(
void
__user
*
)
arg
;
drm_wait_vblank32_t
req32
;
drm_wait_vblank_t
__user
*
request
;
int
err
;
if
(
copy_from_user
(
&
req32
,
argp
,
sizeof
(
req32
)))
return
-
EFAULT
;
request
=
compat_alloc_user_space
(
sizeof
(
*
request
));
if
(
!
access_ok
(
VERIFY_WRITE
,
request
,
sizeof
(
*
request
))
||
__put_user
(
req32
.
request
.
type
,
&
request
->
request
.
type
)
||
__put_user
(
req32
.
request
.
sequence
,
&
request
->
request
.
sequence
)
||
__put_user
(
req32
.
request
.
signal
,
&
request
->
request
.
signal
))
return
-
EFAULT
;
err
=
drm_ioctl
(
file
->
f_dentry
->
d_inode
,
file
,
DRM_IOCTL_WAIT_VBLANK
,
(
unsigned
long
)
request
);
if
(
err
)
return
err
;
if
(
__get_user
(
req32
.
reply
.
type
,
&
request
->
reply
.
type
)
||
__get_user
(
req32
.
reply
.
sequence
,
&
request
->
reply
.
sequence
)
||
__get_user
(
req32
.
reply
.
tval_sec
,
&
request
->
reply
.
tval_sec
)
||
__get_user
(
req32
.
reply
.
tval_usec
,
&
request
->
reply
.
tval_usec
))
return
-
EFAULT
;
if
(
copy_to_user
(
argp
,
&
req32
,
sizeof
(
req32
)))
return
-
EFAULT
;
return
0
;
}
drm_ioctl_compat_t
*
drm_compat_ioctls
[]
=
{
[
DRM_IOCTL_NR
(
DRM_IOCTL_VERSION32
)]
=
compat_drm_version
,
[
DRM_IOCTL_NR
(
DRM_IOCTL_GET_UNIQUE32
)]
=
compat_drm_getunique
,
[
DRM_IOCTL_NR
(
DRM_IOCTL_GET_MAP32
)]
=
compat_drm_getmap
,
[
DRM_IOCTL_NR
(
DRM_IOCTL_GET_CLIENT32
)]
=
compat_drm_getclient
,
[
DRM_IOCTL_NR
(
DRM_IOCTL_GET_STATS32
)]
=
compat_drm_getstats
,
[
DRM_IOCTL_NR
(
DRM_IOCTL_SET_UNIQUE32
)]
=
compat_drm_setunique
,
[
DRM_IOCTL_NR
(
DRM_IOCTL_ADD_MAP32
)]
=
compat_drm_addmap
,
[
DRM_IOCTL_NR
(
DRM_IOCTL_ADD_BUFS32
)]
=
compat_drm_addbufs
,
[
DRM_IOCTL_NR
(
DRM_IOCTL_MARK_BUFS32
)]
=
compat_drm_markbufs
,
[
DRM_IOCTL_NR
(
DRM_IOCTL_INFO_BUFS32
)]
=
compat_drm_infobufs
,
[
DRM_IOCTL_NR
(
DRM_IOCTL_MAP_BUFS32
)]
=
compat_drm_mapbufs
,
[
DRM_IOCTL_NR
(
DRM_IOCTL_FREE_BUFS32
)]
=
compat_drm_freebufs
,
[
DRM_IOCTL_NR
(
DRM_IOCTL_RM_MAP32
)]
=
compat_drm_rmmap
,
[
DRM_IOCTL_NR
(
DRM_IOCTL_SET_SAREA_CTX32
)]
=
compat_drm_setsareactx
,
[
DRM_IOCTL_NR
(
DRM_IOCTL_GET_SAREA_CTX32
)]
=
compat_drm_getsareactx
,
[
DRM_IOCTL_NR
(
DRM_IOCTL_RES_CTX32
)]
=
compat_drm_resctx
,
[
DRM_IOCTL_NR
(
DRM_IOCTL_DMA32
)]
=
compat_drm_dma
,
#if __OS_HAS_AGP
[
DRM_IOCTL_NR
(
DRM_IOCTL_AGP_ENABLE32
)]
=
compat_drm_agp_enable
,
[
DRM_IOCTL_NR
(
DRM_IOCTL_AGP_INFO32
)]
=
compat_drm_agp_info
,
[
DRM_IOCTL_NR
(
DRM_IOCTL_AGP_ALLOC32
)]
=
compat_drm_agp_alloc
,
[
DRM_IOCTL_NR
(
DRM_IOCTL_AGP_FREE32
)]
=
compat_drm_agp_free
,
[
DRM_IOCTL_NR
(
DRM_IOCTL_AGP_BIND32
)]
=
compat_drm_agp_bind
,
[
DRM_IOCTL_NR
(
DRM_IOCTL_AGP_UNBIND32
)]
=
compat_drm_agp_unbind
,
#endif
[
DRM_IOCTL_NR
(
DRM_IOCTL_SG_ALLOC32
)]
=
compat_drm_sg_alloc
,
[
DRM_IOCTL_NR
(
DRM_IOCTL_SG_FREE32
)]
=
compat_drm_sg_free
,
[
DRM_IOCTL_NR
(
DRM_IOCTL_WAIT_VBLANK32
)]
=
compat_drm_wait_vblank
,
};
/**
* Called whenever a 32-bit process running under a 64-bit kernel
* performs an ioctl on /dev/drm.
*
* \param filp file pointer.
* \param cmd command.
* \param arg user argument.
* \return zero on success or negative number on failure.
*/
long
drm_compat_ioctl
(
struct
file
*
filp
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
unsigned
int
nr
=
DRM_IOCTL_NR
(
cmd
);
drm_ioctl_compat_t
*
fn
;
int
ret
;
if
(
nr
>=
DRM_ARRAY_SIZE
(
drm_compat_ioctls
))
return
-
ENOTTY
;
fn
=
drm_compat_ioctls
[
nr
];
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
;
}
EXPORT_SYMBOL
(
drm_compat_ioctl
);
drivers/char/drm/radeon_drv.c
View file @
8678887e
...
...
@@ -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
,
...
...
drivers/char/drm/radeon_drv.h
View file @
8678887e
...
...
@@ -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
...
...
drivers/char/drm/radeon_ioc32.c
0 → 100644
View file @
8678887e
/**
* \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
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment