Пример #1
0
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);
}
Пример #2
0
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;
            }
        }
    }
}