svn commit: r191869 - head/sys/dev/usb/serial

Andrew Thompson thompsa at FreeBSD.org
Thu May 7 02:15:59 UTC 2009


Author: thompsa
Date: Thu May  7 02:15:58 2009
New Revision: 191869
URL: http://svn.freebsd.org/changeset/base/191869

Log:
  - Fix the u3g port detection where it would not calculate the correct number of
    ports when multiple interfaces are present.
  - Claim all interfaces regardless of how many are attached

Modified:
  head/sys/dev/usb/serial/u3g.c

Modified: head/sys/dev/usb/serial/u3g.c
==============================================================================
--- head/sys/dev/usb/serial/u3g.c	Thu May  7 02:13:56 2009	(r191868)
+++ head/sys/dev/usb/serial/u3g.c	Thu May  7 02:15:58 2009	(r191869)
@@ -439,12 +439,9 @@ u3g_attach(device_t dev)
 	struct u3g_softc *sc = device_get_softc(dev);
 	struct usb2_interface *iface;
 	struct usb2_interface_descriptor *id;
-	uint32_t flags;
-	uint8_t m;
-	uint8_t n;
+	int error, iface_valid, flags, nports;
+	int ep, n;
 	uint8_t i;
-	uint8_t x;
-	int error;
 
 	DPRINTF("sc=%p\n", sc);
 
@@ -462,72 +459,68 @@ u3g_attach(device_t dev)
 
 	sc->sc_udev = uaa->device;
 
-	x = 0;		/* interface index */
-	i = 0;		/* endpoint index */
-	m = 0;		/* number of ports */
-
-	while (m != U3G_MAXPORTS) {
-
-		/* update BULK endpoint index */
-		for (n = 0; n != U3G_N_TRANSFER; n++) 
-			u3g_config_tmp[n].ep_index = i;
-
-		iface = usb2_get_iface(uaa->device, x);
-		if (iface == NULL) {
-			if (m != 0)
-				break;	/* end of interfaces */
-			DPRINTF("did not find any modem endpoints\n");
-			goto detach;
-		}
-
+	/* Claim all interfaces on the device */
+	iface_valid = 0;
+	for (i = uaa->info.bIfaceIndex; i < USB_IFACE_MAX; i++) {
+		iface = usb2_get_iface(uaa->device, i);
+		if (iface == NULL)
+			break;
 		id = usb2_get_interface_descriptor(iface);
-		if ((id == NULL) || 
-		    (id->bInterfaceClass != UICLASS_VENDOR)) {
-			/* next interface */
-			x++;
-			i = 0;
+		if (id == NULL || id->bInterfaceClass != UICLASS_VENDOR)
+			continue;
+		usb2_set_parent_iface(uaa->device, i, uaa->info.bIfaceIndex);
+		iface_valid |= (1<<i);
+	}
+
+	i = 0;		/* interface index */
+	ep = 0;		/* endpoint index */
+	nports = 0;	/* number of ports */
+	while (i < USB_IFACE_MAX) {
+		if ((iface_valid & (1<<i)) == 0) {
+			i++;
 			continue;
 		}
 
+		/* update BULK endpoint index */
+		for (n = 0; n < U3G_N_TRANSFER; n++)
+			u3g_config_tmp[n].ep_index = ep;
+
 		/* try to allocate a set of BULK endpoints */
-		error = usb2_transfer_setup(uaa->device, &x,
-		    sc->sc_xfer[m], u3g_config_tmp, U3G_N_TRANSFER, 
-		    &sc->sc_ucom[m], &sc->sc_mtx);
+		error = usb2_transfer_setup(uaa->device, &i,
+		    sc->sc_xfer[nports], u3g_config_tmp, U3G_N_TRANSFER,
+		    &sc->sc_ucom[nports], &sc->sc_mtx);
 		if (error) {
 			/* next interface */
-			x++;
-			i = 0;
+			i++;
+			ep = 0;
 			continue;
 		}
 
-		/* grab other interface, if any */
-                if (x != uaa->info.bIfaceIndex)
-                        usb2_set_parent_iface(uaa->device, x,
-                            uaa->info.bIfaceIndex);
-
 		/* set stall by default */
 		mtx_lock(&sc->sc_mtx);
-		usb2_transfer_set_stall(sc->sc_xfer[m][U3G_BULK_WR]);
-		usb2_transfer_set_stall(sc->sc_xfer[m][U3G_BULK_RD]);
+		usb2_transfer_set_stall(sc->sc_xfer[nports][U3G_BULK_WR]);
+		usb2_transfer_set_stall(sc->sc_xfer[nports][U3G_BULK_RD]);
 		mtx_unlock(&sc->sc_mtx);
 
-		m++;	/* found one port */
-		i++;	/* next endpoint index */
+		nports++;	/* found one port */
+		ep++;
+		if (nports == U3G_MAXPORTS)
+			break;
 	}
+	if (nports == 0) {
+		device_printf(dev, "no ports found\n");
+		goto detach;
+	}
+	sc->sc_numports = nports;
 
-	sc->sc_numports = m;
-
-	error = usb2_com_attach(&sc->sc_super_ucom, sc->sc_ucom, 
+	error = usb2_com_attach(&sc->sc_super_ucom, sc->sc_ucom,
 	    sc->sc_numports, sc, &u3g_callback, &sc->sc_mtx);
 	if (error) {
 		DPRINTF("usb2_com_attach failed\n");
 		goto detach;
 	}
-	if (sc->sc_numports != 1) {
-		/* be verbose */
-		device_printf(dev, "Found %u ports.\n",
-		    (unsigned int)sc->sc_numports);
-	}
+	if (sc->sc_numports > 1)
+		device_printf(dev, "Found %u ports.\n", sc->sc_numports);
 	return (0);
 
 detach:


More information about the svn-src-all mailing list