Back to home page

LXR

 
 

    


0001 /*
0002  *   32bit -> 64bit ioctl wrapper for sequencer API
0003  *   Copyright (c) by Takashi Iwai <tiwai@suse.de>
0004  *
0005  *   This program is free software; you can redistribute it and/or modify
0006  *   it under the terms of the GNU General Public License as published by
0007  *   the Free Software Foundation; either version 2 of the License, or
0008  *   (at your option) any later version.
0009  *
0010  *   This program is distributed in the hope that it will be useful,
0011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
0012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0013  *   GNU General Public License for more details.
0014  *
0015  *   You should have received a copy of the GNU General Public License
0016  *   along with this program; if not, write to the Free Software
0017  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
0018  *
0019  */
0020 
0021 /* This file included from seq.c */
0022 
0023 #include <linux/compat.h>
0024 #include <linux/slab.h>
0025 
0026 struct snd_seq_port_info32 {
0027     struct snd_seq_addr addr;   /* client/port numbers */
0028     char name[64];          /* port name */
0029 
0030     u32 capability; /* port capability bits */
0031     u32 type;       /* port type bits */
0032     s32 midi_channels;      /* channels per MIDI port */
0033     s32 midi_voices;        /* voices per MIDI port */
0034     s32 synth_voices;       /* voices per SYNTH port */
0035 
0036     s32 read_use;           /* R/O: subscribers for output (from this port) */
0037     s32 write_use;          /* R/O: subscribers for input (to this port) */
0038 
0039     u32 kernel;         /* reserved for kernel use (must be NULL) */
0040     u32 flags;      /* misc. conditioning */
0041     unsigned char time_queue;   /* queue # for timestamping */
0042     char reserved[59];      /* for future use */
0043 };
0044 
0045 static int snd_seq_call_port_info_ioctl(struct snd_seq_client *client, unsigned int cmd,
0046                     struct snd_seq_port_info32 __user *data32)
0047 {
0048     int err = -EFAULT;
0049     struct snd_seq_port_info *data;
0050 
0051     data = kmalloc(sizeof(*data), GFP_KERNEL);
0052     if (!data)
0053         return -ENOMEM;
0054 
0055     if (copy_from_user(data, data32, sizeof(*data32)) ||
0056         get_user(data->flags, &data32->flags) ||
0057         get_user(data->time_queue, &data32->time_queue))
0058         goto error;
0059     data->kernel = NULL;
0060 
0061     err = snd_seq_kernel_client_ctl(client->number, cmd, data);
0062     if (err < 0)
0063         goto error;
0064 
0065     if (copy_to_user(data32, data, sizeof(*data32)) ||
0066         put_user(data->flags, &data32->flags) ||
0067         put_user(data->time_queue, &data32->time_queue))
0068         err = -EFAULT;
0069 
0070  error:
0071     kfree(data);
0072     return err;
0073 }
0074 
0075 
0076 
0077 /*
0078  */
0079 
0080 enum {
0081     SNDRV_SEQ_IOCTL_CREATE_PORT32 = _IOWR('S', 0x20, struct snd_seq_port_info32),
0082     SNDRV_SEQ_IOCTL_DELETE_PORT32 = _IOW ('S', 0x21, struct snd_seq_port_info32),
0083     SNDRV_SEQ_IOCTL_GET_PORT_INFO32 = _IOWR('S', 0x22, struct snd_seq_port_info32),
0084     SNDRV_SEQ_IOCTL_SET_PORT_INFO32 = _IOW ('S', 0x23, struct snd_seq_port_info32),
0085     SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT32 = _IOWR('S', 0x52, struct snd_seq_port_info32),
0086 };
0087 
0088 static long snd_seq_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg)
0089 {
0090     struct snd_seq_client *client = file->private_data;
0091     void __user *argp = compat_ptr(arg);
0092 
0093     if (snd_BUG_ON(!client))
0094         return -ENXIO;
0095 
0096     switch (cmd) {
0097     case SNDRV_SEQ_IOCTL_PVERSION:
0098     case SNDRV_SEQ_IOCTL_CLIENT_ID:
0099     case SNDRV_SEQ_IOCTL_SYSTEM_INFO:
0100     case SNDRV_SEQ_IOCTL_GET_CLIENT_INFO:
0101     case SNDRV_SEQ_IOCTL_SET_CLIENT_INFO:
0102     case SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT:
0103     case SNDRV_SEQ_IOCTL_UNSUBSCRIBE_PORT:
0104     case SNDRV_SEQ_IOCTL_CREATE_QUEUE:
0105     case SNDRV_SEQ_IOCTL_DELETE_QUEUE:
0106     case SNDRV_SEQ_IOCTL_GET_QUEUE_INFO:
0107     case SNDRV_SEQ_IOCTL_SET_QUEUE_INFO:
0108     case SNDRV_SEQ_IOCTL_GET_NAMED_QUEUE:
0109     case SNDRV_SEQ_IOCTL_GET_QUEUE_STATUS:
0110     case SNDRV_SEQ_IOCTL_GET_QUEUE_TEMPO:
0111     case SNDRV_SEQ_IOCTL_SET_QUEUE_TEMPO:
0112     case SNDRV_SEQ_IOCTL_GET_QUEUE_TIMER:
0113     case SNDRV_SEQ_IOCTL_SET_QUEUE_TIMER:
0114     case SNDRV_SEQ_IOCTL_GET_QUEUE_CLIENT:
0115     case SNDRV_SEQ_IOCTL_SET_QUEUE_CLIENT:
0116     case SNDRV_SEQ_IOCTL_GET_CLIENT_POOL:
0117     case SNDRV_SEQ_IOCTL_SET_CLIENT_POOL:
0118     case SNDRV_SEQ_IOCTL_REMOVE_EVENTS:
0119     case SNDRV_SEQ_IOCTL_QUERY_SUBS:
0120     case SNDRV_SEQ_IOCTL_GET_SUBSCRIPTION:
0121     case SNDRV_SEQ_IOCTL_QUERY_NEXT_CLIENT:
0122     case SNDRV_SEQ_IOCTL_RUNNING_MODE:
0123         return snd_seq_ioctl(file, cmd, arg);
0124     case SNDRV_SEQ_IOCTL_CREATE_PORT32:
0125         return snd_seq_call_port_info_ioctl(client, SNDRV_SEQ_IOCTL_CREATE_PORT, argp);
0126     case SNDRV_SEQ_IOCTL_DELETE_PORT32:
0127         return snd_seq_call_port_info_ioctl(client, SNDRV_SEQ_IOCTL_DELETE_PORT, argp);
0128     case SNDRV_SEQ_IOCTL_GET_PORT_INFO32:
0129         return snd_seq_call_port_info_ioctl(client, SNDRV_SEQ_IOCTL_GET_PORT_INFO, argp);
0130     case SNDRV_SEQ_IOCTL_SET_PORT_INFO32:
0131         return snd_seq_call_port_info_ioctl(client, SNDRV_SEQ_IOCTL_SET_PORT_INFO, argp);
0132     case SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT32:
0133         return snd_seq_call_port_info_ioctl(client, SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT, argp);
0134     }
0135     return -ENOIOCTLCMD;
0136 }