int ugen_set_interface(struct ugen_softc *sc, int ifaceidx, int altno) { struct usbd_interface *iface; usb_endpoint_descriptor_t *ed; int err; struct ugen_endpoint *sce; u_int8_t niface, nendpt, endptno, endpt; int dir; DPRINTFN(15, ("ugen_set_interface %d %d\n", ifaceidx, altno)); err = usbd_interface_count(sc->sc_udev, &niface); if (err) return (err); if (ifaceidx < 0 || ifaceidx >= niface || usbd_iface_claimed(sc->sc_udev, ifaceidx)) return (USBD_INVAL); err = usbd_device2interface_handle(sc->sc_udev, ifaceidx, &iface); if (err) return (err); err = usbd_endpoint_count(iface, &nendpt); if (err) return (err); for (endptno = 0; endptno < nendpt; endptno++) { ed = usbd_interface2endpoint_descriptor(iface,endptno); endpt = ed->bEndpointAddress; dir = UE_GET_DIR(endpt) == UE_DIR_IN ? IN : OUT; sce = &sc->sc_endpoints[UE_GET_ADDR(endpt)][dir]; sce->sc = 0; sce->edesc = 0; sce->iface = 0; } /* change setting */ err = usbd_set_interface(iface, altno); if (err) goto out; err = usbd_endpoint_count(iface, &nendpt); if (err) goto out; out: for (endptno = 0; endptno < nendpt; endptno++) { ed = usbd_interface2endpoint_descriptor(iface,endptno); endpt = ed->bEndpointAddress; dir = UE_GET_DIR(endpt) == UE_DIR_IN ? IN : OUT; sce = &sc->sc_endpoints[UE_GET_ADDR(endpt)][dir]; sce->sc = sc; sce->edesc = ed; sce->iface = iface; } return (err); }
int ugen_set_interface(struct ugen_softc *sc, int ifaceidx, int altno) { struct usbd_interface *iface; usb_config_descriptor_t *cdesc; usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; struct ugen_endpoint *sce; uint8_t endptno, endpt; int dir, err; DPRINTFN(15, ("ugen_set_interface %d %d\n", ifaceidx, altno)); cdesc = usbd_get_config_descriptor(sc->sc_udev); if (ifaceidx < 0 || ifaceidx >= cdesc->bNumInterface || usbd_iface_claimed(sc->sc_udev, ifaceidx)) return (USBD_INVAL); err = usbd_device2interface_handle(sc->sc_udev, ifaceidx, &iface); if (err) return (err); id = usbd_get_interface_descriptor(iface); for (endptno = 0; endptno < id->bNumEndpoints; endptno++) { ed = usbd_interface2endpoint_descriptor(iface,endptno); endpt = ed->bEndpointAddress; dir = UE_GET_DIR(endpt) == UE_DIR_IN ? IN : OUT; sce = &sc->sc_endpoints[UE_GET_ADDR(endpt)][dir]; sce->sc = 0; sce->edesc = 0; sce->iface = 0; } /* change setting */ err = usbd_set_interface(iface, altno); if (err) return (err); id = usbd_get_interface_descriptor(iface); for (endptno = 0; endptno < id->bNumEndpoints; endptno++) { ed = usbd_interface2endpoint_descriptor(iface,endptno); endpt = ed->bEndpointAddress; dir = UE_GET_DIR(endpt) == UE_DIR_IN ? IN : OUT; sce = &sc->sc_endpoints[UE_GET_ADDR(endpt)][dir]; sce->sc = sc; sce->edesc = ed; sce->iface = iface; } return (err); }
int ugen_set_config(struct ugen_softc *sc, int configno) { struct usbd_device *dev = sc->sc_udev; usb_config_descriptor_t *cdesc; struct usbd_interface *iface; usb_endpoint_descriptor_t *ed; struct ugen_endpoint *sce; u_int8_t niface, nendpt; int ifaceno, endptno, endpt; int err; int dir; DPRINTFN(1,("ugen_set_config: %s to configno %d, sc=%p\n", sc->sc_dev.dv_xname, configno, sc)); /* * We start at 1, not 0, because we don't care whether the * control endpoint is open or not. It is always present. */ for (endptno = 1; endptno < USB_MAX_ENDPOINTS; endptno++) if (sc->sc_is_open[endptno]) { DPRINTFN(1, ("ugen_set_config: %s - endpoint %d is open\n", sc->sc_dev.dv_xname, endptno)); return (USBD_IN_USE); } /* Avoid setting the current value. */ cdesc = usbd_get_config_descriptor(dev); if (!cdesc || cdesc->bConfigurationValue != configno) { if (sc->sc_secondary) { printf("%s: secondary, not changing config to %d\n", __func__, configno); return (USBD_IN_USE); } else { err = usbd_set_config_no(dev, configno, 1); if (err) return (err); } } err = usbd_interface_count(dev, &niface); if (err) return (err); memset(sc->sc_endpoints, 0, sizeof sc->sc_endpoints); for (ifaceno = 0; ifaceno < niface; ifaceno++) { DPRINTFN(1,("ugen_set_config: ifaceno %d\n", ifaceno)); if (usbd_iface_claimed(sc->sc_udev, ifaceno)) { DPRINTF(("%s: iface %d not available\n", __func__, ifaceno)); continue; } err = usbd_device2interface_handle(dev, ifaceno, &iface); if (err) return (err); err = usbd_endpoint_count(iface, &nendpt); if (err) return (err); for (endptno = 0; endptno < nendpt; endptno++) { ed = usbd_interface2endpoint_descriptor(iface,endptno); endpt = ed->bEndpointAddress; dir = UE_GET_DIR(endpt) == UE_DIR_IN ? IN : OUT; sce = &sc->sc_endpoints[UE_GET_ADDR(endpt)][dir]; DPRINTFN(1,("ugen_set_config: endptno %d, endpt=0x%02x" "(%d,%d), sce=%p\n", endptno, endpt, UE_GET_ADDR(endpt), UE_GET_DIR(endpt), sce)); sce->sc = sc; sce->edesc = ed; sce->iface = iface; } } return (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; } } } }