1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * 32bit -> 64bit ioctl wrapper for sequencer API 4 * Copyright (c) by Takashi Iwai <tiwai@suse.de> 5 */ 6 7 /* This file included from seq.c */ 8 9 #include <linux/compat.h> 10 #include <linux/slab.h> 11 12 struct snd_seq_port_info32 { 13 struct snd_seq_addr addr; /* client/port numbers */ 14 char name[64]; /* port name */ 15 16 u32 capability; /* port capability bits */ 17 u32 type; /* port type bits */ 18 s32 midi_channels; /* channels per MIDI port */ 19 s32 midi_voices; /* voices per MIDI port */ 20 s32 synth_voices; /* voices per SYNTH port */ 21 22 s32 read_use; /* R/O: subscribers for output (from this port) */ 23 s32 write_use; /* R/O: subscribers for input (to this port) */ 24 25 u32 kernel; /* reserved for kernel use (must be NULL) */ 26 u32 flags; /* misc. conditioning */ 27 unsigned char time_queue; /* queue # for timestamping */ 28 char reserved[59]; /* for future use */ 29 }; 30 31 static int snd_seq_call_port_info_ioctl(struct snd_seq_client *client, unsigned int cmd, 32 struct snd_seq_port_info32 __user *data32) 33 { 34 int err = -EFAULT; 35 struct snd_seq_port_info *data; 36 37 data = kmalloc(sizeof(*data), GFP_KERNEL); 38 if (!data) 39 return -ENOMEM; 40 41 if (copy_from_user(data, data32, sizeof(*data32)) || 42 get_user(data->flags, &data32->flags) || 43 get_user(data->time_queue, &data32->time_queue)) 44 goto error; 45 data->kernel = NULL; 46 47 err = snd_seq_kernel_client_ctl(client->number, cmd, data); 48 if (err < 0) 49 goto error; 50 51 if (copy_to_user(data32, data, sizeof(*data32)) || 52 put_user(data->flags, &data32->flags) || 53 put_user(data->time_queue, &data32->time_queue)) 54 err = -EFAULT; 55 56 error: 57 kfree(data); 58 return err; 59 } 60 61 62 63 /* 64 */ 65 66 enum { 67 SNDRV_SEQ_IOCTL_CREATE_PORT32 = _IOWR('S', 0x20, struct snd_seq_port_info32), 68 SNDRV_SEQ_IOCTL_DELETE_PORT32 = _IOW ('S', 0x21, struct snd_seq_port_info32), 69 SNDRV_SEQ_IOCTL_GET_PORT_INFO32 = _IOWR('S', 0x22, struct snd_seq_port_info32), 70 SNDRV_SEQ_IOCTL_SET_PORT_INFO32 = _IOW ('S', 0x23, struct snd_seq_port_info32), 71 SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT32 = _IOWR('S', 0x52, struct snd_seq_port_info32), 72 }; 73 74 static long snd_seq_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg) 75 { 76 struct snd_seq_client *client = file->private_data; 77 void __user *argp = compat_ptr(arg); 78 79 if (snd_BUG_ON(!client)) 80 return -ENXIO; 81 82 switch (cmd) { 83 case SNDRV_SEQ_IOCTL_PVERSION: 84 case SNDRV_SEQ_IOCTL_USER_PVERSION: 85 case SNDRV_SEQ_IOCTL_CLIENT_ID: 86 case SNDRV_SEQ_IOCTL_SYSTEM_INFO: 87 case SNDRV_SEQ_IOCTL_GET_CLIENT_INFO: 88 case SNDRV_SEQ_IOCTL_SET_CLIENT_INFO: 89 case SNDRV_SEQ_IOCTL_GET_CLIENT_UMP_INFO: 90 case SNDRV_SEQ_IOCTL_SET_CLIENT_UMP_INFO: 91 case SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT: 92 case SNDRV_SEQ_IOCTL_UNSUBSCRIBE_PORT: 93 case SNDRV_SEQ_IOCTL_CREATE_QUEUE: 94 case SNDRV_SEQ_IOCTL_DELETE_QUEUE: 95 case SNDRV_SEQ_IOCTL_GET_QUEUE_INFO: 96 case SNDRV_SEQ_IOCTL_SET_QUEUE_INFO: 97 case SNDRV_SEQ_IOCTL_GET_NAMED_QUEUE: 98 case SNDRV_SEQ_IOCTL_GET_QUEUE_STATUS: 99 case SNDRV_SEQ_IOCTL_GET_QUEUE_TEMPO: 100 case SNDRV_SEQ_IOCTL_SET_QUEUE_TEMPO: 101 case SNDRV_SEQ_IOCTL_GET_QUEUE_TIMER: 102 case SNDRV_SEQ_IOCTL_SET_QUEUE_TIMER: 103 case SNDRV_SEQ_IOCTL_GET_QUEUE_CLIENT: 104 case SNDRV_SEQ_IOCTL_SET_QUEUE_CLIENT: 105 case SNDRV_SEQ_IOCTL_GET_CLIENT_POOL: 106 case SNDRV_SEQ_IOCTL_SET_CLIENT_POOL: 107 case SNDRV_SEQ_IOCTL_REMOVE_EVENTS: 108 case SNDRV_SEQ_IOCTL_QUERY_SUBS: 109 case SNDRV_SEQ_IOCTL_GET_SUBSCRIPTION: 110 case SNDRV_SEQ_IOCTL_QUERY_NEXT_CLIENT: 111 case SNDRV_SEQ_IOCTL_RUNNING_MODE: 112 return snd_seq_ioctl(file, cmd, arg); 113 case SNDRV_SEQ_IOCTL_CREATE_PORT32: 114 return snd_seq_call_port_info_ioctl(client, SNDRV_SEQ_IOCTL_CREATE_PORT, argp); 115 case SNDRV_SEQ_IOCTL_DELETE_PORT32: 116 return snd_seq_call_port_info_ioctl(client, SNDRV_SEQ_IOCTL_DELETE_PORT, argp); 117 case SNDRV_SEQ_IOCTL_GET_PORT_INFO32: 118 return snd_seq_call_port_info_ioctl(client, SNDRV_SEQ_IOCTL_GET_PORT_INFO, argp); 119 case SNDRV_SEQ_IOCTL_SET_PORT_INFO32: 120 return snd_seq_call_port_info_ioctl(client, SNDRV_SEQ_IOCTL_SET_PORT_INFO, argp); 121 case SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT32: 122 return snd_seq_call_port_info_ioctl(client, SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT, argp); 123 } 124 return -ENOIOCTLCMD; 125 } 126