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