summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorAlexandre Ratchov <ratchov@cvs.openbsd.org>2023-12-10 06:32:15 +0000
committerAlexandre Ratchov <ratchov@cvs.openbsd.org>2023-12-10 06:32:15 +0000
commit044c708297d4f3f9d4e6d499167a7d956b7abfe4 (patch)
treee09d65fbc7a4a1777c67804aca52478b389b2f83 /sys
parent4be756434be2a2b841123e471074cc92ed645be5 (diff)
Skip interfaces already claimed by other uaudio(4) instances.
Fixes support of devices that attach multiple uaudio(4) drivers. Every uaudio(4) instance parses the full set of device descriptors because there are multiple interfaces per driver instance. If there is a second uaudio(4) instance (i.e. a second control & stream interfaces combo), the latter must skip the interfaces already used by the first one (if it didn't, multiple uaudio(4) would try to use the same interface and neither would work). Help from and ok armani@.
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/usb/uaudio.c23
1 files changed, 19 insertions, 4 deletions
diff --git a/sys/dev/usb/uaudio.c b/sys/dev/usb/uaudio.c
index d8e300a52c9..b213c5e2196 100644
--- a/sys/dev/usb/uaudio.c
+++ b/sys/dev/usb/uaudio.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uaudio.c,v 1.173 2023/06/27 09:28:08 ratchov Exp $ */
+/* $OpenBSD: uaudio.c,v 1.174 2023/12/10 06:32:14 ratchov Exp $ */
/*
* Copyright (c) 2018 Alexandre Ratchov <alex@caoua.org>
*
@@ -2584,7 +2584,6 @@ uaudio_process_as(struct uaudio_softc *sc,
}
}
-
while (p->rptr != p->wptr) {
savep = p->rptr;
if (!uaudio_getdesc(p, &dp))
@@ -2710,6 +2709,7 @@ int
uaudio_process_conf(struct uaudio_softc *sc, struct uaudio_blob *p)
{
struct uaudio_blob dp;
+ struct uaudio_alt *a;
unsigned int type, ifnum, altnum, nep, class, subclass;
while (p->rptr != p->wptr) {
@@ -2736,7 +2736,10 @@ uaudio_process_conf(struct uaudio_softc *sc, struct uaudio_blob *p)
switch (subclass) {
case UISUBCLASS_AUDIOCONTROL:
- usbd_claim_iface(sc->udev, ifnum);
+ if (usbd_iface_claimed(sc->udev, ifnum)) {
+ DPRINTF("%s: %d: AC already claimed\n", __func__, ifnum);
+ break;
+ }
if (sc->unit_list != NULL) {
DPRINTF("%s: >1 AC ifaces\n", __func__);
goto done;
@@ -2745,7 +2748,10 @@ uaudio_process_conf(struct uaudio_softc *sc, struct uaudio_blob *p)
return 0;
break;
case UISUBCLASS_AUDIOSTREAM:
- usbd_claim_iface(sc->udev, ifnum);
+ if (usbd_iface_claimed(sc->udev, ifnum)) {
+ DPRINTF("%s: %d: AS already claimed\n", __func__, ifnum);
+ break;
+ }
if (nep == 0) {
DPRINTF("%s: "
"stop altnum %d\n", __func__, altnum);
@@ -2758,6 +2764,15 @@ uaudio_process_conf(struct uaudio_softc *sc, struct uaudio_blob *p)
done:
uaudio_fixup_params(sc);
+ /*
+ * 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);
+
+ usbd_claim_iface(sc->udev, sc->ctl_ifnum);
+
return 1;
}