xref: /openbmc/linux/sound/core/rawmidi_compat.c (revision 1da177e4)
11da177e4SLinus Torvalds /*
21da177e4SLinus Torvalds  *   32bit -> 64bit ioctl wrapper for raw MIDI API
31da177e4SLinus Torvalds  *   Copyright (c) by Takashi Iwai <tiwai@suse.de>
41da177e4SLinus Torvalds  *
51da177e4SLinus Torvalds  *   This program is free software; you can redistribute it and/or modify
61da177e4SLinus Torvalds  *   it under the terms of the GNU General Public License as published by
71da177e4SLinus Torvalds  *   the Free Software Foundation; either version 2 of the License, or
81da177e4SLinus Torvalds  *   (at your option) any later version.
91da177e4SLinus Torvalds  *
101da177e4SLinus Torvalds  *   This program is distributed in the hope that it will be useful,
111da177e4SLinus Torvalds  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
121da177e4SLinus Torvalds  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
131da177e4SLinus Torvalds  *   GNU General Public License for more details.
141da177e4SLinus Torvalds  *
151da177e4SLinus Torvalds  *   You should have received a copy of the GNU General Public License
161da177e4SLinus Torvalds  *   along with this program; if not, write to the Free Software
171da177e4SLinus Torvalds  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
181da177e4SLinus Torvalds  *
191da177e4SLinus Torvalds  */
201da177e4SLinus Torvalds 
211da177e4SLinus Torvalds /* This file included from rawmidi.c */
221da177e4SLinus Torvalds 
231da177e4SLinus Torvalds #include <linux/compat.h>
241da177e4SLinus Torvalds 
251da177e4SLinus Torvalds struct sndrv_rawmidi_params32 {
261da177e4SLinus Torvalds 	s32 stream;
271da177e4SLinus Torvalds 	u32 buffer_size;
281da177e4SLinus Torvalds 	u32 avail_min;
291da177e4SLinus Torvalds 	unsigned int no_active_sensing; /* avoid bit-field */
301da177e4SLinus Torvalds 	unsigned char reserved[16];
311da177e4SLinus Torvalds } __attribute__((packed));
321da177e4SLinus Torvalds 
331da177e4SLinus Torvalds static int snd_rawmidi_ioctl_params_compat(snd_rawmidi_file_t *rfile,
341da177e4SLinus Torvalds 					   struct sndrv_rawmidi_params32 __user *src)
351da177e4SLinus Torvalds {
361da177e4SLinus Torvalds 	snd_rawmidi_params_t params;
371da177e4SLinus Torvalds 	unsigned int val;
381da177e4SLinus Torvalds 
391da177e4SLinus Torvalds 	if (rfile->output == NULL)
401da177e4SLinus Torvalds 		return -EINVAL;
411da177e4SLinus Torvalds 	if (get_user(params.stream, &src->stream) ||
421da177e4SLinus Torvalds 	    get_user(params.buffer_size, &src->buffer_size) ||
431da177e4SLinus Torvalds 	    get_user(params.avail_min, &src->avail_min) ||
441da177e4SLinus Torvalds 	    get_user(val, &src->no_active_sensing))
451da177e4SLinus Torvalds 		return -EFAULT;
461da177e4SLinus Torvalds 	params.no_active_sensing = val;
471da177e4SLinus Torvalds 	switch (params.stream) {
481da177e4SLinus Torvalds 	case SNDRV_RAWMIDI_STREAM_OUTPUT:
491da177e4SLinus Torvalds 		return snd_rawmidi_output_params(rfile->output, &params);
501da177e4SLinus Torvalds 	case SNDRV_RAWMIDI_STREAM_INPUT:
511da177e4SLinus Torvalds 		return snd_rawmidi_input_params(rfile->input, &params);
521da177e4SLinus Torvalds 	}
531da177e4SLinus Torvalds 	return -EINVAL;
541da177e4SLinus Torvalds }
551da177e4SLinus Torvalds 
561da177e4SLinus Torvalds struct sndrv_rawmidi_status32 {
571da177e4SLinus Torvalds 	s32 stream;
581da177e4SLinus Torvalds 	struct compat_timespec tstamp;
591da177e4SLinus Torvalds 	u32 avail;
601da177e4SLinus Torvalds 	u32 xruns;
611da177e4SLinus Torvalds 	unsigned char reserved[16];
621da177e4SLinus Torvalds } __attribute__((packed));
631da177e4SLinus Torvalds 
641da177e4SLinus Torvalds static int snd_rawmidi_ioctl_status_compat(snd_rawmidi_file_t *rfile,
651da177e4SLinus Torvalds 					   struct sndrv_rawmidi_status32 __user *src)
661da177e4SLinus Torvalds {
671da177e4SLinus Torvalds 	int err;
681da177e4SLinus Torvalds 	snd_rawmidi_status_t status;
691da177e4SLinus Torvalds 
701da177e4SLinus Torvalds 	if (rfile->output == NULL)
711da177e4SLinus Torvalds 		return -EINVAL;
721da177e4SLinus Torvalds 	if (get_user(status.stream, &src->stream))
731da177e4SLinus Torvalds 		return -EFAULT;
741da177e4SLinus Torvalds 
751da177e4SLinus Torvalds 	switch (status.stream) {
761da177e4SLinus Torvalds 	case SNDRV_RAWMIDI_STREAM_OUTPUT:
771da177e4SLinus Torvalds 		err = snd_rawmidi_output_status(rfile->output, &status);
781da177e4SLinus Torvalds 		break;
791da177e4SLinus Torvalds 	case SNDRV_RAWMIDI_STREAM_INPUT:
801da177e4SLinus Torvalds 		err = snd_rawmidi_input_status(rfile->input, &status);
811da177e4SLinus Torvalds 		break;
821da177e4SLinus Torvalds 	default:
831da177e4SLinus Torvalds 		return -EINVAL;
841da177e4SLinus Torvalds 	}
851da177e4SLinus Torvalds 	if (err < 0)
861da177e4SLinus Torvalds 		return err;
871da177e4SLinus Torvalds 
881da177e4SLinus Torvalds 	if (put_user(status.tstamp.tv_sec, &src->tstamp.tv_sec) ||
891da177e4SLinus Torvalds 	    put_user(status.tstamp.tv_nsec, &src->tstamp.tv_nsec) ||
901da177e4SLinus Torvalds 	    put_user(status.avail, &src->avail) ||
911da177e4SLinus Torvalds 	    put_user(status.xruns, &src->xruns))
921da177e4SLinus Torvalds 		return -EFAULT;
931da177e4SLinus Torvalds 
941da177e4SLinus Torvalds 	return 0;
951da177e4SLinus Torvalds }
961da177e4SLinus Torvalds 
971da177e4SLinus Torvalds enum {
981da177e4SLinus Torvalds 	SNDRV_RAWMIDI_IOCTL_PARAMS32 = _IOWR('W', 0x10, struct sndrv_rawmidi_params32),
991da177e4SLinus Torvalds 	SNDRV_RAWMIDI_IOCTL_STATUS32 = _IOWR('W', 0x20, struct sndrv_rawmidi_status32),
1001da177e4SLinus Torvalds };
1011da177e4SLinus Torvalds 
1021da177e4SLinus Torvalds static long snd_rawmidi_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg)
1031da177e4SLinus Torvalds {
1041da177e4SLinus Torvalds 	snd_rawmidi_file_t *rfile;
1051da177e4SLinus Torvalds 	void __user *argp = compat_ptr(arg);
1061da177e4SLinus Torvalds 
1071da177e4SLinus Torvalds 	rfile = file->private_data;
1081da177e4SLinus Torvalds 	switch (cmd) {
1091da177e4SLinus Torvalds 	case SNDRV_RAWMIDI_IOCTL_PVERSION:
1101da177e4SLinus Torvalds 	case SNDRV_RAWMIDI_IOCTL_INFO:
1111da177e4SLinus Torvalds 	case SNDRV_RAWMIDI_IOCTL_DROP:
1121da177e4SLinus Torvalds 	case SNDRV_RAWMIDI_IOCTL_DRAIN:
1131da177e4SLinus Torvalds 		return snd_rawmidi_ioctl(file, cmd, (unsigned long)argp);
1141da177e4SLinus Torvalds 	case SNDRV_RAWMIDI_IOCTL_PARAMS32:
1151da177e4SLinus Torvalds 		return snd_rawmidi_ioctl_params_compat(rfile, argp);
1161da177e4SLinus Torvalds 	case SNDRV_RAWMIDI_IOCTL_STATUS32:
1171da177e4SLinus Torvalds 		return snd_rawmidi_ioctl_status_compat(rfile, argp);
1181da177e4SLinus Torvalds 	}
1191da177e4SLinus Torvalds 	return -ENOIOCTLCMD;
1201da177e4SLinus Torvalds }
121