ALSA: rawmidi: Skip UMP devices at SNDRV_CTL_IOCTL_RAWMIDI_NEXT_DEVICE
authorTakashi Iwai <tiwai@suse.de>
Tue, 23 May 2023 07:53:25 +0000 (09:53 +0200)
committerTakashi Iwai <tiwai@suse.de>
Tue, 23 May 2023 10:10:57 +0000 (12:10 +0200)
Applications may look for rawmidi devices with the ioctl
SNDRV_CTL_IOCTL_RAWMIDI_NEXT_DEVICE.  Returning a UMP device from this
ioctl may confuse the existing applications that support only the
legacy rawmidi.

This patch changes the code to skip the UMP devices from the lookup
for avoiding the confusion, and introduces a new ioctl to look for the
UMP devices instead.

Along with this change, bump the CTL protocol version to 2.0.9.

Reviewed-by: Jaroslav Kysela <perex@perex.cz>
Link: https://lore.kernel.org/r/20230523075358.9672-5-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
include/uapi/sound/asound.h
sound/core/rawmidi.c

index b001df4b335e0d467496137410e538f5656f3949..1e4a21036109f2e65395186aa1b7d1ba1aae042f 100644 (file)
@@ -1016,7 +1016,7 @@ struct snd_timer_tread {
  *                                                                          *
  ****************************************************************************/
 
-#define SNDRV_CTL_VERSION              SNDRV_PROTOCOL_VERSION(2, 0, 8)
+#define SNDRV_CTL_VERSION              SNDRV_PROTOCOL_VERSION(2, 0, 9)
 
 struct snd_ctl_card_info {
        int card;                       /* card number */
@@ -1177,6 +1177,7 @@ struct snd_ctl_tlv {
 #define SNDRV_CTL_IOCTL_RAWMIDI_NEXT_DEVICE _IOWR('U', 0x40, int)
 #define SNDRV_CTL_IOCTL_RAWMIDI_INFO   _IOWR('U', 0x41, struct snd_rawmidi_info)
 #define SNDRV_CTL_IOCTL_RAWMIDI_PREFER_SUBDEVICE _IOW('U', 0x42, int)
+#define SNDRV_CTL_IOCTL_UMP_NEXT_DEVICE        _IOWR('U', 0x43, int)
 #define SNDRV_CTL_IOCTL_POWER          _IOWR('U', 0xd0, int)
 #define SNDRV_CTL_IOCTL_POWER_STATE    _IOR('U', 0xd1, int)
 
index 6360e2239a63f43989e88fd2adf6ce632508d627..9936ed282b85cf5684573eff0046ac5bb7d63a31 100644 (file)
@@ -1012,6 +1012,37 @@ static long snd_rawmidi_ioctl(struct file *file, unsigned int cmd, unsigned long
        return -ENOTTY;
 }
 
+/* ioctl to find the next device; either legacy or UMP depending on @find_ump */
+static int snd_rawmidi_next_device(struct snd_card *card, int __user *argp,
+                                  bool find_ump)
+
+{
+       struct snd_rawmidi *rmidi;
+       int device;
+       bool is_ump;
+
+       if (get_user(device, argp))
+               return -EFAULT;
+       if (device >= SNDRV_RAWMIDI_DEVICES) /* next device is -1 */
+               device = SNDRV_RAWMIDI_DEVICES - 1;
+       mutex_lock(&register_mutex);
+       device = device < 0 ? 0 : device + 1;
+       for (; device < SNDRV_RAWMIDI_DEVICES; device++) {
+               rmidi = snd_rawmidi_search(card, device);
+               if (!rmidi)
+                       continue;
+               is_ump = rawmidi_is_ump(rmidi);
+               if (find_ump == is_ump)
+                       break;
+       }
+       if (device == SNDRV_RAWMIDI_DEVICES)
+               device = -1;
+       mutex_unlock(&register_mutex);
+       if (put_user(device, argp))
+               return -EFAULT;
+       return 0;
+}
+
 static int snd_rawmidi_control_ioctl(struct snd_card *card,
                                     struct snd_ctl_file *control,
                                     unsigned int cmd,
@@ -1021,27 +1052,11 @@ static int snd_rawmidi_control_ioctl(struct snd_card *card,
 
        switch (cmd) {
        case SNDRV_CTL_IOCTL_RAWMIDI_NEXT_DEVICE:
-       {
-               int device;
-
-               if (get_user(device, (int __user *)argp))
-                       return -EFAULT;
-               if (device >= SNDRV_RAWMIDI_DEVICES) /* next device is -1 */
-                       device = SNDRV_RAWMIDI_DEVICES - 1;
-               mutex_lock(&register_mutex);
-               device = device < 0 ? 0 : device + 1;
-               while (device < SNDRV_RAWMIDI_DEVICES) {
-                       if (snd_rawmidi_search(card, device))
-                               break;
-                       device++;
-               }
-               if (device == SNDRV_RAWMIDI_DEVICES)
-                       device = -1;
-               mutex_unlock(&register_mutex);
-               if (put_user(device, (int __user *)argp))
-                       return -EFAULT;
-               return 0;
-       }
+               return snd_rawmidi_next_device(card, argp, false);
+#if IS_ENABLED(CONFIG_SND_UMP)
+       case SNDRV_CTL_IOCTL_UMP_NEXT_DEVICE:
+               return snd_rawmidi_next_device(card, argp, true);
+#endif
        case SNDRV_CTL_IOCTL_RAWMIDI_PREFER_SUBDEVICE:
        {
                int val;