void udfu_parse_desc(struct udfu_softc *sc) { struct dfu_functional_descriptor *dd; const usb_descriptor_t *desc; struct usbd_desc_iter iter; usbd_desc_iter_init(sc->sc_udev, &iter); while ((desc = usbd_desc_iter_next(&iter))) { if (desc->bDescriptorType == UDESC_CS_DEVICE) break; } if (!desc) return; dd = (struct dfu_functional_descriptor *)desc; DPRINTF(("%s: %s: bLength=%d bDescriptorType=%d bmAttributes=%d " "wDetachTimeOut=%d wTransferSize=%d bcdDFUVersion=%d\n", sc->sc_dev.dv_xname, __func__, dd->bLength, dd->bDescriptorType, dd->bmAttributes, UGETW(dd->wDetachTimeOut), UGETW(dd->wTransferSize), UGETW(dd->bcdDFUVersion))); sc->sc_will_detach = dd->bmAttributes & BWILLDETACH; sc->sc_detach_timeout = UGETW(dd->wDetachTimeOut); }
void umodem_get_caps(struct usb_attach_arg *uaa, int ctl_iface_no, int *data_iface_idx, int *cm_cap, int *acm_cap) { const usb_descriptor_t *desc; const usb_interface_descriptor_t *id; const struct usb_cdc_cm_descriptor *cmd; const struct usb_cdc_acm_descriptor *acmd; const struct usb_cdc_union_descriptor *uniond; struct usbd_desc_iter iter; int current_iface_no = -1; int data_iface_no = -1; int i; *data_iface_idx = -1; *cm_cap = *acm_cap = 0; usbd_desc_iter_init(uaa->device, &iter); desc = usbd_desc_iter_next(&iter); while (desc) { if (desc->bDescriptorType == UDESC_INTERFACE) { id = (usb_interface_descriptor_t *)desc; current_iface_no = id->bInterfaceNumber; if (current_iface_no != ctl_iface_no && id->bInterfaceClass == UICLASS_CDC_DATA && id->bInterfaceSubClass == UISUBCLASS_DATA && data_iface_no == -1) data_iface_no = current_iface_no; } if (current_iface_no == ctl_iface_no && desc->bDescriptorType == UDESC_CS_INTERFACE) { switch(desc->bDescriptorSubtype) { case UDESCSUB_CDC_CM: cmd = (struct usb_cdc_cm_descriptor *)desc; *cm_cap = cmd->bmCapabilities; data_iface_no = cmd->bDataInterface; break; case UDESCSUB_CDC_ACM: acmd = (struct usb_cdc_acm_descriptor *)desc; *acm_cap = acmd->bmCapabilities; break; case UDESCSUB_CDC_UNION: uniond = (struct usb_cdc_union_descriptor *)desc; data_iface_no = uniond->bSlaveInterface[0]; break; } } desc = usbd_desc_iter_next(&iter); } /* * If we got a data interface number, make sure the corresponding * interface exists and is not already claimed. */ if (data_iface_no != -1) { for (i = 0; i < uaa->nifaces; i++) { id = usbd_get_interface_descriptor(uaa->ifaces[i]); if (id == NULL) continue; if (id->bInterfaceNumber == data_iface_no) { if (!usbd_iface_claimed(uaa->device, i)) *data_iface_idx = i; break; } } } }