]> www.infradead.org Git - users/hch/misc.git/commitdiff
ALSA: rawmidi: Show substream activity in info ioctl
authorTakashi Iwai <tiwai@suse.de>
Fri, 10 Jan 2025 15:59:35 +0000 (16:59 +0100)
committerTakashi Iwai <tiwai@suse.de>
Sun, 12 Jan 2025 12:12:20 +0000 (13:12 +0100)
The UMP legacy rawmidi may turn on/off the substream dynamically
depending on the UMP Function Block information.  So far, there was no
direct way to know whether the substream is disabled (inactive) or
not; at most one can take a look at the substream name string or try
to open and get -ENODEV.

This patch extends the rawmidi info ioctl to show the current inactive
state of the given substream.  When the selected substream is
inactive, info flags field contains the new bit flag
SNDRV_RAWMIDI_INFO_STREAM_INACTIVE.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://patch.msgid.link/20250110155943.31578-3-tiwai@suse.de
Documentation/sound/designs/midi-2.0.rst
include/sound/rawmidi.h
include/uapi/sound/asound.h
sound/core/rawmidi.c
sound/core/ump.c

index d525bc2805f7224715ff0e2ffc5f66f77398323e..d6c17a47c8320d1c45eba752384d75b97788fff9 100644 (file)
@@ -298,6 +298,12 @@ Rawmidi API Extensions
   On the other hand, the UMP rawmidi device number is found in
   `tied_device` field of the legacy rawmidi info, too.
 
+* Each substream of the legacy rawmidi may be enabled / disabled
+  dynamically depending on the UMP FB state.
+  When the selected substream is inactive, it's indicated by the bit
+  0x10 (`SNDRV_RAWMIDI_INFO_STREAM_INACTIVE`) in the `flags` field of
+  the legacy rawmidi info.
+
 
 Control API Extensions
 ======================
index 7f1fec786b72fc7a893e358f2611d1d29f185ad5..6f2e95298fc769855e6f6864c0d38dfddd2ffbd6 100644 (file)
@@ -89,6 +89,7 @@ struct snd_rawmidi_substream {
        unsigned int framing;           /* whether to frame input data */
        unsigned int clock_type;        /* clock source to use for input framing */
        int use_count;                  /* use counter (for output) */
+       bool inactive;                  /* inactive substream (for UMP legacy) */
        size_t bytes;
        spinlock_t lock;
        struct snd_rawmidi *rmidi;
index 1fcff031b5e390066b5b84b4d60787705aed5bd9..9f3b32602ac16536ae6d35ecb407f7f6e1bd50a9 100644 (file)
@@ -728,6 +728,7 @@ enum {
 #define SNDRV_RAWMIDI_INFO_INPUT               0x00000002
 #define SNDRV_RAWMIDI_INFO_DUPLEX              0x00000004
 #define SNDRV_RAWMIDI_INFO_UMP                 0x00000008
+#define SNDRV_RAWMIDI_INFO_STREAM_INACTIVE     0x00000010
 
 #define SNDRV_RAWMIDI_DEVICE_UNKNOWN           -1
 
index 858878fe487ae8259c89e97dc1f8219f0471e284..8a681bff4f7f61bbeeacf97d6776dc8059752cec 100644 (file)
@@ -629,6 +629,8 @@ static int snd_rawmidi_info(struct snd_rawmidi_substream *substream,
        info->subdevice = substream->number;
        info->stream = substream->stream;
        info->flags = rmidi->info_flags;
+       if (substream->inactive)
+               info->flags |= SNDRV_RAWMIDI_INFO_STREAM_INACTIVE;
        strcpy(info->id, rmidi->id);
        strcpy(info->name, rmidi->name);
        strcpy(info->subname, substream->name);
index 0bfab84eaafb643f2ba9ab8bf5059d8316ff2aa4..d6cd11be875045ac901e3d7089efb2a3a267fafb 100644 (file)
@@ -1250,8 +1250,8 @@ static int fill_legacy_mapping(struct snd_ump_endpoint *ump)
        return num;
 }
 
-static void fill_substream_names(struct snd_ump_endpoint *ump,
-                                struct snd_rawmidi *rmidi, int dir)
+static void update_legacy_substreams(struct snd_ump_endpoint *ump,
+                                    struct snd_rawmidi *rmidi, int dir)
 {
        struct snd_rawmidi_substream *s;
        const char *name;
@@ -1265,6 +1265,7 @@ static void fill_substream_names(struct snd_ump_endpoint *ump,
                scnprintf(s->name, sizeof(s->name), "Group %d (%.16s)%s",
                          idx + 1, name,
                          ump->groups[idx].active ? "" : " [Inactive]");
+               s->inactive = !ump->groups[idx].active;
        }
 }
 
@@ -1272,8 +1273,8 @@ static void update_legacy_names(struct snd_ump_endpoint *ump)
 {
        struct snd_rawmidi *rmidi = ump->legacy_rmidi;
 
-       fill_substream_names(ump, rmidi, SNDRV_RAWMIDI_STREAM_INPUT);
-       fill_substream_names(ump, rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT);
+       update_legacy_substreams(ump, rmidi, SNDRV_RAWMIDI_STREAM_INPUT);
+       update_legacy_substreams(ump, rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT);
 }
 
 int snd_ump_attach_legacy_rawmidi(struct snd_ump_endpoint *ump,