2005-07-07 21:51:26 +10:00
/**
* \ file r128_ioc32 . c
*
* 32 - bit ioctl compatibility routines for the R128 DRM .
*
* \ author Dave Airlie < airlied @ linux . ie > with code from patches by Egbert Eich
*
* Copyright ( C ) Paul Mackerras 2005
* Copyright ( C ) Egbert Eich 2003 , 2004
* Copyright ( C ) Dave Airlie 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 "drmP.h"
# include "drm.h"
# include "r128_drm.h"
typedef struct drm_r128_init32 {
int func ;
unsigned int sarea_priv_offset ;
int is_pci ;
int cce_mode ;
int cce_secure ;
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 ;
unsigned int span_offset ;
unsigned int fb_offset ;
unsigned int mmio_offset ;
unsigned int ring_offset ;
unsigned int ring_rptr_offset ;
unsigned int buffers_offset ;
unsigned int agp_textures_offset ;
} drm_r128_init32_t ;
static int compat_r128_init ( struct file * file , unsigned int cmd ,
unsigned long arg )
{
drm_r128_init32_t init32 ;
drm_r128_init_t __user * init ;
2005-09-25 14:28:13 +10:00
2005-07-07 21:51:26 +10:00
if ( copy_from_user ( & init32 , ( void __user * ) arg , sizeof ( init32 ) ) )
return - EFAULT ;
2005-09-25 14:28:13 +10:00
2005-07-07 21:51:26 +10:00
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 . cce_mode , & init - > cce_mode )
| | __put_user ( init32 . cce_secure , & init - > cce_secure )
| | __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 . span_offset , & init - > span_offset )
| | __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 )
2005-09-25 14:28:13 +10:00
| | __put_user ( init32 . agp_textures_offset ,
& init - > agp_textures_offset ) )
2005-07-07 21:51:26 +10:00
return - EFAULT ;
2005-09-25 14:28:13 +10:00
2009-12-16 22:17:09 +00:00
return drm_ioctl ( file , DRM_IOCTL_R128_INIT , ( unsigned long ) init ) ;
2005-07-07 21:51:26 +10:00
}
typedef struct drm_r128_depth32 {
int func ;
int n ;
u32 x ;
u32 y ;
u32 buffer ;
u32 mask ;
} drm_r128_depth32_t ;
static int compat_r128_depth ( struct file * file , unsigned int cmd ,
unsigned long arg )
{
drm_r128_depth32_t depth32 ;
drm_r128_depth_t __user * depth ;
if ( copy_from_user ( & depth32 , ( void __user * ) arg , sizeof ( depth32 ) ) )
return - EFAULT ;
depth = compat_alloc_user_space ( sizeof ( * depth ) ) ;
if ( ! access_ok ( VERIFY_WRITE , depth , sizeof ( * depth ) )
| | __put_user ( depth32 . func , & depth - > func )
| | __put_user ( depth32 . n , & depth - > n )
| | __put_user ( ( int __user * ) ( unsigned long ) depth32 . x , & depth - > x )
| | __put_user ( ( int __user * ) ( unsigned long ) depth32 . y , & depth - > y )
2005-09-25 14:28:13 +10:00
| | __put_user ( ( unsigned int __user * ) ( unsigned long ) depth32 . buffer ,
& depth - > buffer )
| | __put_user ( ( unsigned char __user * ) ( unsigned long ) depth32 . mask ,
& depth - > mask ) )
2005-07-07 21:51:26 +10:00
return - EFAULT ;
2005-09-25 14:28:13 +10:00
2009-12-16 22:17:09 +00:00
return drm_ioctl ( file , DRM_IOCTL_R128_DEPTH , ( unsigned long ) depth ) ;
2005-09-25 14:28:13 +10:00
2005-07-07 21:51:26 +10:00
}
typedef struct drm_r128_stipple32 {
u32 mask ;
} drm_r128_stipple32_t ;
static int compat_r128_stipple ( struct file * file , unsigned int cmd ,
unsigned long arg )
{
drm_r128_stipple32_t stipple32 ;
drm_r128_stipple_t __user * stipple ;
if ( copy_from_user ( & stipple32 , ( void __user * ) arg , sizeof ( stipple32 ) ) )
return - EFAULT ;
stipple = compat_alloc_user_space ( sizeof ( * stipple ) ) ;
if ( ! access_ok ( VERIFY_WRITE , stipple , sizeof ( * stipple ) )
2005-09-25 14:28:13 +10:00
| | __put_user ( ( unsigned int __user * ) ( unsigned long ) stipple32 . mask ,
& stipple - > mask ) )
2005-07-07 21:51:26 +10:00
return - EFAULT ;
2009-12-16 22:17:09 +00:00
return drm_ioctl ( file , DRM_IOCTL_R128_STIPPLE , ( unsigned long ) stipple ) ;
2005-07-07 21:51:26 +10:00
}
typedef struct drm_r128_getparam32 {
int param ;
u32 value ;
} drm_r128_getparam32_t ;
static int compat_r128_getparam ( struct file * file , unsigned int cmd ,
unsigned long arg )
{
drm_r128_getparam32_t getparam32 ;
drm_r128_getparam_t __user * getparam ;
if ( copy_from_user ( & getparam32 , ( void __user * ) arg , sizeof ( getparam32 ) ) )
return - EFAULT ;
getparam = compat_alloc_user_space ( sizeof ( * getparam ) ) ;
if ( ! access_ok ( VERIFY_WRITE , getparam , sizeof ( * getparam ) )
| | __put_user ( getparam32 . param , & getparam - > param )
2005-09-25 14:28:13 +10:00
| | __put_user ( ( void __user * ) ( unsigned long ) getparam32 . value ,
& getparam - > value ) )
2005-07-07 21:51:26 +10:00
return - EFAULT ;
2005-09-25 14:28:13 +10:00
2009-12-16 22:17:09 +00:00
return drm_ioctl ( file , DRM_IOCTL_R128_GETPARAM , ( unsigned long ) getparam ) ;
2005-07-07 21:51:26 +10:00
}
drm_ioctl_compat_t * r128_compat_ioctls [ ] = {
[ DRM_R128_INIT ] = compat_r128_init ,
[ DRM_R128_DEPTH ] = compat_r128_depth ,
[ DRM_R128_STIPPLE ] = compat_r128_stipple ,
[ DRM_R128_GETPARAM ] = compat_r128_getparam ,
} ;
/**
* 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 .
*/
2005-09-25 14:28:13 +10:00
long r128_compat_ioctl ( struct file * filp , unsigned int cmd , unsigned long arg )
2005-07-07 21:51:26 +10:00
{
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 ( r128_compat_ioctls ) )
fn = r128_compat_ioctls [ nr - DRM_COMMAND_BASE ] ;
if ( fn ! = NULL )
2005-09-25 14:28:13 +10:00
ret = ( * fn ) ( filp , cmd , arg ) ;
2005-07-07 21:51:26 +10:00
else
2009-12-16 22:17:09 +00:00
ret = drm_ioctl ( filp , cmd , arg ) ;
2005-07-07 21:51:26 +10:00
return ret ;
}