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