Example #1
0
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);
}
Example #2
0
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);
}
Example #3
0
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);
}
Example #4
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;
            }
        }
    }
}