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 51 data = kmalloc(sizeof(*data), GFP_KERNEL); 52 if (!data) 53 return -ENOMEM; 54 55 if (copy_from_user(data, data32, sizeof(*data32)) || 56 get_user(data->flags, &data32->flags) || 57 get_user(data->time_queue, &data32->time_queue)) 58 goto error; 59 data->kernel = NULL; 60 61 err = snd_seq_kernel_client_ctl(client->number, cmd, data); 62 if (err < 0) 63 goto error; 64 65 if (copy_to_user(data32, data, sizeof(*data32)) || 66 put_user(data->flags, &data32->flags) || 67 put_user(data->time_queue, &data32->time_queue)) 68 err = -EFAULT; 69 70 error: 71 kfree(data); 72 return err; 73 } 74 75 76 77 /* 78 */ 79 80 enum { 81 SNDRV_SEQ_IOCTL_CREATE_PORT32 = _IOWR('S', 0x20, struct snd_seq_port_info32), 82 SNDRV_SEQ_IOCTL_DELETE_PORT32 = _IOW ('S', 0x21, struct snd_seq_port_info32), 83 SNDRV_SEQ_IOCTL_GET_PORT_INFO32 = _IOWR('S', 0x22, struct snd_seq_port_info32), 84 SNDRV_SEQ_IOCTL_SET_PORT_INFO32 = _IOW ('S', 0x23, struct snd_seq_port_info32), 85 SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT32 = _IOWR('S', 0x52, struct snd_seq_port_info32), 86 }; 87 88 static long snd_seq_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg) 89 { 90 struct snd_seq_client *client = file->private_data; 91 void __user *argp = compat_ptr(arg); 92 93 if (snd_BUG_ON(!client)) 94 return -ENXIO; 95 96 switch (cmd) { 97 case SNDRV_SEQ_IOCTL_PVERSION: 98 case SNDRV_SEQ_IOCTL_CLIENT_ID: 99 case SNDRV_SEQ_IOCTL_SYSTEM_INFO: 100 case SNDRV_SEQ_IOCTL_GET_CLIENT_INFO: 101 case SNDRV_SEQ_IOCTL_SET_CLIENT_INFO: 102 case SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT: 103 case SNDRV_SEQ_IOCTL_UNSUBSCRIBE_PORT: 104 case SNDRV_SEQ_IOCTL_CREATE_QUEUE: 105 case SNDRV_SEQ_IOCTL_DELETE_QUEUE: 106 case SNDRV_SEQ_IOCTL_GET_QUEUE_INFO: 107 case SNDRV_SEQ_IOCTL_SET_QUEUE_INFO: 108 case SNDRV_SEQ_IOCTL_GET_NAMED_QUEUE: 109 case SNDRV_SEQ_IOCTL_GET_QUEUE_STATUS: 110 case SNDRV_SEQ_IOCTL_GET_QUEUE_TEMPO: 111 case SNDRV_SEQ_IOCTL_SET_QUEUE_TEMPO: 112 case SNDRV_SEQ_IOCTL_GET_QUEUE_TIMER: 113 case SNDRV_SEQ_IOCTL_SET_QUEUE_TIMER: 114 case SNDRV_SEQ_IOCTL_GET_QUEUE_CLIENT: 115 case SNDRV_SEQ_IOCTL_SET_QUEUE_CLIENT: 116 case SNDRV_SEQ_IOCTL_GET_CLIENT_POOL: 117 case SNDRV_SEQ_IOCTL_SET_CLIENT_POOL: 118 case SNDRV_SEQ_IOCTL_REMOVE_EVENTS: 119 case SNDRV_SEQ_IOCTL_QUERY_SUBS: 120 case SNDRV_SEQ_IOCTL_GET_SUBSCRIPTION: 121 case SNDRV_SEQ_IOCTL_QUERY_NEXT_CLIENT: 122 case SNDRV_SEQ_IOCTL_RUNNING_MODE: 123 return snd_seq_ioctl(file, cmd, arg); 124 case SNDRV_SEQ_IOCTL_CREATE_PORT32: 125 return snd_seq_call_port_info_ioctl(client, SNDRV_SEQ_IOCTL_CREATE_PORT, argp); 126 case SNDRV_SEQ_IOCTL_DELETE_PORT32: 127 return snd_seq_call_port_info_ioctl(client, SNDRV_SEQ_IOCTL_DELETE_PORT, argp); 128 case SNDRV_SEQ_IOCTL_GET_PORT_INFO32: 129 return snd_seq_call_port_info_ioctl(client, SNDRV_SEQ_IOCTL_GET_PORT_INFO, argp); 130 case SNDRV_SEQ_IOCTL_SET_PORT_INFO32: 131 return snd_seq_call_port_info_ioctl(client, SNDRV_SEQ_IOCTL_SET_PORT_INFO, argp); 132 case SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT32: 133 return snd_seq_call_port_info_ioctl(client, SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT, argp); 134 } 135 return -ENOIOCTLCMD; 136 } 137