From owner-svn-src-all@FreeBSD.ORG Thu Mar 5 16:15:08 2009 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 F3F36106566B; Thu, 5 Mar 2009 16:15:07 +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 D6A748FC15; Thu, 5 Mar 2009 16:15:07 +0000 (UTC) (envelope-from thompsa@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n25GF7f9090003; Thu, 5 Mar 2009 16:15:07 GMT (envelope-from thompsa@svn.freebsd.org) Received: (from thompsa@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n25GF7kL090002; Thu, 5 Mar 2009 16:15:07 GMT (envelope-from thompsa@svn.freebsd.org) Message-Id: <200903051615.n25GF7kL090002@svn.freebsd.org> From: Andrew Thompson Date: Thu, 5 Mar 2009 16:15:07 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r189405 - head/sys/dev/usb/serial 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: Thu, 05 Mar 2009 16:15:08 -0000 Author: thompsa Date: Thu Mar 5 16:15:07 2009 New Revision: 189405 URL: http://svn.freebsd.org/changeset/base/189405 Log: Add support for the UNION interface descriptor, used by Nokia phones. PR: usb/117185 Modified: head/sys/dev/usb/serial/umodem.c Modified: head/sys/dev/usb/serial/umodem.c ============================================================================== --- head/sys/dev/usb/serial/umodem.c Thu Mar 5 16:03:44 2009 (r189404) +++ head/sys/dev/usb/serial/umodem.c Thu Mar 5 16:15:07 2009 (r189405) @@ -69,6 +69,7 @@ __FBSDID("$FreeBSD$"); /* * Comm Class spec: http://www.usb.org/developers/devclass_docs/usbccs10.pdf * http://www.usb.org/developers/devclass_docs/usbcdc11.pdf + * http://www.usb.org/developers/devclass_docs/cdc_wmc10.zip */ /* @@ -253,8 +254,6 @@ static int umodem_probe(device_t dev) { struct usb2_attach_arg *uaa = device_get_ivars(dev); - uint8_t cm; - uint8_t acm; int error; DPRINTFN(11, "\n"); @@ -263,19 +262,6 @@ umodem_probe(device_t dev) return (ENXIO); } error = usb2_lookup_id_by_uaa(umodem_devs, sizeof(umodem_devs), uaa); - if (error) { - return (error); - } - if (uaa->driver_info == NULL) { - /* some modems do not have any capabilities */ - return (error); - } - umodem_get_caps(uaa, &cm, &acm); - if (!(cm & USB_CDC_CM_DOES_CM) || - !(cm & USB_CDC_CM_OVER_DATA) || - !(acm & USB_CDC_ACM_HAS_LINE)) { - error = ENXIO; - } return (error); } @@ -285,6 +271,7 @@ umodem_attach(device_t dev) struct usb2_attach_arg *uaa = device_get_ivars(dev); struct umodem_softc *sc = device_get_softc(dev); struct usb2_cdc_cm_descriptor *cmd; + struct usb2_cdc_union_descriptor *cud; uint8_t i; int error; @@ -302,10 +289,20 @@ umodem_attach(device_t dev) cmd = umodem_get_desc(uaa, UDESC_CS_INTERFACE, UDESCSUB_CDC_CM); if ((cmd == NULL) || (cmd->bLength < sizeof(*cmd))) { - device_printf(dev, "no CM descriptor!\n"); - goto detach; + + cud = usb2_find_descriptor(uaa->device, NULL, + uaa->info.bIfaceIndex, UDESC_CS_INTERFACE, + 0 - 1, UDESCSUB_CDC_UNION, 0 - 1); + + if ((cud == NULL) || (cud->bLength < sizeof(*cud))) { + device_printf(dev, "no CM or union descriptor!\n"); + goto detach; + } + + sc->sc_data_iface_no = cud->bSlaveInterface[0]; + } else { + sc->sc_data_iface_no = cmd->bDataInterface; } - sc->sc_data_iface_no = cmd->bDataInterface; device_printf(dev, "data interface %d, has %sCM over " "data, has %sbreak\n", @@ -419,21 +416,19 @@ umodem_get_caps(struct usb2_attach_arg * struct usb2_cdc_cm_descriptor *cmd; struct usb2_cdc_acm_descriptor *cad; - *cm = *acm = 0; - cmd = umodem_get_desc(uaa, UDESC_CS_INTERFACE, UDESCSUB_CDC_CM); if ((cmd == NULL) || (cmd->bLength < sizeof(*cmd))) { - DPRINTF("no CM desc\n"); - return; - } - *cm = cmd->bmCapabilities; + DPRINTF("no CM desc (faking one)\n"); + *cm = USB_CDC_CM_DOES_CM | USB_CDC_CM_OVER_DATA; + } else + *cm = cmd->bmCapabilities; cad = umodem_get_desc(uaa, UDESC_CS_INTERFACE, UDESCSUB_CDC_ACM); if ((cad == NULL) || (cad->bLength < sizeof(*cad))) { DPRINTF("no ACM desc\n"); - return; - } - *acm = cad->bmCapabilities; + *acm = 0; + } else + *acm = cad->bmCapabilities; } static void