ALSA: core: Handle user defined ioctls

Handle ioctl magic 'U' as an user defined ioctl so that ALSA core calls
substream's ioctl handler.  This gets rid of a requirement that ALSA core
needs to be changed every time when a new user defined ioctl is introduced.

Change-Id: I8dfebb3100ac40670032e3bd6ca40defc9ac1140
Signed-off-by: Joonwoo Park <joonwoop@codeaurora.org>
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 4636247..7403b40 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -1534,6 +1534,20 @@
 	err = substream->ops->ioctl(substream, cmd, arg);
 	return err;
 }
+
+static int snd_user_ioctl(struct snd_pcm_substream *substream,
+			  unsigned int cmd, void __user *arg)
+{
+	struct snd_pcm_runtime *runtime;
+	int err = 0;
+
+	if (PCM_RUNTIME_CHECK(substream))
+		return -ENXIO;
+	runtime = substream->runtime;
+	err = substream->ops->ioctl(substream, cmd, arg);
+	return err;
+}
+
 /*
  * drop ioctl
  *
@@ -2605,6 +2619,9 @@
 	case SNDRV_COMPRESS_TSTAMP:
 	case SNDRV_COMPRESS_DRAIN:
 		return snd_compressed_ioctl(substream, cmd, arg);
+	default:
+		if (((cmd >> 8) & 0xff) == 'U')
+			return snd_user_ioctl(substream, cmd, arg);
 	}
 	snd_printd("unknown ioctl = 0x%x\n", cmd);
 	return -ENOTTY;
@@ -2788,10 +2805,12 @@
 				  unsigned long arg)
 {
 	struct snd_pcm_file *pcm_file;
+	unsigned char ioctl_magic;
 
 	pcm_file = file->private_data;
+	ioctl_magic = ((cmd >> 8) & 0xff);
 
-	if ((((cmd >> 8) & 0xff) != 'A') && (((cmd >> 8) & 0xff) != 'C'))
+	if (ioctl_magic != 'A' && ioctl_magic != 'C' && ioctl_magic != 'U')
 		return -ENOTTY;
 
 	return snd_pcm_capture_ioctl1(file, pcm_file->substream, cmd,