@ -452,6 +452,76 @@ static unsigned int joydev_poll(struct file *file, poll_table *wait)
( joydev - > exist ? 0 : ( POLLHUP | POLLERR ) ) ;
}
static int joydev_handle_JSIOCSAXMAP ( struct joydev * joydev ,
void __user * argp , size_t len )
{
__u8 * abspam ;
int i ;
int retval = 0 ;
len = min ( len , sizeof ( joydev - > abspam ) ) ;
/* Validate the map. */
abspam = kmalloc ( len , GFP_KERNEL ) ;
if ( ! abspam )
return - ENOMEM ;
if ( copy_from_user ( abspam , argp , len ) ) {
retval = - EFAULT ;
goto out ;
}
for ( i = 0 ; i < joydev - > nabs ; i + + ) {
if ( abspam [ i ] > ABS_MAX ) {
retval = - EINVAL ;
goto out ;
}
}
memcpy ( joydev - > abspam , abspam , len ) ;
out :
kfree ( abspam ) ;
return retval ;
}
static int joydev_handle_JSIOCSBTNMAP ( struct joydev * joydev ,
void __user * argp , size_t len )
{
__u16 * keypam ;
int i ;
int retval = 0 ;
len = min ( len , sizeof ( joydev - > keypam ) ) ;
/* Validate the map. */
keypam = kmalloc ( len , GFP_KERNEL ) ;
if ( ! keypam )
return - ENOMEM ;
if ( copy_from_user ( keypam , argp , len ) ) {
retval = - EFAULT ;
goto out ;
}
for ( i = 0 ; i < joydev - > nkey ; i + + ) {
if ( keypam [ i ] > KEY_MAX | | keypam [ i ] < BTN_MISC ) {
retval = - EINVAL ;
goto out ;
}
}
memcpy ( joydev - > keypam , keypam , len ) ;
for ( i = 0 ; i < joydev - > nkey ; i + + )
joydev - > keymap [ keypam [ i ] - BTN_MISC ] = i ;
out :
kfree ( keypam ) ;
return retval ;
}
static int joydev_ioctl_common ( struct joydev * joydev ,
unsigned int cmd , void __user * argp )
{
@ -512,46 +582,18 @@ static int joydev_ioctl_common(struct joydev *joydev,
switch ( cmd & ~ IOCSIZE_MASK ) {
case ( JSIOCSAXMAP & ~ IOCSIZE_MASK ) :
len = min_t ( size_t , _IOC_SIZE ( cmd ) , sizeof ( joydev - > abspam ) ) ;
/*
* FIXME : we should not copy into our axis map before
* validating the data .
*/
if ( copy_from_user ( joydev - > abspam , argp , len ) )
return - EFAULT ;
for ( i = 0 ; i < joydev - > nabs ; i + + ) {
if ( joydev - > abspam [ i ] > ABS_MAX )
return - EINVAL ;
joydev - > absmap [ joydev - > abspam [ i ] ] = i ;
}
return 0 ;
return joydev_handle_JSIOCSAXMAP ( joydev , argp , _IOC_SIZE ( cmd ) ) ;
case ( JSIOCGAXMAP & ~ IOCSIZE_MASK ) :
len = min_t ( size_t , _IOC_SIZE ( cmd ) , sizeof ( joydev - > abspam ) ) ;
return copy_to_user ( argp , joydev - > abspam , len ) ? - EFAULT : 0 ;
return copy_to_user ( argp , joydev - > abspam , len ) ? - EFAULT : len ;
case ( JSIOCSBTNMAP & ~ IOCSIZE_MASK ) :
len = min_t ( size_t , _IOC_SIZE ( cmd ) , sizeof ( joydev - > keypam ) ) ;
/*
* FIXME : we should not copy into our keymap before
* validating the data .
*/
if ( copy_from_user ( joydev - > keypam , argp , len ) )
return - EFAULT ;
for ( i = 0 ; i < joydev - > nkey ; i + + ) {
if ( joydev - > keypam [ i ] > KEY_MAX | |
joydev - > keypam [ i ] < BTN_MISC )
return - EINVAL ;
joydev - > keymap [ joydev - > keypam [ i ] - BTN_MISC ] = i ;
}
return 0 ;
return joydev_handle_JSIOCSBTNMAP ( joydev , argp , _IOC_SIZE ( cmd ) ) ;
case ( JSIOCGBTNMAP & ~ IOCSIZE_MASK ) :
len = min_t ( size_t , _IOC_SIZE ( cmd ) , sizeof ( joydev - > keypam ) ) ;
return copy_to_user ( argp , joydev - > keypam , len ) ? - EFAULT : 0 ;
return copy_to_user ( argp , joydev - > keypam , len ) ? - EFAULT : len ;
case JSIOCGNAME ( 0 ) :
name = dev - > name ;