static int auvitek_start_xfer(struct auvitek_softc *sc) { struct auvitek_xfer *ax = &sc->sc_ax; uint32_t vframe_len, uframe_len, nframes; usbd_status err; int i; err = usbd_set_interface(sc->sc_isoc_iface, AUVITEK_XFER_ALTNO); if (err != USBD_NORMAL_COMPLETION) { aprint_error_dev(sc->sc_dev, "couldn't set altno %d: %s\n", AUVITEK_XFER_ALTNO, usbd_errstr(err)); return EIO; } vframe_len = 720 * 480 * 2; uframe_len = ax->ax_maxpktlen; nframes = (vframe_len + uframe_len - 1) / uframe_len; nframes = (nframes + 7) & ~7; ax->ax_nframes = nframes; ax->ax_uframe_len = uframe_len; for (i = 0; i < AUVITEK_NISOC_XFERS; i++) { struct auvitek_isoc *isoc = &ax->ax_i[i]; isoc->i_ax = ax; isoc->i_frlengths = kmem_alloc(sizeof(isoc->i_frlengths[0]) * nframes, KM_SLEEP); } err = usbd_open_pipe(sc->sc_isoc_iface, ax->ax_endpt, USBD_EXCLUSIVE_USE, &ax->ax_pipe); if (err != USBD_NORMAL_COMPLETION) { aprint_error_dev(sc->sc_dev, "couldn't open pipe: %s\n", usbd_errstr(err)); return EIO; } for (i = 0; i < AUVITEK_NISOC_XFERS; i++) { struct auvitek_isoc *isoc = &ax->ax_i[i]; isoc->i_xfer = usbd_alloc_xfer(sc->sc_udev); if (isoc->i_xfer == NULL) { aprint_error_dev(sc->sc_dev, "couldn't allocate usb xfer\n"); return ENOMEM; } isoc->i_buf = usbd_alloc_buffer(isoc->i_xfer, nframes * uframe_len); if (isoc->i_buf == NULL) { aprint_error_dev(sc->sc_dev, "couldn't allocate usb xfer buffer\n"); return ENOMEM; } } return auvitek_isoc_start(sc); }
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); }
Static usbd_status umass_init_insystem(struct umass_softc *sc) { usbd_status err; err = usbd_set_interface(sc->sc_iface, 1); if (err) { DPRINTF(UDMASS_USB, ("%s: could not switch to Alt Interface 1\n", USBDEVNAME(sc->sc_dev))); return (err); } return (USBD_NORMAL_COMPLETION); }
void emdtv_dtv_attach(struct emdtv_softc *sc) { usb_endpoint_descriptor_t *ed; usbd_status status; int i; for (i = 0; i < EMDTV_NXFERS; i++) { sc->sc_ix[i].ix_altix = (i & 1) ? &sc->sc_ix[i - 1] : &sc->sc_ix[i + 1]; sc->sc_ix[i].ix_sc = sc; } ed = usbd_interface2endpoint_descriptor(sc->sc_iface, 3); if (ed == NULL) { aprint_error_dev(sc->sc_dev, "couldn't find endpoint 3\n"); return; } sc->sc_isoc_maxpacketsize = UGETW(ed->wMaxPacketSize); sc->sc_isoc_buflen = sc->sc_isoc_maxpacketsize * EMDTV_NFRAMES; aprint_debug_dev(sc->sc_dev, "calling usbd_open_pipe, ep 0x%02x\n", ed->bEndpointAddress); status = usbd_open_pipe(sc->sc_iface, ed->bEndpointAddress, USBD_EXCLUSIVE_USE|USBD_MPSAFE, &sc->sc_isoc_pipe); if (status != USBD_NORMAL_COMPLETION) { aprint_error_dev(sc->sc_dev, "couldn't open isoc pipe\n"); usbd_set_interface(sc->sc_iface, 0); return; } emdtv_write_1(sc, UR_GET_STATUS, 0x48, 0x00); emdtv_write_1(sc, UR_GET_STATUS, 0x12, 0x77); usbd_delay_ms(sc->sc_udev, 6); emdtv_gpio_ctl(sc, EMDTV_GPIO_ANALOG_ON, false); emdtv_gpio_ctl(sc, EMDTV_GPIO_TS1_ON, true); emdtv_gpio_ctl(sc, EMDTV_GPIO_TUNER1_ON, true); emdtv_gpio_ctl(sc, EMDTV_GPIO_DEMOD1_RESET, true); usbd_delay_ms(sc->sc_udev, 100); emdtv_dtv_rescan(sc, NULL, NULL); }
static int auvitek_stop_xfer(struct auvitek_softc *sc) { struct auvitek_xfer *ax = &sc->sc_ax; usbd_status err; int i; if (ax->ax_pipe != NULL) { usbd_abort_pipe(ax->ax_pipe); usbd_close_pipe(ax->ax_pipe); ax->ax_pipe = NULL; } for (i = 0; i < AUVITEK_NISOC_XFERS; i++) { struct auvitek_isoc *isoc = &ax->ax_i[i]; if (isoc->i_xfer != NULL) { usbd_free_buffer(isoc->i_xfer); usbd_free_xfer(isoc->i_xfer); isoc->i_xfer = NULL; } if (isoc->i_frlengths != NULL) { kmem_free(isoc->i_frlengths, sizeof(isoc->i_frlengths[0]) * ax->ax_nframes); isoc->i_frlengths = NULL; } } usbd_delay_ms(sc->sc_udev, 1000); err = usbd_set_interface(sc->sc_isoc_iface, 0); if (err != USBD_NORMAL_COMPLETION) { aprint_error_dev(sc->sc_dev, "couldn't set zero bw interface: %s\n", usbd_errstr(err)); return EIO; } return 0; }
/* * Attach the interface. */ static int lgue_attach(device_t dev) { struct lgue_softc *sc; struct usb_attach_arg *uaa; struct ifnet *ifp; usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; int i; u_char eaddr[ETHER_ADDR_LEN]; usbd_status err; sc = device_get_softc(dev); uaa = device_get_ivars(dev); sc->lgue_ctl_iface = uaa->iface; sc->lgue_udev = uaa->device; /* It has only config but in case... */ if (usbd_set_config_no(sc->lgue_udev, LGUE_CONFIG_NO, 0)) { device_printf(dev, "setting config no %d failed\n", LGUE_CONFIG_NO); return(ENXIO); } /* Get control and data intefaces */ id = usbd_get_interface_descriptor(uaa->iface); sc->lgue_ctl_iface_no = id->bInterfaceNumber; sc->lgue_data_iface_no = lgue_get_data_iface_no(sc->lgue_udev, id); if (sc->lgue_data_iface_no == -1) { device_printf(dev, "no data interface number\n"); goto bad; } /* Claim data interface */ for (i = 0; i < uaa->nifaces; ++i) { if (uaa->ifaces[i] != NULL) { id = usbd_get_interface_descriptor(uaa->ifaces[i]); if (id != NULL && id->bInterfaceNumber == sc->lgue_data_iface_no) { err = usbd_set_interface(uaa->ifaces[i], LGUE_ALTERNATE_SETTING); if ( err != USBD_NORMAL_COMPLETION) { device_printf(dev, "no alternate data interface. err:%s\n", usbd_errstr(err)); goto bad; } sc->lgue_data_iface = uaa->ifaces[i]; uaa->ifaces[i] = NULL; } } } if (sc->lgue_data_iface == NULL) { device_printf(dev, "no data interface\n"); goto bad; } /* Find data interface endpoints */ id = usbd_get_interface_descriptor(sc->lgue_data_iface); sc->lgue_ed[LGUE_ENDPT_RX] = sc->lgue_ed[LGUE_ENDPT_TX] = -1; for (i = 0; i < id->bNumEndpoints; ++i) { ed = usbd_interface2endpoint_descriptor(sc->lgue_data_iface, i); if (!ed) { device_printf(dev, "couldn't get endpoint descriptor %d\n", i); goto bad; } if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { sc->lgue_ed[LGUE_ENDPT_RX] = ed->bEndpointAddress; } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { sc->lgue_ed[LGUE_ENDPT_TX] = ed->bEndpointAddress; } } if (sc->lgue_ed[LGUE_ENDPT_RX] == -1) { device_printf(dev, "couldn't find data bilk in\n"); goto bad; } if (sc->lgue_ed[LGUE_ENDPT_TX] == -1) { device_printf(dev, "couldn't find data bilk out\n"); goto bad; } /* Find control interface endpoint */ id = usbd_get_interface_descriptor(sc->lgue_ctl_iface); sc->lgue_ed[LGUE_ENDPT_INTR] = -1; for (i = 0; i < id->bNumEndpoints; ++i) { ed = usbd_interface2endpoint_descriptor(sc->lgue_ctl_iface, i); if (!ed) { device_printf(dev, "couldn't get endpoint descriptor %d\n", i); goto bad; } if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) { sc->lgue_ed[LGUE_ENDPT_INTR] = ed->bEndpointAddress; } } if (sc->lgue_ed[LGUE_ENDPT_INTR] == -1) { device_printf(dev, "couldn't find interrupt bilk in\n"); goto bad; } /* Create interface */ ifp = &sc->lgue_arpcom.ac_if; ifp->if_softc = sc; if_initname(ifp, device_get_name(dev), device_get_unit(dev)); lgue_getmac(sc, eaddr); ifp->if_mtu = lgue_getmtu(sc); ifp->if_data.ifi_mtu = ifp->if_mtu; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_baudrate = 10000000; ifp->if_ioctl = lgue_ioctl; ifp->if_start = lgue_start; ifp->if_watchdog = lgue_watchdog; ifp->if_init = lgue_init; ifq_set_maxlen(&ifp->if_snd, IFQ_MAXLEN); ifq_set_ready(&ifp->if_snd); /* Call attach routine */ ether_ifattach(ifp, eaddr, NULL); usb_register_netisr(); sc->lgue_dying = 0; return(0); bad: return(ENXIO); }
/* set ISOC configuration */ int ubt_set_isoc_config(struct ubt_softc *sc) { usb_endpoint_descriptor_t *ed; int rd_addr, wr_addr, rd_size, wr_size; uint8_t count, i; int err; err = usbd_set_interface(sc->sc_iface1, sc->sc_config); if (err != USBD_NORMAL_COMPLETION) { kprintf( "%s: Could not set config %d on ISOC interface. %s (%d)\n", device_get_nameunit(sc->sc_dev), sc->sc_config, usbd_errstr(err), err); return err == USBD_IN_USE ? EBUSY : EIO; } /* * We wont get past the above if there are any pipes open, so no * need to worry about buf/xfer/pipe deallocation. If we get an * error after this, the frame quantities will be 0 and no SCO * data will be possible. */ sc->sc_scord_size = rd_size = 0; sc->sc_scord_addr = rd_addr = -1; sc->sc_scowr_size = wr_size = 0; sc->sc_scowr_addr = wr_addr = -1; count = 0; (void)usbd_endpoint_count(sc->sc_iface1, &count); for (i = 0 ; i < count ; i++) { ed = usbd_interface2endpoint_descriptor(sc->sc_iface1, i); if (ed == NULL) { kprintf("%s: could not read endpoint descriptor %d\n", device_get_nameunit(sc->sc_dev), i); return EIO; } DPRINTFN(5, "%s: endpoint type %02x (%02x) addr %02x (%s)\n", device_get_nameunit(sc->sc_dev), UE_GET_XFERTYPE(ed->bmAttributes), UE_GET_ISO_TYPE(ed->bmAttributes), ed->bEndpointAddress, UE_GET_DIR(ed->bEndpointAddress) ? "in" : "out"); if (UE_GET_XFERTYPE(ed->bmAttributes) != UE_ISOCHRONOUS) continue; if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN) { rd_addr = ed->bEndpointAddress; rd_size = UGETW(ed->wMaxPacketSize); } else { wr_addr = ed->bEndpointAddress; wr_size = UGETW(ed->wMaxPacketSize); } } if (rd_addr == -1) { kprintf( "%s: missing ISOC IN endpoint on interface config %d\n", device_get_nameunit(sc->sc_dev), sc->sc_config); return ENOENT; } if (wr_addr == -1) { kprintf( "%s: missing ISOC OUT endpoint on interface config %d\n", device_get_nameunit(sc->sc_dev), sc->sc_config); return ENOENT; } #ifdef DIAGNOSTIC if (rd_size > MLEN) { kprintf("%s: rd_size=%d exceeds MLEN\n", device_get_nameunit(sc->sc_dev), rd_size); return EOVERFLOW; } if (wr_size > MLEN) { kprintf("%s: wr_size=%d exceeds MLEN\n", device_get_nameunit(sc->sc_dev), wr_size); return EOVERFLOW; } #endif sc->sc_scord_size = rd_size; sc->sc_scord_addr = rd_addr; sc->sc_scowr_size = wr_size; sc->sc_scowr_addr = wr_addr; return 0; }
void ulpt_attach(struct device *parent, struct device *self, void *aux) { struct ulpt_softc *sc = (struct ulpt_softc *)self; struct usb_attach_arg *uaa = aux; struct usbd_device *dev = uaa->device; struct usbd_interface *iface = uaa->iface; usb_interface_descriptor_t *ifcd = usbd_get_interface_descriptor(iface); usb_interface_descriptor_t *id, *iend; usb_config_descriptor_t *cdesc; usbd_status err; usb_endpoint_descriptor_t *ed; u_int8_t epcount; int i, altno; DPRINTFN(10,("ulpt_attach: sc=%p\n", sc)); //printf("%s: iclass %d/%d\n", sc->sc_dev.dv_xname, // ifcd->bInterfaceClass, ifcd->bInterfaceSubClass); /* XXX * Stepping through the alternate settings needs to be abstracted out. */ cdesc = usbd_get_config_descriptor(dev); if (cdesc == NULL) { printf("%s: failed to get configuration descriptor\n", sc->sc_dev.dv_xname); return; } iend = (usb_interface_descriptor_t *) ((char *)cdesc + UGETW(cdesc->wTotalLength)); #ifdef DIAGNOSTIC if (ifcd < (usb_interface_descriptor_t *)cdesc || ifcd >= iend) panic("ulpt: iface desc out of range"); #endif /* Step through all the descriptors looking for bidir mode */ for (id = ifcd, altno = 0; id < iend; id = (void *)((char *)id + id->bLength)) { if (id->bDescriptorType == UDESC_INTERFACE && id->bInterfaceNumber == ifcd->bInterfaceNumber) { if (id->bInterfaceClass == UICLASS_PRINTER && id->bInterfaceSubClass == UISUBCLASS_PRINTER && (id->bInterfaceProtocol == UIPROTO_PRINTER_BI /*|| id->bInterfaceProtocol == UIPROTO_PRINTER_1284*/)) goto found; altno++; } } id = ifcd; /* not found, use original */ found: if (id != ifcd) { /* Found a new bidir setting */ DPRINTF(("ulpt_attach: set altno = %d\n", altno)); err = usbd_set_interface(iface, altno); if (err) { printf("%s: setting alternate interface failed\n", sc->sc_dev.dv_xname); usbd_deactivate(sc->sc_udev); return; } } epcount = 0; (void)usbd_endpoint_count(iface, &epcount); sc->sc_in = -1; sc->sc_out = -1; for (i = 0; i < epcount; i++) { ed = usbd_interface2endpoint_descriptor(iface, i); if (ed == NULL) { printf("%s: couldn't get ep %d\n", sc->sc_dev.dv_xname, i); return; } if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { sc->sc_in = ed->bEndpointAddress; } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { sc->sc_out = ed->bEndpointAddress; } } if (sc->sc_out == -1) { printf("%s: could not find bulk out endpoint\n", sc->sc_dev.dv_xname); usbd_deactivate(sc->sc_udev); return; } if (usbd_get_quirks(dev)->uq_flags & UQ_BROKEN_BIDIR) { /* This device doesn't handle reading properly. */ sc->sc_in = -1; } printf("%s: using %s-directional mode\n", sc->sc_dev.dv_xname, sc->sc_in >= 0 ? "bi" : "uni"); DPRINTFN(10, ("ulpt_attach: bulk=%d\n", sc->sc_out)); sc->sc_iface = iface; sc->sc_ifaceno = id->bInterfaceNumber; sc->sc_udev = dev; /* maybe the device needs firmware */ sc->sc_fwdev = ulpt_lookup(uaa->vendor, uaa->product); if (sc->sc_fwdev) { if (rootvp == NULL) mountroothook_establish(ulpt_load_firmware, sc); else ulpt_load_firmware(sc); } #if 0 /* * This code is disabled because for some mysterious reason it causes * printing not to work. But only sometimes, and mostly with * UHCI and less often with OHCI. *sigh* */ { usb_config_descriptor_t *cd = usbd_get_config_descriptor(dev); usb_device_request_t req; int len, alen; req.bmRequestType = UT_READ_CLASS_INTERFACE; req.bRequest = UR_GET_DEVICE_ID; USETW(req.wValue, cd->bConfigurationValue); USETW2(req.wIndex, id->bInterfaceNumber, id->bAlternateSetting); USETW(req.wLength, DEVINFOSIZE - 1); err = usbd_do_request_flags(dev, &req, devinfop, USBD_SHORT_XFER_OK, &alen, USBD_DEFAULT_TIMEOUT); if (err) { printf("%s: cannot get device id\n", sc->sc_dev.dv_xname); } else if (alen <= 2) { printf("%s: empty device id, no printer connected?\n", sc->sc_dev.dv_xname); } else { /* devinfop now contains an IEEE-1284 device ID */ len = ((devinfop[0] & 0xff) << 8) | (devinfop[1] & 0xff); if (len > DEVINFOSIZE - 3) len = DEVINFOSIZE - 3; devinfo[len] = 0; printf("%s: device id <", sc->sc_dev.dv_xname); ieee1284_print_id(devinfop+2); printf(">\n"); } } #endif }