Author: thompsa
Date: Wed Jan 13 20:54:18 2010
New Revision: 202243
URL: http://svn.freebsd.org/changeset/base/202243

Log:
  Update to Fredrik's latest uhso driver. This changes port detection, adds
  comments and other code nits.
  
  Submitted by: Fredrik Lindberg <f...@shapeshifter.se>

Modified:
  head/share/man/man4/uhso.4
  head/sys/dev/usb/net/uhso.c
  head/sys/dev/usb/usbdevs

Modified: head/share/man/man4/uhso.4
==============================================================================
--- head/share/man/man4/uhso.4  Wed Jan 13 20:51:23 2010        (r202242)
+++ head/share/man/man4/uhso.4  Wed Jan 13 20:54:18 2010        (r202243)
@@ -23,11 +23,11 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd Aug 12, 2009
+.Dd January 14, 2010
 .Os
 .Dt UHSO 4
 .Sh NAME
-.Nm hso
+.Nm uhso
 .Nd support for several HSxPA devices from Option N.V.
 .Sh SYNOPSIS
 The module can be loaded at boot time by placing the following line in
@@ -47,12 +47,12 @@ driver which makes them behave like a
 .Xr tty 4 .
 The packet interface is exposed as a network interface.
 .Pp
-To establish a connection on the packet interface the use of the proprietary
+Connection of the packet interface is achieved by using the proprietary
 AT commands
 .Dq Li AT_OWANCALL
 and
 .Dq Li AT_OWANDATA
-are required on any of the serial ports.
+on any of the available serial ports.
 .Pp
 The network interface must be configured manually using the data obtain from
 these calls.
@@ -70,12 +70,23 @@ driver supports at least the following c
 Option GlobeSurfer iCON 7.2 (new firmware)
 .It
 Option iCON 225
+.It
+Option iCON 505
 .El
 .Pp
 The device features a mass storage device referred to as
 .Dq Zero-CD
-which contains drivers for Microsoft Windows.
-The driver automatically switches the device to modem mode.
+which contains drivers for Microsoft Windows, this is the default
+mode for the device.
+The
+.Nm
+driver automatically switches the device from
+.Dq Zero-CD
+mode to modem mode.
+This behavior can be disabled by setting
+.Va hw.usb.uhso.auto_switch
+to 0 using
+.Xr sysctl 8
 .Sh EXAMPLES
 Establishing a packet interface connection
 .Bd -literal -offset indent

Modified: head/sys/dev/usb/net/uhso.c
==============================================================================
--- head/sys/dev/usb/net/uhso.c Wed Jan 13 20:51:23 2010        (r202242)
+++ head/sys/dev/usb/net/uhso.c Wed Jan 13 20:54:18 2010        (r202243)
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2009 Fredrik Lindberg
+ * Copyright (c) 2009 Fredrik Lindberg <f...@shapeshifter.se>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -63,13 +63,15 @@ __FBSDID("$FreeBSD$");
 #include <dev/usb/usb_process.h>
 #include <dev/usb/usb_device.h>
 #include <dev/usb/usb_busdma.h>
+#include <dev/usb/usb_controller.h>
+#include <dev/usb/usb_bus.h>
 #include <dev/usb/serial/usb_serial.h>
 #include <dev/usb/usb_msctest.h>
 
 struct uhso_tty {
        struct uhso_softc *ht_sc;
        struct usb_xfer *ht_xfer[3];
-       int             ht_muxport;
+       int             ht_muxport; /* Mux. port no */
        int             ht_open;
        char            ht_name[32];
 };
@@ -78,7 +80,7 @@ struct uhso_softc {
        device_t                sc_dev;
        struct usb_device       *sc_udev;
        struct mtx              sc_mtx;
-       uint32_t                sc_type;
+       uint32_t                sc_type;        /* Interface definition */
 
        struct usb_xfer         *sc_xfer[3];
        uint8_t                 sc_iface_no;
@@ -91,14 +93,14 @@ struct uhso_softc {
        /* Network */
        struct usb_xfer         *sc_if_xfer[2];
        struct ifnet            *sc_ifp;
-       struct mbuf             *sc_mwait;      /* partial packet */
-       size_t                  sc_waitlen;     /* no. of outstanding bytes */
+       struct mbuf             *sc_mwait;      /* Partial packet */
+       size_t                  sc_waitlen;     /* No. of outstanding bytes */
        struct ifqueue          sc_rxq;
        struct callout          sc_c;
 
        /* TTY related structures */
        struct ucom_super_softc sc_super_ucom;
-       int                     sc_ttys;
+       int                     sc_ttys;
        struct uhso_tty         *sc_tty;
        struct ucom_softc       *sc_ucom;
        int                     sc_msr;
@@ -106,7 +108,6 @@ struct uhso_softc {
        int                     sc_line;
 };
 
-
 #define UHSO_MAX_MTU           2048
 
 /*
@@ -135,7 +136,7 @@ struct uhso_softc {
  * Port types
  */
 #define UHSO_PORT_UNKNOWN      0x00
-#define UHSO_PORT_SERIAL               0x01    /* Serial port */
+#define UHSO_PORT_SERIAL       0x01    /* Serial port */
 #define UHSO_PORT_NETWORK      0x02    /* Network packet interface */
 
 /*
@@ -145,12 +146,14 @@ struct uhso_softc {
 #define UHSO_MPORT_TYPE_APP    0x01    /* Application */
 #define UHSO_MPORT_TYPE_PCSC   0x02
 #define UHSO_MPORT_TYPE_GPS    0x03
-#define UHSO_MPORT_TYPE_APP2   0x04
+#define UHSO_MPORT_TYPE_APP2   0x04    /* Secondary application */
 #define UHSO_MPORT_TYPE_MAX    UHSO_MPORT_TYPE_APP2
 #define UHSO_MPORT_TYPE_NOMAX  8       /* Max number of mux ports */
 
 /*
  * Port definitions
+ * Note that these definitions are arbitray and doesn't match
+ * values returned by the auto config descriptor.
  */
 #define UHSO_PORT_TYPE_CTL     0x01
 #define UHSO_PORT_TYPE_APP     0x02
@@ -176,8 +179,12 @@ static char *uhso_port[] = {
        "Network/Serial"
 };
 
-/* Map between interface port type read from device and description type */
-static char uhso_port_map[] = {
+/*
+ * Map between interface port type read from device and description type.
+ * The position in this array is a direct map to the auto config
+ * descriptor values.
+ */
+static unsigned char uhso_port_map[] = {
        0,
        UHSO_PORT_TYPE_DIAG,
        UHSO_PORT_TYPE_GPS,
@@ -193,7 +200,7 @@ static char uhso_port_map[] = {
 };
 static char uhso_port_map_max = sizeof(uhso_port_map) / sizeof(char);
 
-static char uhso_mux_port_map[] = {
+static unsigned char uhso_mux_port_map[] = {
        UHSO_PORT_TYPE_CTL,
        UHSO_PORT_TYPE_APP,
        UHSO_PORT_TYPE_PCSC,
@@ -202,7 +209,7 @@ static char uhso_mux_port_map[] = {
 };
 
 static char *uhso_port_type[] = {
-       "Unknown",
+       "Unknown",  /* Not a valid port */
        "Control",
        "Application",
        "Application (Secondary)",
@@ -233,7 +240,6 @@ static char *uhso_port_type_sysctl[] = {
        "voice",
 };
 
-
 #define UHSO_STATIC_IFACE      0x01
 #define UHSO_AUTO_IFACE                0x02
 
@@ -263,11 +269,16 @@ static const struct usb_device_id uhso_d
        /* Option iCON 321 */
        UHSO_DEV(OPTION, ICON321, UHSO_STATIC_IFACE),
        /* Option iCON 322 */
-       UHSO_DEV(OPTION, GTICON322, UHSO_STATIC_IFACE)
+       UHSO_DEV(OPTION, GTICON322, UHSO_STATIC_IFACE),
+       /* Option iCON 505 */
+       UHSO_DEV(OPTION, ICON505, UHSO_AUTO_IFACE),
 #undef UHSO_DEV
 };
 
 SYSCTL_NODE(_hw_usb, OID_AUTO, uhso, CTLFLAG_RW, 0, "USB uhso");
+static int uhso_autoswitch = 1;
+SYSCTL_INT(_hw_usb_uhso, OID_AUTO, auto_switch, CTLFLAG_RW,
+    &uhso_autoswitch, 0, "Automatically switch to modem mode");
 
 #ifdef USB_DEBUG
 #ifdef UHSO_DEBUG
@@ -335,6 +346,7 @@ static usb_callback_t uhso_bs_intr_callb
 static usb_callback_t uhso_ifnet_read_callback;
 static usb_callback_t uhso_ifnet_write_callback;
 
+/* Config used for the default control pipes */
 static const struct usb_config uhso_ctrl_config[UHSO_CTRL_MAX] = {
        [UHSO_CTRL_READ] = {
                .type = UE_CONTROL,
@@ -356,6 +368,7 @@ static const struct usb_config uhso_ctrl
        }
 };
 
+/* Config for the multiplexed serial ports */
 static const struct usb_config uhso_mux_config[UHSO_MUX_ENDPT_MAX] = {
        [UHSO_MUX_ENDPT_INTR] = {
                .type = UE_INTERRUPT,
@@ -367,6 +380,7 @@ static const struct usb_config uhso_mux_
        }
 };
 
+/* Config for the raw IP-packet interface */
 static const struct usb_config uhso_ifnet_config[UHSO_IFNET_MAX] = {
        [UHSO_IFNET_READ] = {
                .type = UE_BULK,
@@ -387,6 +401,7 @@ static const struct usb_config uhso_ifne
        }
 };
 
+/* Config for interfaces with normal bulk serial ports */
 static const struct usb_config uhso_bs_config[UHSO_BULK_ENDPT_MAX] = {
        [UHSO_BULK_ENDPT_READ] = {
                .type = UE_BULK,
@@ -416,20 +431,19 @@ static const struct usb_config uhso_bs_c
        }
 };
 
-static int uhso_probe_iface(struct uhso_softc *, int,
+static int  uhso_probe_iface(struct uhso_softc *, int,
     int (*probe)(struct uhso_softc *, int));
-static int uhso_probe_iface_auto(struct uhso_softc *, int);
-static int uhso_probe_iface_static(struct uhso_softc *, int);
-
-static int uhso_attach_muxserial(struct uhso_softc *, struct usb_interface *,
+static int  uhso_probe_iface_auto(struct uhso_softc *, int);
+static int  uhso_probe_iface_static(struct uhso_softc *, int);
+static int  uhso_attach_muxserial(struct uhso_softc *, struct usb_interface *,
     int type);
-static int uhso_attach_bulkserial(struct uhso_softc *, struct usb_interface *,
+static int  uhso_attach_bulkserial(struct uhso_softc *, struct usb_interface *,
     int type);
-static int uhso_attach_ifnet(struct uhso_softc *, struct usb_interface *,
+static int  uhso_attach_ifnet(struct uhso_softc *, struct usb_interface *,
     int type);
 static void uhso_test_autoinst(void *, struct usb_device *,
                struct usb_attach_arg *);
-static int uhso_driver_loaded(struct module *, int, void *);
+static int  uhso_driver_loaded(struct module *, int, void *);
 
 static void uhso_ucom_start_read(struct ucom_softc *);
 static void uhso_ucom_stop_read(struct ucom_softc *);
@@ -438,12 +452,11 @@ static void uhso_ucom_stop_write(struct 
 static void uhso_ucom_cfg_get_status(struct ucom_softc *, uint8_t *, uint8_t 
*);
 static void uhso_ucom_cfg_set_dtr(struct ucom_softc *, uint8_t);
 static void uhso_ucom_cfg_set_rts(struct ucom_softc *, uint8_t);
-
 static void uhso_if_init(void *);
 static void uhso_if_start(struct ifnet *);
 static void uhso_if_stop(struct uhso_softc *);
-static int uhso_if_ioctl(struct ifnet *, u_long, caddr_t);
-static int uhso_if_output(struct ifnet *, struct mbuf *, struct sockaddr *,
+static int  uhso_if_ioctl(struct ifnet *, u_long, caddr_t);
+static int  uhso_if_output(struct ifnet *, struct mbuf *, struct sockaddr *,
     struct route *);
 static void uhso_if_rxflush(void *);
 
@@ -512,11 +525,6 @@ uhso_attach(device_t self)
        usb_error_t uerr;
        char *desc;
 
-       device_set_usb_desc(self);
-
-       UHSO_DPRINTF(0, "Device is in modem mode, devClass=%x\n",
-           uaa->device->ddesc.bDeviceClass);
-
        sc->sc_dev = self;
        sc->sc_udev = uaa->device;
        mtx_init(&sc->sc_mtx, "uhso", NULL, MTX_DEF);
@@ -552,7 +560,6 @@ uhso_attach(device_t self)
        if (error != 0)
                goto out;
 
-
        sctx = device_get_sysctl_ctx(sc->sc_dev);
        soid = device_get_sysctl_tree(sc->sc_dev);
 
@@ -560,6 +567,18 @@ uhso_attach(device_t self)
            CTLFLAG_RD, uhso_port[UHSO_IFACE_PORT(sc->sc_type)], 0,
            "Port available at this interface");
 
+       /*
+        * The default interface description on most Option devices aren't
+        * very helpful. So we skip device_set_usb_desc and set the
+        * device description manually.
+        */
+       device_set_desc_copy(self, 
uhso_port_type[UHSO_IFACE_PORT_TYPE(sc->sc_type)]); 
+       /* Announce device */
+       device_printf(self, "<%s port> at <%s %s> on %s\n",
+           uhso_port_type[UHSO_IFACE_PORT_TYPE(sc->sc_type)],
+           uaa->device->manufacturer, uaa->device->product,
+           device_get_nameunit(uaa->device->bus->bdev));
+
        if (sc->sc_ttys > 0) {
                SYSCTL_ADD_INT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "ports",
                    CTLFLAG_RD, &sc->sc_ttys, 0, "Number of attached serial 
ports");
@@ -568,11 +587,14 @@ uhso_attach(device_t self)
                    "port", CTLFLAG_RD, NULL, "Serial ports");
        }
 
+       /*
+        * Loop through the number of found TTYs and create sysctl
+        * nodes for them.
+        */
        for (i = 0; i < sc->sc_ttys; i++) {
                ht = &sc->sc_tty[i];
                ucom = &sc->sc_ucom[i];
 
-
                if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_MUX)
                        port = uhso_mux_port_map[ht->ht_muxport];
                else
@@ -607,7 +629,6 @@ uhso_attach(device_t self)
 out:
        uhso_detach(sc->sc_dev);
        return (ENXIO);
-
 }
 
 static int
@@ -633,21 +654,17 @@ uhso_detach(device_t self)
        }
 
        if (sc->sc_ifp != NULL) {
-
                callout_drain(&sc->sc_c);
-
                mtx_lock(&sc->sc_mtx);
                uhso_if_stop(sc);
                bpfdetach(sc->sc_ifp);
                if_detach(sc->sc_ifp);
                if_free(sc->sc_ifp);
                mtx_unlock(&sc->sc_mtx);
-
                usbd_transfer_unsetup(sc->sc_if_xfer, UHSO_IFNET_MAX);
        }
 
        mtx_destroy(&sc->sc_mtx);
-
        return (0);
 }
 
@@ -658,7 +675,7 @@ uhso_test_autoinst(void *arg, struct usb
        struct usb_interface *iface;
        struct usb_interface_descriptor *id;
 
-       if (uaa->dev_state != UAA_DEV_READY)
+       if (uaa->dev_state != UAA_DEV_READY || !uhso_autoswitch)
                return;
 
        iface = usbd_get_iface(udev, 0);
@@ -694,7 +711,13 @@ uhso_driver_loaded(struct module *mod, i
        return (0);
 }
 
-static int uhso_probe_iface_auto(struct uhso_softc *sc, int index)
+/*
+ * Probe the interface type by querying the device. The elements
+ * of an array indicates the capabilities of a particular interface.
+ * Returns a bit mask with the interface capabilities.
+ */
+static int
+uhso_probe_iface_auto(struct uhso_softc *sc, int index)
 {
        struct usb_device_request req;
        usb_error_t uerr;
@@ -716,7 +739,7 @@ static int uhso_probe_iface_auto(struct 
                return (0);
        }
 
-       UHSO_DPRINTF(3, "actlen=%d\n", actlen);
+       UHSO_DPRINTF(1, "actlen=%d\n", actlen);
        UHSO_HEXDUMP(buf, 17);
 
        if (index < 0 || index > 16) {
@@ -724,21 +747,25 @@ static int uhso_probe_iface_auto(struct 
                return (0);
        }
 
-       UHSO_DPRINTF(3, "index=%d, type=%x\n", index, buf[index]);
+       UHSO_DPRINTF(1, "index=%d, type=%x[%s]\n", index, buf[index],
+           uhso_port_type[(int)uhso_port_map[(int)buf[index]]]);
 
        if (buf[index] >= uhso_port_map_max)
                port = 0;
        else
                port = uhso_port_map[(int)buf[index]];
 
-       if (port == UHSO_PORT_TYPE_NETWORK)
-               return (UHSO_IFACE_SPEC(UHSO_IF_BULK,
-                   UHSO_PORT_NETWORK, port));
-       else if (port == UHSO_PORT_TYPE_VOICE)
+       switch (port) {
+       case UHSO_PORT_TYPE_NETWORK:
+               return (UHSO_IFACE_SPEC(UHSO_IF_NET | UHSO_IF_MUX,
+                   UHSO_PORT_SERIAL | UHSO_PORT_NETWORK, port));
+       case UHSO_PORT_TYPE_VOICE:
+               /* Don't claim 'voice' ports */
                return (0);
-       else
+       default:
                return (UHSO_IFACE_SPEC(UHSO_IF_BULK,
                    UHSO_PORT_SERIAL, port));
+       }
 
        return (0);
 }
@@ -750,10 +777,12 @@ uhso_probe_iface_static(struct uhso_soft
 
        cd = usbd_get_config_descriptor(sc->sc_udev);
        if (cd->bNumInterface <= 3) {
+               /* Cards with 3 or less interfaces */
                switch (index) {
                case 0:
                        return UHSO_IFACE_SPEC(UHSO_IF_NET | UHSO_IF_MUX,
-                           UHSO_PORT_SERIAL | UHSO_PORT_NETWORK, 0);
+                           UHSO_PORT_SERIAL | UHSO_PORT_NETWORK,
+                           UHSO_PORT_TYPE_NETWORK);
                case 1:
                        return UHSO_IFACE_SPEC(UHSO_IF_BULK,
                            UHSO_PORT_SERIAL, UHSO_PORT_TYPE_DIAG);
@@ -761,12 +790,13 @@ uhso_probe_iface_static(struct uhso_soft
                        return UHSO_IFACE_SPEC(UHSO_IF_BULK,
                            UHSO_PORT_SERIAL, UHSO_PORT_TYPE_MODEM);
                }
-       }
-       else {
+       } else {
+               /* Cards with 4 interfaces */
                switch (index) {
                case 0:
                        return UHSO_IFACE_SPEC(UHSO_IF_NET | UHSO_IF_MUX,
-                           UHSO_PORT_SERIAL | UHSO_PORT_NETWORK, 0);
+                           UHSO_PORT_SERIAL | UHSO_PORT_NETWORK,
+                           UHSO_PORT_TYPE_NETWORK);
                case 1:
                        return UHSO_IFACE_SPEC(UHSO_IF_BULK,
                            UHSO_PORT_SERIAL, UHSO_PORT_TYPE_DIAG2);
@@ -781,14 +811,18 @@ uhso_probe_iface_static(struct uhso_soft
        return (0);
 }
 
+/*
+ * Probes an interface for its particular capabilities and attaches if
+ * it's a supported interface.
+ */
 static int
 uhso_probe_iface(struct uhso_softc *sc, int index,
     int (*probe)(struct uhso_softc *, int))
 {
        struct usb_interface *iface;
-       int type, error, error0;
+       int type, error;
 
-       UHSO_DPRINTF(1, "Probing for interface %d, cb=%p\n", index, probe);
+       UHSO_DPRINTF(1, "Probing for interface %d, probe_func=%p\n", index, 
probe);
 
        type = probe(sc, index);
        UHSO_DPRINTF(1, "Probe result %x\n", type);
@@ -798,27 +832,41 @@ uhso_probe_iface(struct uhso_softc *sc, 
        sc->sc_type = type;
        iface = usbd_get_iface(sc->sc_udev, index);
 
-       if (UHSO_IFACE_USB_TYPE(type) & (UHSO_IF_MUX | UHSO_IF_NET)) {
-               error0 = uhso_attach_muxserial(sc, iface, type);
+       if (UHSO_IFACE_PORT_TYPE(type) == UHSO_PORT_TYPE_NETWORK) {
                error = uhso_attach_ifnet(sc, iface, type);
-
-               if (error0 && error)
+               if (error) {
+                       UHSO_DPRINTF(1, "uhso_attach_ifnet failed");
                        return (ENXIO);
+               }
 
-               if (sc->sc_ttys > 0) {
+               /*
+                * If there is an additional interrupt endpoint on this
+                * interface we most likley have a multiplexed serial port
+                * available.
+                */
+               if (iface->idesc->bNumEndpoints < 3) {
+                       sc->sc_type = UHSO_IFACE_SPEC( 
+                           UHSO_IFACE_USB_TYPE(type) & ~UHSO_IF_MUX,
+                           UHSO_IFACE_PORT(type) & ~UHSO_PORT_SERIAL,
+                           UHSO_IFACE_PORT_TYPE(type));
+                       return (0);
+               }
+
+               UHSO_DPRINTF(1, "Trying to attach mux. serial\n");
+               error = uhso_attach_muxserial(sc, iface, type);
+               if (error == 0 && sc->sc_ttys > 0) {
                        error = ucom_attach(&sc->sc_super_ucom, sc->sc_ucom,
                            sc->sc_ttys, sc, &uhso_ucom_callback, &sc->sc_mtx);
                        if (error) {
                                device_printf(sc->sc_dev, "ucom_attach 
failed\n");
                                return (ENXIO);
                        }
-               }
 
-               mtx_lock(&sc->sc_mtx);
-               usbd_transfer_start(sc->sc_xfer[UHSO_MUX_ENDPT_INTR]);
-               mtx_unlock(&sc->sc_mtx);
-       }
-       else if ((UHSO_IFACE_USB_TYPE(type) & UHSO_IF_BULK) &&
+                       mtx_lock(&sc->sc_mtx);
+                       usbd_transfer_start(sc->sc_xfer[UHSO_MUX_ENDPT_INTR]);
+                       mtx_unlock(&sc->sc_mtx);
+               }
+       } else if ((UHSO_IFACE_USB_TYPE(type) & UHSO_IF_BULK) &&
            UHSO_IFACE_PORT(type) & UHSO_PORT_SERIAL) {
 
                error = uhso_attach_bulkserial(sc, iface, type);
@@ -833,12 +881,18 @@ uhso_probe_iface(struct uhso_softc *sc, 
                }
        }
        else {
+               UHSO_DPRINTF(0, "Unknown type %x\n", type);
                return (ENXIO);
        }
 
        return (0);
 }
 
+/*
+ * Expands allocated memory to fit an additional TTY.
+ * Two arrays are kept with matching indexes, one for ucom and one
+ * for our private data.
+ */
 static int
 uhso_alloc_tty(struct uhso_softc *sc)
 {
@@ -856,11 +910,15 @@ uhso_alloc_tty(struct uhso_softc *sc)
 
        sc->sc_tty[sc->sc_ttys - 1].ht_sc = sc;
 
-       UHSO_DPRINTF(2, "Allocated TTY %d\n", sc->sc_ttys - 1); 
+       UHSO_DPRINTF(1, "Allocated TTY %d\n", sc->sc_ttys - 1); 
        return (sc->sc_ttys - 1);
 }
 
-
+/*
+ * Attach a multiplexed serial port
+ * Data is read/written with requests on the default control pipe. An interrupt
+ * endpoint returns when there is new data to be read.
+ */
 static int
 uhso_attach_muxserial(struct uhso_softc *sc, struct usb_interface *iface,
     int type)
@@ -885,6 +943,10 @@ uhso_attach_muxserial(struct uhso_softc 
        if (desc->bDescriptorSubtype == 0)
                return (ENXIO);
 
+       /*
+        * The bitmask is one octet, loop through the number of
+        * bits that are set and create a TTY for each.
+        */
        for (i = 0; i < 8; i++) {
                port = (1 << i);
                if ((port & desc->bDescriptorSubtype) == port) {
@@ -905,6 +967,7 @@ uhso_attach_muxserial(struct uhso_softc 
                }
        }
 
+       /* Setup the intr. endpoint */
        uerr = usbd_transfer_setup(sc->sc_udev,
            &iface->idesc->bInterfaceNumber, sc->sc_xfer,
            uhso_mux_config, 1, sc, &sc->sc_mtx);
@@ -914,6 +977,10 @@ uhso_attach_muxserial(struct uhso_softc 
        return (0);
 }
 
+/*
+ * Interrupt callback for the multiplexed serial port. Indicates
+ * which serial port that has data waiting.
+ */
 static void
 uhso_mux_intr_callback(struct usb_xfer *xfer, usb_error_t error)
 {
@@ -943,6 +1010,7 @@ uhso_mux_intr_callback(struct usb_xfer *
                if (mux > UHSO_MPORT_TYPE_NOMAX)
                        break;
 
+               /* Issue a read for this serial port */
                usbd_xfer_set_priv(
                    sc->sc_tty[mux].ht_xfer[UHSO_CTRL_READ],
                    &sc->sc_tty[mux]);
@@ -962,7 +1030,6 @@ tr_setup:
                usbd_xfer_set_stall(xfer);
                goto tr_setup;
        }
-
 }
 
 static void
@@ -1079,7 +1146,6 @@ uhso_mux_write_callback(struct usb_xfer 
                        break;
                break;
        }
-
 }
 
 static int
@@ -1089,9 +1155,7 @@ uhso_attach_bulkserial(struct uhso_softc
        usb_error_t uerr;
        int tty;
 
-       /*
-        * Try attaching RD/WR/INTR first
-        */
+       /* Try attaching RD/WR/INTR first */
        uerr = usbd_transfer_setup(sc->sc_udev,
            &iface->idesc->bInterfaceNumber, sc->sc_xfer,
            uhso_bs_config, UHSO_BULK_ENDPT_MAX, sc, &sc->sc_mtx);
@@ -1146,7 +1210,6 @@ tr_setup:
        }
 }
 
-
 static void
 uhso_bs_write_callback(struct usb_xfer *xfer, usb_error_t error)
 {
@@ -1208,9 +1271,7 @@ uhso_bs_intr_callback(struct usb_xfer *x
        int actlen;
        struct usb_cdc_notification cdc;
 
-
        usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
-
        UHSO_DPRINTF(3, "status %d, actlen=%d\n", USB_GET_STATE(xfer), actlen);
 
        switch (USB_GET_STATE(xfer)) {
@@ -1228,14 +1289,14 @@ uhso_bs_intr_callback(struct usb_xfer *x
                usbd_copy_out(pc, 0, &cdc, actlen);
 
                if (UGETW(cdc.wIndex) != sc->sc_iface_no) {
-                       UHSO_DPRINTF(0, "Interface missmatch, got %d expected 
%d\n",
+                       UHSO_DPRINTF(0, "Interface mismatch, got %d expected 
%d\n",
                            UGETW(cdc.wIndex), sc->sc_iface_no);
                        goto tr_setup;
                }
 
                if (cdc.bmRequestType == UCDC_NOTIFICATION &&
                    cdc.bNotification == UCDC_N_SERIAL_STATE) {
-                       UHSO_DPRINTF(1, "notify = 0x%02x\n", cdc.data[0]);
+                       UHSO_DPRINTF(2, "notify = 0x%02x\n", cdc.data[0]);
 
                        sc->sc_msr = 0;
                        sc->sc_lsr = 0;
@@ -1299,7 +1360,6 @@ uhso_ucom_cfg_set_rts(struct ucom_softc 
        uhso_bs_cfg(sc);
 }
 
-
 static void
 uhso_ucom_start_read(struct ucom_softc *ucom)
 {
@@ -1373,7 +1433,6 @@ uhso_ucom_stop_write(struct ucom_softc *
        else if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_BULK) {
                usbd_transfer_stop(sc->sc_xfer[UHSO_BULK_ENDPT_WRITE]);
        }
-
 }
 
 static int uhso_attach_ifnet(struct uhso_softc *sc, struct usb_interface 
*iface,
@@ -1393,7 +1452,7 @@ static int uhso_attach_ifnet(struct uhso
                return (-1);
        }
 
-       sc->sc_ifp = ifp = if_alloc(IFT_PPP);
+       sc->sc_ifp = ifp = if_alloc(IFT_OTHER);
        if (sc->sc_ifp == NULL) {
                device_printf(sc->sc_dev, "if_alloc() failed\n");
                return (-1);
@@ -1406,7 +1465,6 @@ static int uhso_attach_ifnet(struct uhso
 
        if_initname(ifp, device_get_name(sc->sc_dev), 
device_get_unit(sc->sc_dev));
        ifp->if_mtu = UHSO_MAX_MTU;
-
        ifp->if_ioctl = uhso_if_ioctl;
        ifp->if_init = uhso_if_init;
        ifp->if_start = uhso_if_start;
@@ -1448,6 +1506,7 @@ uhso_ifnet_read_callback(struct usb_xfer
                        m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
                        usbd_copy_out(pc, 0, mtod(m, uint8_t *), actlen);
                        m->m_pkthdr.len = m->m_len = actlen;
+                       /* Enqueue frame for further processing */
                        _IF_ENQUEUE(&sc->sc_rxq, m);
                        if (!callout_pending(&sc->sc_c) ||
                            !callout_active(&sc->sc_c)) {
@@ -1470,7 +1529,11 @@ tr_setup:
 }
 
 /*
- * Defered RX processing, called with mutex locked.
+ * Deferred RX processing, called with mutex locked.
+ *
+ * Each frame we receive might contain several small ip-packets aswell
+ * as partial ip-packets. We need to separate/assemble them into individual
+ * packets before sending them to the ip-layer.
  */
 static void
 uhso_if_rxflush(void *arg)
@@ -1493,7 +1556,7 @@ uhso_if_rxflush(void *arg)
                        _IF_DEQUEUE(&sc->sc_rxq, m);
                        if (m == NULL)
                                break;
-                       UHSO_DPRINTF(2, "dequeue m=%p, len=%d\n", m, m->m_len);
+                       UHSO_DPRINTF(3, "dequeue m=%p, len=%d\n", m, m->m_len);
                }
                mtx_unlock(&sc->sc_mtx);
 
@@ -1502,7 +1565,7 @@ uhso_if_rxflush(void *arg)
                        m0 = mwait;
                        mwait = NULL;
 
-                       UHSO_DPRINTF(1, "partial m0=%p(%d), concat w/ 
m=%p(%d)\n",
+                       UHSO_DPRINTF(3, "partial m0=%p(%d), concat w/ 
m=%p(%d)\n",
                            m0, m0->m_len, m, m->m_len);
                        len = m->m_len + m0->m_len;
 
@@ -1518,7 +1581,7 @@ uhso_if_rxflush(void *arg)
                                mtx_lock(&sc->sc_mtx);
                                continue;
                        }
-                       UHSO_DPRINTF(2, "Constructed mbuf=%p, len=%d\n",
+                       UHSO_DPRINTF(3, "Constructed mbuf=%p, len=%d\n",
                            m, m->m_pkthdr.len);
                }
 
@@ -1560,7 +1623,7 @@ uhso_if_rxflush(void *arg)
                        continue;
                }
 
-               UHSO_DPRINTF(1, "m=%p, len=%d, cp=%p, iplen=%d\n",
+               UHSO_DPRINTF(3, "m=%p, len=%d, cp=%p, iplen=%d\n",
                    m, m->m_pkthdr.len, cp, iplen);
 
                m0 = NULL;
@@ -1581,12 +1644,12 @@ uhso_if_rxflush(void *arg)
                        m_adj(m0, iplen);
                        m0 = m_defrag(m0, M_WAIT);
 
-                       UHSO_DPRINTF(1, "New mbuf=%p, len=%d/%d, m0=%p, "
+                       UHSO_DPRINTF(3, "New mbuf=%p, len=%d/%d, m0=%p, "
                            "m0_len=%d/%d\n", m, m->m_pkthdr.len, m->m_len,
                            m0, m0->m_pkthdr.len, m0->m_len);
                }
                else if (iplen > m->m_pkthdr.len) {
-                       UHSO_DPRINTF(1, "Defered mbuf=%p, len=%d\n",
+                       UHSO_DPRINTF(3, "Deferred mbuf=%p, len=%d\n",
                            m, m->m_pkthdr.len);
                        mwait = m;
                        m = NULL;
@@ -1649,7 +1712,6 @@ tr_setup:
                usbd_xfer_set_stall(xfer);
                goto tr_setup;
        }
-
 }
 
 static int
@@ -1698,7 +1760,7 @@ uhso_if_init(void *priv)
        ifp->if_drv_flags |= IFF_DRV_RUNNING;
        mtx_unlock(&sc->sc_mtx);
 
-       UHSO_DPRINTF(3, "ifnet initialized\n");
+       UHSO_DPRINTF(2, "ifnet initialized\n");
 }
 
 static int
@@ -1722,7 +1784,6 @@ uhso_if_output(struct ifnet *ifp, struct
                return (ENOBUFS);
        }
        ifp->if_opackets++;
-
        return (0);
 }
 
@@ -1749,6 +1810,5 @@ uhso_if_stop(struct uhso_softc *sc)
 
        usbd_transfer_stop(sc->sc_if_xfer[UHSO_IFNET_READ]);
        usbd_transfer_stop(sc->sc_if_xfer[UHSO_IFNET_WRITE]);
-
        sc->sc_ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
 }

Modified: head/sys/dev/usb/usbdevs
==============================================================================
--- head/sys/dev/usb/usbdevs    Wed Jan 13 20:51:23 2010        (r202242)
+++ head/sys/dev/usb/usbdevs    Wed Jan 13 20:54:18 2010        (r202243)
@@ -2111,6 +2111,7 @@ product OPTION GE40X_3            0x7381  Globetrot
 product OPTION ICONEDGE                0xc031  GlobeSurfer iCON EDGE
 product OPTION MODHSXPA                0xd013  Globetrotter HSUPA
 product OPTION ICON321         0xd031  Globetrotter HSUPA
+product OPTION ICON505         0xd055  Globetrotter iCON 505
 
 /* OQO */
 product OQO WIFI01             0x0002  model 01 WiFi interface
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to