Index | Thread | Search

From:
Alexandre Ratchov <alex@caoua.org>
Subject:
uaudio: Fix confusion between the inteface index and the interface number
To:
tech@openbsd.org
Date:
Sat, 25 May 2024 10:22:22 +0200

Download raw body.

Thread
  • Alexandre Ratchov:

    uaudio: Fix confusion between the inteface index and the interface number

uaudio(4) uses the usbd_iface_{claim,claimed}() functions, which take
the interface index as argument, not the interface number. Both
numbers are the same for most of the available hardware, but not
all. This diff fixes the confusion.

I was surprised that there's no usbdi routine to convert the interface
number to the index, or did I miss it?

OK?

Index: uaudio.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/uaudio.c,v
diff -u -p -r1.174 uaudio.c
--- uaudio.c	10 Dec 2023 06:32:14 -0000	1.174
+++ uaudio.c	25 May 2024 07:38:00 -0000
@@ -2702,6 +2702,22 @@ uaudio_fixup_params(struct uaudio_softc 
 	}
 }
 
+int
+uaudio_iface_index(struct uaudio_softc *sc, int ifnum)
+{
+	int i, nifaces;
+
+	nifaces = sc->udev->cdesc->bNumInterfaces;
+
+	for (i = 0; i < nifaces; i++) {
+		if (sc->udev->ifaces[i].idesc->bInterfaceNumber == ifnum)
+			return i;
+	}
+
+	printf("%s: %d: invalid interface number\n", __func__, ifnum);
+	return -1;
+}
+
 /*
  * Parse all descriptors and build configuration of the device.
  */
@@ -2711,6 +2727,7 @@ uaudio_process_conf(struct uaudio_softc 
 	struct uaudio_blob dp;
 	struct uaudio_alt *a;
 	unsigned int type, ifnum, altnum, nep, class, subclass;
+	int i;
 
 	while (p->rptr != p->wptr) {
 		if (!uaudio_getdesc(p, &dp))
@@ -2736,7 +2753,8 @@ uaudio_process_conf(struct uaudio_softc 
 
 		switch (subclass) {
 		case UISUBCLASS_AUDIOCONTROL:
-			if (usbd_iface_claimed(sc->udev, ifnum)) {
+			i = uaudio_iface_index(sc, ifnum);
+			if (i != -1 && usbd_iface_claimed(sc->udev, i)) {
 				DPRINTF("%s: %d: AC already claimed\n", __func__, ifnum);
 				break;
 			}
@@ -2748,7 +2766,8 @@ uaudio_process_conf(struct uaudio_softc 
 				return 0;
 			break;
 		case UISUBCLASS_AUDIOSTREAM:
-			if (usbd_iface_claimed(sc->udev, ifnum)) {
+			i = uaudio_iface_index(sc, ifnum);
+			if (i != -1 && usbd_iface_claimed(sc->udev, i)) {
 				DPRINTF("%s: %d: AS already claimed\n", __func__, ifnum);
 				break;
 			}
@@ -2768,10 +2787,19 @@ done:
 	 * Claim all interfaces we use. This prevents other uaudio(4)
 	 * devices from trying to use them.
 	 */
-	for (a = sc->alts; a != NULL; a = a->next)
-		usbd_claim_iface(sc->udev, a->ifnum);
+	for (a = sc->alts; a != NULL; a = a->next) {
+		i = uaudio_iface_index(sc, a->ifnum);
+		if (i != -1) {
+			DPRINTF("%s: claim: %d at %d\n", __func__, a->ifnum, i);
+			usbd_claim_iface(sc->udev, i);
+		}
+	}
 
-	usbd_claim_iface(sc->udev, sc->ctl_ifnum);
+	i = uaudio_iface_index(sc, sc->ctl_ifnum);
+	if (i != -1) {
+		DPRINTF("%s: claim: ac %d at %d\n", __func__, sc->ctl_ifnum, i);
+		usbd_claim_iface(sc->udev, i);
+	}
 
 	return 1;
 }