Skip to content

Commit 54852e8

Browse files
committed
ALSA: usb-audio: Parse UMP Endpoint and Function Blocks at first
Try to parse the UMP Endpoint and UMP Function Blocks for building the topology at first. Only when those are missing (e.g. on an older USB MIDI 2.0 spec or a unidirectional endpoint), the driver still creates blocks based on USB group terminal block information as fallback. Link: https://lore.kernel.org/r/20230612081054.17200-4-tiwai@suse.de Signed-off-by: Takashi Iwai <tiwai@suse.de>
1 parent 37e0e14 commit 54852e8

1 file changed

Lines changed: 33 additions & 1 deletion

File tree

sound/usb/midi2.c

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ struct snd_usb_midi2_ump {
8080
struct snd_usb_midi2_endpoint *eps[2]; /* USB MIDI endpoints */
8181
int index; /* rawmidi device index */
8282
unsigned char usb_block_id; /* USB GTB id used for finding a pair */
83+
bool ump_parsed; /* Parsed UMP 1.1 EP/FB info*/
8384
struct list_head list; /* list to umidi->rawmidi_list */
8485
};
8586

@@ -786,6 +787,31 @@ static int find_matching_ep_partner(struct snd_usb_midi2_interface *umidi,
786787
return 0;
787788
}
788789

790+
/* Call UMP helper to parse UMP endpoints;
791+
* this needs to be called after starting the input streams for bi-directional
792+
* communications
793+
*/
794+
static int parse_ump_endpoints(struct snd_usb_midi2_interface *umidi)
795+
{
796+
struct snd_usb_midi2_ump *rmidi;
797+
int err;
798+
799+
list_for_each_entry(rmidi, &umidi->rawmidi_list, list) {
800+
if (!rmidi->ump ||
801+
!(rmidi->ump->core.info_flags & SNDRV_RAWMIDI_INFO_DUPLEX))
802+
continue;
803+
err = snd_ump_parse_endpoint(rmidi->ump);
804+
if (!err) {
805+
rmidi->ump_parsed = true;
806+
} else {
807+
if (err == -ENOMEM)
808+
return err;
809+
/* fall back to GTB later */
810+
}
811+
}
812+
return 0;
813+
}
814+
789815
/* create a UMP block from a GTB entry */
790816
static int create_gtb_block(struct snd_usb_midi2_ump *rmidi, int dir, int blk)
791817
{
@@ -856,7 +882,7 @@ static int create_blocks_from_gtb(struct snd_usb_midi2_interface *umidi)
856882
if (!rmidi->ump)
857883
continue;
858884
/* Blocks have been already created? */
859-
if (rmidi->ump->info.num_blocks)
885+
if (rmidi->ump_parsed || rmidi->ump->info.num_blocks)
860886
continue;
861887
/* loop over GTBs */
862888
for (dir = 0; dir < 2; dir++) {
@@ -1110,6 +1136,12 @@ int snd_usb_midi_v2_create(struct snd_usb_audio *chip,
11101136
goto error;
11111137
}
11121138

1139+
err = parse_ump_endpoints(umidi);
1140+
if (err < 0) {
1141+
usb_audio_err(chip, "Failed to parse UMP endpoint\n");
1142+
goto error;
1143+
}
1144+
11131145
err = create_blocks_from_gtb(umidi);
11141146
if (err < 0) {
11151147
usb_audio_err(chip, "Failed to create GTB blocks\n");

0 commit comments

Comments
 (0)