lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20230612081054.17200-4-tiwai@suse.de>
Date:   Mon, 12 Jun 2023 10:10:47 +0200
From:   Takashi Iwai <tiwai@...e.de>
To:     alsa-devel@...a-project.org
Cc:     linux-kernel@...r.kernel.org
Subject: [PATCH 03/10] 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.

Signed-off-by: Takashi Iwai <tiwai@...e.de>
---
 sound/usb/midi2.c | 34 +++++++++++++++++++++++++++++++++-
 1 file changed, 33 insertions(+), 1 deletion(-)

diff --git a/sound/usb/midi2.c b/sound/usb/midi2.c
index 341783418a6a..fad094e15999 100644
--- a/sound/usb/midi2.c
+++ b/sound/usb/midi2.c
@@ -80,6 +80,7 @@ struct snd_usb_midi2_ump {
 	struct snd_usb_midi2_endpoint *eps[2];	/* USB MIDI endpoints */
 	int index;				/* rawmidi device index */
 	unsigned char usb_block_id;		/* USB GTB id used for finding a pair */
+	bool ump_parsed;			/* Parsed UMP 1.1 EP/FB info*/
 	struct list_head list;		/* list to umidi->rawmidi_list */
 };
 
@@ -786,6 +787,31 @@ static int find_matching_ep_partner(struct snd_usb_midi2_interface *umidi,
 	return 0;
 }
 
+/* Call UMP helper to parse UMP endpoints;
+ * this needs to be called after starting the input streams for bi-directional
+ * communications
+ */
+static int parse_ump_endpoints(struct snd_usb_midi2_interface *umidi)
+{
+	struct snd_usb_midi2_ump *rmidi;
+	int err;
+
+	list_for_each_entry(rmidi, &umidi->rawmidi_list, list) {
+		if (!rmidi->ump ||
+		    !(rmidi->ump->core.info_flags & SNDRV_RAWMIDI_INFO_DUPLEX))
+			continue;
+		err = snd_ump_parse_endpoint(rmidi->ump);
+		if (!err) {
+			rmidi->ump_parsed = true;
+		} else {
+			if (err == -ENOMEM)
+				return err;
+			/* fall back to GTB later */
+		}
+	}
+	return 0;
+}
+
 /* create a UMP block from a GTB entry */
 static int create_gtb_block(struct snd_usb_midi2_ump *rmidi, int dir, int blk)
 {
@@ -856,7 +882,7 @@ static int create_blocks_from_gtb(struct snd_usb_midi2_interface *umidi)
 		if (!rmidi->ump)
 			continue;
 		/* Blocks have been already created? */
-		if (rmidi->ump->info.num_blocks)
+		if (rmidi->ump_parsed || rmidi->ump->info.num_blocks)
 			continue;
 		/* loop over GTBs */
 		for (dir = 0; dir < 2; dir++) {
@@ -1110,6 +1136,12 @@ int snd_usb_midi_v2_create(struct snd_usb_audio *chip,
 		goto error;
 	}
 
+	err = parse_ump_endpoints(umidi);
+	if (err < 0) {
+		usb_audio_err(chip, "Failed to parse UMP endpoint\n");
+		goto error;
+	}
+
 	err = create_blocks_from_gtb(umidi);
 	if (err < 0) {
 		usb_audio_err(chip, "Failed to create GTB blocks\n");
-- 
2.35.3

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ