0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/compat.h>
0010 #include <linux/slab.h>
0011
0012 struct snd_seq_port_info32 {
0013 struct snd_seq_addr addr;
0014 char name[64];
0015
0016 u32 capability;
0017 u32 type;
0018 s32 midi_channels;
0019 s32 midi_voices;
0020 s32 synth_voices;
0021
0022 s32 read_use;
0023 s32 write_use;
0024
0025 u32 kernel;
0026 u32 flags;
0027 unsigned char time_queue;
0028 char reserved[59];
0029 };
0030
0031 static int snd_seq_call_port_info_ioctl(struct snd_seq_client *client, unsigned int cmd,
0032 struct snd_seq_port_info32 __user *data32)
0033 {
0034 int err = -EFAULT;
0035 struct snd_seq_port_info *data;
0036
0037 data = kmalloc(sizeof(*data), GFP_KERNEL);
0038 if (!data)
0039 return -ENOMEM;
0040
0041 if (copy_from_user(data, data32, sizeof(*data32)) ||
0042 get_user(data->flags, &data32->flags) ||
0043 get_user(data->time_queue, &data32->time_queue))
0044 goto error;
0045 data->kernel = NULL;
0046
0047 err = snd_seq_kernel_client_ctl(client->number, cmd, data);
0048 if (err < 0)
0049 goto error;
0050
0051 if (copy_to_user(data32, data, sizeof(*data32)) ||
0052 put_user(data->flags, &data32->flags) ||
0053 put_user(data->time_queue, &data32->time_queue))
0054 err = -EFAULT;
0055
0056 error:
0057 kfree(data);
0058 return err;
0059 }
0060
0061
0062
0063
0064
0065
0066 enum {
0067 SNDRV_SEQ_IOCTL_CREATE_PORT32 = _IOWR('S', 0x20, struct snd_seq_port_info32),
0068 SNDRV_SEQ_IOCTL_DELETE_PORT32 = _IOW ('S', 0x21, struct snd_seq_port_info32),
0069 SNDRV_SEQ_IOCTL_GET_PORT_INFO32 = _IOWR('S', 0x22, struct snd_seq_port_info32),
0070 SNDRV_SEQ_IOCTL_SET_PORT_INFO32 = _IOW ('S', 0x23, struct snd_seq_port_info32),
0071 SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT32 = _IOWR('S', 0x52, struct snd_seq_port_info32),
0072 };
0073
0074 static long snd_seq_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg)
0075 {
0076 struct snd_seq_client *client = file->private_data;
0077 void __user *argp = compat_ptr(arg);
0078
0079 if (snd_BUG_ON(!client))
0080 return -ENXIO;
0081
0082 switch (cmd) {
0083 case SNDRV_SEQ_IOCTL_PVERSION:
0084 case SNDRV_SEQ_IOCTL_CLIENT_ID:
0085 case SNDRV_SEQ_IOCTL_SYSTEM_INFO:
0086 case SNDRV_SEQ_IOCTL_GET_CLIENT_INFO:
0087 case SNDRV_SEQ_IOCTL_SET_CLIENT_INFO:
0088 case SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT:
0089 case SNDRV_SEQ_IOCTL_UNSUBSCRIBE_PORT:
0090 case SNDRV_SEQ_IOCTL_CREATE_QUEUE:
0091 case SNDRV_SEQ_IOCTL_DELETE_QUEUE:
0092 case SNDRV_SEQ_IOCTL_GET_QUEUE_INFO:
0093 case SNDRV_SEQ_IOCTL_SET_QUEUE_INFO:
0094 case SNDRV_SEQ_IOCTL_GET_NAMED_QUEUE:
0095 case SNDRV_SEQ_IOCTL_GET_QUEUE_STATUS:
0096 case SNDRV_SEQ_IOCTL_GET_QUEUE_TEMPO:
0097 case SNDRV_SEQ_IOCTL_SET_QUEUE_TEMPO:
0098 case SNDRV_SEQ_IOCTL_GET_QUEUE_TIMER:
0099 case SNDRV_SEQ_IOCTL_SET_QUEUE_TIMER:
0100 case SNDRV_SEQ_IOCTL_GET_QUEUE_CLIENT:
0101 case SNDRV_SEQ_IOCTL_SET_QUEUE_CLIENT:
0102 case SNDRV_SEQ_IOCTL_GET_CLIENT_POOL:
0103 case SNDRV_SEQ_IOCTL_SET_CLIENT_POOL:
0104 case SNDRV_SEQ_IOCTL_REMOVE_EVENTS:
0105 case SNDRV_SEQ_IOCTL_QUERY_SUBS:
0106 case SNDRV_SEQ_IOCTL_GET_SUBSCRIPTION:
0107 case SNDRV_SEQ_IOCTL_QUERY_NEXT_CLIENT:
0108 case SNDRV_SEQ_IOCTL_RUNNING_MODE:
0109 return snd_seq_ioctl(file, cmd, arg);
0110 case SNDRV_SEQ_IOCTL_CREATE_PORT32:
0111 return snd_seq_call_port_info_ioctl(client, SNDRV_SEQ_IOCTL_CREATE_PORT, argp);
0112 case SNDRV_SEQ_IOCTL_DELETE_PORT32:
0113 return snd_seq_call_port_info_ioctl(client, SNDRV_SEQ_IOCTL_DELETE_PORT, argp);
0114 case SNDRV_SEQ_IOCTL_GET_PORT_INFO32:
0115 return snd_seq_call_port_info_ioctl(client, SNDRV_SEQ_IOCTL_GET_PORT_INFO, argp);
0116 case SNDRV_SEQ_IOCTL_SET_PORT_INFO32:
0117 return snd_seq_call_port_info_ioctl(client, SNDRV_SEQ_IOCTL_SET_PORT_INFO, argp);
0118 case SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT32:
0119 return snd_seq_call_port_info_ioctl(client, SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT, argp);
0120 }
0121 return -ENOIOCTLCMD;
0122 }