2005-07-07 21:51:26 +10:00
/**
* \ file mga_ioc32 . c
*
* 32 - bit ioctl compatibility routines for the MGA 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 "mga_drm.h"
typedef struct drm32_mga_init {
int func ;
2005-09-25 14:28:13 +10:00
u32 sarea_priv_offset ;
2005-07-07 21:51:26 +10:00
int chipset ;
2005-09-25 14:28:13 +10:00
int sgram ;
2005-07-07 21:51:26 +10:00
unsigned int maccess ;
2005-09-25 14:28:13 +10:00
unsigned int fb_cpp ;
2005-07-07 21:51:26 +10:00
unsigned int front_offset , front_pitch ;
2005-09-25 14:28:13 +10:00
unsigned int back_offset , back_pitch ;
unsigned int depth_cpp ;
unsigned int depth_offset , depth_pitch ;
unsigned int texture_offset [ MGA_NR_TEX_HEAPS ] ;
unsigned int texture_size [ MGA_NR_TEX_HEAPS ] ;
2005-07-07 21:51:26 +10:00
u32 fb_offset ;
u32 mmio_offset ;
u32 status_offset ;
u32 warp_offset ;
u32 primary_offset ;
u32 buffers_offset ;
} drm_mga_init32_t ;
static int compat_mga_init ( struct file * file , unsigned int cmd ,
unsigned long arg )
{
drm_mga_init32_t init32 ;
drm_mga_init_t __user * init ;
int err = 0 , i ;
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 . chipset , & init - > chipset )
| | __put_user ( init32 . sgram , & init - > sgram )
| | __put_user ( init32 . maccess , & init - > maccess )
| | __put_user ( init32 . fb_cpp , & init - > fb_cpp )
| | __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_cpp , & init - > depth_cpp )
| | __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 . status_offset , & init - > status_offset )
| | __put_user ( init32 . warp_offset , & init - > warp_offset )
| | __put_user ( init32 . primary_offset , & init - > primary_offset )
| | __put_user ( init32 . buffers_offset , & init - > buffers_offset ) )
return - EFAULT ;
2005-09-25 14:28:13 +10:00
for ( i = 0 ; i < MGA_NR_TEX_HEAPS ; i + + ) {
err | =
__put_user ( init32 . texture_offset [ i ] ,
& init - > texture_offset [ i ] ) ;
err | =
__put_user ( init32 . texture_size [ i ] , & init - > texture_size [ i ] ) ;
2005-07-07 21:51:26 +10:00
}
if ( err )
return - EFAULT ;
2005-09-25 14:28:13 +10:00
2005-07-07 21:51:26 +10:00
return drm_ioctl ( file - > f_dentry - > d_inode , file ,
2005-09-25 14:28:13 +10:00
DRM_IOCTL_MGA_INIT , ( unsigned long ) init ) ;
2005-07-07 21:51:26 +10:00
}
typedef struct drm_mga_getparam32 {
int param ;
u32 value ;
} drm_mga_getparam32_t ;
static int compat_mga_getparam ( struct file * file , unsigned int cmd ,
unsigned long arg )
{
drm_mga_getparam32_t getparam32 ;
drm_mga_getparam_t __user * getparam ;
2005-09-25 14:28:13 +10:00
2005-07-07 21:51:26 +10:00
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
return drm_ioctl ( file - > f_dentry - > d_inode , file ,
2005-07-07 21:51:26 +10:00
DRM_IOCTL_MGA_GETPARAM , ( unsigned long ) getparam ) ;
}
2005-08-05 22:11:22 +10:00
typedef struct drm_mga_drm_bootstrap32 {
u32 texture_handle ;
u32 texture_size ;
u32 primary_size ;
u32 secondary_bin_count ;
u32 secondary_bin_size ;
u32 agp_mode ;
u8 agp_size ;
} drm_mga_dma_bootstrap32_t ;
static int compat_mga_dma_bootstrap ( struct file * file , unsigned int cmd ,
unsigned long arg )
{
drm_mga_dma_bootstrap32_t dma_bootstrap32 ;
drm_mga_dma_bootstrap_t __user * dma_bootstrap ;
int err ;
if ( copy_from_user ( & dma_bootstrap32 , ( void __user * ) arg ,
sizeof ( dma_bootstrap32 ) ) )
return - EFAULT ;
dma_bootstrap = compat_alloc_user_space ( sizeof ( * dma_bootstrap ) ) ;
if ( ! access_ok ( VERIFY_WRITE , dma_bootstrap , sizeof ( * dma_bootstrap ) )
| | __put_user ( dma_bootstrap32 . texture_handle ,
& dma_bootstrap - > texture_handle )
| | __put_user ( dma_bootstrap32 . texture_size ,
& dma_bootstrap - > texture_size )
| | __put_user ( dma_bootstrap32 . primary_size ,
& dma_bootstrap - > primary_size )
| | __put_user ( dma_bootstrap32 . secondary_bin_count ,
& dma_bootstrap - > secondary_bin_count )
| | __put_user ( dma_bootstrap32 . secondary_bin_size ,
& dma_bootstrap - > secondary_bin_size )
| | __put_user ( dma_bootstrap32 . agp_mode , & dma_bootstrap - > agp_mode )
| | __put_user ( dma_bootstrap32 . agp_size , & dma_bootstrap - > agp_size ) )
return - EFAULT ;
err = drm_ioctl ( file - > f_dentry - > d_inode , file ,
DRM_IOCTL_MGA_DMA_BOOTSTRAP ,
( unsigned long ) dma_bootstrap ) ;
if ( err )
return err ;
if ( __get_user ( dma_bootstrap32 . texture_handle ,
& dma_bootstrap - > texture_handle )
| | __get_user ( dma_bootstrap32 . texture_size ,
& dma_bootstrap - > texture_size )
| | __get_user ( dma_bootstrap32 . primary_size ,
& dma_bootstrap - > primary_size )
| | __get_user ( dma_bootstrap32 . secondary_bin_count ,
& dma_bootstrap - > secondary_bin_count )
| | __get_user ( dma_bootstrap32 . secondary_bin_size ,
& dma_bootstrap - > secondary_bin_size )
2005-09-25 14:28:13 +10:00
| | __get_user ( dma_bootstrap32 . agp_mode , & dma_bootstrap - > agp_mode )
| | __get_user ( dma_bootstrap32 . agp_size , & dma_bootstrap - > agp_size ) )
2005-08-05 22:11:22 +10:00
return - EFAULT ;
if ( copy_to_user ( ( void __user * ) arg , & dma_bootstrap32 ,
2005-09-25 14:28:13 +10:00
sizeof ( dma_bootstrap32 ) ) )
2005-08-05 22:11:22 +10:00
return - EFAULT ;
return 0 ;
}
2005-07-07 21:51:26 +10:00
drm_ioctl_compat_t * mga_compat_ioctls [ ] = {
[ DRM_MGA_INIT ] = compat_mga_init ,
[ DRM_MGA_GETPARAM ] = compat_mga_getparam ,
2005-08-05 22:11:22 +10:00
[ DRM_MGA_DMA_BOOTSTRAP ] = compat_mga_dma_bootstrap ,
2005-07-07 21:51:26 +10:00
} ;
/**
* 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 mga_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 ) ;
2005-09-25 14:28:13 +10:00
2005-07-07 21:51:26 +10:00
if ( nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE ( mga_compat_ioctls ) )
fn = mga_compat_ioctls [ nr - DRM_COMMAND_BASE ] ;
lock_kernel ( ) ; /* XXX for now */
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
ret = drm_ioctl ( filp - > f_dentry - > d_inode , filp , cmd , arg ) ;
unlock_kernel ( ) ;
return ret ;
}