Index | Thread | Search

From:
David Gwynne <david@gwynne.id.au>
Subject:
umsm(4): don't deactivate the whole usb device if umsm claims an unworkable interface
To:
tech@openbsd.org
Cc:
kevlo@openbsd.org
Date:
Thu, 18 Jun 2026 11:37:38 +1000

Download raw body.

Thread
we got a bunch of Quectel EM060K-GL modems at work and, as i've come to
expect from mobile modems, there was a new and exciting bug to fix.

when i plugged it in, it looked like this:

umsm0 at uhub1 port 1 configuration 1 interface 0 "Quectel EM060K-GL" rev 2.00/5.04 addr 2
ucom0 at umsm0: usb1.0.00001.0
umsm1 at uhub1 port 1 configuration 1 interface 1 "Quectel EM060K-GL" rev 2.00/5.04 addr 2
ucom1 at umsm1: usb1.0.00001.1
umsm2 at uhub1 port 1 configuration 1 interface 2 "Quectel EM060K-GL" rev 2.00/5.04 addr 2
ucom2 at umsm2: usb1.0.00001.2
umsm3 at uhub1 port 1 configuration 1 interface 3 "Quectel EM060K-GL" rev 2.00/5.04 addr 2
ucom3 at umsm3: usb1.0.00001.3
umb0 at uhub1 port 1 configuration 1 interface 8 "Quectel EM060K-GL" rev 2.00/5.04 addr 2
umsm4 at uhub1 port 1 configuration 1 interface 12 "Quectel EM060K-GL" rev 2.00/5.04 addr 2
umsm4: missing endpoint

but any attempt to use any of these devices resulted in errors.
opening /dev/cuaU things would return EIO, and ifconfig against the
umb device produced weird errors.

after a lot of trial and error, i figured out that if i prevented
umsm4 from attaching, the remaining devices would work as expected.
while using kevlo@ as a rubber duck, he pointed out that this device
was working in the past (as per
https://marc.info/?l=openbsd-tech&m=171644719119922&w=2).

the difference between then and now is that umsm used to only attach
to low interfaces, but i found a quectel device that used high
interfaces for umsm and got rid of that restriction, which is in
line with the advice from quectel themselves about how to support
these devices. however, this allows umsm(4) to attach to interface
12 on EM060K modems, which now breaks them.

the problem is that umsm_attach tries to find the necessary endpoints
to drive the usb interface, and if it can't then it calls
usbd_deactivate(). this kills the entire usb device, not just the
interface it was working against. removing this line allows umsm_attach
to fail gracefully on interface 12 above, but leaves the rest of
them still working.

ok?

ps, this is in line with the guidance from quectel on how to support
these devices. it's worth pointing out that linux maintains a big
table that lists specific interfaces it will support on specific
versions of quectel modems. kevlo@ and i are considering moving
toward following the linux example in the future.

Index: umsm.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/umsm.c,v
diff -u -p -r1.130 umsm.c
--- umsm.c	18 Jun 2026 01:20:17 -0000	1.130
+++ umsm.c	18 Jun 2026 01:21:39 -0000
@@ -447,7 +447,6 @@ umsm_attach(struct device *parent, struc
 	}
 	if (uca.bulkin == -1 || uca.bulkout == -1) {
 		printf("%s: missing endpoint\n", sc->sc_dev.dv_xname);
-		usbd_deactivate(sc->sc_udev);
 		return;
 	}