From owner-freebsd-usb@FreeBSD.ORG Thu Oct 30 17:30:01 2008 Return-Path: Delivered-To: freebsd-usb@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 5AF411065677 for ; Thu, 30 Oct 2008 17:30:01 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id 32D718FC20 for ; Thu, 30 Oct 2008 17:30:01 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.14.3/8.14.3) with ESMTP id m9UHU1lj085647 for ; Thu, 30 Oct 2008 17:30:01 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.3/8.14.3/Submit) id m9UHU1Bc085644; Thu, 30 Oct 2008 17:30:01 GMT (envelope-from gnats) Resent-Date: Thu, 30 Oct 2008 17:30:01 GMT Resent-Message-Id: <200810301730.m9UHU1Bc085644@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-usb@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Andrey Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 7DBC4106567A for ; Thu, 30 Oct 2008 17:28:42 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from www.freebsd.org (www.freebsd.org [IPv6:2001:4f8:fff6::21]) by mx1.freebsd.org (Postfix) with ESMTP id 6BEFB8FC0C for ; Thu, 30 Oct 2008 17:28:42 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from www.freebsd.org (localhost [127.0.0.1]) by www.freebsd.org (8.14.3/8.14.3) with ESMTP id m9UHSfRp012982 for ; Thu, 30 Oct 2008 17:28:41 GMT (envelope-from nobody@www.freebsd.org) Received: (from nobody@localhost) by www.freebsd.org (8.14.3/8.14.3/Submit) id m9UHSfr9012981; Thu, 30 Oct 2008 17:28:41 GMT (envelope-from nobody) Message-Id: <200810301728.m9UHSfr9012981@www.freebsd.org> Date: Thu, 30 Oct 2008 17:28:41 GMT From: Andrey To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-3.1 Cc: Subject: usb/128485: Nokia N80 modem support X-BeenThere: freebsd-usb@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: FreeBSD support for USB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 30 Oct 2008 17:30:01 -0000 >Number: 128485 >Category: usb >Synopsis: Nokia N80 modem support >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-usb >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Thu Oct 30 17:30:00 UTC 2008 >Closed-Date: >Last-Modified: >Originator: Andrey >Release: FreeBSD 6.3-RELEASE #0 >Organization: none >Environment: FreeBSD dron-hm.dron.dp.ua 6.3-RELEASE FreeBSD 6.3-RELEASE #0: Wed Jan 16 04:45:45 UTC 2008 root@dessler.cse.buffalo.edu:/usr/obj/usr/src/sys/SMP i386 >Description: I have an Nokia N80 smartphone, but in FreeBSD there is no modem were defined, only ugen device... So I can't use this hardwae to connect to internet... >How-To-Repeat: install FreeBSD and plug an Nokia N80 :) >Fix: after some debug and using google next patch were born: --- umodem.c.orig 2008-10-22 23:02:46.000000000 +0300 +++ umodem.c.without_debug 2008-10-30 19:04:44.000000000 +0200 @@ -69,6 +69,7 @@ /* * 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 */ /* @@ -127,6 +128,7 @@ { USB_VENDOR_KYOCERA, USB_PRODUCT_KYOCERA_AHK3001V, 0 }, { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC5720, 0 }, { USB_VENDOR_CURITEL, USB_PRODUCT_CURITEL_PC5740, 0 }, + { 0x0421, 0x0445, 0 }, { 0, 0, 0 }, }; @@ -179,7 +181,8 @@ usb_cdc_line_state_t *state); Static void umodem_get_caps(usbd_device_handle, int *, int *); - +Static usb_cdc_union_descriptor_t * + umodem_get_union(usbd_device_handle dev, int iface_no); Static void umodem_get_status(void *, int portno, u_char *lsr, u_char *msr); Static void umodem_set(void *, int, int, int); Static void umodem_dtr(struct umodem_softc *, int); @@ -269,7 +272,6 @@ return ret; } - USB_ATTACH(umodem) { USB_ATTACH_START(umodem, sc, uaa); @@ -277,6 +279,7 @@ usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; usb_cdc_cm_descriptor_t *cmd; + usb_cdc_union_descriptor_t *cud; char *devinfo = NULL; const char *devname; usbd_status err; @@ -309,10 +312,13 @@ /* Get the data interface no. */ cmd = umodem_get_desc(dev, UDESC_CS_INTERFACE, UDESCSUB_CDC_CM); if (cmd == NULL) { - printf("%s: no CM descriptor\n", devname); + cud = umodem_get_union(dev, sc->sc_ctl_iface_no); + if (cud == NULL) { + printf("%s: no CM and Union descriptors\n", devname); goto bad; - } - sc->sc_data_iface_no = data_ifcno = cmd->bDataInterface; + }else data_ifcno = cud->bSlaveInterface[0]; + }else data_ifcno = cmd->bDataInterface; + sc->sc_data_iface_no = data_ifcno; printf("%s: data interface %d, has %sCM over data, has %sbreak\n", devname, data_ifcno, @@ -558,19 +564,36 @@ *cm = *acm = 0; - cmd = umodem_get_desc(dev, UDESC_CS_INTERFACE, UDESCSUB_CDC_CM); - if (cmd == NULL) { - DPRINTF(("umodem_get_desc: no CM desc\n")); - return; - } - *cm = cmd->bmCapabilities; - cad = umodem_get_desc(dev, UDESC_CS_INTERFACE, UDESCSUB_CDC_ACM); if (cad == NULL) { DPRINTF(("umodem_get_desc: no ACM desc\n")); return; } *acm = cad->bmCapabilities; + + cmd = umodem_get_desc(dev, UDESC_CS_INTERFACE, UDESCSUB_CDC_CM); + if (cmd == NULL) { + DPRINTF(("umodem_get_desc: no CM desc\n")); + *cm = USB_CDC_CM_DOES_CM | USB_CDC_CM_OVER_DATA; + }else *cm = cmd->bmCapabilities; +} + +usb_cdc_union_descriptor_t * +umodem_get_union(usbd_device_handle dev, int iface_no) +{ + usb_cdc_union_descriptor_t *desc; + usb_config_descriptor_t *cd = usbd_get_config_descriptor(dev); + uByte *p = (uByte *)cd; + uByte *end = p + UGETW(cd->wTotalLength); + while (p < end) { + desc = (usb_cdc_union_descriptor_t *)p; + if (desc->bDescriptorType == UDESC_CS_INTERFACE && + desc->bDescriptorSubtype == UDESCSUB_CDC_UNION && + desc->bMasterInterface == iface_no) + return (desc); + p += desc->bLength; + } + return (0); } void With this patch moden is appeared in a system... Patch attached with submission follows: --- umodem.c.orig 2008-10-22 23:02:46.000000000 +0300 +++ umodem.c.without_debug 2008-10-30 19:04:44.000000000 +0200 @@ -69,6 +69,7 @@ /* * 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 */ /* @@ -127,6 +128,7 @@ { USB_VENDOR_KYOCERA, USB_PRODUCT_KYOCERA_AHK3001V, 0 }, { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC5720, 0 }, { USB_VENDOR_CURITEL, USB_PRODUCT_CURITEL_PC5740, 0 }, + { 0x0421, 0x0445, 0 }, { 0, 0, 0 }, }; @@ -179,7 +181,8 @@ usb_cdc_line_state_t *state); Static void umodem_get_caps(usbd_device_handle, int *, int *); - +Static usb_cdc_union_descriptor_t * + umodem_get_union(usbd_device_handle dev, int iface_no); Static void umodem_get_status(void *, int portno, u_char *lsr, u_char *msr); Static void umodem_set(void *, int, int, int); Static void umodem_dtr(struct umodem_softc *, int); @@ -269,7 +272,6 @@ return ret; } - USB_ATTACH(umodem) { USB_ATTACH_START(umodem, sc, uaa); @@ -277,6 +279,7 @@ usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; usb_cdc_cm_descriptor_t *cmd; + usb_cdc_union_descriptor_t *cud; char *devinfo = NULL; const char *devname; usbd_status err; @@ -309,10 +312,13 @@ /* Get the data interface no. */ cmd = umodem_get_desc(dev, UDESC_CS_INTERFACE, UDESCSUB_CDC_CM); if (cmd == NULL) { - printf("%s: no CM descriptor\n", devname); + cud = umodem_get_union(dev, sc->sc_ctl_iface_no); + if (cud == NULL) { + printf("%s: no CM and Union descriptors\n", devname); goto bad; - } - sc->sc_data_iface_no = data_ifcno = cmd->bDataInterface; + }else data_ifcno = cud->bSlaveInterface[0]; + }else data_ifcno = cmd->bDataInterface; + sc->sc_data_iface_no = data_ifcno; printf("%s: data interface %d, has %sCM over data, has %sbreak\n", devname, data_ifcno, @@ -558,19 +564,36 @@ *cm = *acm = 0; - cmd = umodem_get_desc(dev, UDESC_CS_INTERFACE, UDESCSUB_CDC_CM); - if (cmd == NULL) { - DPRINTF(("umodem_get_desc: no CM desc\n")); - return; - } - *cm = cmd->bmCapabilities; - cad = umodem_get_desc(dev, UDESC_CS_INTERFACE, UDESCSUB_CDC_ACM); if (cad == NULL) { DPRINTF(("umodem_get_desc: no ACM desc\n")); return; } *acm = cad->bmCapabilities; + + cmd = umodem_get_desc(dev, UDESC_CS_INTERFACE, UDESCSUB_CDC_CM); + if (cmd == NULL) { + DPRINTF(("umodem_get_desc: no CM desc\n")); + *cm = USB_CDC_CM_DOES_CM | USB_CDC_CM_OVER_DATA; + }else *cm = cmd->bmCapabilities; +} + +usb_cdc_union_descriptor_t * +umodem_get_union(usbd_device_handle dev, int iface_no) +{ + usb_cdc_union_descriptor_t *desc; + usb_config_descriptor_t *cd = usbd_get_config_descriptor(dev); + uByte *p = (uByte *)cd; + uByte *end = p + UGETW(cd->wTotalLength); + while (p < end) { + desc = (usb_cdc_union_descriptor_t *)p; + if (desc->bDescriptorType == UDESC_CS_INTERFACE && + desc->bDescriptorSubtype == UDESCSUB_CDC_UNION && + desc->bMasterInterface == iface_no) + return (desc); + p += desc->bLength; + } + return (0); } void >Release-Note: >Audit-Trail: >Unformatted: