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 _access_endpoint(struct libusb_transfer *transfer) { struct handle_priv *hpriv; struct device_priv *dpriv; char *s, devnode[16]; int fd, endpt; mode_t mode; hpriv = (struct handle_priv *)transfer->dev_handle->os_priv; dpriv = (struct device_priv *)transfer->dev_handle->dev->os_priv; endpt = UE_GET_ADDR(transfer->endpoint); mode = IS_XFERIN(transfer) ? O_RDONLY : O_WRONLY; usbi_dbg("endpoint %d mode %d", endpt, mode); if (hpriv->endpoints[endpt] < 0) { strlcpy(devnode, dpriv->devnode, sizeof(devnode)); s = strchr(devnode, '.'); snprintf(s, 4, ".%02d", endpt); if (((fd = open(devnode, O_RDWR)) < 0) && (errno == ENXIO)) if ((fd = open(devnode, mode)) < 0) return (-1); hpriv->endpoints[endpt] = fd; } return (hpriv->endpoints[endpt]); }
int _access_endpoint(struct libusb_transfer *transfer) { struct handle_priv *hpriv; struct device_priv *dpriv; char devnode[16]; int fd, endpt; mode_t mode; hpriv = (struct handle_priv *)transfer->dev_handle->os_priv; dpriv = (struct device_priv *)transfer->dev_handle->dev->os_priv; endpt = UE_GET_ADDR(transfer->endpoint); mode = IS_XFERIN(transfer) ? O_RDONLY : O_WRONLY; usbi_dbg("endpoint %d mode %d", endpt, mode); if (hpriv->endpoints[endpt] < 0) { /* Pick the right endpoint node */ snprintf(devnode, sizeof(devnode), DEVPATH "%s.%02d", dpriv->devname, endpt); /* We may need to read/write to the same endpoint later. */ if (((fd = open(devnode, O_RDWR)) < 0) && (errno == ENXIO)) if ((fd = open(devnode, mode)) < 0) return (-1); hpriv->endpoints[endpt] = fd; } return (hpriv->endpoints[endpt]); }
static int ensure_ep_open(usb_dev_handle *dev, int ep, int mode) { struct bsd_usb_dev_handle_info *info = dev->impl_info; int fd; char buf[20]; /* Get the address for this endpoint; we could check * the mode against the direction; but we've done that * already in the usb_bulk_read/write. */ ep = UE_GET_ADDR(ep); if (info->ep_fd[ep] < 0) { #ifdef __FreeBSD_kernel__ snprintf(buf, sizeof(buf) - 1, "%s.%d", dev->device->filename, ep); #else snprintf(buf, sizeof(buf) - 1, "%s.%02d", dev->device->filename, ep); #endif /* Try to open it O_RDWR first for those devices which have in and out * endpoints with the same address (eg 0x02 and 0x82) */ fd = open(buf, O_RDWR); if (fd < 0 && errno == ENXIO) fd = open(buf, mode); if (fd < 0) USB_ERROR_STR(-errno, "can't open %s for bulk read: %s", buf, strerror(errno)); info->ep_fd[ep] = fd; } return info->ep_fd[ep]; }
int usb_interrupt_read(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout) { int fd, ret, retrieved = 0, one = 1; /* Ensure the endpoint address is correct */ ep |= USB_ENDPOINT_IN; fd = ensure_ep_open(dev, ep, O_RDONLY); if (fd < 0) { if (usb_debug >= 2) { #ifdef __FreeBSD_kernel__ fprintf (stderr, "usb_interrupt_read: got negative open file descriptor for endpoint %d\n", UE_GET_ADDR(ep)); #else fprintf (stderr, "usb_interrupt_read: got negative open file descriptor for endpoint %02d\n", UE_GET_ADDR(ep)); #endif } return fd; } ret = ioctl(fd, USB_SET_TIMEOUT, &timeout); if (ret < 0) USB_ERROR_STR(-errno, "error setting timeout: %s", strerror(errno)); ret = ioctl(fd, USB_SET_SHORT_XFER, &one); if (ret < 0) USB_ERROR_STR(-errno, "error setting short xfer: %s", strerror(errno)); do { ret = read(fd, bytes+retrieved, size-retrieved); if (ret < 0) #ifdef __FreeBSD_kernel__ USB_ERROR_STR(-errno, "error reading from interrupt endpoint %s.%d: %s", dev->device->filename, UE_GET_ADDR(ep), strerror(errno)); #else USB_ERROR_STR(-errno, "error reading from interrupt endpoint %s.%02d: %s", dev->device->filename, UE_GET_ADDR(ep), strerror(errno)); #endif retrieved += ret; } while (ret > 0 && retrieved < size); return retrieved; }
static usb_error_t usbd_setup_endpoint(irp *ip, uint8_t ifidx, struct usb_endpoint_descriptor *ep) { device_t dev = IRP_NDIS_DEV(ip); struct ndis_softc *sc = device_get_softc(dev); struct ndisusb_ep *ne; struct usb_config cfg; struct usb_xfer *xfer; usb_error_t status; /* check for non-supported transfer types */ if (UE_GET_XFERTYPE(ep->bmAttributes) == UE_CONTROL || UE_GET_XFERTYPE(ep->bmAttributes) == UE_ISOCHRONOUS) { device_printf(dev, "%s: unsuppotted transfer types %#x\n", __func__, UE_GET_XFERTYPE(ep->bmAttributes)); return (USB_ERR_INVAL); } ne = &sc->ndisusb_ep[NDISUSB_GET_ENDPT(ep->bEndpointAddress)]; InitializeListHead(&ne->ne_active); InitializeListHead(&ne->ne_pending); KeInitializeSpinLock(&ne->ne_lock); ne->ne_dirin = UE_GET_DIR(ep->bEndpointAddress) >> 7; memset(&cfg, 0, sizeof(struct usb_config)); cfg.type = UE_GET_XFERTYPE(ep->bmAttributes); cfg.endpoint = UE_GET_ADDR(ep->bEndpointAddress); cfg.direction = UE_GET_DIR(ep->bEndpointAddress); cfg.callback = &usbd_non_isoc_callback; cfg.bufsize = UGETW(ep->wMaxPacketSize); cfg.flags.proxy_buffer = 1; if (UE_GET_DIR(ep->bEndpointAddress) == UE_DIR_IN) cfg.flags.short_xfer_ok = 1; status = usbd_transfer_setup(sc->ndisusb_dev, &ifidx, ne->ne_xfer, &cfg, 1, sc, &sc->ndisusb_mtx); if (status != USB_ERR_NORMAL_COMPLETION) { device_printf(dev, "couldn't setup xfer: %s\n", usbd_errstr(status)); return (status); } xfer = ne->ne_xfer[0]; usbd_xfer_set_priv(xfer, ne); if (UE_GET_DIR(ep->bEndpointAddress) == UE_DIR_IN) usbd_xfer_set_timeout(xfer, NDISUSB_NO_TIMEOUT); else { if (UE_GET_XFERTYPE(ep->bmAttributes) == UE_BULK) usbd_xfer_set_timeout(xfer, NDISUSB_TX_TIMEOUT); else usbd_xfer_set_timeout(xfer, NDISUSB_INTR_TIMEOUT); } return (status); }
int usb_interrupt_write(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout) { int fd, ret, sent = 0; /* Ensure the endpoint address is correct */ ep &= ~USB_ENDPOINT_IN; fd = ensure_ep_open(dev, ep, O_WRONLY); if (fd < 0) { if (usb_debug >= 2) { #ifdef __FreeBSD_kernel__ fprintf (stderr, "usb_interrupt_write: got negative open file descriptor for endpoint %d\n", UE_GET_ADDR(ep)); #else fprintf (stderr, "usb_interrupt_write: got negative open file descriptor for endpoint %02d\n", UE_GET_ADDR(ep)); #endif } return fd; } ret = ioctl(fd, USB_SET_TIMEOUT, &timeout); if (ret < 0) USB_ERROR_STR(-errno, "error setting timeout: %s", strerror(errno)); do { ret = write(fd, bytes+sent, size-sent); if (ret < 0) #ifdef __FreeBSD_kernel__ USB_ERROR_STR(-errno, "error writing to interrupt endpoint %s.%d: %s", dev->device->filename, UE_GET_ADDR(ep), strerror(errno)); #else USB_ERROR_STR(-errno, "error writing to interrupt endpoint %s.%02d: %s", dev->device->filename, UE_GET_ADDR(ep), strerror(errno)); #endif sent += ret; } while (ret > 0 && sent < size); return sent; }
static int init_keyboard(ukbd_state_t *state, int *type, int flags) { usb_endpoint_descriptor_t *ed; usbd_status err; *type = KB_OTHER; state->ks_ifstate |= DISCONNECTED; ed = usbd_interface2endpoint_descriptor(state->ks_iface, 0); if (!ed) { kprintf("ukbd: could not read endpoint descriptor\n"); return EIO; } DPRINTFN(10,("ukbd:init_keyboard: \ bLength=%d bDescriptorType=%d bEndpointAddress=%d-%s bmAttributes=%d wMaxPacketSize=%d bInterval=%d\n", ed->bLength, ed->bDescriptorType, UE_GET_ADDR(ed->bEndpointAddress), UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN ? "in":"out", UE_GET_XFERTYPE(ed->bmAttributes), UGETW(ed->wMaxPacketSize), ed->bInterval)); if (UE_GET_DIR(ed->bEndpointAddress) != UE_DIR_IN || UE_GET_XFERTYPE(ed->bmAttributes) != UE_INTERRUPT) { kprintf("ukbd: unexpected endpoint\n"); return EINVAL; } if ((usbd_get_quirks(state->ks_uaa->device)->uq_flags & UQ_NO_SET_PROTO) == 0) { err = usbd_set_protocol(state->ks_iface, 0); DPRINTFN(5, ("ukbd:init_keyboard: protocol set\n")); if (err) { kprintf("ukbd: set protocol failed\n"); return EIO; } } /* Ignore if SETIDLE fails since it is not crucial. */ usbd_set_idle(state->ks_iface, 0, 0); state->ks_ep_addr = ed->bEndpointAddress; state->ks_ifstate &= ~DISCONNECTED; return 0; }
static usbd_status alloc_all_endpoints_genuine(struct umidi_softc *sc) { usb_interface_descriptor_t *interface_desc; usb_config_descriptor_t *config_desc; usb_descriptor_t *desc; int num_ep; size_t remain, descsize; struct umidi_endpoint *p, *q, *lowest, *endep, tmpep; int epaddr; interface_desc = usbd_get_interface_descriptor(sc->sc_iface); num_ep = interface_desc->bNumEndpoints; sc->sc_endpoints = p = malloc(sizeof(struct umidi_endpoint) * num_ep, M_USBDEV, M_WAITOK); if (!p) return USBD_NOMEM; sc->sc_out_num_jacks = sc->sc_in_num_jacks = 0; sc->sc_out_num_endpoints = sc->sc_in_num_endpoints = 0; epaddr = -1; /* get the list of endpoints for midi stream */ config_desc = usbd_get_config_descriptor(sc->sc_udev); desc = (usb_descriptor_t *) config_desc; remain = (size_t)UGETW(config_desc->wTotalLength); while (remain>=sizeof(usb_descriptor_t)) { descsize = desc->bLength; if (descsize>remain || descsize==0) break; if (desc->bDescriptorType==UDESC_ENDPOINT && remain>=USB_ENDPOINT_DESCRIPTOR_SIZE && UE_GET_XFERTYPE(TO_EPD(desc)->bmAttributes) == UE_BULK) { epaddr = TO_EPD(desc)->bEndpointAddress; } else if (desc->bDescriptorType==UDESC_CS_ENDPOINT && remain>=UMIDI_CS_ENDPOINT_DESCRIPTOR_SIZE && epaddr!=-1) { if (num_ep>0) { num_ep--; p->sc = sc; p->addr = epaddr; p->num_jacks = TO_CSEPD(desc)->bNumEmbMIDIJack; if (UE_GET_DIR(epaddr)==UE_DIR_OUT) { sc->sc_out_num_endpoints++; sc->sc_out_num_jacks += p->num_jacks; } else { sc->sc_in_num_endpoints++; sc->sc_in_num_jacks += p->num_jacks; } p++; } } else epaddr = -1; desc = NEXT_D(desc); remain-=descsize; } /* sort endpoints */ num_ep = sc->sc_out_num_endpoints + sc->sc_in_num_endpoints; p = sc->sc_endpoints; endep = p + num_ep; while (p<endep) { lowest = p; for (q=p+1; q<endep; q++) { if ((UE_GET_DIR(lowest->addr)==UE_DIR_IN && UE_GET_DIR(q->addr)==UE_DIR_OUT) || ((UE_GET_DIR(lowest->addr)== UE_GET_DIR(q->addr)) && (UE_GET_ADDR(lowest->addr)> UE_GET_ADDR(q->addr)))) lowest = q; } if (lowest != p) { memcpy((void *)&tmpep, (void *)p, sizeof(tmpep)); memcpy((void *)p, (void *)lowest, sizeof(tmpep)); memcpy((void *)lowest, (void *)&tmpep, sizeof(tmpep)); } p->num_open = 0; p++; } sc->sc_out_ep = sc->sc_out_num_endpoints ? sc->sc_endpoints : NULL; sc->sc_in_ep = sc->sc_in_num_endpoints ? sc->sc_endpoints+sc->sc_out_num_endpoints : NULL; return USBD_NORMAL_COMPLETION; }
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 uvisor_attach(struct device *parent, struct device *self, void *aux) { struct uvisor_softc *sc = (struct uvisor_softc *)self; struct usb_attach_arg *uaa = aux; struct usbd_device *dev = uaa->device; struct usbd_interface *iface; usb_interface_descriptor_t *id; struct uvisor_connection_info coninfo; struct uvisor_palm_connection_info palmconinfo; usb_endpoint_descriptor_t *ed; int i, j, hasin, hasout, port; usbd_status err; struct ucom_attach_args uca; DPRINTFN(10,("\nuvisor_attach: sc=%p\n", sc)); /* Move the device into the configured state. */ err = usbd_set_config_index(dev, UVISOR_CONFIG_INDEX, 1); if (err) { printf(": failed to set configuration, err=%s\n", usbd_errstr(err)); goto bad; } err = usbd_device2interface_handle(dev, UVISOR_IFACE_INDEX, &iface); if (err) { printf(": failed to get interface, err=%s\n", usbd_errstr(err)); goto bad; } sc->sc_flags = uvisor_lookup(uaa->vendor, uaa->product)->uv_flags; sc->sc_vendor = uaa->vendor; if ((sc->sc_flags & (VISOR | PALM4)) == 0) { printf("%s: device is neither visor nor palm\n", sc->sc_dev.dv_xname); goto bad; } id = usbd_get_interface_descriptor(iface); sc->sc_udev = dev; sc->sc_iface = iface; uca.ibufsize = UVISORIBUFSIZE; uca.obufsize = UVISOROBUFSIZE; uca.ibufsizepad = UVISORIBUFSIZE; uca.opkthdrlen = 0; uca.device = dev; uca.iface = iface; uca.methods = &uvisor_methods; uca.arg = sc; err = uvisor_init(sc, &coninfo, &palmconinfo); if (err) { printf("%s: init failed, %s\n", sc->sc_dev.dv_xname, usbd_errstr(err)); goto bad; } if (sc->sc_flags & VISOR) { sc->sc_numcon = UGETW(coninfo.num_ports); if (sc->sc_numcon > UVISOR_MAX_CONN) sc->sc_numcon = UVISOR_MAX_CONN; /* Attach a ucom for each connection. */ for (i = 0; i < sc->sc_numcon; ++i) { switch (coninfo.connections[i].port_function_id) { case UVISOR_FUNCTION_GENERIC: uca.info = "Generic"; break; case UVISOR_FUNCTION_DEBUGGER: uca.info = "Debugger"; break; case UVISOR_FUNCTION_HOTSYNC: uca.info = "HotSync"; break; case UVISOR_FUNCTION_REMOTE_FILE_SYS: uca.info = "Remote File System"; break; default: uca.info = "unknown"; break; } port = coninfo.connections[i].port; uca.portno = port; uca.bulkin = port | UE_DIR_IN; uca.bulkout = port | UE_DIR_OUT; /* Verify that endpoints exist. */ hasin = 0; hasout = 0; for (j = 0; j < id->bNumEndpoints; j++) { ed = usbd_interface2endpoint_descriptor(iface, j); if (ed == NULL) break; if (UE_GET_ADDR(ed->bEndpointAddress) == port && (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) { if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN) hasin++; else hasout++; } } if (hasin == 1 && hasout == 1) sc->sc_subdevs[i] = config_found_sm(self, &uca, ucomprint, ucomsubmatch); else printf("%s: no proper endpoints for port %d (%d,%d)\n", sc->sc_dev.dv_xname, port, hasin, hasout); } } else { sc->sc_numcon = palmconinfo.num_ports; if (sc->sc_numcon > UVISOR_MAX_CONN) sc->sc_numcon = UVISOR_MAX_CONN; /* Attach a ucom for each connection. */ for (i = 0; i < sc->sc_numcon; ++i) { /* * XXX this should copy out 4-char string from the * XXX port_function_id, but where would the string go? * XXX uca.info is a const char *, not an array. */ uca.info = "sync"; uca.portno = i; if (palmconinfo.endpoint_numbers_different) { port = palmconinfo.connections[i].end_point_info; uca.bulkin = (port >> 4) | UE_DIR_IN; uca.bulkout = (port & 0xf) | UE_DIR_OUT; } else { port = palmconinfo.connections[i].port; uca.bulkin = port | UE_DIR_IN; uca.bulkout = port | UE_DIR_OUT; } sc->sc_subdevs[i] = config_found_sm(self, &uca, ucomprint, ucomsubmatch); }