From 8bd72ab6a4258384e08e8bea4c2ca553254ff48d Mon Sep 17 00:00:00 2001 From: itohy Date: Fri, 15 Apr 2005 14:43:05 +0000 Subject: [PATCH] If CM descriptor is found, use the data interface in it; if CM descriptor is NOT found but UNION descriotor is found, use the data interface in it. Do not require CM or ACM descriptors as long as the data interface is found. Should fix NetBSD PR #29754 by rivo nurges. --- sys/dev/usb/umodem.c | 9 +++------ sys/dev/usb/umodem_common.c | 40 ++++++++++++++++++++++--------------- sys/dev/usb/umodemvar.h | 4 ++-- 3 files changed, 29 insertions(+), 24 deletions(-) diff --git a/sys/dev/usb/umodem.c b/sys/dev/usb/umodem.c index 56b07d9d2432..16521f921e98 100644 --- a/sys/dev/usb/umodem.c +++ b/sys/dev/usb/umodem.c @@ -1,4 +1,4 @@ -/* $NetBSD: umodem.c,v 1.51 2005/04/15 14:14:09 itohy Exp $ */ +/* $NetBSD: umodem.c,v 1.52 2005/04/15 14:43:05 itohy Exp $ */ /* * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -51,7 +51,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: umodem.c,v 1.51 2005/04/15 14:14:09 itohy Exp $"); +__KERNEL_RCSID(0, "$NetBSD: umodem.c,v 1.52 2005/04/15 14:43:05 itohy Exp $"); #include #include @@ -115,10 +115,7 @@ USB_MATCH(umodem) id->bInterfaceProtocol != UIPROTO_CDC_AT) return (UMATCH_NONE); - umodem_get_caps(uaa->device, &cm, &acm, id); - if (!(cm & USB_CDC_CM_DOES_CM) || - !(cm & USB_CDC_CM_OVER_DATA) || - !(acm & USB_CDC_ACM_HAS_LINE)) + if (umodem_get_caps(uaa->device, &cm, &acm, id) == -1) return (UMATCH_NONE); return (UMATCH_IFACECLASS_IFACESUBCLASS_IFACEPROTO); diff --git a/sys/dev/usb/umodem_common.c b/sys/dev/usb/umodem_common.c index 8d39a26392e2..18e8a0fc00b4 100644 --- a/sys/dev/usb/umodem_common.c +++ b/sys/dev/usb/umodem_common.c @@ -1,4 +1,4 @@ -/* $NetBSD: umodem_common.c,v 1.1 2005/04/15 14:14:09 itohy Exp $ */ +/* $NetBSD: umodem_common.c,v 1.2 2005/04/15 14:43:05 itohy Exp $ */ /* * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -51,7 +51,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: umodem_common.c,v 1.1 2005/04/15 14:14:09 itohy Exp $"); +__KERNEL_RCSID(0, "$NetBSD: umodem_common.c,v 1.2 2005/04/15 14:43:05 itohy Exp $"); #include #include @@ -112,7 +112,6 @@ umodem_common_attach(device_ptr_t self, struct umodem_softc *sc, usbd_device_handle dev = uaa->device; usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; - const usb_cdc_cm_descriptor_t *cmd; char devinfo[1024]; usbd_status err; int data_ifcno; @@ -129,17 +128,15 @@ umodem_common_attach(device_ptr_t self, struct umodem_softc *sc, devinfo, id->bInterfaceClass, id->bInterfaceSubClass); sc->sc_ctl_iface_no = id->bInterfaceNumber; - umodem_get_caps(dev, &sc->sc_cm_cap, &sc->sc_acm_cap, id); - /* Get the data interface no. */ - cmd = (usb_cdc_cm_descriptor_t *)usb_find_desc_if(dev, - UDESC_CS_INTERFACE, - UDESCSUB_CDC_CM, id); - if (cmd == NULL) { - printf("%s: no CM descriptor\n", USBDEVNAME(sc->sc_dev)); + sc->sc_data_iface_no = data_ifcno = + umodem_get_caps(dev, &sc->sc_cm_cap, &sc->sc_acm_cap, id); + + if (data_ifcno == -1) { + printf("%s: no pointer to data interface\n", + USBDEVNAME(sc->sc_dev)); goto bad; } - sc->sc_data_iface_no = data_ifcno = cmd->bDataInterface; printf("%s: data interface %d, has %sCM over data, has %sbreak\n", USBDEVNAME(sc->sc_dev), data_ifcno, @@ -367,12 +364,13 @@ umodem_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) } } -void +int umodem_get_caps(usbd_device_handle dev, int *cm, int *acm, usb_interface_descriptor_t *id) { const usb_cdc_cm_descriptor_t *cmd; const usb_cdc_acm_descriptor_t *cad; + const usb_cdc_union_descriptor_t *cud; *cm = *acm = 0; @@ -381,9 +379,9 @@ umodem_get_caps(usbd_device_handle dev, int *cm, int *acm, UDESCSUB_CDC_CM, id); if (cmd == NULL) { DPRINTF(("umodem_get_desc: no CM desc\n")); - return; + } else { + *cm = cmd->bmCapabilities; } - *cm = cmd->bmCapabilities; cad = (usb_cdc_acm_descriptor_t *)usb_find_desc_if(dev, UDESC_CS_INTERFACE, @@ -391,9 +389,19 @@ umodem_get_caps(usbd_device_handle dev, int *cm, int *acm, id); if (cad == NULL) { DPRINTF(("umodem_get_desc: no ACM desc\n")); - return; + } else { + *acm = cad->bmCapabilities; } - *acm = cad->bmCapabilities; + + cud = (usb_cdc_union_descriptor_t *)usb_find_desc_if(dev, + UDESC_CS_INTERFACE, + UDESCSUB_CDC_UNION, + id); + if (cud == NULL) { + DPRINTF(("umodem_get_desc: no UNION desc\n")); + } + + return cmd ? cmd->bDataInterface : cud ? cud->bSlaveInterface[0] : -1; } void diff --git a/sys/dev/usb/umodemvar.h b/sys/dev/usb/umodemvar.h index 3766386251b7..465eab8b02ec 100644 --- a/sys/dev/usb/umodemvar.h +++ b/sys/dev/usb/umodemvar.h @@ -1,4 +1,4 @@ -/* $NetBSD: umodemvar.h,v 1.1 2005/04/15 14:14:09 itohy Exp $ */ +/* $NetBSD: umodemvar.h,v 1.2 2005/04/15 14:43:05 itohy Exp $ */ /* * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -71,7 +71,7 @@ struct umodem_softc { int umodem_common_attach(device_ptr_t, struct umodem_softc *, struct usb_attach_arg *, struct ucom_attach_args *); -void umodem_get_caps(usbd_device_handle, int *, int *, +int umodem_get_caps(usbd_device_handle, int *, int *, usb_interface_descriptor_t *); void umodem_get_status(void *, int portno, u_char *lsr, u_char *msr);