From owner-freebsd-usb@FreeBSD.ORG Fri Feb 22 16:30:05 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 E1E3116A400 for ; Fri, 22 Feb 2008 16:30:05 +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 D9D6213C43E for ; Fri, 22 Feb 2008 16:30:05 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.14.2/8.14.2) with ESMTP id m1MGU5i5086021 for ; Fri, 22 Feb 2008 16:30:05 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.2/8.14.1/Submit) id m1MGU5W0086017; Fri, 22 Feb 2008 16:30:05 GMT (envelope-from gnats) Date: Fri, 22 Feb 2008 16:30:05 GMT Message-Id: <200802221630.m1MGU5W0086017@freefall.freebsd.org> To: freebsd-usb@FreeBSD.org From: Jeremie Le Hen Cc: Subject: Re: usb/117185: [umodem] [patch] Add support for UNION interface descriptor X-BeenThere: freebsd-usb@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: Jeremie Le Hen List-Id: FreeBSD support for USB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 22 Feb 2008 16:30:06 -0000 The following reply was made to PR usb/117185; it has been noted by GNATS. From: Jeremie Le Hen To: FreeBSD-gnats-submit@freebsd.org Cc: freebsd-usb@FreeBSD.org, Eugene Grosbein , jeremie@le-hen.org Subject: Re: usb/117185: [umodem] [patch] Add support for UNION interface descriptor Date: Fri, 22 Feb 2008 17:27:01 +0100 Corrects a typo in the previous patch. --- umodem_nokia.patch begins here --- Index: sys/dev/usb/umodem.c =================================================================== RCS file: /mnt/octobre/space/freebsd-cvs/src/sys/dev/usb/umodem.c,v retrieving revision 1.71 diff -u -r1.71 umodem.c --- sys/dev/usb/umodem.c 29 Jul 2007 18:16:43 -0000 1.71 +++ sys/dev/usb/umodem.c 22 Feb 2008 15:51:50 -0000 @@ -172,13 +172,14 @@ struct task sc_task; }; -static void *umodem_get_desc(usbd_device_handle dev, int type, int subtype); +static void *umodem_get_desc(usbd_device_handle dev, usb_descriptor_t *, int type, int subtype); +static usbd_interface_handle umodem_get_interface(struct usb_attach_arg *uaa, int ifcno); static usbd_status umodem_set_comm_feature(struct umodem_softc *sc, int feature, int state); static usbd_status umodem_set_line_coding(struct umodem_softc *sc, usb_cdc_line_state_t *state); -static void umodem_get_caps(usbd_device_handle, int *, int *); +static int umodem_get_caps(struct usb_attach_arg *, int, int *, int *); static void umodem_get_status(void *, int portno, u_char *lsr, u_char *msr); static void umodem_set(void *, int, int, int); @@ -262,10 +263,7 @@ if (ret == UMATCH_NONE) return (ret); - umodem_get_caps(uaa->device, &cm, &acm); - if (!(cm & USB_CDC_CM_DOES_CM) || - !(cm & USB_CDC_CM_OVER_DATA) || - !(acm & USB_CDC_ACM_HAS_LINE)) + if (umodem_get_caps(uaa, -1, &cm, &acm) == -1) return (UMATCH_NONE); return ret; @@ -279,7 +277,6 @@ usbd_device_handle dev = uaa->device; usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; - usb_cdc_cm_descriptor_t *cmd; int data_ifcno; int i; struct ucom_softc *ucom; @@ -297,15 +294,14 @@ device_printf(self, "iclass %d/%d\n", id->bInterfaceClass, id->bInterfaceSubClass); - umodem_get_caps(dev, &sc->sc_cm_cap, &sc->sc_acm_cap); - /* Get the data interface no. */ - cmd = umodem_get_desc(dev, UDESC_CS_INTERFACE, UDESCSUB_CDC_CM); - if (cmd == NULL) { - device_printf(sc->sc_dev, "no CM descriptor\n"); + sc->sc_data_iface_no = data_ifcno = + umodem_get_caps(uaa, sc->sc_ctl_iface_no, &sc->sc_cm_cap, &sc->sc_acm_cap); + + if (data_ifcno == -1) { + device_printf(sc->sc_dev,"no pointer to data interface\n"); goto bad; } - sc->sc_data_iface_no = data_ifcno = cmd->bDataInterface; device_printf(sc->sc_dev, "data interface %d, has %sCM over data, has %sbreak\n", @@ -530,27 +526,50 @@ ucom_status_change(&sc->sc_ucom); } -void -umodem_get_caps(usbd_device_handle dev, int *cm, int *acm) +static int +umodem_get_caps(struct usb_attach_arg *uaa, int ctl_iface_no, int *cm, int *acm) { usb_cdc_cm_descriptor_t *cmd; usb_cdc_acm_descriptor_t *cad; + usb_cdc_union_descriptor_t *cud; + usbd_device_handle dev = uaa->device; + usbd_interface_handle iface; + int iface_no = 0; *cm = *acm = 0; - cmd = umodem_get_desc(dev, UDESC_CS_INTERFACE, UDESCSUB_CDC_CM); + cmd = umodem_get_desc(dev, NULL, UDESC_CS_INTERFACE, UDESCSUB_CDC_CM); if (cmd == NULL) { DPRINTF(("umodem_get_desc: no CM desc\n")); - return; + } else { + *cm = cmd->bmCapabilities; } - *cm = cmd->bmCapabilities; - cad = umodem_get_desc(dev, UDESC_CS_INTERFACE, UDESCSUB_CDC_ACM); + cad = umodem_get_desc(dev, NULL, UDESC_CS_INTERFACE, UDESCSUB_CDC_ACM); if (cad == NULL) { DPRINTF(("umodem_get_desc: no ACM desc\n")); - return; + } else { + *acm = cad->bmCapabilities; + } + + cud = NULL; + while ((cud = umodem_get_desc(dev, (usb_descriptor_t *)cud, + UDESC_CS_INTERFACE, UDESCSUB_CDC_UNION))) + { + iface_no = cud->bSlaveInterface[0]; + if (ctl_iface_no == -1) + break; + + iface = umodem_get_interface(uaa,iface_no); + if (ctl_iface_no == cud->bMasterInterface && + usbd_get_interface_descriptor(iface)->bNumEndpoints >= 2) + break; + } + if (cud == NULL) { + DPRINTF(("umodem_get_caps: no UNION desc\n")); } - *acm = cad->bmCapabilities; + + return cmd ? cmd->bDataInterface : cud ? iface_no : -1; } void @@ -566,6 +585,23 @@ *msr = sc->sc_msr; } +static usbd_interface_handle +umodem_get_interface(struct usb_attach_arg *uaa, int ifcno) +{ + int i; + usb_interface_descriptor_t *id; + + for (i = 0; i < uaa->nifaces; i++) { + if (uaa->ifaces[i] != NULL) { + id = usbd_get_interface_descriptor(uaa->ifaces[i]); + if (id != NULL && id->bInterfaceNumber == ifcno) { + return uaa->ifaces[i]; + } + } + } + return NULL; +} + int umodem_param(void *addr, int portno, struct termios *t) { @@ -756,14 +792,17 @@ return (USBD_NORMAL_COMPLETION); } -void * -umodem_get_desc(usbd_device_handle dev, int type, int subtype) +static void * +umodem_get_desc(usbd_device_handle dev, usb_descriptor_t *restart, int type, int subtype) { usb_descriptor_t *desc; usb_config_descriptor_t *cd = usbd_get_config_descriptor(dev); uByte *p = (uByte *)cd; uByte *end = p + UGETW(cd->wTotalLength); + if (restart) + p = (uByte *)(restart) + restart->bLength; + while (p < end) { desc = (usb_descriptor_t *)p; if (desc->bDescriptorType == type && --- umodem_nokia.patch ends here---