seq_compat.c (4007B)
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 12struct 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 31static 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 66enum { 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 74static 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_CLIENT_ID: 85 case SNDRV_SEQ_IOCTL_SYSTEM_INFO: 86 case SNDRV_SEQ_IOCTL_GET_CLIENT_INFO: 87 case SNDRV_SEQ_IOCTL_SET_CLIENT_INFO: 88 case SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT: 89 case SNDRV_SEQ_IOCTL_UNSUBSCRIBE_PORT: 90 case SNDRV_SEQ_IOCTL_CREATE_QUEUE: 91 case SNDRV_SEQ_IOCTL_DELETE_QUEUE: 92 case SNDRV_SEQ_IOCTL_GET_QUEUE_INFO: 93 case SNDRV_SEQ_IOCTL_SET_QUEUE_INFO: 94 case SNDRV_SEQ_IOCTL_GET_NAMED_QUEUE: 95 case SNDRV_SEQ_IOCTL_GET_QUEUE_STATUS: 96 case SNDRV_SEQ_IOCTL_GET_QUEUE_TEMPO: 97 case SNDRV_SEQ_IOCTL_SET_QUEUE_TEMPO: 98 case SNDRV_SEQ_IOCTL_GET_QUEUE_TIMER: 99 case SNDRV_SEQ_IOCTL_SET_QUEUE_TIMER: 100 case SNDRV_SEQ_IOCTL_GET_QUEUE_CLIENT: 101 case SNDRV_SEQ_IOCTL_SET_QUEUE_CLIENT: 102 case SNDRV_SEQ_IOCTL_GET_CLIENT_POOL: 103 case SNDRV_SEQ_IOCTL_SET_CLIENT_POOL: 104 case SNDRV_SEQ_IOCTL_REMOVE_EVENTS: 105 case SNDRV_SEQ_IOCTL_QUERY_SUBS: 106 case SNDRV_SEQ_IOCTL_GET_SUBSCRIPTION: 107 case SNDRV_SEQ_IOCTL_QUERY_NEXT_CLIENT: 108 case SNDRV_SEQ_IOCTL_RUNNING_MODE: 109 return snd_seq_ioctl(file, cmd, arg); 110 case SNDRV_SEQ_IOCTL_CREATE_PORT32: 111 return snd_seq_call_port_info_ioctl(client, SNDRV_SEQ_IOCTL_CREATE_PORT, argp); 112 case SNDRV_SEQ_IOCTL_DELETE_PORT32: 113 return snd_seq_call_port_info_ioctl(client, SNDRV_SEQ_IOCTL_DELETE_PORT, argp); 114 case SNDRV_SEQ_IOCTL_GET_PORT_INFO32: 115 return snd_seq_call_port_info_ioctl(client, SNDRV_SEQ_IOCTL_GET_PORT_INFO, argp); 116 case SNDRV_SEQ_IOCTL_SET_PORT_INFO32: 117 return snd_seq_call_port_info_ioctl(client, SNDRV_SEQ_IOCTL_SET_PORT_INFO, argp); 118 case SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT32: 119 return snd_seq_call_port_info_ioctl(client, SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT, argp); 120 } 121 return -ENOIOCTLCMD; 122}