summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2005-09-28 00:20:13 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2005-09-28 00:20:13 +0000
commitbd960b2b5472bc650b8b4b0db04b5c76af1b7452 (patch)
treea287567287285c97be62506ce59a725edc918635
parent01a02ebc13e9a5e01710dccf377f02130dd19dfb (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.c113
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)
{