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 uftdi_match(struct device *parent, void *match, void *aux) { struct usb_attach_arg *uaa = aux; int err; u_int8_t nifaces; if (usb_lookup(uftdi_devs, uaa->vendor, uaa->product) == NULL) return (UMATCH_NONE); /* Get the number of interfaces. */ if (uaa->iface != NULL) { nifaces = uaa->nifaces; } else { err = usbd_set_config_index(uaa->device, UFTDI_CONFIG_INDEX, 1); if (err) return (UMATCH_NONE); err = usbd_interface_count(uaa->device, &nifaces); if (err) return (UMATCH_NONE); usbd_set_config_index(uaa->device, USB_UNCONFIG_INDEX, 1); } /* JTAG on USB interface 0 */ if (uaa->vendor == USB_VENDOR_FTDI && uaa->product == USB_PRODUCT_FTDI_OPENRD && uaa->ifaceno == 0) return (UMATCH_NONE); if (nifaces <= 1) return (UMATCH_VENDOR_PRODUCT); /* Dual UART chip */ if (uaa->iface != NULL) return (UMATCH_VENDOR_IFACESUBCLASS); else return (UMATCH_NONE); }
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); }