ALSA: pcm: Allow NULL ioctl ops
authorTakashi Iwai <tiwai@suse.de>
Sun, 17 Nov 2019 08:53:03 +0000 (09:53 +0100)
committerTakashi Iwai <tiwai@suse.de>
Wed, 20 Nov 2019 18:39:54 +0000 (19:39 +0100)
Currently PCM ioctl ops is a mandatory field but almost all drivers
simply pass snd_pcm_lib_ioctl.  For simplicity, allow to set NULL in
the field and call snd_pcm_lib_ioctl() as default.

Link: https://lore.kernel.org/r/20191117085308.23915-4-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/core/pcm_native.c

index f1646735bde62b5f4b6cd8638f862822c7370121..704ea75199e4c241495e61a8c9701fb05e1bc56d 100644 (file)
@@ -178,6 +178,16 @@ void snd_pcm_stream_unlock_irqrestore(struct snd_pcm_substream *substream,
 }
 EXPORT_SYMBOL_GPL(snd_pcm_stream_unlock_irqrestore);
 
+/* Run PCM ioctl ops */
+static int snd_pcm_ops_ioctl(struct snd_pcm_substream *substream,
+                            unsigned cmd, void *arg)
+{
+       if (substream->ops->ioctl)
+               return substream->ops->ioctl(substream, cmd, arg);
+       else
+               return snd_pcm_lib_ioctl(substream, cmd, arg);
+}
+
 int snd_pcm_info(struct snd_pcm_substream *substream, struct snd_pcm_info *info)
 {
        struct snd_pcm *pcm = substream->pcm;
@@ -448,8 +458,9 @@ static int fixup_unreferenced_params(struct snd_pcm_substream *substream,
                m = hw_param_mask_c(params, SNDRV_PCM_HW_PARAM_FORMAT);
                i = hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_CHANNELS);
                if (snd_mask_single(m) && snd_interval_single(i)) {
-                       err = substream->ops->ioctl(substream,
-                                       SNDRV_PCM_IOCTL1_FIFO_SIZE, params);
+                       err = snd_pcm_ops_ioctl(substream,
+                                               SNDRV_PCM_IOCTL1_FIFO_SIZE,
+                                               params);
                        if (err < 0)
                                return err;
                }
@@ -971,7 +982,7 @@ static int snd_pcm_channel_info(struct snd_pcm_substream *substream,
                return -EINVAL;
        memset(info, 0, sizeof(*info));
        info->channel = channel;
-       return substream->ops->ioctl(substream, SNDRV_PCM_IOCTL1_CHANNEL_INFO, info);
+       return snd_pcm_ops_ioctl(substream, SNDRV_PCM_IOCTL1_CHANNEL_INFO, info);
 }
 
 static int snd_pcm_channel_info_user(struct snd_pcm_substream *substream,
@@ -1647,7 +1658,7 @@ static int snd_pcm_pre_reset(struct snd_pcm_substream *substream, int state)
 static int snd_pcm_do_reset(struct snd_pcm_substream *substream, int state)
 {
        struct snd_pcm_runtime *runtime = substream->runtime;
-       int err = substream->ops->ioctl(substream, SNDRV_PCM_IOCTL1_RESET, NULL);
+       int err = snd_pcm_ops_ioctl(substream, SNDRV_PCM_IOCTL1_RESET, NULL);
        if (err < 0)
                return err;
        runtime->hw_ptr_base = 0;