diff options
author | Alexandre Ratchov <ratchov@cvs.openbsd.org> | 2023-12-10 06:32:15 +0000 |
---|---|---|
committer | Alexandre Ratchov <ratchov@cvs.openbsd.org> | 2023-12-10 06:32:15 +0000 |
commit | 044c708297d4f3f9d4e6d499167a7d956b7abfe4 (patch) | |
tree | e09d65fbc7a4a1777c67804aca52478b389b2f83 /sys | |
parent | 4be756434be2a2b841123e471074cc92ed645be5 (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.c | 23 |
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; } |