2015-02-20 17:14:10 +01:00
/*
* Copyright ( c ) 2015 Etienne Gemsa < etienne . gemsa @ lse . epita . fr >
2016-05-27 00:49:08 +00:00
* Copyright ( c ) 2015 - 2016 Dmitry V . Levin < ldv @ altlinux . org >
2018-04-05 01:40:00 +00:00
* Copyright ( c ) 2015 - 2018 The strace developers .
2015-02-20 17:14:10 +01:00
* All rights reserved .
*
* Redistribution and use in source and binary forms , with or without
* modification , are permitted provided that the following conditions
* are met :
* 1. Redistributions of source code must retain the above copyright
* notice , this list of conditions and the following disclaimer .
* 2. Redistributions in binary form must reproduce the above copyright
* notice , this list of conditions and the following disclaimer in the
* documentation and / or other materials provided with the distribution .
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission .
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ` ` AS IS ' ' AND ANY EXPRESS OR
* IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED .
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT , INDIRECT ,
* INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES ( INCLUDING , BUT
* NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE ,
* DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT
* ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
*/
# include "defs.h"
2018-04-02 20:16:00 +02:00
# include "xlat/evdev_abs.h"
2015-02-20 17:14:10 +01:00
# ifdef HAVE_LINUX_INPUT_H
2016-05-27 00:39:33 +00:00
# include <linux / ioctl.h>
# include <linux / input.h>
2016-05-27 00:49:08 +00:00
2016-05-27 00:39:33 +00:00
# include "xlat / evdev_autorepeat.h"
# include "xlat / evdev_ff_status.h"
# include "xlat / evdev_ff_types.h"
# include "xlat / evdev_keycode.h"
# include "xlat / evdev_leds.h"
# include "xlat / evdev_misc.h"
# include "xlat / evdev_mtslots.h"
# include "xlat / evdev_prop.h"
# include "xlat / evdev_relative_axes.h"
# include "xlat / evdev_snd.h"
# include "xlat / evdev_switch.h"
# include "xlat / evdev_sync.h"
# ifndef SYN_MAX
# define SYN_MAX 0xf
# endif
evdev: fix build with old kernel headers
* configure.ac: Check whether struct input_absinfo.resolution is defined
in <linux/input.h>.
* evdev.c (SYN_MAX): Add fallback definition.
(abs_ioctl): Wrap use of struct input_absinfo.resolution in #ifdef check.
(keycode_V2_ioctl, mtslots_ioctl, repeat_ioctl): Wrap in #ifdef checks.
(evdev_read_ioctl): Wrap in #ifdef checks the code that uses EV_SW,
EVIOCGREP, EVIOCGKEYCODE_V2, EVIOCGMTSLOTS, EVIOCGPROP, and EVIOCGSW.
(evdev_write_ioctl): Wrap in #ifdef checks the code that uses EVIOCSREP,
EVIOCSKEYCODE_V2, EVIOCSCLOCKID, and EVIOCREVOKE.
2015-02-22 02:50:33 +03:00
2018-04-02 20:16:00 +02:00
const size_t evdev_abs_size = ARRAY_SIZE ( evdev_abs ) - 1 ;
2015-02-20 17:14:10 +01:00
static int
2016-12-26 10:26:03 +00:00
abs_ioctl ( struct tcb * const tcp , const kernel_ulong_t arg )
2015-02-20 17:14:10 +01:00
{
2016-05-27 00:41:14 +00:00
tprints ( " , " ) ;
2015-02-20 17:14:10 +01:00
2016-05-27 00:41:14 +00:00
struct input_absinfo absinfo ;
2015-02-20 17:14:10 +01:00
2016-05-27 00:41:14 +00:00
if ( ! umove_or_printaddr ( tcp , arg , & absinfo ) ) {
tprintf ( " {value=%u "
" , minimum=%u, " ,
absinfo . value ,
absinfo . minimum ) ;
if ( ! abbrev ( tcp ) ) {
tprintf ( " maximum=%u "
" , fuzz=%u "
" , flat=%u " ,
absinfo . maximum ,
absinfo . fuzz ,
absinfo . flat ) ;
2016-05-27 00:39:33 +00:00
# ifdef HAVE_STRUCT_INPUT_ABSINFO_RESOLUTION
2016-05-27 00:41:14 +00:00
tprintf ( " , resolution=%u " ,
absinfo . resolution ) ;
2016-05-27 00:39:33 +00:00
# endif
2016-05-27 00:41:14 +00:00
} else {
tprints ( " ... " ) ;
}
2015-02-20 17:14:10 +01:00
tprints ( " } " ) ;
}
2016-05-27 00:41:14 +00:00
2017-08-28 00:39:15 +00:00
return RVAL_IOCTL_DECODED ;
2015-02-20 17:14:10 +01:00
}
static int
2016-12-26 10:26:03 +00:00
keycode_ioctl ( struct tcb * const tcp , const kernel_ulong_t arg )
2015-02-20 17:14:10 +01:00
{
2016-05-27 00:41:25 +00:00
tprints ( " , " ) ;
2015-02-20 17:14:10 +01:00
unsigned int keycode [ 2 ] ;
2016-05-27 00:41:25 +00:00
if ( ! umove_or_printaddr ( tcp , arg , & keycode ) ) {
tprintf ( " [%u, " , keycode [ 0 ] ) ;
2018-04-02 21:09:15 +02:00
printxval_index ( evdev_keycode , keycode [ 1 ] , " KEY_??? " ) ;
2016-05-27 00:41:25 +00:00
tprints ( " ] " ) ;
2015-02-20 17:14:10 +01:00
}
2017-08-28 00:39:15 +00:00
return RVAL_IOCTL_DECODED ;
2015-02-20 17:14:10 +01:00
}
2016-05-27 00:39:33 +00:00
# ifdef EVIOCGKEYCODE_V2
2015-02-20 17:14:10 +01:00
static int
2016-12-26 10:26:03 +00:00
keycode_V2_ioctl ( struct tcb * const tcp , const kernel_ulong_t arg )
2015-02-20 17:14:10 +01:00
{
2016-05-27 00:41:34 +00:00
tprints ( " , " ) ;
2015-02-20 17:14:10 +01:00
struct input_keymap_entry ike ;
2016-05-27 00:41:34 +00:00
if ( umove_or_printaddr ( tcp , arg , & ike ) )
2017-08-28 00:39:15 +00:00
return RVAL_IOCTL_DECODED ;
2015-02-20 17:14:10 +01:00
2016-05-27 00:41:34 +00:00
tprintf ( " {flags=% " PRIu8
" , len=% " PRIu8 " , " ,
ike . flags ,
ike . len ) ;
2015-02-20 17:14:10 +01:00
if ( ! abbrev ( tcp ) ) {
2015-02-21 23:05:26 +00:00
unsigned int i ;
2016-05-27 00:41:34 +00:00
tprintf ( " index=% " PRIu16 " , keycode= " , ike . index ) ;
2018-04-02 21:09:15 +02:00
printxval_index ( evdev_keycode , ike . keycode , " KEY_??? " ) ;
2015-02-21 23:05:26 +00:00
tprints ( " , scancode=[ " ) ;
for ( i = 0 ; i < ARRAY_SIZE ( ike . scancode ) ; i + + ) {
if ( i > 0 )
tprints ( " , " ) ;
tprintf ( " % " PRIx8 , ike . scancode [ i ] ) ;
}
2016-05-27 00:41:34 +00:00
tprints ( " ] " ) ;
2015-02-20 17:14:10 +01:00
} else {
2016-05-27 00:41:34 +00:00
tprints ( " ... " ) ;
2015-02-20 17:14:10 +01:00
}
2016-05-27 00:41:34 +00:00
tprints ( " } " ) ;
2017-08-28 00:39:15 +00:00
return RVAL_IOCTL_DECODED ;
2015-02-20 17:14:10 +01:00
}
2016-05-27 00:39:33 +00:00
# endif /* EVIOCGKEYCODE_V2 */
2015-02-20 17:14:10 +01:00
static int
2016-12-26 10:26:03 +00:00
getid_ioctl ( struct tcb * const tcp , const kernel_ulong_t arg )
2015-02-20 17:14:10 +01:00
{
2016-05-27 00:41:43 +00:00
tprints ( " , " ) ;
2015-02-20 17:14:10 +01:00
struct input_id id ;
2016-05-27 00:41:43 +00:00
if ( ! umove_or_printaddr ( tcp , arg , & id ) )
tprintf ( " {ID_BUS=% " PRIu16
" , ID_VENDOR=% " PRIu16
" , ID_PRODUCT=% " PRIu16
" , ID_VERSION=% " PRIu16 " } " ,
id . bustype ,
id . vendor ,
id . product ,
id . version ) ;
2015-02-20 17:14:10 +01:00
2017-08-28 00:39:15 +00:00
return RVAL_IOCTL_DECODED ;
2015-02-20 17:14:10 +01:00
}
static int
2018-04-02 20:32:19 +02:00
decode_bitset_ ( struct tcb * const tcp , const kernel_ulong_t arg ,
const struct xlat decode_nr [ ] , const unsigned int max_nr ,
const char * const dflt , size_t decode_nr_size , enum xlat_type xt )
2015-02-20 17:14:10 +01:00
{
2016-05-27 00:41:51 +00:00
tprints ( " , " ) ;
2015-02-20 17:14:10 +01:00
unsigned int size ;
2016-12-26 10:26:03 +00:00
if ( ( kernel_ulong_t ) tcp - > u_rval > max_nr )
2015-02-20 17:14:10 +01:00
size = max_nr ;
else
size = tcp - > u_rval ;
char decoded_arg [ size ] ;
2016-05-27 00:41:51 +00:00
if ( umove_or_printaddr ( tcp , arg , & decoded_arg ) )
2017-08-28 00:39:15 +00:00
return RVAL_IOCTL_DECODED ;
2015-02-20 17:14:10 +01:00
2016-05-27 00:41:51 +00:00
tprints ( " [ " ) ;
2015-02-20 17:14:10 +01:00
int bit_displayed = 0 ;
int i = next_set_bit ( decoded_arg , 0 , size ) ;
if ( i < 0 ) {
tprints ( " 0 " ) ;
} else {
2018-04-02 20:32:19 +02:00
printxval_dispatch ( decode_nr , decode_nr_size , i , dflt , xt ) ;
2015-02-20 17:14:10 +01:00
while ( ( i = next_set_bit ( decoded_arg , i + 1 , size ) ) > 0 ) {
if ( abbrev ( tcp ) & & bit_displayed > = 3 ) {
tprints ( " , ... " ) ;
break ;
}
tprints ( " , " ) ;
2018-04-02 20:32:19 +02:00
printxval_dispatch ( decode_nr , decode_nr_size , i , dflt ,
xt ) ;
2015-02-20 17:14:10 +01:00
bit_displayed + + ;
}
}
tprints ( " ] " ) ;
2017-08-28 00:39:15 +00:00
return RVAL_IOCTL_DECODED ;
2015-02-20 17:14:10 +01:00
}
2018-04-02 20:32:19 +02:00
# define decode_bitset(tcp_, arg_, decode_nr_, max_nr_, dflt_, xt_) \
decode_bitset_ ( ( tcp_ ) , ( arg_ ) , ( decode_nr_ ) , ( max_nr_ ) , \
( dflt_ ) , ARRAY_SIZE ( decode_nr_ ) , ( xt_ ) )
2016-05-27 00:39:33 +00:00
# ifdef EVIOCGMTSLOTS
2015-02-20 17:14:10 +01:00
static int
evdev: change type of ioctl 3rd argument from long to kernel_ureg_t
* evdev.c (ff_effect_ioctl, abs_ioctl, keycode_ioctl, keycode_V2_ioctl,
getid_ioctl, decode_bitset, mtslots_ioctl, repeat_ioctl, bit_ioctl,
evdev_read_ioctl, evdev_write_ioctl, evdev_ioctl): Change arg type
from long to kernel_ureg_t.
2016-12-21 03:03:09 +00:00
mtslots_ioctl ( struct tcb * const tcp , const unsigned int code ,
2016-12-26 10:26:03 +00:00
const kernel_ulong_t arg )
2015-02-20 17:14:10 +01:00
{
2016-05-27 00:41:59 +00:00
tprints ( " , " ) ;
const size_t size = _IOC_SIZE ( code ) / sizeof ( int ) ;
if ( ! size ) {
printaddr ( arg ) ;
2017-08-28 00:39:15 +00:00
return RVAL_IOCTL_DECODED ;
2016-05-27 00:41:59 +00:00
}
2015-02-20 17:14:10 +01:00
2016-05-27 00:41:59 +00:00
int buffer [ size ] ;
2015-02-20 17:14:10 +01:00
2016-05-27 00:41:59 +00:00
if ( umove_or_printaddr ( tcp , arg , & buffer ) )
2017-08-28 00:39:15 +00:00
return RVAL_IOCTL_DECODED ;
2015-02-20 17:14:10 +01:00
2016-05-27 00:41:59 +00:00
tprints ( " {code= " ) ;
2015-02-20 17:14:10 +01:00
printxval ( evdev_mtslots , buffer [ 0 ] , " ABS_MT_??? " ) ;
tprints ( " , values=[ " ) ;
2016-05-27 00:41:59 +00:00
unsigned int i ;
2015-02-20 17:14:10 +01:00
for ( i = 1 ; i < ARRAY_SIZE ( buffer ) ; i + + )
tprintf ( " %s%d " , i > 1 ? " , " : " " , buffer [ i ] ) ;
tprints ( " ]} " ) ;
2016-05-27 00:41:59 +00:00
2017-08-28 00:39:15 +00:00
return RVAL_IOCTL_DECODED ;
2015-02-20 17:14:10 +01:00
}
2016-05-27 00:39:33 +00:00
# endif /* EVIOCGMTSLOTS */
2015-02-20 17:14:10 +01:00
2016-05-27 00:39:33 +00:00
# if defined EVIOCGREP || defined EVIOCSREP
2015-02-20 17:14:10 +01:00
static int
2016-12-26 10:26:03 +00:00
repeat_ioctl ( struct tcb * const tcp , const kernel_ulong_t arg )
2015-02-20 17:14:10 +01:00
{
2015-07-06 22:33:39 +00:00
tprints ( " , " ) ;
printpair_int ( tcp , arg , " %u " ) ;
2017-08-28 00:39:15 +00:00
return RVAL_IOCTL_DECODED ;
2015-02-20 17:14:10 +01:00
}
2016-05-27 00:39:33 +00:00
# endif /* EVIOCGREP || EVIOCSREP */
2015-02-20 17:14:10 +01:00
2016-05-27 00:40:18 +00:00
static int
evdev: change type of ioctl 3rd argument from long to kernel_ureg_t
* evdev.c (ff_effect_ioctl, abs_ioctl, keycode_ioctl, keycode_V2_ioctl,
getid_ioctl, decode_bitset, mtslots_ioctl, repeat_ioctl, bit_ioctl,
evdev_read_ioctl, evdev_write_ioctl, evdev_ioctl): Change arg type
from long to kernel_ureg_t.
2016-12-21 03:03:09 +00:00
bit_ioctl ( struct tcb * const tcp , const unsigned int ev_nr ,
2016-12-26 10:26:03 +00:00
const kernel_ulong_t arg )
2016-05-27 00:40:18 +00:00
{
switch ( ev_nr ) {
case EV_SYN :
return decode_bitset ( tcp , arg , evdev_sync ,
2018-04-02 21:09:15 +02:00
SYN_MAX , " SYN_??? " , XT_INDEXED ) ;
2016-05-27 00:40:18 +00:00
case EV_KEY :
return decode_bitset ( tcp , arg , evdev_keycode ,
2018-04-02 21:09:15 +02:00
KEY_MAX , " KEY_??? " , XT_INDEXED ) ;
2016-05-27 00:40:18 +00:00
case EV_REL :
return decode_bitset ( tcp , arg , evdev_relative_axes ,
2018-04-02 21:09:15 +02:00
REL_MAX , " REL_??? " , XT_INDEXED ) ;
2016-05-27 00:40:18 +00:00
case EV_ABS :
2016-05-27 00:42:25 +00:00
return decode_bitset ( tcp , arg , evdev_abs ,
2018-04-02 21:09:15 +02:00
ABS_MAX , " ABS_??? " , XT_INDEXED ) ;
2016-05-27 00:40:18 +00:00
case EV_MSC :
2016-05-27 00:42:25 +00:00
return decode_bitset ( tcp , arg , evdev_misc ,
2018-04-02 21:09:15 +02:00
MSC_MAX , " MSC_??? " , XT_INDEXED ) ;
2016-05-27 00:40:18 +00:00
case EV_SW :
2016-05-27 00:42:25 +00:00
return decode_bitset ( tcp , arg , evdev_switch ,
2018-04-02 21:09:15 +02:00
SW_MAX , " SW_??? " , XT_INDEXED ) ;
2016-05-27 00:40:18 +00:00
case EV_LED :
2016-05-27 00:42:25 +00:00
return decode_bitset ( tcp , arg , evdev_leds ,
2018-04-02 21:09:15 +02:00
LED_MAX , " LED_??? " , XT_INDEXED ) ;
2016-05-27 00:40:18 +00:00
case EV_SND :
2016-05-27 00:42:25 +00:00
return decode_bitset ( tcp , arg , evdev_snd ,
2018-04-02 21:09:15 +02:00
SND_MAX , " SND_??? " , XT_INDEXED ) ;
2016-05-27 00:40:18 +00:00
case EV_REP :
return decode_bitset ( tcp , arg , evdev_autorepeat ,
2018-04-02 21:09:15 +02:00
REP_MAX , " REP_??? " , XT_INDEXED ) ;
2016-05-27 00:40:18 +00:00
case EV_FF :
return decode_bitset ( tcp , arg , evdev_ff_types ,
2018-04-02 21:09:15 +02:00
FF_MAX , " FF_??? " , XT_SORTED ) ;
2016-05-27 00:40:18 +00:00
case EV_PWR :
2016-05-28 00:12:01 +00:00
tprints ( " , " ) ;
2016-05-27 00:40:18 +00:00
printnum_int ( tcp , arg , " %d " ) ;
2017-08-28 00:39:15 +00:00
return RVAL_IOCTL_DECODED ;
2016-05-27 00:40:18 +00:00
case EV_FF_STATUS :
return decode_bitset ( tcp , arg , evdev_ff_status ,
2018-04-02 20:32:19 +02:00
FF_STATUS_MAX , " FF_STATUS_??? " ,
2018-04-02 21:09:15 +02:00
XT_INDEXED ) ;
2016-05-27 00:40:18 +00:00
default :
2016-05-28 00:49:17 +00:00
tprints ( " , " ) ;
printaddr ( arg ) ;
2017-08-28 00:39:15 +00:00
return RVAL_IOCTL_DECODED ;
2016-05-27 00:40:18 +00:00
}
}
2015-02-20 17:14:10 +01:00
static int
evdev: change type of ioctl 3rd argument from long to kernel_ureg_t
* evdev.c (ff_effect_ioctl, abs_ioctl, keycode_ioctl, keycode_V2_ioctl,
getid_ioctl, decode_bitset, mtslots_ioctl, repeat_ioctl, bit_ioctl,
evdev_read_ioctl, evdev_write_ioctl, evdev_ioctl): Change arg type
from long to kernel_ureg_t.
2016-12-21 03:03:09 +00:00
evdev_read_ioctl ( struct tcb * const tcp , const unsigned int code ,
2016-12-26 10:26:03 +00:00
const kernel_ulong_t arg )
2015-02-20 17:14:10 +01:00
{
2016-05-27 00:40:10 +00:00
/* fixed-number fixed-length commands */
2015-02-20 17:14:10 +01:00
switch ( code ) {
case EVIOCGVERSION :
tprints ( " , " ) ;
2016-05-27 00:42:07 +00:00
printnum_int ( tcp , arg , " %#x " ) ;
2017-08-28 00:39:15 +00:00
return RVAL_IOCTL_DECODED ;
2015-02-20 17:14:10 +01:00
case EVIOCGEFFECTS :
tprints ( " , " ) ;
2016-05-27 00:42:25 +00:00
printnum_int ( tcp , arg , " %u " ) ;
2017-08-28 00:39:15 +00:00
return RVAL_IOCTL_DECODED ;
2015-02-20 17:14:10 +01:00
case EVIOCGID :
return getid_ioctl ( tcp , arg ) ;
2016-05-27 00:39:33 +00:00
# ifdef EVIOCGREP
2015-02-20 17:14:10 +01:00
case EVIOCGREP :
2016-05-27 00:42:25 +00:00
return repeat_ioctl ( tcp , arg ) ;
2016-05-27 00:39:33 +00:00
# endif
2015-02-20 17:14:10 +01:00
case EVIOCGKEYCODE :
return keycode_ioctl ( tcp , arg ) ;
2016-05-27 00:39:33 +00:00
# ifdef EVIOCGKEYCODE_V2
2015-02-20 17:14:10 +01:00
case EVIOCGKEYCODE_V2 :
return keycode_V2_ioctl ( tcp , arg ) ;
2016-05-27 00:39:33 +00:00
# endif
2015-02-20 17:14:10 +01:00
}
2016-05-27 00:40:10 +00:00
/* fixed-number variable-length commands */
2015-02-20 17:14:10 +01:00
switch ( _IOC_NR ( code ) ) {
2016-05-27 00:39:33 +00:00
# ifdef EVIOCGMTSLOTS
2015-02-20 17:14:10 +01:00
case _IOC_NR ( EVIOCGMTSLOTS ( 0 ) ) :
return mtslots_ioctl ( tcp , code , arg ) ;
2016-05-27 00:39:33 +00:00
# endif
2015-02-20 17:14:10 +01:00
case _IOC_NR ( EVIOCGNAME ( 0 ) ) :
case _IOC_NR ( EVIOCGPHYS ( 0 ) ) :
case _IOC_NR ( EVIOCGUNIQ ( 0 ) ) :
tprints ( " , " ) ;
2016-05-27 00:42:18 +00:00
if ( syserror ( tcp ) )
printaddr ( arg ) ;
else
2016-12-20 16:43:26 +00:00
printstrn ( tcp , arg , tcp - > u_rval ) ;
2017-08-28 00:39:15 +00:00
return RVAL_IOCTL_DECODED ;
2016-05-27 00:39:33 +00:00
# ifdef EVIOCGPROP
2015-02-20 17:14:10 +01:00
case _IOC_NR ( EVIOCGPROP ( 0 ) ) :
2016-05-27 00:42:25 +00:00
return decode_bitset ( tcp , arg , evdev_prop ,
2018-04-02 20:32:19 +02:00
INPUT_PROP_MAX , " PROP_??? " ,
2018-04-02 21:09:15 +02:00
XT_INDEXED ) ;
2016-05-27 00:39:33 +00:00
# endif
2015-02-20 17:14:10 +01:00
case _IOC_NR ( EVIOCGSND ( 0 ) ) :
2016-05-27 00:42:25 +00:00
return decode_bitset ( tcp , arg , evdev_snd ,
2018-04-02 21:09:15 +02:00
SND_MAX , " SND_??? " , XT_INDEXED ) ;
2016-05-27 00:39:33 +00:00
# ifdef EVIOCGSW
2015-02-20 17:14:10 +01:00
case _IOC_NR ( EVIOCGSW ( 0 ) ) :
2016-05-27 00:42:25 +00:00
return decode_bitset ( tcp , arg , evdev_switch ,
2018-04-02 21:09:15 +02:00
SW_MAX , " SW_??? " , XT_INDEXED ) ;
2016-05-27 00:39:33 +00:00
# endif
2015-02-20 17:14:10 +01:00
case _IOC_NR ( EVIOCGKEY ( 0 ) ) :
2016-05-27 00:42:25 +00:00
return decode_bitset ( tcp , arg , evdev_keycode ,
2018-04-02 21:09:15 +02:00
KEY_MAX , " KEY_??? " , XT_INDEXED ) ;
2015-02-20 17:14:10 +01:00
case _IOC_NR ( EVIOCGLED ( 0 ) ) :
2016-05-27 00:42:25 +00:00
return decode_bitset ( tcp , arg , evdev_leds ,
2018-04-02 21:09:15 +02:00
LED_MAX , " LED_??? " , XT_INDEXED ) ;
2015-02-20 17:14:10 +01:00
}
2016-05-27 00:40:10 +00:00
/* multi-number fixed-length commands */
if ( ( _IOC_NR ( code ) & ~ ABS_MAX ) = = _IOC_NR ( EVIOCGABS ( 0 ) ) )
return abs_ioctl ( tcp , arg ) ;
/* multi-number variable-length commands */
2016-05-27 00:40:18 +00:00
if ( ( _IOC_NR ( code ) & ~ EV_MAX ) = = _IOC_NR ( EVIOCGBIT ( 0 , 0 ) ) )
return bit_ioctl ( tcp , _IOC_NR ( code ) & EV_MAX , arg ) ;
2016-05-27 00:40:10 +00:00
return 0 ;
2015-02-20 17:14:10 +01:00
}
static int
evdev: change type of ioctl 3rd argument from long to kernel_ureg_t
* evdev.c (ff_effect_ioctl, abs_ioctl, keycode_ioctl, keycode_V2_ioctl,
getid_ioctl, decode_bitset, mtslots_ioctl, repeat_ioctl, bit_ioctl,
evdev_read_ioctl, evdev_write_ioctl, evdev_ioctl): Change arg type
from long to kernel_ureg_t.
2016-12-21 03:03:09 +00:00
evdev_write_ioctl ( struct tcb * const tcp , const unsigned int code ,
2016-12-26 10:26:03 +00:00
const kernel_ulong_t arg )
2015-02-20 17:14:10 +01:00
{
2016-05-27 00:40:10 +00:00
/* fixed-number fixed-length commands */
2015-02-20 17:14:10 +01:00
switch ( code ) {
2016-05-27 00:39:33 +00:00
# ifdef EVIOCSREP
2015-02-20 17:14:10 +01:00
case EVIOCSREP :
return repeat_ioctl ( tcp , arg ) ;
2016-05-27 00:39:33 +00:00
# endif
2015-02-20 17:14:10 +01:00
case EVIOCSKEYCODE :
return keycode_ioctl ( tcp , arg ) ;
2016-05-27 00:39:33 +00:00
# ifdef EVIOCSKEYCODE_V2
2015-02-20 17:14:10 +01:00
case EVIOCSKEYCODE_V2 :
return keycode_V2_ioctl ( tcp , arg ) ;
2016-05-27 00:39:33 +00:00
# endif
2015-02-20 17:14:10 +01:00
case EVIOCRMFF :
2016-05-27 00:40:27 +00:00
tprintf ( " , %d " , ( int ) arg ) ;
2017-08-28 00:39:15 +00:00
return RVAL_IOCTL_DECODED ;
2015-02-20 17:14:10 +01:00
case EVIOCGRAB :
2016-05-27 00:39:33 +00:00
# ifdef EVIOCREVOKE
2015-02-20 17:14:10 +01:00
case EVIOCREVOKE :
2016-05-27 00:39:33 +00:00
# endif
2016-12-26 10:16:35 +00:00
tprintf ( " , % " PRI_klu , arg ) ;
2017-08-28 00:39:15 +00:00
return RVAL_IOCTL_DECODED ;
2016-05-27 00:40:45 +00:00
# ifdef EVIOCSCLOCKID
case EVIOCSCLOCKID :
2015-02-20 17:14:10 +01:00
tprints ( " , " ) ;
printnum_int ( tcp , arg , " %u " ) ;
2017-08-28 00:39:15 +00:00
return RVAL_IOCTL_DECODED ;
2016-05-27 00:40:45 +00:00
# endif
2018-03-27 01:57:00 +00:00
default : {
int rc = evdev_write_ioctl_mpers ( tcp , code , arg ) ;
if ( rc ! = RVAL_DECODED )
return rc ;
}
2015-02-20 17:14:10 +01:00
}
2016-05-27 00:40:10 +00:00
/* multi-number fixed-length commands */
if ( ( _IOC_NR ( code ) & ~ ABS_MAX ) = = _IOC_NR ( EVIOCSABS ( 0 ) ) )
return abs_ioctl ( tcp , arg ) ;
return 0 ;
2015-02-20 17:14:10 +01:00
}
2018-03-27 01:57:00 +00:00
void
print_evdev_ff_type ( const kernel_ulong_t val )
{
printxval ( evdev_ff_types , val , " FF_??? " ) ;
}
int
evdev_ioctl ( struct tcb * const tcp ,
const unsigned int code , const kernel_ulong_t arg )
2015-02-20 17:14:10 +01:00
{
2017-06-17 22:23:09 +00:00
switch ( _IOC_DIR ( code ) ) {
2015-02-20 17:14:10 +01:00
case _IOC_READ :
2016-05-27 00:40:02 +00:00
if ( entering ( tcp ) )
return 0 ;
2015-02-20 17:14:10 +01:00
return evdev_read_ioctl ( tcp , code , arg ) ;
case _IOC_WRITE :
2016-05-27 00:40:02 +00:00
return evdev_write_ioctl ( tcp , code , arg ) | RVAL_DECODED ;
2015-02-20 17:14:10 +01:00
default :
2016-05-27 00:40:02 +00:00
return RVAL_DECODED ;
2015-02-20 17:14:10 +01:00
}
}
# endif /* HAVE_LINUX_INPUT_H */