From owner-svn-src-all@FreeBSD.ORG Fri Nov 19 01:23:10 2010 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 732EA1065698; Fri, 19 Nov 2010 01:23:10 +0000 (UTC) (envelope-from thompsa@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 60E618FC13; Fri, 19 Nov 2010 01:23:10 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id oAJ1NARX051333; Fri, 19 Nov 2010 01:23:10 GMT (envelope-from thompsa@svn.freebsd.org) Received: (from thompsa@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id oAJ1NA1r051329; Fri, 19 Nov 2010 01:23:10 GMT (envelope-from thompsa@svn.freebsd.org) Message-Id: <201011190123.oAJ1NA1r051329@svn.freebsd.org> From: Andrew Thompson Date: Fri, 19 Nov 2010 01:23:10 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org X-SVN-Group: stable-8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r215478 - in stable/8: share/man/man4 sys/dev/usb sys/dev/usb/net X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 19 Nov 2010 01:23:10 -0000 Author: thompsa Date: Fri Nov 19 01:23:09 2010 New Revision: 215478 URL: http://svn.freebsd.org/changeset/base/215478 Log: MFC r210275 - Support for Globetrotter iCON 452. - Fixed the interface probe routine to only attach to USB interfaces the driver actually supports. This allows other drivers to attach to things like MicroSD slots etc. - Fixed network interface enumeration to be globally sequential instead of relying on the USB interface numbers. This make sure the first network interface always is at uhso0 and the second at usho1 and so on. - Added a radio kill switch; exposed through sysctl. - Updated the manual page to be verbose about the number of serial ports and include iCON 452 in the set of tested hardware. Submitted by: Fredrik Lindberg Modified: stable/8/share/man/man4/uhso.4 stable/8/sys/dev/usb/net/uhso.c stable/8/sys/dev/usb/usbdevs Directory Properties: stable/8/share/man/man4/ (props changed) stable/8/sys/ (props changed) stable/8/sys/amd64/include/xen/ (props changed) stable/8/sys/cddl/contrib/opensolaris/ (props changed) stable/8/sys/contrib/dev/acpica/ (props changed) stable/8/sys/contrib/pf/ (props changed) stable/8/sys/dev/xen/xenpci/ (props changed) Modified: stable/8/share/man/man4/uhso.4 ============================================================================== --- stable/8/share/man/man4/uhso.4 Fri Nov 19 01:20:53 2010 (r215477) +++ stable/8/share/man/man4/uhso.4 Fri Nov 19 01:23:09 2010 (r215478) @@ -43,8 +43,9 @@ based on their packet interface. Each device has a set of serial ports and a raw IP packet interface. The serial ports of the device are accessed through the .Xr ucom 4 -driver which makes them behave like a -.Xr tty 4 . +driver which makes them behave like +.Xr tty 4 +devices. The packet interface is exposed as a network interface. .Pp Establishing a connection on the packet interface is achieved by using the @@ -60,10 +61,19 @@ these calls. Each device usually have at least two or more serial ports, their individual purpose can be identified through .Xr sysctl 8 . +Ports identified as +.Dq Modem +features a normal modem interface that can be used with PPP. +Ports identified as +.Dq Diagnostic +uses a proprietary binary interface used for firmware upgrades, this port does not +have a AT command interface and can not be used to control the device. +Other ports features an AT command interface that can be used for normal device control. .Sh HARDWARE The .Nm -driver supports at least the following cards +driver should work with most devices from Option. +The following devices have been verified to work .Pp .Bl -bullet -compact .It @@ -71,6 +81,8 @@ Option GlobeSurfer iCON 7.2 (new firmwar .It Option iCON 225 .It +Option iCON 452 +.It Option iCON 505 .El .Pp @@ -88,7 +100,8 @@ This behavior can be disabled by setting to 0 using .Xr sysctl 8 .Sh EXAMPLES -Establishing a packet interface connection +Establishing a packet interface connection using the AT command interface available +at one of the serial ports .Bd -literal -offset indent AT+CGDCONT=1,,"apn.provider" AT_OWANCALL=1,1,1 Modified: stable/8/sys/dev/usb/net/uhso.c ============================================================================== --- stable/8/sys/dev/usb/net/uhso.c Fri Nov 19 01:20:53 2010 (r215477) +++ stable/8/sys/dev/usb/net/uhso.c Fri Nov 19 01:23:09 2010 (r215478) @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2009 Fredrik Lindberg + * Copyright (c) 2010 Fredrik Lindberg * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include @@ -81,6 +82,7 @@ struct uhso_softc { struct usb_device *sc_udev; struct mtx sc_mtx; uint32_t sc_type; /* Interface definition */ + int sc_radio; struct usb_xfer *sc_xfer[3]; uint8_t sc_iface_no; @@ -155,6 +157,7 @@ struct uhso_softc { * Note that these definitions are arbitrary and do not match the values * returned by the auto config descriptor. */ +#define UHSO_PORT_TYPE_UNKNOWN 0x00 #define UHSO_PORT_TYPE_CTL 0x01 #define UHSO_PORT_TYPE_APP 0x02 #define UHSO_PORT_TYPE_APP2 0x03 @@ -185,7 +188,7 @@ static char *uhso_port[] = { * descriptor values. */ static unsigned char uhso_port_map[] = { - 0, + UHSO_PORT_TYPE_UNKNOWN, UHSO_PORT_TYPE_DIAG, UHSO_PORT_TYPE_GPS, UHSO_PORT_TYPE_GPSCTL, @@ -243,6 +246,9 @@ static char *uhso_port_type_sysctl[] = { #define UHSO_STATIC_IFACE 0x01 #define UHSO_AUTO_IFACE 0x02 +/* ifnet device unit allocations */ +static struct unrhdr *uhso_ifnet_unit = NULL; + static const struct usb_device_id uhso_devs[] = { #define UHSO_DEV(v,p,i) { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, i) } /* Option GlobeSurfer iCON 7.2 */ @@ -272,6 +278,8 @@ static const struct usb_device_id uhso_d UHSO_DEV(OPTION, GTICON322, UHSO_STATIC_IFACE), /* Option iCON 505 */ UHSO_DEV(OPTION, ICON505, UHSO_AUTO_IFACE), + /* Option iCON 452 */ + UHSO_DEV(OPTION, ICON505, UHSO_AUTO_IFACE), #undef UHSO_DEV }; @@ -432,9 +440,9 @@ static const struct usb_config uhso_bs_c }; 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); + int (*probe)(struct usb_device *, int)); +static int uhso_probe_iface_auto(struct usb_device *, int); +static int uhso_probe_iface_static(struct usb_device *, 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 *, @@ -444,6 +452,8 @@ static int uhso_attach_ifnet(struct uhs 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_radio_sysctl(SYSCTL_HANDLER_ARGS); +static int uhso_radio_ctrl(struct uhso_softc *, int); static void uhso_ucom_start_read(struct ucom_softc *); static void uhso_ucom_stop_read(struct ucom_softc *); @@ -497,6 +507,7 @@ static int uhso_probe(device_t self) { struct usb_attach_arg *uaa = device_get_ivars(self); + int error; if (uaa->usb_mode != USB_MODE_HOST) return (ENXIO); @@ -505,7 +516,20 @@ uhso_probe(device_t self) if (uaa->device->ddesc.bDeviceClass != 0xff) return (ENXIO); - return (usbd_lookup_id_by_uaa(uhso_devs, sizeof(uhso_devs), uaa)); + error = usbd_lookup_id_by_uaa(uhso_devs, sizeof(uhso_devs), uaa); + if (error != 0) + return (error); + + /* + * Probe device to see if we are able to attach + * to this interface or not. + */ + if (USB_GET_DRIVER_INFO(uaa) == UHSO_AUTO_IFACE) { + if (uhso_probe_iface_auto(uaa->device, + uaa->info.bIfaceNum) == 0) + return (ENXIO); + } + return (error); } static int @@ -517,7 +541,7 @@ uhso_attach(device_t self) struct usb_interface_descriptor *id; struct sysctl_ctx_list *sctx; struct sysctl_oid *soid; - struct sysctl_oid *tree, *tty_node; + struct sysctl_oid *tree = NULL, *tty_node; struct ucom_softc *ucom; struct uhso_tty *ht; int i, error, port; @@ -531,6 +555,7 @@ uhso_attach(device_t self) sc->sc_ucom = NULL; sc->sc_ttys = 0; + sc->sc_radio = 1; cd = usbd_get_config_descriptor(uaa->device); id = usbd_get_interface_descriptor(uaa->iface); @@ -566,6 +591,8 @@ uhso_attach(device_t self) SYSCTL_ADD_STRING(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "type", CTLFLAG_RD, uhso_port[UHSO_IFACE_PORT(sc->sc_type)], 0, "Port available at this interface"); + SYSCTL_ADD_PROC(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "radio", + CTLTYPE_INT | CTLFLAG_RW, sc, 0, uhso_radio_sysctl, "I", "Enable radio"); /* * The default interface description on most Option devices isn't @@ -655,6 +682,7 @@ uhso_detach(device_t self) if (sc->sc_ifp != NULL) { callout_drain(&sc->sc_c); + free_unr(uhso_ifnet_unit, sc->sc_ifp->if_dunit); mtx_lock(&sc->sc_mtx); uhso_if_stop(sc); bpfdetach(sc->sc_ifp); @@ -701,9 +729,12 @@ uhso_driver_loaded(struct module *mod, i /* register our autoinstall handler */ uhso_etag = EVENTHANDLER_REGISTER(usb_dev_configured, uhso_test_autoinst, NULL, EVENTHANDLER_PRI_ANY); + /* create our unit allocator for inet devs */ + uhso_ifnet_unit = new_unrhdr(0, INT_MAX, NULL); break; case MOD_UNLOAD: EVENTHANDLER_DEREGISTER(usb_dev_configured, uhso_etag); + delete_unrhdr(uhso_ifnet_unit); break; default: return (EOPNOTSUPP); @@ -717,7 +748,7 @@ uhso_driver_loaded(struct module *mod, i * Returns a bit mask with the interface capabilities. */ static int -uhso_probe_iface_auto(struct uhso_softc *sc, int index) +uhso_probe_iface_auto(struct usb_device *udev, int index) { struct usb_device_request req; usb_error_t uerr; @@ -731,11 +762,11 @@ uhso_probe_iface_auto(struct uhso_softc USETW(req.wIndex, 0); USETW(req.wLength, 17); - uerr = usbd_do_request_flags(sc->sc_udev, NULL, &req, buf, + uerr = usbd_do_request_flags(udev, NULL, &req, buf, 0, &actlen, USB_MS_HZ); if (uerr != 0) { - device_printf(sc->sc_dev, "usbd_do_request_flags failed: %s\n", - usbd_errstr(uerr)); + printf("%s: usbd_do_request_flags failed, %s\n", + __func__, usbd_errstr(uerr)); return (0); } @@ -759,23 +790,35 @@ uhso_probe_iface_auto(struct uhso_softc 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); - default: + case UHSO_PORT_TYPE_DIAG: + case UHSO_PORT_TYPE_DIAG2: + case UHSO_PORT_TYPE_CTL: + case UHSO_PORT_TYPE_APP: + case UHSO_PORT_TYPE_APP2: + case UHSO_PORT_TYPE_MODEM: return (UHSO_IFACE_SPEC(UHSO_IF_BULK, UHSO_PORT_SERIAL, port)); + case UHSO_PORT_TYPE_MSD: + return (0); + case UHSO_PORT_TYPE_UNKNOWN: + default: + return (0); } return (0); } +/* + * Returns the capabilities of interfaces for devices that don't + * support the automatic query. + * Returns a bit mask with the interface capabilities. + */ static int -uhso_probe_iface_static(struct uhso_softc *sc, int index) +uhso_probe_iface_static(struct usb_device *udev, int index) { struct usb_config_descriptor *cd; - cd = usbd_get_config_descriptor(sc->sc_udev); + cd = usbd_get_config_descriptor(udev); if (cd->bNumInterface <= 3) { /* Cards with 3 or less interfaces */ switch (index) { @@ -817,14 +860,14 @@ uhso_probe_iface_static(struct uhso_soft */ static int uhso_probe_iface(struct uhso_softc *sc, int index, - int (*probe)(struct uhso_softc *, int)) + int (*probe)(struct usb_device *, int)) { struct usb_interface *iface; int type, error; UHSO_DPRINTF(1, "Probing for interface %d, probe_func=%p\n", index, probe); - type = probe(sc, index); + type = probe(sc->sc_udev, index); UHSO_DPRINTF(1, "Probe result %x\n", type); if (type <= 0) return (ENXIO); @@ -888,6 +931,47 @@ uhso_probe_iface(struct uhso_softc *sc, return (0); } +static int +uhso_radio_ctrl(struct uhso_softc *sc, int onoff) +{ + struct usb_device_request req; + usb_error_t uerr; + + req.bmRequestType = UT_VENDOR; + req.bRequest = onoff ? 0x82 : 0x81; + USETW(req.wValue, 0); + USETW(req.wIndex, 0); + USETW(req.wLength, 0); + + uerr = usbd_do_request(sc->sc_udev, NULL, &req, NULL); + if (uerr != 0) { + device_printf(sc->sc_dev, "usbd_do_request_flags failed: %s\n", + usbd_errstr(uerr)); + return (-1); + } + return (onoff); +} + +static int +uhso_radio_sysctl(SYSCTL_HANDLER_ARGS) +{ + struct uhso_softc *sc = arg1; + int error, radio; + + radio = sc->sc_radio; + error = sysctl_handle_int(oidp, &radio, 0, req); + if (error) + return (error); + if (radio != sc->sc_radio) { + radio = radio != 0 ? 1 : 0; + error = uhso_radio_ctrl(sc, radio); + if (error != -1) + sc->sc_radio = radio; + + } + return (0); +} + /* * Expands allocated memory to fit an additional TTY. * Two arrays are kept with matching indexes, one for ucom and one @@ -1435,13 +1519,14 @@ uhso_ucom_stop_write(struct ucom_softc * } } -static int uhso_attach_ifnet(struct uhso_softc *sc, struct usb_interface *iface, - int type) +static int +uhso_attach_ifnet(struct uhso_softc *sc, struct usb_interface *iface, int type) { struct ifnet *ifp; usb_error_t uerr; struct sysctl_ctx_list *sctx; struct sysctl_oid *soid; + unsigned int devunit; uerr = usbd_transfer_setup(sc->sc_udev, &iface->idesc->bInterfaceNumber, sc->sc_if_xfer, @@ -1463,7 +1548,14 @@ static int uhso_attach_ifnet(struct uhso callout_reset(&sc->sc_c, 1, uhso_if_rxflush, sc); mtx_unlock(&sc->sc_mtx); - if_initname(ifp, device_get_name(sc->sc_dev), device_get_unit(sc->sc_dev)); + /* + * We create our own unit numbers for ifnet devices because the + * USB interface unit numbers can be at arbitrary positions yielding + * odd looking device names. + */ + devunit = alloc_unr(uhso_ifnet_unit); + + if_initname(ifp, device_get_name(sc->sc_dev), devunit); ifp->if_mtu = UHSO_MAX_MTU; ifp->if_ioctl = uhso_if_ioctl; ifp->if_init = uhso_if_init; Modified: stable/8/sys/dev/usb/usbdevs ============================================================================== --- stable/8/sys/dev/usb/usbdevs Fri Nov 19 01:20:53 2010 (r215477) +++ stable/8/sys/dev/usb/usbdevs Fri Nov 19 01:23:09 2010 (r215478) @@ -2398,6 +2398,7 @@ product OPTION ICONEDGE 0xc031 GlobeSur product OPTION MODHSXPA 0xd013 Globetrotter HSUPA product OPTION ICON321 0xd031 Globetrotter HSUPA product OPTION ICON505 0xd055 Globetrotter iCON 505 +product OPTION_ICON452 0x7901 Globetrotter iCON 452 /* OvisLink product */ product OVISLINK RT3072 0x3072 RT3072