ALSA: ump: Add info flag bit for static blocks

UMP v1.1 spec allows to inform whether the function blocks are static
and not dynamically updated.  Add a new flag bit to
snd_ump_endpoint_info to reflect that attribute, too.

The flag is set when a USB MIDI device is still in the old MIDI 2.0
without UMP 1.1 support.  Then the driver falls back to GTBs, and they
are supposed to be static-only.

Link: https://lore.kernel.org/r/20230612081054.17200-10-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
Takashi Iwai 2023-06-12 10:10:53 +02:00
parent 6a8b4800ae
commit 01dfa8e969
3 changed files with 16 additions and 0 deletions

View File

@ -780,6 +780,9 @@ struct snd_rawmidi_status {
}; };
#endif #endif
/* UMP EP info flags */
#define SNDRV_UMP_EP_INFO_STATIC_BLOCKS 0x01
/* UMP EP Protocol / JRTS capability bits */ /* UMP EP Protocol / JRTS capability bits */
#define SNDRV_UMP_EP_INFO_PROTO_MIDI_MASK 0x0300 #define SNDRV_UMP_EP_INFO_PROTO_MIDI_MASK 0x0300
#define SNDRV_UMP_EP_INFO_PROTO_MIDI1 0x0100 /* MIDI 1.0 */ #define SNDRV_UMP_EP_INFO_PROTO_MIDI1 0x0100 /* MIDI 1.0 */

View File

@ -490,6 +490,8 @@ static void snd_ump_proc_read(struct snd_info_entry *entry,
ump->info.sw_revision[2], ump->info.sw_revision[2],
ump->info.sw_revision[3]); ump->info.sw_revision[3]);
} }
snd_iprintf(buffer, "Static Blocks: %s\n",
(ump->info.flags & SNDRV_UMP_EP_INFO_STATIC_BLOCKS) ? "Yes" : "No");
snd_iprintf(buffer, "Num Blocks: %d\n\n", ump->info.num_blocks); snd_iprintf(buffer, "Num Blocks: %d\n\n", ump->info.num_blocks);
list_for_each_entry(fb, &ump->block_list, list) { list_for_each_entry(fb, &ump->block_list, list) {
@ -608,6 +610,9 @@ static int ump_handle_ep_info_msg(struct snd_ump_endpoint *ump,
ump->info.num_blocks = 1; ump->info.num_blocks = 1;
} }
if (buf->ep_info.static_function_block)
ump->info.flags |= SNDRV_UMP_EP_INFO_STATIC_BLOCKS;
ump->info.protocol_caps = (buf->ep_info.protocol << 8) | ump->info.protocol_caps = (buf->ep_info.protocol << 8) |
buf->ep_info.jrts; buf->ep_info.jrts;
@ -708,6 +713,12 @@ static bool is_fb_info_updated(struct snd_ump_endpoint *ump,
{ {
char tmpbuf[offsetof(struct snd_ump_block_info, name)]; char tmpbuf[offsetof(struct snd_ump_block_info, name)];
if (ump->info.flags & SNDRV_UMP_EP_INFO_STATIC_BLOCKS) {
ump_info(ump, "Skipping static FB info update (blk#%d)\n",
fb->info.block_id);
return 0;
}
memcpy(tmpbuf, &fb->info, sizeof(tmpbuf)); memcpy(tmpbuf, &fb->info, sizeof(tmpbuf));
fill_fb_info(ump, (struct snd_ump_block_info *)tmpbuf, buf); fill_fb_info(ump, (struct snd_ump_block_info *)tmpbuf, buf);
return memcmp(&fb->info, tmpbuf, sizeof(tmpbuf)) != 0; return memcmp(&fb->info, tmpbuf, sizeof(tmpbuf)) != 0;

View File

@ -888,6 +888,8 @@ static int create_blocks_from_gtb(struct snd_usb_midi2_interface *umidi)
/* Blocks have been already created? */ /* Blocks have been already created? */
if (rmidi->ump_parsed || rmidi->ump->info.num_blocks) if (rmidi->ump_parsed || rmidi->ump->info.num_blocks)
continue; continue;
/* GTB is static-only */
rmidi->ump->info.flags |= SNDRV_UMP_EP_INFO_STATIC_BLOCKS;
/* loop over GTBs */ /* loop over GTBs */
for (dir = 0; dir < 2; dir++) { for (dir = 0; dir < 2; dir++) {
if (!rmidi->eps[dir]) if (!rmidi->eps[dir])