1 /* 2 * 32bit -> 64bit ioctl wrapper for sequencer API 3 * Copyright (c) by Takashi Iwai <tiwai@suse.de> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 * 19 */ 20 21 /* This file included from seq.c */ 22 23 #include <linux/compat.h> 24 #include <linux/slab.h> 25 26 struct snd_seq_port_info32 { 27 struct snd_seq_addr addr; /* client/port numbers */ 28 char name[64]; /* port name */ 29 30 u32 capability; /* port capability bits */ 31 u32 type; /* port type bits */ 32 s32 midi_channels; /* channels per MIDI port */ 33 s32 midi_voices; /* voices per MIDI port */ 34 s32 synth_voices; /* voices per SYNTH port */ 35 36 s32 read_use; /* R/O: subscribers for output (from this port) */ 37 s32 write_use; /* R/O: subscribers for input (to this port) */ 38 39 u32 kernel; /* reserved for kernel use (must be NULL) */ 40 u32 flags; /* misc. conditioning */ 41 unsigned char time_queue; /* queue # for timestamping */ 42 char reserved[59]; /* for future use */ 43 }; 44 45 static int snd_seq_call_port_info_ioctl(struct snd_seq_client *client, unsigned int cmd, 46 struct snd_seq_port_info32 __user *data32) 47 { 48 int err = -EFAULT; 49 struct snd_seq_port_info *data; 50 mm_segment_t fs; 51 52 data = memdup_user(data32, sizeof(*data32)); 53 if (IS_ERR(data)) 54 return PTR_ERR(data); 55 56 if (get_user(data->flags, &data32->flags) || 57 get_user(data->time_queue, &data32->time_queue)) 58 goto error; 59 data->kernel = NULL; 60 61 fs = snd_enter_user(); 62 err = snd_seq_do_ioctl(client, cmd, data); 63 snd_leave_user(fs); 64 if (err < 0) 65 goto error; 66 67 if (copy_to_user(data32, data, sizeof(*data32)) || 68 put_user(data->flags, &data32->flags) || 69 put_user(data->time_queue, &data32->time_queue)) 70 err = -EFAULT; 71 72 error: 73 kfree(data); 74 return err; 75 } 76 77 78 79 /* 80 */ 81 82 enum { 83 SNDRV_SEQ_IOCTL_CREATE_PORT32 = _IOWR('S', 0x20, struct snd_seq_port_info32), 84 SNDRV_SEQ_IOCTL_DELETE_PORT32 = _IOW ('S', 0x21, struct snd_seq_port_info32), 85 SNDRV_SEQ_IOCTL_GET_PORT_INFO32 = _IOWR('S', 0x22, struct snd_seq_port_info32), 86 SNDRV_SEQ_IOCTL_SET_PORT_INFO32 = _IOW ('S', 0x23, struct snd_seq_port_info32), 87 SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT32 = _IOWR('S', 0x52, struct snd_seq_port_info32), 88 }; 89 90 static long snd_seq_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg) 91 { 92 struct snd_seq_client *client = file->private_data; 93 void __user *argp = compat_ptr(arg); 94 95 if (snd_BUG_ON(!client)) 96 return -ENXIO; 97 98 switch (cmd) { 99 case SNDRV_SEQ_IOCTL_PVERSION: 100 case SNDRV_SEQ_IOCTL_CLIENT_ID: 101 case SNDRV_SEQ_IOCTL_SYSTEM_INFO: 102 case SNDRV_SEQ_IOCTL_GET_CLIENT_INFO: 103 case SNDRV_SEQ_IOCTL_SET_CLIENT_INFO: 104 case SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT: 105 case SNDRV_SEQ_IOCTL_UNSUBSCRIBE_PORT: 106 case SNDRV_SEQ_IOCTL_CREATE_QUEUE: 107 case SNDRV_SEQ_IOCTL_DELETE_QUEUE: 108 case SNDRV_SEQ_IOCTL_GET_QUEUE_INFO: 109 case SNDRV_SEQ_IOCTL_SET_QUEUE_INFO: 110 case SNDRV_SEQ_IOCTL_GET_NAMED_QUEUE: 111 case SNDRV_SEQ_IOCTL_GET_QUEUE_STATUS: 112 case SNDRV_SEQ_IOCTL_GET_QUEUE_TEMPO: 113 case SNDRV_SEQ_IOCTL_SET_QUEUE_TEMPO: 114 case SNDRV_SEQ_IOCTL_GET_QUEUE_TIMER: 115 case SNDRV_SEQ_IOCTL_SET_QUEUE_TIMER: 116 case SNDRV_SEQ_IOCTL_GET_QUEUE_CLIENT: 117 case SNDRV_SEQ_IOCTL_SET_QUEUE_CLIENT: 118 case SNDRV_SEQ_IOCTL_GET_CLIENT_POOL: 119 case SNDRV_SEQ_IOCTL_SET_CLIENT_POOL: 120 case SNDRV_SEQ_IOCTL_REMOVE_EVENTS: 121 case SNDRV_SEQ_IOCTL_QUERY_SUBS: 122 case SNDRV_SEQ_IOCTL_GET_SUBSCRIPTION: 123 case SNDRV_SEQ_IOCTL_QUERY_NEXT_CLIENT: 124 case SNDRV_SEQ_IOCTL_RUNNING_MODE: 125 return snd_seq_do_ioctl(client, cmd, argp); 126 case SNDRV_SEQ_IOCTL_CREATE_PORT32: 127 return snd_seq_call_port_info_ioctl(client, SNDRV_SEQ_IOCTL_CREATE_PORT, argp); 128 case SNDRV_SEQ_IOCTL_DELETE_PORT32: 129 return snd_seq_call_port_info_ioctl(client, SNDRV_SEQ_IOCTL_DELETE_PORT, argp); 130 case SNDRV_SEQ_IOCTL_GET_PORT_INFO32: 131 return snd_seq_call_port_info_ioctl(client, SNDRV_SEQ_IOCTL_GET_PORT_INFO, argp); 132 case SNDRV_SEQ_IOCTL_SET_PORT_INFO32: 133 return snd_seq_call_port_info_ioctl(client, SNDRV_SEQ_IOCTL_SET_PORT_INFO, argp); 134 case SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT32: 135 return snd_seq_call_port_info_ioctl(client, SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT, argp); 136 } 137 return -ENOIOCTLCMD; 138 } 139