diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2005-09-28 00:20:13 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2005-09-28 00:20:13 +0000 |
commit | bd960b2b5472bc650b8b4b0db04b5c76af1b7452 (patch) | |
tree | a287567287285c97be62506ce59a725edc918635 | |
parent | 01a02ebc13e9a5e01710dccf377f02130dd19dfb (diff) |
add support for the nokia 6680 with a ca-42 cable.
When looping over all the descriptors to fund functional
descriptors for CM, ACM, and UNION, I make sure to only look for
these descriptors in the interface number we are using. At least
on the 6680, there are lots of interfaces, and more than one of
them have UNION and ACM functional descriptors. Only the ones at
the CDC/ACM/AT interface are the ones to use...
diff from Staffan Ulberg, on top of a diff from Tony Lambiris
-rw-r--r-- | sys/dev/usb/umodem.c | 113 |
1 files changed, 47 insertions, 66 deletions
diff --git a/sys/dev/usb/umodem.c b/sys/dev/usb/umodem.c index ed5da79db46..2d01c98873e 100644 --- a/sys/dev/usb/umodem.c +++ b/sys/dev/usb/umodem.c @@ -1,4 +1,4 @@ -/* $OpenBSD: umodem.c,v 1.18 2005/08/01 05:36:49 brad Exp $ */ +/* $OpenBSD: umodem.c,v 1.19 2005/09/28 00:20:12 dlg Exp $ */ /* $NetBSD: umodem.c,v 1.45 2002/09/23 05:51:23 simonb Exp $ */ /* @@ -122,14 +122,11 @@ struct umodem_softc { u_char sc_msr; /* Modem status register */ }; -Static void *umodem_get_desc(usbd_device_handle dev, int type, int subtype); 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 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); @@ -160,7 +157,7 @@ USB_MATCH(umodem) USB_MATCH_START(umodem, uaa); usb_interface_descriptor_t *id; usb_device_descriptor_t *dd; - int cm, acm, ret; + int ret; if (uaa->iface == NULL) return (UMATCH_NONE); @@ -182,15 +179,6 @@ USB_MATCH(umodem) id->bInterfaceProtocol == UIPROTO_CDC_AT) ret = UMATCH_IFACECLASS_IFACESUBCLASS_IFACEPROTO; - 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)) - return (UMATCH_NONE); - return (ret); } @@ -200,10 +188,15 @@ USB_ATTACH(umodem) usbd_device_handle dev = uaa->device; usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; - usb_cdc_cm_descriptor_t *cmd; + usb_cdc_cm_descriptor_t *cmd; + usb_interface_descriptor_t *idesc; + const usb_cdc_acm_descriptor_t *acmd; + const usb_cdc_union_descriptor_t *uniond; + const usb_descriptor_t *desc; + usbd_desc_iter_t iter; char *devinfop; usbd_status err; - int data_ifcno; + int current_iface_no = -1; int i; struct ucom_attach_args uca; @@ -219,18 +212,47 @@ USB_ATTACH(umodem) usbd_devinfo_free(devinfop); sc->sc_ctl_iface_no = id->bInterfaceNumber; - umodem_get_caps(dev, &sc->sc_cm_cap, &sc->sc_acm_cap); + /* Get the data interface no. and capabilities */ + sc->sc_cm_cap = 0; + sc->sc_data_iface_no = 0; + sc->sc_acm_cap = 0; + usb_desc_iter_init(dev, &iter); + desc = usb_desc_iter_next(&iter); + while (desc) { + if (desc->bDescriptorType == UDESC_INTERFACE) { + idesc = (usb_interface_descriptor_t *)desc; + current_iface_no = idesc->bInterfaceNumber; + } + if (current_iface_no == sc->sc_ctl_iface_no && + desc->bDescriptorType == UDESC_CS_INTERFACE) { + switch(desc->bDescriptorSubtype) { + case UDESCSUB_CDC_CM: + cmd = (usb_cdc_cm_descriptor_t *)desc; + sc->sc_cm_cap = cmd->bmCapabilities; + sc->sc_data_iface_no = cmd->bDataInterface; + break; + case UDESCSUB_CDC_ACM: + acmd = (usb_cdc_acm_descriptor_t *)desc; + sc->sc_acm_cap = acmd->bmCapabilities; + break; + case UDESCSUB_CDC_UNION: + uniond = (usb_cdc_union_descriptor_t *)desc; + sc->sc_data_iface_no = + uniond->bSlaveInterface[0]; + break; + } + } + desc = usb_desc_iter_next(&iter); + } - /* 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", USBDEVNAME(sc->sc_dev)); + if (sc->sc_data_iface_no == 0) { + 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, + USBDEVNAME(sc->sc_dev), sc->sc_data_iface_no, sc->sc_cm_cap & USB_CDC_CM_OVER_DATA ? "" : "no ", sc->sc_acm_cap & USB_CDC_ACM_HAS_BREAK ? "" : "no "); @@ -238,7 +260,8 @@ USB_ATTACH(umodem) 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 == data_ifcno) { + if (id != NULL && + id->bInterfaceNumber == sc->sc_data_iface_no) { sc->sc_data_iface = uaa->ifaces[i]; uaa->ifaces[i] = NULL; } @@ -458,29 +481,6 @@ umodem_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) } void -umodem_get_caps(usbd_device_handle dev, int *cm, int *acm) -{ - usb_cdc_cm_descriptor_t *cmd; - usb_cdc_acm_descriptor_t *cad; - - *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; -} - -void umodem_get_status(void *addr, int portno, u_char *lsr, u_char *msr) { struct umodem_softc *sc = addr; @@ -683,25 +683,6 @@ umodem_set_line_coding(struct umodem_softc *sc, usb_cdc_line_state_t *state) return (USBD_NORMAL_COMPLETION); } -void * -umodem_get_desc(usbd_device_handle dev, 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); - - while (p < end) { - desc = (usb_descriptor_t *)p; - if (desc->bDescriptorType == type && - desc->bDescriptorSubtype == subtype) - return (desc); - p += desc->bLength; - } - - return (0); -} - usbd_status umodem_set_comm_feature(struct umodem_softc *sc, int feature, int state) { |