2019-05-27 09:55:05 +03:00
// SPDX-License-Identifier: GPL-2.0-or-later
2005-04-17 02:20:36 +04:00
/*
* 32 bit - > 64 bit ioctl wrapper for raw MIDI API
* Copyright ( c ) by Takashi Iwai < tiwai @ suse . de >
*/
/* This file included from rawmidi.c */
# include <linux/compat.h>
2005-11-17 15:56:51 +03:00
struct snd_rawmidi_params32 {
2005-04-17 02:20:36 +04:00
s32 stream ;
u32 buffer_size ;
u32 avail_min ;
unsigned int no_active_sensing ; /* avoid bit-field */
unsigned char reserved [ 16 ] ;
} __attribute__ ( ( packed ) ) ;
2005-11-17 15:56:51 +03:00
static int snd_rawmidi_ioctl_params_compat ( struct snd_rawmidi_file * rfile ,
struct snd_rawmidi_params32 __user * src )
2005-04-17 02:20:36 +04:00
{
2005-11-17 15:56:51 +03:00
struct snd_rawmidi_params params ;
2005-04-17 02:20:36 +04:00
unsigned int val ;
if ( get_user ( params . stream , & src - > stream ) | |
get_user ( params . buffer_size , & src - > buffer_size ) | |
get_user ( params . avail_min , & src - > avail_min ) | |
get_user ( val , & src - > no_active_sensing ) )
return - EFAULT ;
params . no_active_sensing = val ;
switch ( params . stream ) {
case SNDRV_RAWMIDI_STREAM_OUTPUT :
2018-04-19 19:16:15 +03:00
if ( ! rfile - > output )
return - EINVAL ;
2005-04-17 02:20:36 +04:00
return snd_rawmidi_output_params ( rfile - > output , & params ) ;
case SNDRV_RAWMIDI_STREAM_INPUT :
2018-04-19 19:16:15 +03:00
if ( ! rfile - > input )
return - EINVAL ;
2005-04-17 02:20:36 +04:00
return snd_rawmidi_input_params ( rfile - > input , & params ) ;
}
return - EINVAL ;
}
2018-04-24 15:06:12 +03:00
struct compat_snd_rawmidi_status64 {
2005-04-17 02:20:36 +04:00
s32 stream ;
2018-04-24 15:06:12 +03:00
u8 rsvd [ 4 ] ; /* alignment */
s64 tstamp_sec ;
s64 tstamp_nsec ;
2005-04-17 02:20:36 +04:00
u32 avail ;
u32 xruns ;
unsigned char reserved [ 16 ] ;
} __attribute__ ( ( packed ) ) ;
2018-04-24 15:06:12 +03:00
static int snd_rawmidi_ioctl_status_compat64 ( struct snd_rawmidi_file * rfile ,
struct compat_snd_rawmidi_status64 __user * src )
2005-04-17 02:20:36 +04:00
{
int err ;
2018-04-24 15:06:12 +03:00
struct snd_rawmidi_status64 status ;
struct compat_snd_rawmidi_status64 compat_status ;
2005-04-17 02:20:36 +04:00
if ( get_user ( status . stream , & src - > stream ) )
return - EFAULT ;
switch ( status . stream ) {
case SNDRV_RAWMIDI_STREAM_OUTPUT :
2018-04-19 19:16:15 +03:00
if ( ! rfile - > output )
return - EINVAL ;
2005-04-17 02:20:36 +04:00
err = snd_rawmidi_output_status ( rfile - > output , & status ) ;
break ;
case SNDRV_RAWMIDI_STREAM_INPUT :
2018-04-19 19:16:15 +03:00
if ( ! rfile - > input )
return - EINVAL ;
2005-04-17 02:20:36 +04:00
err = snd_rawmidi_input_status ( rfile - > input , & status ) ;
break ;
default :
return - EINVAL ;
}
if ( err < 0 )
return err ;
2018-04-24 15:06:12 +03:00
compat_status = ( struct compat_snd_rawmidi_status64 ) {
. stream = status . stream ,
. tstamp_sec = status . tstamp_sec ,
. tstamp_nsec = status . tstamp_nsec ,
. avail = status . avail ,
. xruns = status . xruns ,
} ;
2016-02-28 13:28:08 +03:00
2018-04-24 15:06:12 +03:00
if ( copy_to_user ( src , & compat_status , sizeof ( * src ) ) )
2016-02-28 13:28:08 +03:00
return - EFAULT ;
return 0 ;
}
2005-04-17 02:20:36 +04:00
enum {
2005-11-17 15:56:51 +03:00
SNDRV_RAWMIDI_IOCTL_PARAMS32 = _IOWR ( ' W ' , 0x10 , struct snd_rawmidi_params32 ) ,
2018-04-24 15:06:12 +03:00
SNDRV_RAWMIDI_IOCTL_STATUS_COMPAT32 = _IOWR ( ' W ' , 0x20 , struct snd_rawmidi_status32 ) ,
SNDRV_RAWMIDI_IOCTL_STATUS_COMPAT64 = _IOWR ( ' W ' , 0x20 , struct compat_snd_rawmidi_status64 ) ,
2005-04-17 02:20:36 +04:00
} ;
static long snd_rawmidi_ioctl_compat ( struct file * file , unsigned int cmd , unsigned long arg )
{
2005-11-17 15:56:51 +03:00
struct snd_rawmidi_file * rfile ;
2005-04-17 02:20:36 +04:00
void __user * argp = compat_ptr ( arg ) ;
rfile = file - > private_data ;
switch ( cmd ) {
case SNDRV_RAWMIDI_IOCTL_PVERSION :
case SNDRV_RAWMIDI_IOCTL_INFO :
case SNDRV_RAWMIDI_IOCTL_DROP :
case SNDRV_RAWMIDI_IOCTL_DRAIN :
return snd_rawmidi_ioctl ( file , cmd , ( unsigned long ) argp ) ;
case SNDRV_RAWMIDI_IOCTL_PARAMS32 :
return snd_rawmidi_ioctl_params_compat ( rfile , argp ) ;
2018-04-24 15:06:12 +03:00
case SNDRV_RAWMIDI_IOCTL_STATUS_COMPAT32 :
return snd_rawmidi_ioctl_status32 ( rfile , argp ) ;
case SNDRV_RAWMIDI_IOCTL_STATUS_COMPAT64 :
return snd_rawmidi_ioctl_status_compat64 ( rfile , argp ) ;
2005-04-17 02:20:36 +04:00
}
return - ENOIOCTLCMD ;
}