NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

kern/55330: u3g(4) assumes a consecutive numbering of USB interfaces for serial ports



>Number:         55330
>Category:       kern
>Synopsis:       u3g(4) assumes a consecutive numbering of USB interfaces for serial ports
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sun May 31 16:00:00 +0000 2020
>Originator:     Reinhard Speyerer
>Release:        NetBSD 9.0
>Organization:
>Environment:
NetBSD netbsd 9.0 NetBSD 9.0 (GENERIC) #0: Fri Feb 14 00:06:28 UTC 2020  mkrepro%mkrepro.NetBSD.org@localhost:/usr/src/sys/arch/i386/compile/GENERIC i386
(with the proposed patch for PR #55329 applied)

>Description:
u3g(4) assumes a consecutive numbering of USB interfaces for serial ports
which causes some ports to not be available when this is not the case like
the following (/sys/kernel/debug/usb/devices output from Linux):

T:  Bus=02 Lev=03 Prnt=06 Port=01 Cnt=02 Dev#=  9 Spd=480  MxCh= 0
D:  Ver= 2.00 Cls=02(comm.) Sub=00 Prot=00 MxPS=64 #Cfgs=  1
P:  Vendor=1199 ProdID=68a3 Rev= 0.06
S:  Manufacturer=Sierra Wireless, Incorporated
S:  Product=MC7710
S:  SerialNumber=358xxxxxxxxxxxx
C:* #Ifs= 5 Cfg#= 1 Atr=e0 MxPwr=  0mA
I:* If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=sierra
E:  Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=4ms
I:* If#= 1 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=sierra
E:  Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=4ms
I:* If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=sierra
E:  Ad=83(I) Atr=03(Int.) MxPS=  64 Ivl=2ms
E:  Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=4ms
I:* If#=12 Alt= 0 #EPs= 1 Cls=02(comm.) Sub=06 Prot=00 Driver=cdc_ether
E:  Ad=85(I) Atr=03(Int.) MxPS=  64 Ivl=2ms
I:  If#=13 Alt= 0 #EPs= 0 Cls=0a(data ) Sub=00 Prot=00 Driver=cdc_ether
I:* If#=13 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=cdc_ether
E:  Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=4ms

Replace calls to usbd_device2interface_handle in u3g_match() and
u3g_attach() with the interface already passed in uiaa->uiaa_iface and
store the interface in sc->sc_iface for later use by u3g_open()/

Also skip Direct IP interfaces in u3g_match() to avoid potential side effects.

>How-To-Repeat:
Connect a Sierra Wireless MC7710 set to
AT!UDPID=68a3
AT!UDUSBCOMP=5
AT!CUSTOM="GPSENABLE",0
to a USB port and check dmesg(1) output:

[   363.433249] u3g0 at uhub5 port 2 configuration 1 interface 0
[   363.433249] ucom4 at u3g0 portno 0: 3G Modem
[   363.433249] u3g1 at uhub5 port 2 configuration 1 interface 1
[   363.433249] ucom5 at u3g1 portno 0: 3G Modem
[   363.433249] u3g_match: failed to get interface, err=INVAL
[   363.433249] cdce0 at uhub5 port 2 configuration 1 interface 12
[   363.433249] cdce0: Sierra Wireless, Incorporated (0x1199) MC7710 (0x68a3), rev 2.00/0.06, addr 4
[   363.443255] cdce0: Ethernet address 00:a0:c6:00:00:00

>Fix:
Apply this patch

--- u3g.c.orig	2019-05-09 04:43:35.000000000 +0200
+++ u3g.c	2020-05-25 12:48:45.000000000 +0200
@@ -116,2 +116,3 @@ struct u3g_softc {
 	int			sc_ifaceno;	/* Device interface number */
+	struct usbd_interface	*sc_iface;	/* Device interface */
 
@@ -269,5 +270,4 @@ u3g_match(device_t parent, cfdata_t matc
 	struct usbif_attach_arg *uiaa = aux;
-	struct usbd_interface *iface;
+	struct usbd_interface *iface = uiaa->uiaa_iface;
 	usb_interface_descriptor_t *id;
-	usbd_status error;
 
@@ -276,10 +276,2 @@ u3g_match(device_t parent, cfdata_t matc
 
-	error = usbd_device2interface_handle(uiaa->uiaa_device,
-	    uiaa->uiaa_ifaceno, &iface);
-	if (error) {
-		printf("u3g_match: failed to get interface, err=%s\n",
-		    usbd_errstr(error));
-		return UMATCH_NONE;
-	}
-
 	id = usbd_get_interface_descriptor(iface);
@@ -300,2 +292,12 @@ u3g_match(device_t parent, cfdata_t matc
 	/*
+	 * Sierra Wireless modems use the vendor-specific class also for
+	 * Direct IP or QMI interfaces, which we should avoid attaching to.
+	 */
+	if (uiaa->uiaa_vendor == USB_VENDOR_SIERRA &&
+	    id->bInterfaceClass == UICLASS_VENDOR &&
+	    uiaa->uiaa_product == USB_PRODUCT_SIERRA_USB305 &&
+	     uiaa->uiaa_ifaceno >= 7)
+		return UMATCH_NONE;
+
+	/*
 	 * 3G modems generally report vendor-specific class
@@ -314,3 +316,3 @@ u3g_attach(device_t parent, device_t sel
 	struct usbd_device *dev = uiaa->uiaa_device;
-	struct usbd_interface *iface;
+	struct usbd_interface *iface = uiaa->uiaa_iface;
 	usb_interface_descriptor_t *id;
@@ -328,9 +330,2 @@ u3g_attach(device_t parent, device_t sel
 
-	error = usbd_device2interface_handle(dev, uiaa->uiaa_ifaceno, &iface);
-	if (error) {
-		aprint_error_dev(self, "failed to get interface, err=%s\n",
-		    usbd_errstr(error));
-		return;
-	}
-
 	id = usbd_get_interface_descriptor(iface);
@@ -350,2 +345,3 @@ u3g_attach(device_t parent, device_t sel
 	sc->sc_ifaceno = uiaa->uiaa_ifaceno;
+	sc->sc_iface = uiaa->uiaa_iface;
 	intr_address = -1;
@@ -576,3 +572,2 @@ u3g_open(void *arg, int portno)
 	usb_interface_descriptor_t *id;
-	struct usbd_interface *ih;
 	usbd_status err;
@@ -584,10 +579,6 @@ u3g_open(void *arg, int portno)
 
-	err = usbd_device2interface_handle(sc->sc_udev, sc->sc_ifaceno, &ih);
-	if (err)
-		return EIO;
-
-	id = usbd_get_interface_descriptor(ih);
+	id = usbd_get_interface_descriptor(sc->sc_iface);
 
 	for (nin = i = 0; i < id->bNumEndpoints; i++) {
-		ed = usbd_interface2endpoint_descriptor(ih, i);
+		ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i);
 		if (ed == NULL)

to the NetBSD 9.0 sources and rebuild the kernel. After reboot:

[   118.868012] u3g0 at uhub5 port 2 configuration 1 interface 0
[   118.868012] ucom4 at u3g0 portno 0: 3G Modem
[   118.868012] u3g1 at uhub5 port 2 configuration 1 interface 1
[   118.868012] ucom5 at u3g1 portno 0: 3G Modem
[   118.868012] u3g2 at uhub5 port 2 configuration 1 interface 3
[   118.868012] ucom6 at u3g2 portno 0: 3G Modem
[   118.868012] cdce0 at uhub5 port 2 configuration 1 interface 12
[   118.868012] cdce0: Sierra Wireless, Incorporated (0x1199) MC7710 (0x68a3), rev 2.00/0.06, addr 4
[   118.878021] cdce0: Ethernet address 00:a0:c6:00:00:00

For performance reasons it may be advisable to use the cdce(4) interface
instead of pppd(8) at HSDPA and LTE speeds if the device/firmware supports
AT!UDUSBCOMP=5 (please check with AT!UDUSBCOMP=? first). These interfaces
can be managed using the vendor-specific AT!SCACT,... AT commands like
Direct IP interfaces.



Home | Main Index | Thread Index | Old Index