jresult_t cdc_open_data_pipes(uwh_cdc_dev_h dev_ctx) { jresult_t rc = 0; jcdc_dev_softc_t *sc = (jcdc_dev_softc_t *)dev_ctx; DECLARE_FNAME("cdc_open_data_pipes"); DBG_V(DHOST_CDC_GENERAL, ("%s: Entered\n", fname)); /* Open bulk pipes */ rc = usbd_open_pipe(sc->d_iface, sc->bulk_ep_in, USBD_EXCLUSIVE_USE, &sc->bulk_pipe_in); if (rc) { DBG_E(DHOST_CDC_GENERAL, ("%s: Error opening bulk in pipe.\n", fname)); return rc; } rc = usbd_open_pipe(sc->d_iface, sc->bulk_ep_out, USBD_EXCLUSIVE_USE, &sc->bulk_pipe_out); if (rc) { DBG_E(DHOST_CDC_GENERAL, ("%s: Error opening bulk out pipe.\n", fname)); usbd_close_pipe(sc->bulk_pipe_in); } return rc; }
int urioopen(dev_t dev, int flag, int mode, struct lwp *l) { struct urio_softc *sc; usbd_status err; sc = device_lookup_private(&urio_cd, URIOUNIT(dev)); if (sc == NULL) return ENXIO; DPRINTFN(5, ("urioopen: flag=%d, mode=%d, unit=%d\n", flag, mode, URIOUNIT(dev))); if (sc->sc_dying) return (EIO); if (sc->sc_in_pipe != NULL) return (EBUSY); if ((flag & (FWRITE|FREAD)) != (FWRITE|FREAD)) return (EACCES); err = usbd_open_pipe(sc->sc_iface, sc->sc_in_addr, 0, &sc->sc_in_pipe); if (err) return (EIO); err = usbd_open_pipe(sc->sc_iface, sc->sc_out_addr,0,&sc->sc_out_pipe); if (err) { usbd_close_pipe(sc->sc_in_pipe); sc->sc_in_pipe = NULL; return (EIO); } return (0); }
/* Return : None */ int parse_descriptors(pModule_data_t pModule) { _uint32 eix; usbd_descriptors_t * pDesc; struct usbd_desc_node *ifc, *ept; if(verbosity >=3) printf("Try to get interface descriptors %i, %i, %i\n", (int)(pModule -> pInstance -> config), (int)(pModule -> pInstance -> iface), (int)(pModule -> pInstance -> alternate)); if( usbd_interface_descriptor( pModule -> pDevice, pModule -> pInstance -> config, pModule -> pInstance -> iface, pModule -> pInstance -> alternate, &ifc ) ) { // Trace interfaces for( eix = 0; ( pDesc = usbd_parse_descriptors( pModule -> pDevice, ifc, USB_DESC_ENDPOINT, eix, &ept ) ) != NULL; ++eix ) { switch( pDesc->endpoint.bmAttributes ) { case USB_ATTRIB_CONTROL: usbd_open_pipe( pModule -> pDevice, pDesc, &(pModule -> ep_cntl)); pModule -> ep_cnt_size = pDesc -> endpoint.wMaxPacketSize; // Size of input buffer pModule -> ep_cnt_buf = usbd_alloc( pModule -> ep_cnt_size); break; case USB_ATTRIB_ISOCHRONOUS: break; case USB_ATTRIB_BULK: break; case USB_ATTRIB_INTERRUPT: // Can have two endpoints: IN & OUT switch( pDesc -> endpoint.bEndpointAddress & USB_ENDPOINT_IN ) { case USB_ENDPOINT_OUT: break; case USB_ENDPOINT_IN: if( EOK == usbd_open_pipe( pModule -> pDevice, pDesc, &(pModule -> ep_int ))) { pModule -> ep_int_size = pDesc -> endpoint.wMaxPacketSize; // Size of input buffer } break; } break; } } } return( ( pModule -> ep_int && pModule -> ep_cntl) ? EOK : ENODEV ); }
/* alloc/free pipe */ static usbd_status alloc_pipe(struct umidi_endpoint *ep) { struct umidi_softc *sc = ep->sc; usbd_status err; DPRINTF(("%s: alloc_pipe %p\n", sc->sc_dev.dv_xname, ep)); SIMPLEQ_INIT(&ep->intrq); ep->pending = 0; ep->busy = 0; ep->used = 0; ep->xfer = usbd_alloc_xfer(sc->sc_udev); if (ep->xfer == NULL) return USBD_NOMEM; ep->buffer = usbd_alloc_buffer(ep->xfer, ep->packetsize); if (ep->buffer == NULL) { usbd_free_xfer(ep->xfer); return USBD_NOMEM; } err = usbd_open_pipe(sc->sc_iface, ep->addr, 0, &ep->pipe); if (err != USBD_NORMAL_COMPLETION) { usbd_free_xfer(ep->xfer); return err; } return USBD_NORMAL_COMPLETION; }
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 ugl_openpipes(struct ugl_softc *sc) { struct ugl_chain *c; usbd_status err; int i; /* Open RX and TX pipes. */ err = usbd_open_pipe(sc->sc_iface, sc->sc_ed[UGL_ENDPT_RX], USBD_EXCLUSIVE_USE, &sc->sc_ep[UGL_ENDPT_RX]); if (err) { printf("%s: open rx pipe failed: %s\n", sc->sc_dev.dv_xname, usbd_errstr(err)); return (EIO); } err = usbd_open_pipe(sc->sc_iface, sc->sc_ed[UGL_ENDPT_TX], USBD_EXCLUSIVE_USE, &sc->sc_ep[UGL_ENDPT_TX]); if (err) { printf("%s: open tx pipe failed: %s\n", sc->sc_dev.dv_xname, usbd_errstr(err)); return (EIO); } err = usbd_open_pipe_intr(sc->sc_iface, sc->sc_ed[UGL_ENDPT_INTR], USBD_EXCLUSIVE_USE, &sc->sc_ep[UGL_ENDPT_INTR], sc, sc->sc_ibuf, UGL_INTR_PKTLEN, ugl_intr, UGL_INTR_INTERVAL); if (err) { printf("%s: open intr pipe failed: %s\n", sc->sc_dev.dv_xname, usbd_errstr(err)); return (EIO); } /* Start up the receive pipe. */ for (i = 0; i < UGL_RX_LIST_CNT; i++) { c = &sc->sc_cdata.ugl_rx_chain[i]; usbd_setup_xfer(c->ugl_xfer, sc->sc_ep[UGL_ENDPT_RX], c, c->ugl_buf, UGL_BUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY, USBD_NO_TIMEOUT, ugl_rxeof); usbd_transfer(c->ugl_xfer); } return (0); }
int urioopen(struct dev_open_args *ap) { cdev_t dev = ap->a_head.a_dev; #if (USBDI >= 1) struct urio_softc * sc; #endif int unit = URIOUNIT(dev); sc = devclass_get_softc(urio_devclass, unit); if (sc == NULL) return (ENXIO); DPRINTFN(5, ("urioopen: flag=%d, mode=%d, unit=%d\n", ap->a_oflags, ap->a_devtype, unit)); if (sc->sc_opened) return EBUSY; if ((ap->a_oflags & (FWRITE|FREAD)) != (FWRITE|FREAD)) return EACCES; sc->sc_opened = 1; sc->sc_pipeh_in = 0; sc->sc_pipeh_out = 0; if (usbd_open_pipe(sc->sc_iface, sc->sc_epaddr[RIO_IN], 0, &sc->sc_pipeh_in) != USBD_NORMAL_COMPLETION) { sc->sc_pipeh_in = 0; return EIO; }; if (usbd_open_pipe(sc->sc_iface, sc->sc_epaddr[RIO_OUT], 0, &sc->sc_pipeh_out) != USBD_NORMAL_COMPLETION) { usbd_close_pipe(sc->sc_pipeh_in); sc->sc_pipeh_in = 0; sc->sc_pipeh_out = 0; return EIO; }; return 0; }
int kue_open_pipes(struct kue_softc *sc) { usbd_status err; struct kue_chain *c; int i; DPRINTFN(5,("%s: %s: enter\n", sc->kue_dev.dv_xname,__func__)); /* Open RX and TX pipes. */ err = usbd_open_pipe(sc->kue_iface, sc->kue_ed[KUE_ENDPT_RX], USBD_EXCLUSIVE_USE, &sc->kue_ep[KUE_ENDPT_RX]); if (err) { printf("%s: open rx pipe failed: %s\n", sc->kue_dev.dv_xname, usbd_errstr(err)); return (EIO); } err = usbd_open_pipe(sc->kue_iface, sc->kue_ed[KUE_ENDPT_TX], USBD_EXCLUSIVE_USE, &sc->kue_ep[KUE_ENDPT_TX]); if (err) { printf("%s: open tx pipe failed: %s\n", sc->kue_dev.dv_xname, usbd_errstr(err)); return (EIO); } /* Start up the receive pipe. */ for (i = 0; i < KUE_RX_LIST_CNT; i++) { c = &sc->kue_cdata.kue_rx_chain[i]; usbd_setup_xfer(c->kue_xfer, sc->kue_ep[KUE_ENDPT_RX], c, c->kue_buf, KUE_BUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY, USBD_NO_TIMEOUT, kue_rxeof); DPRINTFN(5,("%s: %s: start read\n", sc->kue_dev.dv_xname, __func__)); usbd_transfer(c->kue_xfer); } return (0); }
/* alloc/free pipe */ static usbd_status alloc_pipe(struct umidi_endpoint *ep) { struct umidi_softc *sc = ep->sc; usbd_status err; usb_endpoint_descriptor_t *epd; epd = usbd_get_endpoint_descriptor(sc->sc_iface, ep->addr); /* * For output, an improvement would be to have a buffer bigger than * wMaxPacketSize by num_jacks-1 additional packet slots; that would * allow out_solicit to fill the buffer to the full packet size in * all cases. But to use usbd_alloc_buffer to get a slightly larger * buffer would not be a good way to do that, because if the addition * would make the buffer exceed USB_MEM_SMALL then a substantially * larger block may be wastefully allocated. Some flavor of double * buffering could serve the same purpose, but would increase the * code complexity, so for now I will live with the current slight * penalty of reducing max transfer size by (num_open-num_scheduled) * packet slots. */ ep->buffer_size = UGETW(epd->wMaxPacketSize); ep->buffer_size -= ep->buffer_size % UMIDI_PACKET_SIZE; DPRINTF(("%s: alloc_pipe %p, buffer size %u\n", USBDEVNAME(sc->sc_dev), ep, ep->buffer_size)); ep->num_scheduled = 0; ep->this_schedule = 0; ep->next_schedule = 0; ep->soliciting = 0; ep->armed = 0; ep->xfer = usbd_alloc_xfer(sc->sc_udev); if (ep->xfer == NULL) { err = USBD_NOMEM; goto quit; } ep->buffer = usbd_alloc_buffer(ep->xfer, ep->buffer_size); if (ep->buffer == NULL) { usbd_free_xfer(ep->xfer); err = USBD_NOMEM; goto quit; } ep->next_slot = ep->buffer; err = usbd_open_pipe(sc->sc_iface, ep->addr, 0, &ep->pipe); if (err) usbd_free_xfer(ep->xfer); ep->solicit_cookie = softint_establish(SOFTINT_CLOCK, out_solicit, ep); quit: return err; }
int urioopen(dev_t dev, int flag, int mode, struct proc *p) { struct urio_softc *sc; usbd_status err; if (URIOUNIT(dev) >= urio_cd.cd_ndevs) return (ENXIO); sc = urio_cd.cd_devs[URIOUNIT(dev)]; if (sc == NULL) return (ENXIO); DPRINTFN(5, ("urioopen: flag=%d, mode=%d, unit=%d\n", flag, mode, URIOUNIT(dev))); if (usbd_is_dying(sc->sc_udev)) return (EIO); if (sc->sc_in_pipe != NULL) return (EBUSY); if ((flag & (FWRITE|FREAD)) != (FWRITE|FREAD)) return (EACCES); err = usbd_open_pipe(sc->sc_iface, sc->sc_in_addr, 0, &sc->sc_in_pipe); if (err) return (EIO); err = usbd_open_pipe(sc->sc_iface, sc->sc_out_addr,0,&sc->sc_out_pipe); if (err) { usbd_close_pipe(sc->sc_in_pipe); sc->sc_in_pipe = NULL; return (EIO); } return (0); }
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 void cdce_init(void *xsc) { struct cdce_softc *sc = xsc; struct ifnet *ifp = GET_IFP(sc); struct ue_chain *c; usbd_status err; int i; if (ifp->if_flags & IFF_RUNNING) return; CDCE_LOCK(sc); cdce_reset(sc); if (usb_ether_tx_list_init(sc, &sc->cdce_cdata, sc->cdce_udev) == ENOBUFS) { printf("%s: tx list init failed\n", USBDEVNAME(sc->cdce_dev)); CDCE_UNLOCK(sc); return; } if (usb_ether_rx_list_init(sc, &sc->cdce_cdata, sc->cdce_udev) == ENOBUFS) { printf("%s: rx list init failed\n", USBDEVNAME(sc->cdce_dev)); CDCE_UNLOCK(sc); return; } /* Maybe set multicast / broadcast here??? */ err = usbd_open_pipe(sc->cdce_data_iface, sc->cdce_bulkin_no, USBD_EXCLUSIVE_USE, &sc->cdce_bulkin_pipe); if (err) { printf("%s: open rx pipe failed: %s\n", USBDEVNAME(sc->cdce_dev), usbd_errstr(err)); CDCE_UNLOCK(sc); return; } err = usbd_open_pipe(sc->cdce_data_iface, sc->cdce_bulkout_no, USBD_EXCLUSIVE_USE, &sc->cdce_bulkout_pipe); if (err) { printf("%s: open tx pipe failed: %s\n", USBDEVNAME(sc->cdce_dev), usbd_errstr(err)); CDCE_UNLOCK(sc); return; } for (i = 0; i < UE_RX_LIST_CNT; i++) { c = &sc->cdce_cdata.ue_rx_chain[i]; usbd_setup_xfer(c->ue_xfer, sc->cdce_bulkin_pipe, c, mtod(c->ue_mbuf, char *), UE_BUFSZ, USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, cdce_rxeof); usbd_transfer(c->ue_xfer); } ifp->if_flags |= IFF_RUNNING; ifp->if_flags &= ~IFF_OACTIVE; CDCE_UNLOCK(sc); return; }
/* ARGSUSED */ static int udsir_open(void *h, int flag, int mode, struct lwp *l) { struct udsir_softc *sc = h; int error; usbd_status err; DPRINTFN(0, ("%s: sc=%p\n", __func__, sc)); err = usbd_open_pipe(sc->sc_iface, sc->sc_rd_addr, 0, &sc->sc_rd_pipe); if (err != USBD_NORMAL_COMPLETION) { error = EIO; goto bad1; } err = usbd_open_pipe(sc->sc_iface, sc->sc_wr_addr, 0, &sc->sc_wr_pipe); if (err != USBD_NORMAL_COMPLETION) { error = EIO; goto bad2; } error = usbd_create_xfer(sc->sc_rd_pipe, sc->sc_rd_maxpsz, USBD_SHORT_XFER_OK, 0, &sc->sc_rd_xfer); if (error) goto bad3; error = usbd_create_xfer(sc->sc_wr_pipe, IRDA_MAX_FRAME_SIZE, USBD_FORCE_SHORT_XFER, 0, &sc->sc_wr_xfer); if (error) goto bad4; sc->sc_rd_buf = usbd_get_buffer(sc->sc_rd_xfer); sc->sc_wr_buf = usbd_get_buffer(sc->sc_wr_xfer); sc->sc_ur_buf = kmem_alloc(IRDA_MAX_FRAME_SIZE, KM_SLEEP); if (sc->sc_ur_buf == NULL) { error = ENOMEM; goto bad5; } sc->sc_rd_index = sc->sc_rd_count = 0; sc->sc_closing = 0; sc->sc_rd_readinprogress = 0; sc->sc_rd_expectdataticks = 0; sc->sc_ur_framelen = 0; sc->sc_rd_err = 0; sc->sc_wr_stalewrite = 0; sc->sc_direction = udir_idle; sc->sc_params.speed = 0; sc->sc_params.ebofs = 0; sc->sc_params.maxsize = min(sc->sc_rd_maxpsz, sc->sc_wr_maxpsz); deframe_init(&sc->sc_framestate, sc->sc_ur_buf, IRDA_MAX_FRAME_SIZE); /* Increment reference for thread */ sc->sc_refcnt++; error = kthread_create(PRI_NONE, 0, NULL, udsir_thread, sc, &sc->sc_thread, "%s", device_xname(sc->sc_dev)); if (error) { sc->sc_refcnt--; goto bad5; } return 0; bad5: usbd_destroy_xfer(sc->sc_wr_xfer); sc->sc_wr_xfer = NULL; bad4: usbd_destroy_xfer(sc->sc_rd_xfer); sc->sc_rd_xfer = NULL; bad3: usbd_close_pipe(sc->sc_wr_pipe); sc->sc_wr_pipe = NULL; bad2: usbd_close_pipe(sc->sc_rd_pipe); sc->sc_rd_pipe = NULL; bad1: return error; }
void smsc_init(void *xsc) { struct smsc_softc *sc = xsc; struct ifnet *ifp = &sc->sc_ac.ac_if; struct smsc_chain *c; usbd_status err; int s, i; s = splnet(); /* Cancel pending I/O */ smsc_stop(sc); /* Reset the ethernet interface. */ smsc_reset(sc); /* Init RX ring. */ if (smsc_rx_list_init(sc) == ENOBUFS) { printf("%s: rx list init failed\n", sc->sc_dev.dv_xname); splx(s); return; } /* Init TX ring. */ if (smsc_tx_list_init(sc) == ENOBUFS) { printf("%s: tx list init failed\n", sc->sc_dev.dv_xname); splx(s); return; } /* Program promiscuous mode and multicast filters. */ smsc_iff(sc); /* Open RX and TX pipes. */ err = usbd_open_pipe(sc->sc_iface, sc->sc_ed[SMSC_ENDPT_RX], USBD_EXCLUSIVE_USE, &sc->sc_ep[SMSC_ENDPT_RX]); if (err) { printf("%s: open rx pipe failed: %s\n", sc->sc_dev.dv_xname, usbd_errstr(err)); splx(s); return; } err = usbd_open_pipe(sc->sc_iface, sc->sc_ed[SMSC_ENDPT_TX], USBD_EXCLUSIVE_USE, &sc->sc_ep[SMSC_ENDPT_TX]); if (err) { printf("%s: open tx pipe failed: %s\n", sc->sc_dev.dv_xname, usbd_errstr(err)); splx(s); return; } /* Start up the receive pipe. */ for (i = 0; i < SMSC_RX_LIST_CNT; i++) { c = &sc->sc_cdata.rx_chain[i]; usbd_setup_xfer(c->sc_xfer, sc->sc_ep[SMSC_ENDPT_RX], c, c->sc_buf, sc->sc_bufsz, USBD_SHORT_XFER_OK | USBD_NO_COPY, USBD_NO_TIMEOUT, smsc_rxeof); usbd_transfer(c->sc_xfer); } /* TCP/UDP checksum offload engines. */ smsc_sethwcsum(sc); /* Indicate we are up and running. */ ifp->if_flags |= IFF_RUNNING; ifp->if_flags &= ~IFF_OACTIVE; timeout_add_sec(&sc->sc_stat_ch, 1); splx(s); }
static int atausb_attach(device_t dev) { struct atausb_softc *sc = device_get_softc(dev); struct usb_attach_arg *uaa = device_get_ivars(dev); usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; usbd_device_handle udev; usb_device_request_t request; char devinfo[1024], *proto, *subclass; u_int8_t maxlun; int err, i; sc->dev = dev; usbd_devinfo(uaa->device, 0, devinfo); device_set_desc_copy(dev, devinfo); sc->bulkin = sc->bulkout = sc->bulkirq = -1; sc->bulkin_pipe = sc->bulkout_pipe= sc->bulkirq_pipe = NULL; sc->iface = uaa->iface; sc->ifaceno = uaa->ifaceno; sc->maxlun = 0; sc->timeout = 5000; sc->locked_ch = NULL; sc->restart_ch = NULL; spin_init(&sc->locked_mtx); id = usbd_get_interface_descriptor(sc->iface); switch (id->bInterfaceProtocol) { case UIPROTO_MASS_BBB: case UIPROTO_MASS_BBB_OLD: proto = "Bulk-Only"; break; case UIPROTO_MASS_CBI: proto = "CBI"; break; case UIPROTO_MASS_CBI_I: proto = "CBI with CCI"; break; default: proto = "Unknown"; } switch (id->bInterfaceSubClass) { case UISUBCLASS_RBC: subclass = "RBC"; break; case UISUBCLASS_QIC157: case UISUBCLASS_SFF8020I: case UISUBCLASS_SFF8070I: subclass = "ATAPI"; break; case UISUBCLASS_SCSI: subclass = "SCSI"; break; case UISUBCLASS_UFI: subclass = "UFI"; break; default: subclass = "Unknown"; } device_printf(dev, "using %s over %s\n", subclass, proto); if (strcmp(proto, "Bulk-Only") || (strcmp(subclass, "ATAPI") && strcmp(subclass, "SCSI"))) return ENXIO; for (i = 0 ; i < id->bNumEndpoints ; i++) { if (!(ed = usbd_interface2endpoint_descriptor(sc->iface, i))) { device_printf(sc->dev, "could not read endpoint descriptor\n"); return ENXIO; } if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) { sc->bulkin = ed->bEndpointAddress; } if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) { sc->bulkout = ed->bEndpointAddress; } if (id->bInterfaceProtocol == UIPROTO_MASS_CBI_I && UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && (ed->bmAttributes & UE_XFERTYPE) == UE_INTERRUPT) { sc->bulkirq = ed->bEndpointAddress; } } /* check whether we found at least the endpoints we need */ if (!sc->bulkin || !sc->bulkout) { device_printf(sc->dev, "needed endpoints not found (%d,%d)\n", sc->bulkin, sc->bulkout); atausb_detach(dev); return ENXIO; } /* open the pipes */ if (usbd_open_pipe(sc->iface, sc->bulkout, USBD_EXCLUSIVE_USE, &sc->bulkout_pipe)) { device_printf(sc->dev, "cannot open bulkout pipe (%d)\n", sc->bulkout); atausb_detach(dev); return ENXIO; } if (usbd_open_pipe(sc->iface, sc->bulkin, USBD_EXCLUSIVE_USE, &sc->bulkin_pipe)) { device_printf(sc->dev, "cannot open bulkin pipe (%d)\n", sc->bulkin); atausb_detach(dev); return ENXIO; } if (id->bInterfaceProtocol == UIPROTO_MASS_CBI_I) { if (usbd_open_pipe(sc->iface, sc->bulkirq, USBD_EXCLUSIVE_USE, &sc->bulkirq_pipe)) { device_printf(sc->dev, "cannot open bulkirq pipe (%d)\n", sc->bulkirq); atausb_detach(dev); return ENXIO; } } sc->state = ATAUSB_S_ATTACH; /* alloc needed number of transfer handles */ for (i = 0; i < ATAUSB_T_MAX; i++) { sc->transfer[i] = usbd_alloc_xfer(uaa->device); if (!sc->transfer[i]) { device_printf(sc->dev, "out of memory\n"); atausb_detach(dev); return ENXIO; } } /* driver is ready to process requests here */ sc->state = ATAUSB_S_IDLE; /* get number of devices so we can add matching channels */ usbd_interface2device_handle(sc->iface, &udev); request.bmRequestType = UT_READ_CLASS_INTERFACE; request.bRequest = 0xfe; /* GET_MAX_LUN; */ USETW(request.wValue, 0); USETW(request.wIndex, sc->ifaceno); USETW(request.wLength, sizeof(maxlun)); switch ((err = usbd_do_request(udev, &request, &maxlun))) { case USBD_NORMAL_COMPLETION: if (bootverbose) device_printf(sc->dev, "maxlun=%d\n", maxlun); sc->maxlun = maxlun; break; default: if (bootverbose) device_printf(sc->dev, "get maxlun not supported %s\n", usbd_errstr(err)); } /* ata channels are children to this USB control device */ for (i = 0; i <= sc->maxlun; i++) { /* XXX TGEN devclass_find_free_unit() implementation */ int freeunit = 2; while (freeunit < devclass_get_maxunit(ata_devclass) && devclass_get_device(ata_devclass, freeunit) != NULL) freeunit++; if (!device_add_child(sc->dev, "ata", freeunit)) { device_printf(sc->dev, "failed to attach ata child device\n"); atausb_detach(dev); return ENXIO; } } bus_generic_attach(sc->dev); return 0; }
Static int ucomopen(dev_t dev, int flag, int mode, usb_proc_ptr p) { int unit = UCOMUNIT(dev); struct ucom_softc *sc; usbd_status err; struct tty *tp; int s; int error; USB_GET_SC_OPEN(ucom, unit, sc); if (sc->sc_dying) return (ENXIO); tp = sc->sc_tty; DPRINTF(("%s: ucomopen: tp = %p\n", USBDEVNAME(sc->sc_dev), tp)); if (ISSET(tp->t_state, TS_ISOPEN) && ISSET(tp->t_state, TS_XCLUDE) && suser(p)) return (EBUSY); /* * Do the following iff this is a first open. */ s = spltty(); while (sc->sc_opening) tsleep(&sc->sc_opening, PRIBIO, "ucomop", 0); sc->sc_opening = 1; if (!ISSET(tp->t_state, TS_ISOPEN)) { struct termios t; sc->sc_poll = 0; sc->sc_lsr = sc->sc_msr = sc->sc_mcr = 0; tp->t_dev = dev; /* * Initialize the termios status to the defaults. Add in the * sticky bits from TIOCSFLAGS. */ t.c_ispeed = 0; t.c_ospeed = TTYDEF_SPEED; t.c_cflag = TTYDEF_CFLAG; /* Make sure ucomparam() will do something. */ tp->t_ospeed = 0; (void)ucomparam(tp, &t); tp->t_iflag = TTYDEF_IFLAG; tp->t_oflag = TTYDEF_OFLAG; tp->t_lflag = TTYDEF_LFLAG; ttychars(tp); ttsetwater(tp); /* * Turn on DTR. We must always do this, even if carrier is not * present, because otherwise we'd have to use TIOCSDTR * immediately after setting CLOCAL, which applications do not * expect. We always assert DTR while the device is open * unless explicitly requested to deassert it. */ (void)ucomctl(sc, TIOCM_DTR | TIOCM_RTS, DMBIS); /* Device specific open */ if (sc->sc_callback->ucom_open != NULL) { error = sc->sc_callback->ucom_open(sc->sc_parent, sc->sc_portno); if (error) { ucom_cleanup(sc); sc->sc_opening = 0; wakeup(&sc->sc_opening); splx(s); return (error); } } DPRINTF(("ucomopen: open pipes in = %d out = %d\n", sc->sc_bulkin_no, sc->sc_bulkout_no)); /* Open the bulk pipes */ /* Bulk-in pipe */ err = usbd_open_pipe(sc->sc_iface, sc->sc_bulkin_no, 0, &sc->sc_bulkin_pipe); if (err) { printf("%s: open bulk in error (addr %d): %s\n", USBDEVNAME(sc->sc_dev), sc->sc_bulkin_no, usbd_errstr(err)); error = EIO; goto fail_0; } /* Bulk-out pipe */ err = usbd_open_pipe(sc->sc_iface, sc->sc_bulkout_no, USBD_EXCLUSIVE_USE, &sc->sc_bulkout_pipe); if (err) { printf("%s: open bulk out error (addr %d): %s\n", USBDEVNAME(sc->sc_dev), sc->sc_bulkout_no, usbd_errstr(err)); error = EIO; goto fail_1; } /* Allocate a request and an input buffer and start reading. */ sc->sc_ixfer = usbd_alloc_xfer(sc->sc_udev); if (sc->sc_ixfer == NULL) { error = ENOMEM; goto fail_2; } sc->sc_ibuf = usbd_alloc_buffer(sc->sc_ixfer, sc->sc_ibufsizepad); if (sc->sc_ibuf == NULL) { error = ENOMEM; goto fail_3; } sc->sc_oxfer = usbd_alloc_xfer(sc->sc_udev); if (sc->sc_oxfer == NULL) { error = ENOMEM; goto fail_3; } sc->sc_obuf = usbd_alloc_buffer(sc->sc_oxfer, sc->sc_obufsize + sc->sc_opkthdrlen); if (sc->sc_obuf == NULL) { error = ENOMEM; goto fail_4; } /* * Handle initial DCD. */ if (ISSET(sc->sc_msr, UMSR_DCD) || (minor(dev) & UCOM_CALLOUT_MASK)) (*linesw[tp->t_line].l_modem)(tp, 1); ucomstartread(sc); } sc->sc_opening = 0; wakeup(&sc->sc_opening); splx(s); error = ttyopen(dev, tp); if (error) goto bad; error = (*linesw[tp->t_line].l_open)(dev, tp); if (error) goto bad; disc_optim(tp, &tp->t_termios, sc); DPRINTF(("%s: ucomopen: success\n", USBDEVNAME(sc->sc_dev))); sc->sc_poll = 1; sc->sc_refcnt++; return (0); fail_4: usbd_free_xfer(sc->sc_oxfer); sc->sc_oxfer = NULL; fail_3: usbd_free_xfer(sc->sc_ixfer); sc->sc_ixfer = NULL; fail_2: usbd_close_pipe(sc->sc_bulkout_pipe); sc->sc_bulkout_pipe = NULL; fail_1: usbd_close_pipe(sc->sc_bulkin_pipe); sc->sc_bulkin_pipe = NULL; fail_0: sc->sc_opening = 0; wakeup(&sc->sc_opening); splx(s); return (error); bad: if (!ISSET(tp->t_state, TS_ISOPEN)) { /* * We failed to open the device, and nobody else had it opened. * Clean up the state as appropriate. */ ucom_cleanup(sc); } DPRINTF(("%s: ucomopen: failed\n", USBDEVNAME(sc->sc_dev))); return (error); }
int wi_usb_open_pipes(struct wi_usb_softc *sc) { usbd_status err; int error = 0; struct wi_usb_chain *c; int i; DPRINTFN(10,("%s: %s: enter\n", sc->wi_usb_dev.dv_xname,__func__)); sc->wi_usb_refcnt++; /* Open RX and TX pipes. */ err = usbd_open_pipe(sc->wi_usb_iface, sc->wi_usb_ed[WI_USB_ENDPT_RX], USBD_EXCLUSIVE_USE, &sc->wi_usb_ep[WI_USB_ENDPT_RX]); if (err) { printf("%s: open rx pipe failed: %s\n", sc->wi_usb_dev.dv_xname, usbd_errstr(err)); error = EIO; goto done; } err = usbd_open_pipe(sc->wi_usb_iface, sc->wi_usb_ed[WI_USB_ENDPT_TX], USBD_EXCLUSIVE_USE, &sc->wi_usb_ep[WI_USB_ENDPT_TX]); if (err) { printf("%s: open tx pipe failed: %s\n", sc->wi_usb_dev.dv_xname, usbd_errstr(err)); error = EIO; goto done; } /* is this used? */ err = usbd_open_pipe_intr(sc->wi_usb_iface, sc->wi_usb_ed[WI_USB_ENDPT_INTR], USBD_EXCLUSIVE_USE, &sc->wi_usb_ep[WI_USB_ENDPT_INTR], sc, &sc->wi_usb_ibuf, WI_USB_INTR_PKTLEN, wi_usb_intr, WI_USB_INTR_INTERVAL); if (err) { printf("%s: open intr pipe failed: %s\n", sc->wi_usb_dev.dv_xname, usbd_errstr(err)); error = EIO; goto done; } /* Start up the receive pipe. */ for (i = 0; i < WI_USB_RX_LIST_CNT; i++) { c = &sc->wi_usb_rx_chain[i]; usbd_setup_xfer(c->wi_usb_xfer, sc->wi_usb_ep[WI_USB_ENDPT_RX], c, c->wi_usb_buf, WI_USB_BUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY, USBD_NO_TIMEOUT, wi_usb_rxeof); DPRINTFN(10,("%s: %s: start read\n", sc->wi_usb_dev.dv_xname, __func__)); usbd_transfer(c->wi_usb_xfer); } done: if (--sc->wi_usb_refcnt < 0) usb_detach_wakeup(&sc->wi_usb_dev); return (error); }
int ucomopen(dev_t dev, int flag, int mode, struct proc *p) { int unit = UCOMUNIT(dev); usbd_status err; struct ucom_softc *sc; struct tty *tp; struct termios t; int s; int error; if (unit >= ucom_cd.cd_ndevs) return (ENXIO); sc = ucom_cd.cd_devs[unit]; if (sc == NULL) return (ENXIO); if (sc->sc_dying) return (EIO); if (ISSET(sc->sc_dev.dv_flags, DVF_ACTIVE) == 0) return (ENXIO); /* open the pipes if this is the first open */ ucom_lock(sc); if (sc->sc_open++ == 0) { s = splusb(); DPRINTF(("ucomopen: open pipes in=%d out=%d\n", sc->sc_bulkin_no, sc->sc_bulkout_no)); DPRINTF(("ucomopen: hid %p pipes in=%p out=%p\n", sc->sc_uhidev, sc->sc_ipipe, sc->sc_opipe)); if (sc->sc_bulkin_no != -1) { /* Open the bulk pipes */ err = usbd_open_pipe(sc->sc_iface, sc->sc_bulkin_no, 0, &sc->sc_bulkin_pipe); if (err) { DPRINTF(("%s: open bulk out error (addr %d), err=%s\n", sc->sc_dev.dv_xname, sc->sc_bulkin_no, usbd_errstr(err))); error = EIO; goto fail_0; } err = usbd_open_pipe(sc->sc_iface, sc->sc_bulkout_no, USBD_EXCLUSIVE_USE, &sc->sc_bulkout_pipe); if (err) { DPRINTF(("%s: open bulk in error (addr %d), err=%s\n", sc->sc_dev.dv_xname, sc->sc_bulkout_no, usbd_errstr(err))); error = EIO; goto fail_1; } /* Allocate a request and an input buffer and start reading. */ sc->sc_ixfer = usbd_alloc_xfer(sc->sc_udev); if (sc->sc_ixfer == NULL) { error = ENOMEM; goto fail_2; } sc->sc_ibuf = usbd_alloc_buffer(sc->sc_ixfer, sc->sc_ibufsizepad); if (sc->sc_ibuf == NULL) { error = ENOMEM; goto fail_2; } sc->sc_oxfer = usbd_alloc_xfer(sc->sc_udev); if (sc->sc_oxfer == NULL) { error = ENOMEM; goto fail_3; } } else { /* * input/output pipes and xfers already allocated * as is the input buffer. */ sc->sc_ipipe = sc->sc_uhidev->sc_ipipe; sc->sc_ixfer = sc->sc_uhidev->sc_ixfer; sc->sc_opipe = sc->sc_uhidev->sc_opipe; sc->sc_oxfer = sc->sc_uhidev->sc_oxfer; } sc->sc_obuf = usbd_alloc_buffer(sc->sc_oxfer, sc->sc_obufsize + sc->sc_opkthdrlen); if (sc->sc_obuf == NULL) { error = ENOMEM; goto fail_4; } if (sc->sc_methods->ucom_open != NULL) { error = sc->sc_methods->ucom_open(sc->sc_parent, sc->sc_portno); if (error) { ucom_cleanup(sc); splx(s); ucom_unlock(sc); return (error); } } ucom_status_change(sc); ucomstartread(sc); splx(s); } ucom_unlock(sc); s = spltty(); tp = sc->sc_tty; splx(s); DPRINTF(("ucomopen: unit=%d, tp=%p\n", unit, tp)); tp->t_dev = dev; if (!ISSET(tp->t_state, TS_ISOPEN)) { SET(tp->t_state, TS_WOPEN); ttychars(tp); /* * Initialize the termios status to the defaults. Add in the * sticky bits from TIOCSFLAGS. */ t.c_ispeed = 0; t.c_ospeed = TTYDEF_SPEED; t.c_cflag = TTYDEF_CFLAG; if (ISSET(sc->sc_swflags, TIOCFLAG_CLOCAL)) SET(t.c_cflag, CLOCAL); if (ISSET(sc->sc_swflags, TIOCFLAG_CRTSCTS)) SET(t.c_cflag, CRTSCTS); if (ISSET(sc->sc_swflags, TIOCFLAG_MDMBUF)) SET(t.c_cflag, MDMBUF); /* Make sure ucomparam() will do something. */ tp->t_ospeed = 0; (void) ucomparam(tp, &t); tp->t_iflag = TTYDEF_IFLAG; tp->t_oflag = TTYDEF_OFLAG; tp->t_lflag = TTYDEF_LFLAG; s = spltty(); ttsetwater(tp); /* * Turn on DTR. We must always do this, even if carrier is not * present, because otherwise we'd have to use TIOCSDTR * immediately after setting CLOCAL, which applications do not * expect. We always assert DTR while the device is open * unless explicitly requested to deassert it. */ ucom_dtr(sc, 1); /* XXX CLR(sc->sc_rx_flags, RX_ANY_BLOCK);*/ ucom_hwiflow(sc); if (ISSET(sc->sc_swflags, TIOCFLAG_SOFTCAR) || UCOMCUA(dev) || ISSET(sc->sc_msr, UMSR_DCD) || ISSET(tp->t_cflag, MDMBUF)) SET(tp->t_state, TS_CARR_ON); else CLR(tp->t_state, TS_CARR_ON); } else if (ISSET(tp->t_state, TS_XCLUDE) && p->p_ucred->cr_uid != 0) { error = EBUSY; goto bad; } else s = spltty(); if (UCOMCUA(dev)) { if (ISSET(tp->t_state, TS_ISOPEN)) { /* Someone is already dialed in */ error = EBUSY; goto bad1; } sc->sc_cua = 1; } else { /* tty (not cua) device, wait for carrier */ if (ISSET(flag, O_NONBLOCK)) { if (sc->sc_cua) { error = EBUSY; goto bad1; } } else { while (sc->sc_cua || (!ISSET(tp->t_cflag, CLOCAL) && !ISSET(tp->t_state, TS_CARR_ON))) { SET(tp->t_state, TS_WOPEN); error = ttysleep(tp, &tp->t_rawq, TTIPRI | PCATCH, ttopen, 0); /* * If TS_WOPEN has been reset, that means the * cua device has been closed. We don't want * to fail in that case, so just go around * again. */ if (error && ISSET(tp->t_state, TS_WOPEN)) { CLR(tp->t_state, TS_WOPEN); goto bad1; } } } } splx(s); error = ttyopen(UCOMUNIT(dev), tp); if (error) goto bad; error = (*LINESW(tp, l_open))(dev, tp); if (error) goto bad; return (0); fail_4: if (sc->sc_uhidev == NULL) usbd_free_xfer(sc->sc_oxfer); sc->sc_oxfer = NULL; fail_3: usbd_free_xfer(sc->sc_ixfer); sc->sc_ixfer = NULL; fail_2: usbd_close_pipe(sc->sc_bulkout_pipe); sc->sc_bulkout_pipe = NULL; fail_1: usbd_close_pipe(sc->sc_bulkin_pipe); sc->sc_bulkin_pipe = NULL; fail_0: splx(s); ucom_unlock(sc); return (error); bad1: splx(s); bad: ucom_lock(sc); ucom_cleanup(sc); ucom_unlock(sc); return (error); }
int ugenopen(dev_t dev, int flag, int mode, struct proc *p) { struct ugen_softc *sc; int unit = UGENUNIT(dev); int endpt = UGENENDPOINT(dev); usb_endpoint_descriptor_t *edesc; struct ugen_endpoint *sce; int dir, isize; usbd_status err; struct usbd_xfer *xfer; void *buf; int i, j; if (unit >= ugen_cd.cd_ndevs) return (ENXIO); sc = ugen_cd.cd_devs[unit]; if (sc == NULL) return (ENXIO); DPRINTFN(5, ("ugenopen: flag=%d, mode=%d, unit=%d endpt=%d\n", flag, mode, unit, endpt)); if (sc == NULL || usbd_is_dying(sc->sc_udev)) return (ENXIO); if (sc->sc_is_open[endpt]) return (EBUSY); if (endpt == USB_CONTROL_ENDPOINT) { sc->sc_is_open[USB_CONTROL_ENDPOINT] = 1; return (0); } /* Make sure there are pipes for all directions. */ for (dir = OUT; dir <= IN; dir++) { if (flag & (dir == OUT ? FWRITE : FREAD)) { sce = &sc->sc_endpoints[endpt][dir]; if (sce == 0 || sce->edesc == 0) return (ENXIO); } } /* Actually open the pipes. */ /* XXX Should back out properly if it fails. */ for (dir = OUT; dir <= IN; dir++) { if (!(flag & (dir == OUT ? FWRITE : FREAD))) continue; sce = &sc->sc_endpoints[endpt][dir]; sce->state = 0; sce->timeout = USBD_NO_TIMEOUT; DPRINTFN(5, ("ugenopen: sc=%p, endpt=%d, dir=%d, sce=%p\n", sc, endpt, dir, sce)); edesc = sce->edesc; switch (edesc->bmAttributes & UE_XFERTYPE) { case UE_INTERRUPT: if (dir == OUT) { err = usbd_open_pipe(sce->iface, edesc->bEndpointAddress, 0, &sce->pipeh); if (err) return (EIO); break; } isize = UGETW(edesc->wMaxPacketSize); if (isize == 0) /* shouldn't happen */ return (EINVAL); sce->ibuf = malloc(isize, M_USBDEV, M_WAITOK); DPRINTFN(5, ("ugenopen: intr endpt=%d,isize=%d\n", endpt, isize)); clalloc(&sce->q, UGEN_IBSIZE, 0); err = usbd_open_pipe_intr(sce->iface, edesc->bEndpointAddress, USBD_SHORT_XFER_OK, &sce->pipeh, sce, sce->ibuf, isize, ugenintr, USBD_DEFAULT_INTERVAL); if (err) { free(sce->ibuf, M_USBDEV, 0); clfree(&sce->q); return (EIO); } DPRINTFN(5, ("ugenopen: interrupt open done\n")); break; case UE_BULK: err = usbd_open_pipe(sce->iface, edesc->bEndpointAddress, 0, &sce->pipeh); if (err) return (EIO); break; case UE_ISOCHRONOUS: if (dir == OUT) return (EINVAL); isize = UGETW(edesc->wMaxPacketSize); if (isize == 0) /* shouldn't happen */ return (EINVAL); sce->ibuf = malloc(isize * UGEN_NISOFRAMES, M_USBDEV, M_WAITOK); sce->cur = sce->fill = sce->ibuf; sce->limit = sce->ibuf + isize * UGEN_NISOFRAMES; DPRINTFN(5, ("ugenopen: isoc endpt=%d, isize=%d\n", endpt, isize)); err = usbd_open_pipe(sce->iface, edesc->bEndpointAddress, 0, &sce->pipeh); if (err) { free(sce->ibuf, M_USBDEV, 0); return (EIO); } for(i = 0; i < UGEN_NISOREQS; ++i) { sce->isoreqs[i].sce = sce; xfer = usbd_alloc_xfer(sc->sc_udev); if (xfer == 0) goto bad; sce->isoreqs[i].xfer = xfer; buf = usbd_alloc_buffer (xfer, isize * UGEN_NISORFRMS); if (buf == 0) { i++; goto bad; } sce->isoreqs[i].dmabuf = buf; for(j = 0; j < UGEN_NISORFRMS; ++j) sce->isoreqs[i].sizes[j] = isize; usbd_setup_isoc_xfer (xfer, sce->pipeh, &sce->isoreqs[i], sce->isoreqs[i].sizes, UGEN_NISORFRMS, USBD_NO_COPY, ugen_isoc_rintr); (void)usbd_transfer(xfer); } DPRINTFN(5, ("ugenopen: isoc open done\n")); break; bad: while (--i >= 0) /* implicit buffer free */ usbd_free_xfer(sce->isoreqs[i].xfer); return (ENOMEM); case UE_CONTROL: sce->timeout = USBD_DEFAULT_TIMEOUT; return (EINVAL); } } sc->sc_is_open[endpt] = 1; return (0); }
int ucomopen(dev_t dev, int flag, int mode, struct lwp *l) { int unit = UCOMUNIT(dev); usbd_status err; struct ucom_softc *sc = device_lookup_private(&ucom_cd, unit); struct ucom_buffer *ub; struct tty *tp; int s, i; int error; if (sc == NULL) return (ENXIO); if (sc->sc_dying) return (EIO); if (!device_is_active(sc->sc_dev)) return (ENXIO); tp = sc->sc_tty; DPRINTF(("ucomopen: unit=%d, tp=%p\n", unit, tp)); if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp)) return (EBUSY); s = spltty(); /* * Do the following iff this is a first open. */ while (sc->sc_opening) tsleep(&sc->sc_opening, PRIBIO, "ucomop", 0); if (sc->sc_dying) { splx(s); return (EIO); } sc->sc_opening = 1; if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) { struct termios t; tp->t_dev = dev; if (sc->sc_methods->ucom_open != NULL) { error = sc->sc_methods->ucom_open(sc->sc_parent, sc->sc_portno); if (error) { ucom_cleanup(sc); sc->sc_opening = 0; wakeup(&sc->sc_opening); splx(s); return (error); } } ucom_status_change(sc); /* * Initialize the termios status to the defaults. Add in the * sticky bits from TIOCSFLAGS. */ t.c_ispeed = 0; t.c_ospeed = TTYDEF_SPEED; t.c_cflag = TTYDEF_CFLAG; if (ISSET(sc->sc_swflags, TIOCFLAG_CLOCAL)) SET(t.c_cflag, CLOCAL); if (ISSET(sc->sc_swflags, TIOCFLAG_CRTSCTS)) SET(t.c_cflag, CRTSCTS); if (ISSET(sc->sc_swflags, TIOCFLAG_MDMBUF)) SET(t.c_cflag, MDMBUF); /* Make sure ucomparam() will do something. */ tp->t_ospeed = 0; (void) ucomparam(tp, &t); tp->t_iflag = TTYDEF_IFLAG; tp->t_oflag = TTYDEF_OFLAG; tp->t_lflag = TTYDEF_LFLAG; ttychars(tp); ttsetwater(tp); /* * Turn on DTR. We must always do this, even if carrier is not * present, because otherwise we'd have to use TIOCSDTR * immediately after setting CLOCAL, which applications do not * expect. We always assert DTR while the device is open * unless explicitly requested to deassert it. Ditto RTS. */ ucom_dtr(sc, 1); ucom_rts(sc, 1); DPRINTF(("ucomopen: open pipes in=%d out=%d\n", sc->sc_bulkin_no, sc->sc_bulkout_no)); /* Open the bulk pipes */ err = usbd_open_pipe(sc->sc_iface, sc->sc_bulkin_no, USBD_EXCLUSIVE_USE, &sc->sc_bulkin_pipe); if (err) { DPRINTF(("%s: open bulk in error (addr %d), err=%s\n", USBDEVNAME(sc->sc_dev), sc->sc_bulkin_no, usbd_errstr(err))); error = EIO; goto fail_0; } err = usbd_open_pipe(sc->sc_iface, sc->sc_bulkout_no, USBD_EXCLUSIVE_USE, &sc->sc_bulkout_pipe); if (err) { DPRINTF(("%s: open bulk out error (addr %d), err=%s\n", USBDEVNAME(sc->sc_dev), sc->sc_bulkout_no, usbd_errstr(err))); error = EIO; goto fail_1; } sc->sc_rx_unblock = 0; sc->sc_rx_stopped = 0; sc->sc_tx_stopped = 0; memset(sc->sc_ibuff, 0, sizeof(sc->sc_ibuff)); memset(sc->sc_obuff, 0, sizeof(sc->sc_obuff)); SIMPLEQ_INIT(&sc->sc_ibuff_empty); SIMPLEQ_INIT(&sc->sc_ibuff_full); SIMPLEQ_INIT(&sc->sc_obuff_free); SIMPLEQ_INIT(&sc->sc_obuff_full); /* Allocate input buffers */ for (ub = &sc->sc_ibuff[0]; ub != &sc->sc_ibuff[UCOM_IN_BUFFS]; ub++) { ub->ub_xfer = usbd_alloc_xfer(sc->sc_udev); if (ub->ub_xfer == NULL) { error = ENOMEM; goto fail_2; } ub->ub_data = usbd_alloc_buffer(ub->ub_xfer, sc->sc_ibufsizepad); if (ub->ub_data == NULL) { error = ENOMEM; goto fail_2; } if (ucomsubmitread(sc, ub) != USBD_NORMAL_COMPLETION) { error = EIO; goto fail_2; } } for (ub = &sc->sc_obuff[0]; ub != &sc->sc_obuff[UCOM_OUT_BUFFS]; ub++) { ub->ub_xfer = usbd_alloc_xfer(sc->sc_udev); if (ub->ub_xfer == NULL) { error = ENOMEM; goto fail_2; } ub->ub_data = usbd_alloc_buffer(ub->ub_xfer, sc->sc_obufsize); if (ub->ub_data == NULL) { error = ENOMEM; goto fail_2; } SIMPLEQ_INSERT_TAIL(&sc->sc_obuff_free, ub, ub_link); } } sc->sc_opening = 0; wakeup(&sc->sc_opening); splx(s); error = ttyopen(tp, UCOMDIALOUT(dev), ISSET(flag, O_NONBLOCK)); if (error) goto bad; error = (*tp->t_linesw->l_open)(dev, tp); if (error) goto bad; return (0); fail_2: usbd_abort_pipe(sc->sc_bulkin_pipe); for (i = 0; i < UCOM_IN_BUFFS; i++) { if (sc->sc_ibuff[i].ub_xfer != NULL) { usbd_free_xfer(sc->sc_ibuff[i].ub_xfer); sc->sc_ibuff[i].ub_xfer = NULL; sc->sc_ibuff[i].ub_data = NULL; } } usbd_abort_pipe(sc->sc_bulkout_pipe); for (i = 0; i < UCOM_OUT_BUFFS; i++) { if (sc->sc_obuff[i].ub_xfer != NULL) { usbd_free_xfer(sc->sc_obuff[i].ub_xfer); sc->sc_obuff[i].ub_xfer = NULL; sc->sc_obuff[i].ub_data = NULL; } } usbd_close_pipe(sc->sc_bulkout_pipe); sc->sc_bulkout_pipe = NULL; fail_1: usbd_close_pipe(sc->sc_bulkin_pipe); sc->sc_bulkin_pipe = NULL; fail_0: sc->sc_opening = 0; wakeup(&sc->sc_opening); splx(s); return (error); bad: s = spltty(); CLR(tp->t_state, TS_BUSY); if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) { /* * We failed to open the device, and nobody else had it opened. * Clean up the state as appropriate. */ ucom_cleanup(sc); } splx(s); return (error); }
/* * Init */ static void lgue_init(void *xsc) { struct lgue_softc *sc; struct ifnet *ifp; usbd_status err; sc = xsc; ifp = &sc->lgue_arpcom.ac_if; if (ifp->if_flags & IFF_RUNNING) return; /* Create RX and TX bufs */ if (sc->lgue_tx_xfer == NULL) { sc->lgue_tx_xfer = usbd_alloc_xfer(sc->lgue_udev); if (sc->lgue_tx_xfer == NULL) { if_printf(ifp, "tx buffer allocate failed\n"); return; } } sc->lgue_tx_buf = kmalloc(LGUE_BUFSZ, M_USBDEV, M_WAITOK); if (sc->lgue_rx_xfer == NULL) { sc->lgue_rx_xfer = usbd_alloc_xfer(sc->lgue_udev); if (sc->lgue_rx_xfer == NULL) { if_printf(ifp, "rx buffer allocate failed\n"); return; } } sc->lgue_rx_buf = kmalloc(LGUE_BUFSZ, M_USBDEV, M_WAITOK); /* Create INTR buf */ if (sc->lgue_intr_xfer == NULL) { sc->lgue_intr_xfer = usbd_alloc_xfer(sc->lgue_udev); if (sc->lgue_intr_xfer == NULL) { if_printf(ifp, "intr buffer allocate failed\n"); return; } } sc->lgue_intr_buf = kmalloc(LGUE_BUFSZ, M_USBDEV, M_WAITOK); /* Open RX and TX pipes. */ err = usbd_open_pipe(sc->lgue_data_iface, sc->lgue_ed[LGUE_ENDPT_RX], USBD_EXCLUSIVE_USE, &sc->lgue_ep[LGUE_ENDPT_RX]); if (err) { if_printf(ifp, "open RX pipe failed: %s\n", usbd_errstr(err)); return; } err = usbd_open_pipe(sc->lgue_data_iface, sc->lgue_ed[LGUE_ENDPT_TX], USBD_EXCLUSIVE_USE, &sc->lgue_ep[LGUE_ENDPT_TX]); if (err) { if_printf(ifp, "open TX pipe failed: %s\n", usbd_errstr(err)); return; } /* Open INTR pipe. */ err = usbd_open_pipe(sc->lgue_ctl_iface, sc->lgue_ed[LGUE_ENDPT_INTR], USBD_EXCLUSIVE_USE, &sc->lgue_ep[LGUE_ENDPT_INTR]); if (err) { if_printf(ifp, "open INTR pipe failed: %s\n", usbd_errstr(err)); return; } /* Create internal queue */ STAILQ_INIT(&sc->lgue_tx_queue); ifp->if_flags |= IFF_RUNNING; ifq_clr_oactive(&ifp->if_snd); sc->lgue_dying = 0; lgue_rxstart(ifp); lgue_intrstart(ifp); }
int smsc_init(struct ifnet *ifp) { struct smsc_softc *sc = ifp->if_softc; struct smsc_chain *c; usbd_status err; int s, i; if (sc->sc_dying) return EIO; s = splnet(); /* Cancel pending I/O */ if (ifp->if_flags & IFF_RUNNING) smsc_stop(ifp, 1); /* Reset the ethernet interface. */ smsc_reset(sc); /* Init RX ring. */ if (smsc_rx_list_init(sc) == ENOBUFS) { aprint_error_dev(sc->sc_dev, "rx list init failed\n"); splx(s); return EIO; } /* Init TX ring. */ if (smsc_tx_list_init(sc) == ENOBUFS) { aprint_error_dev(sc->sc_dev, "tx list init failed\n"); splx(s); return EIO; } /* Load the multicast filter. */ smsc_setmulti(sc); /* TCP/UDP checksum offload engines. */ smsc_sethwcsum(sc); /* Open RX and TX pipes. */ err = usbd_open_pipe(sc->sc_iface, sc->sc_ed[SMSC_ENDPT_RX], USBD_EXCLUSIVE_USE, &sc->sc_ep[SMSC_ENDPT_RX]); if (err) { printf("%s: open rx pipe failed: %s\n", device_xname(sc->sc_dev), usbd_errstr(err)); splx(s); return EIO; } err = usbd_open_pipe(sc->sc_iface, sc->sc_ed[SMSC_ENDPT_TX], USBD_EXCLUSIVE_USE, &sc->sc_ep[SMSC_ENDPT_TX]); if (err) { printf("%s: open tx pipe failed: %s\n", device_xname(sc->sc_dev), usbd_errstr(err)); splx(s); return EIO; } /* Start up the receive pipe. */ for (i = 0; i < SMSC_RX_LIST_CNT; i++) { c = &sc->sc_cdata.rx_chain[i]; usbd_setup_xfer(c->sc_xfer, sc->sc_ep[SMSC_ENDPT_RX], c, c->sc_buf, sc->sc_bufsz, USBD_SHORT_XFER_OK | USBD_NO_COPY, USBD_NO_TIMEOUT, smsc_rxeof); usbd_transfer(c->sc_xfer); } /* Indicate we are up and running. */ ifp->if_flags |= IFF_RUNNING; ifp->if_flags &= ~IFF_OACTIVE; splx(s); callout_reset(&sc->sc_stat_ch, hz, smsc_tick, sc); return 0; }
int uhidev_open(struct uhidev *scd) { struct uhidev_softc *sc = scd->sc_parent; usbd_status err; int error; DPRINTF(("uhidev_open: open pipe, state=%d refcnt=%d\n", scd->sc_state, sc->sc_refcnt)); if (scd->sc_state & UHIDEV_OPEN) return (EBUSY); scd->sc_state |= UHIDEV_OPEN; if (sc->sc_refcnt++) return (0); if (sc->sc_isize == 0) return (0); sc->sc_ibuf = malloc(sc->sc_isize, M_USBDEV, M_WAITOK); /* Set up input interrupt pipe. */ DPRINTF(("uhidev_open: isize=%d, ep=0x%02x\n", sc->sc_isize, sc->sc_iep_addr)); err = usbd_open_pipe_intr(sc->sc_iface, sc->sc_iep_addr, USBD_SHORT_XFER_OK, &sc->sc_ipipe, sc, sc->sc_ibuf, sc->sc_isize, uhidev_intr, USBD_DEFAULT_INTERVAL); if (err != USBD_NORMAL_COMPLETION) { DPRINTF(("uhidopen: usbd_open_pipe_intr failed, " "error=%d\n", err)); error = EIO; goto out1; } DPRINTF(("uhidev_open: sc->sc_ipipe=%p\n", sc->sc_ipipe)); sc->sc_ixfer = usbd_alloc_xfer(sc->sc_udev); if (sc->sc_ixfer == NULL) { DPRINTF(("uhidev_open: couldn't allocate an xfer\n")); error = ENOMEM; goto out1; // xxxx } /* * Set up output interrupt pipe if an output interrupt endpoint * exists. */ if (sc->sc_oep_addr != -1) { DPRINTF(("uhidev_open: oep=0x%02x\n", sc->sc_oep_addr)); err = usbd_open_pipe(sc->sc_iface, sc->sc_oep_addr, 0, &sc->sc_opipe); if (err != USBD_NORMAL_COMPLETION) { DPRINTF(("uhidev_open: usbd_open_pipe failed, " "error=%d\n", err)); error = EIO; goto out2; } DPRINTF(("uhidev_open: sc->sc_opipe=%p\n", sc->sc_opipe)); sc->sc_oxfer = usbd_alloc_xfer(sc->sc_udev); if (sc->sc_oxfer == NULL) { DPRINTF(("uhidev_open: couldn't allocate an xfer\n")); error = ENOMEM; goto out3; } sc->sc_owxfer = usbd_alloc_xfer(sc->sc_udev); if (sc->sc_owxfer == NULL) { DPRINTF(("uhidev_open: couldn't allocate owxfer\n")); error = ENOMEM; goto out3; } } return (0); out3: /* Abort output pipe */ usbd_close_pipe(sc->sc_opipe); out2: /* Abort input pipe */ usbd_close_pipe(sc->sc_ipipe); out1: DPRINTF(("uhidev_open: failed in someway")); free(sc->sc_ibuf, M_USBDEV); scd->sc_state &= ~UHIDEV_OPEN; sc->sc_refcnt = 0; sc->sc_ipipe = NULL; sc->sc_opipe = NULL; if (sc->sc_oxfer != NULL) { usbd_free_xfer(sc->sc_oxfer); sc->sc_oxfer = NULL; } if (sc->sc_owxfer != NULL) { usbd_free_xfer(sc->sc_owxfer); sc->sc_owxfer = NULL; } return (error); }
/******************************************************************************* * * Bluetooth Unit/USB callbacks * * All of this will be called at the IPL_ we specified above */ int ubt_enable(struct device *self) { struct ubt_softc *sc = device_get_softc(self); usbd_status err; int i, error; DPRINTFN(1, "%s: sc=%p\n", __func__, sc); if (sc->sc_enabled) return 0; crit_enter(); /* Events */ sc->sc_evt_buf = kmalloc(UBT_BUFSIZ_EVENT, M_USBDEV, M_NOWAIT); if (sc->sc_evt_buf == NULL) { error = ENOMEM; goto bad; } err = usbd_open_pipe_intr(sc->sc_iface0, sc->sc_evt_addr, USBD_SHORT_XFER_OK, &sc->sc_evt_pipe, sc, sc->sc_evt_buf, UBT_BUFSIZ_EVENT, ubt_recv_event, UBT_INTR_TIMEOUT); if (err != USBD_NORMAL_COMPLETION) { error = EIO; kprintf("can't open events pipe_intr\n"); goto bad; } /* Commands */ sc->sc_cmd_xfer = usbd_alloc_xfer(sc->sc_udev); if (sc->sc_cmd_xfer == NULL) { kprintf("can't allocate cmd_xfer\n"); error = ENOMEM; goto bad; } sc->sc_cmd_buf = usbd_alloc_buffer(sc->sc_cmd_xfer, UBT_BUFSIZ_CMD); if (sc->sc_cmd_buf == NULL) { kprintf("can't allocate cmd_buf\n"); error = ENOMEM; goto bad; } sc->sc_cmd_busy = 0; /* ACL read */ err = usbd_open_pipe(sc->sc_iface0, sc->sc_aclrd_addr, USBD_EXCLUSIVE_USE, &sc->sc_aclrd_pipe); if (err != USBD_NORMAL_COMPLETION) { kprintf("can't open aclrd pipe\n"); error = EIO; goto bad; } sc->sc_aclrd_xfer = usbd_alloc_xfer(sc->sc_udev); if (sc->sc_aclrd_xfer == NULL) { kprintf("can't allocate aclrd_xfer\n"); error = ENOMEM; goto bad; } sc->sc_aclrd_buf = usbd_alloc_buffer(sc->sc_aclrd_xfer, UBT_BUFSIZ_ACL); if (sc->sc_aclrd_buf == NULL) { kprintf("can't allocate aclrd_buf\n"); error = ENOMEM; goto bad; } sc->sc_aclrd_busy = 0; ubt_recv_acl_start(sc); /* ACL write */ err = usbd_open_pipe(sc->sc_iface0, sc->sc_aclwr_addr, USBD_EXCLUSIVE_USE, &sc->sc_aclwr_pipe); if (err != USBD_NORMAL_COMPLETION) { kprintf("can't open aclwr pipe\n"); error = EIO; goto bad; } sc->sc_aclwr_xfer = usbd_alloc_xfer(sc->sc_udev); if (sc->sc_aclwr_xfer == NULL) { kprintf("can't allocate aclwr_xfer\n"); error = ENOMEM; goto bad; } sc->sc_aclwr_buf = usbd_alloc_buffer(sc->sc_aclwr_xfer, UBT_BUFSIZ_ACL); if (sc->sc_aclwr_buf == NULL) { kprintf("can't allocate aclwr_buf\n"); error = ENOMEM; goto bad; } sc->sc_aclwr_busy = 0; /* SCO read */ if (sc->sc_scord_size > 0) { err = usbd_open_pipe(sc->sc_iface1, sc->sc_scord_addr, USBD_EXCLUSIVE_USE, &sc->sc_scord_pipe); if (err != USBD_NORMAL_COMPLETION) { error = EIO; goto bad; } for (i = 0 ; i < UBT_NXFERS ; i++) { sc->sc_scord[i].xfer = usbd_alloc_xfer(sc->sc_udev); if (sc->sc_scord[i].xfer == NULL) { error = ENOMEM; goto bad; } sc->sc_scord[i].buf = usbd_alloc_buffer(sc->sc_scord[i].xfer, sc->sc_scord_size * UBT_NFRAMES); if (sc->sc_scord[i].buf == NULL) { error = ENOMEM; goto bad; } sc->sc_scord[i].softc = sc; sc->sc_scord[i].busy = 0; ubt_recv_sco_start1(sc, &sc->sc_scord[i]); } } /* SCO write */ if (sc->sc_scowr_size > 0) { err = usbd_open_pipe(sc->sc_iface1, sc->sc_scowr_addr, USBD_EXCLUSIVE_USE, &sc->sc_scowr_pipe); if (err != USBD_NORMAL_COMPLETION) { error = EIO; goto bad; } for (i = 0 ; i < UBT_NXFERS ; i++) { sc->sc_scowr[i].xfer = usbd_alloc_xfer(sc->sc_udev); if (sc->sc_scowr[i].xfer == NULL) { error = ENOMEM; goto bad; } sc->sc_scowr[i].buf = usbd_alloc_buffer(sc->sc_scowr[i].xfer, sc->sc_scowr_size * UBT_NFRAMES); if (sc->sc_scowr[i].buf == NULL) { error = ENOMEM; goto bad; } sc->sc_scowr[i].softc = sc; sc->sc_scowr[i].busy = 0; } sc->sc_scowr_busy = 0; } sc->sc_enabled = 1; crit_exit(); return 0; bad: ubt_abortdealloc(sc); crit_exit(); return error; }
static int uticom_download_fw(struct uticom_softc *sc, int pipeno, struct usbd_device *dev) { u_char *obuf, *firmware; size_t firmware_size; int buffer_size, pos; uint8_t cs = 0, *buffer; usbd_status err; struct uticom_fw_header *header; struct usbd_xfer *oxfer = 0; usbd_status error = 0; struct usbd_pipe *pipe; error = loadfirmware("tusb3410", &firmware, &firmware_size); if (error) return (error); buffer_size = UTICOM_FW_BUFSZ + sizeof(struct uticom_fw_header); buffer = malloc(buffer_size, M_USBDEV, M_WAITOK | M_CANFAIL); if (!buffer) { printf("%s: uticom_download_fw: out of memory\n", sc->sc_dev.dv_xname); free(firmware, M_DEVBUF); return ENOMEM; } memcpy(buffer, firmware, firmware_size); memset(buffer + firmware_size, 0xff, buffer_size - firmware_size); for (pos = sizeof(struct uticom_fw_header); pos < buffer_size; pos++) cs = (uint8_t)(cs + buffer[pos]); header = (struct uticom_fw_header*)buffer; header->length = (uint16_t)(buffer_size - sizeof(struct uticom_fw_header)); header->checkSum = cs; DPRINTF(("%s: downloading firmware ...\n", sc->sc_dev.dv_xname)); err = usbd_open_pipe(sc->sc_iface, pipeno, USBD_EXCLUSIVE_USE, &pipe); if (err) { printf("%s: open bulk out error (addr %d): %s\n", sc->sc_dev.dv_xname, pipeno, usbd_errstr(err)); error = EIO; goto finish; } oxfer = usbd_alloc_xfer(dev); if (oxfer == NULL) { error = ENOMEM; goto finish; } obuf = usbd_alloc_buffer(oxfer, buffer_size); if (obuf == NULL) { error = ENOMEM; goto finish; } memcpy(obuf, buffer, buffer_size); usbd_setup_xfer(oxfer, pipe, (void *)sc, obuf, buffer_size, USBD_NO_COPY | USBD_SYNCHRONOUS, USBD_NO_TIMEOUT, 0); err = usbd_transfer(oxfer); if (err != USBD_NORMAL_COMPLETION) printf("%s: uticom_download_fw: error: %s\n", sc->sc_dev.dv_xname, usbd_errstr(err)); finish: free(firmware, M_DEVBUF); usbd_free_buffer(oxfer); usbd_free_xfer(oxfer); oxfer = NULL; usbd_abort_pipe(pipe); usbd_close_pipe(pipe); free(buffer, M_USBDEV); return err; }
int uirda_open(void *h, int flag, int mode, struct lwp *l) { struct uirda_softc *sc = h; int error; usbd_status err; DPRINTF(("%s: sc=%p\n", __func__, sc)); err = usbd_open_pipe(sc->sc_iface, sc->sc_rd_addr, 0, &sc->sc_rd_pipe); if (err) { error = EIO; goto bad1; } err = usbd_open_pipe(sc->sc_iface, sc->sc_wr_addr, 0, &sc->sc_wr_pipe); if (err) { error = EIO; goto bad2; } sc->sc_rd_xfer = usbd_alloc_xfer(sc->sc_udev); if (sc->sc_rd_xfer == NULL) { error = ENOMEM; goto bad3; } sc->sc_wr_xfer = usbd_alloc_xfer(sc->sc_udev); if (sc->sc_wr_xfer == NULL) { error = ENOMEM; goto bad4; } sc->sc_rd_buf = usbd_alloc_buffer(sc->sc_rd_xfer, IRDA_MAX_FRAME_SIZE + sc->sc_hdszi); if (sc->sc_rd_buf == NULL) { error = ENOMEM; goto bad5; } sc->sc_wr_buf = usbd_alloc_buffer(sc->sc_wr_xfer, IRDA_MAX_FRAME_SIZE + UIRDA_OUTPUT_HEADER_SIZE + 2 + 1 /* worst case ST-UIRDA */); if (sc->sc_wr_buf == NULL) { error = ENOMEM; goto bad5; } sc->sc_rd_count = 0; sc->sc_rd_err = 0; sc->sc_params.speed = 0; sc->sc_params.ebofs = 0; sc->sc_params.maxsize = IRDA_MAX_FRAME_SIZE; sc->sc_wr_hdr = -1; err = uirda_start_read(sc); /* XXX check err */ return (0); bad5: usbd_free_xfer(sc->sc_wr_xfer); sc->sc_wr_xfer = NULL; bad4: usbd_free_xfer(sc->sc_rd_xfer); sc->sc_rd_xfer = NULL; bad3: usbd_close_pipe(sc->sc_wr_pipe); sc->sc_wr_pipe = NULL; bad2: usbd_close_pipe(sc->sc_rd_pipe); sc->sc_rd_pipe = NULL; bad1: return (error); }
int stuirda_fwload(struct uirda_softc *sc) { int rc; firmware_handle_t fh; off_t fwsize; usb_device_descriptor_t usbddsc; usbd_xfer_handle fwxfer; usbd_pipe_handle fwpipe; usbd_status status; usb_device_request_t req; char *buffer; char *p; char fwname[12]; int n; u_int8_t *usbbuf; /* size_t bsize; */ printf("%s: needing to download firmware\n", device_xname(sc->sc_dev)); status = usbd_get_device_desc(sc->sc_udev, &usbddsc); if (status) { printf("%s: can't get device descriptor, status %d\n", device_xname(sc->sc_dev), status); return status; } rc = usbd_get_class_desc(sc->sc_udev, UDESC_IRDA, 0, USB_IRDA_DESCRIPTOR_SIZE, &sc->sc_irdadesc); printf("error %d reading class desc\n", rc); snprintf(fwname, sizeof(fwname), "4210%02x%02x.sb", usbddsc.bcdDevice[1], usbddsc.bcdDevice[0]); printf("%s: Attempting to load firmware %s\n", device_xname(sc->sc_dev), fwname); rc = firmware_open("stuirda", fwname, &fh); if (rc) { printf("%s: Cannot load firmware\n", device_xname(sc->sc_dev)); return rc; } fwsize = firmware_get_size(fh); printf("%s: Firmware size %lld\n", device_xname(sc->sc_dev), (long long)fwsize); buffer = firmware_malloc(fwsize); if (buffer == NULL) { printf("%s: Cannot load firmware: out of memory\n", device_xname(sc->sc_dev)); goto giveup2; } rc = firmware_read(fh, 0, buffer, (size_t)fwsize); if (rc) { printf("%s: Cannot read firmware\n", device_xname(sc->sc_dev)); goto giveup3; } for (p = buffer + sizeof("Product Version:"); p < buffer + fwsize - 5; p++) { if (0x1A == *p) break; } if (0x1a != *p || memcmp(p+1, "STMP", 4) != 0) { /* firmware bad */ printf("%s: Bad firmware\n", device_xname(sc->sc_dev)); goto giveup3; } p += 5; req.bmRequestType = UT_WRITE_VENDOR_DEVICE; req.bRequest = 2 /* XXX magic */; USETW(req.wValue, 0); USETW(req.wIndex, 0); USETW(req.wLength, 0); rc = usbd_do_request(sc->sc_udev, &req, 0); if (rc) { printf("%s: Cannot switch to f/w d/l mode, error %d\n", device_xname(sc->sc_dev), rc); goto giveup3; } delay(100000); rc = usbd_open_pipe(sc->sc_iface, sc->sc_wr_addr, 0, &fwpipe); if (rc) { printf("%s: Cannot open pipe, rc=%d\n", device_xname(sc->sc_dev), rc); goto giveup3; } fwxfer = usbd_alloc_xfer(sc->sc_udev); if (fwxfer == NULL) { printf("%s: Cannot alloc xfer\n", device_xname(sc->sc_dev)); goto giveup4; } usbbuf = usbd_alloc_buffer(fwxfer, 1024); if (usbbuf == NULL) { printf("%s: Cannot alloc usb buf\n", device_xname(sc->sc_dev)); goto giveup5; } n = (buffer + fwsize - p); while (n > 0) { if (n > 1023) n = 1023; memcpy(usbbuf, p, n); rc = usbd_bulk_transfer(fwxfer, fwpipe, USBD_SYNCHRONOUS|USBD_FORCE_SHORT_XFER, 5000, usbbuf, &n, "uirda-fw-wr"); printf("%s: write: rc=%d, %d left\n", device_xname(sc->sc_dev), rc, n); if (rc) { printf("%s: write: rc=%d, %d bytes written\n", device_xname(sc->sc_dev), rc, n); goto giveup4; } printf("%s: written %d\n", device_xname(sc->sc_dev), n); p += n; n = (buffer + fwsize - p); } delay(100000); /* TODO: more code here */ rc = 0; usbd_free_buffer(fwxfer); giveup5: usbd_free_xfer(fwxfer); giveup4: usbd_close_pipe(fwpipe); giveup3: firmware_free(buffer, fwsize); giveup2: firmware_close(fh); return rc; }
Static int url_openpipes(struct url_softc *sc) { struct url_chain *c; usbd_status err; int i; int error = 0; if (sc->sc_dying) return (EIO); sc->sc_refcnt++; /* Open RX pipe */ err = usbd_open_pipe(sc->sc_ctl_iface, sc->sc_bulkin_no, USBD_EXCLUSIVE_USE, &sc->sc_pipe_rx); if (err) { printf("%s: open rx pipe failed: %s\n", USBDEVNAME(sc->sc_dev), usbd_errstr(err)); error = EIO; goto done; } /* Open TX pipe */ err = usbd_open_pipe(sc->sc_ctl_iface, sc->sc_bulkout_no, USBD_EXCLUSIVE_USE, &sc->sc_pipe_tx); if (err) { printf("%s: open tx pipe failed: %s\n", USBDEVNAME(sc->sc_dev), usbd_errstr(err)); error = EIO; goto done; } #if 0 /* XXX: interrupt endpoint is not yet supported */ /* Open Interrupt pipe */ err = usbd_open_pipe_intr(sc->sc_ctl_iface, sc->sc_intrin_no, USBD_EXCLUSIVE_USE, &sc->sc_pipe_intr, sc, &sc->sc_cdata.url_ibuf, URL_INTR_PKGLEN, url_intr, URL_INTR_INTERVAL); if (err) { printf("%s: open intr pipe failed: %s\n", USBDEVNAME(sc->sc_dev), usbd_errstr(err)); error = EIO; goto done; } #endif /* Start up the receive pipe. */ for (i = 0; i < URL_RX_LIST_CNT; i++) { c = &sc->sc_cdata.url_rx_chain[i]; usbd_setup_xfer(c->url_xfer, sc->sc_pipe_rx, c, c->url_buf, URL_BUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY, USBD_NO_TIMEOUT, url_rxeof); (void)usbd_transfer(c->url_xfer); DPRINTF(("%s: %s: start read\n", USBDEVNAME(sc->sc_dev), __func__)); } done: if (--sc->sc_refcnt < 0) usb_detach_wakeup(USBDEV(sc->sc_dev)); return (error); }
int uscanneropen(dev_t dev, int flag, int mode, struct lwp *l) { struct uscanner_softc *sc; int unit = USCANNERUNIT(dev); usbd_status err; sc = device_lookup_private(&uscanner_cd, unit); if (sc == NULL) return ENXIO; DPRINTFN(5, ("uscanneropen: flag=%d, mode=%d, unit=%d\n", flag, mode, unit)); if (sc->sc_dying) return (ENXIO); if (sc->sc_state & USCANNER_OPEN) return (EBUSY); sc->sc_state |= USCANNER_OPEN; sc->sc_bulkin_buffer = malloc(USCANNER_BUFFERSIZE, M_USBDEV, M_WAITOK); sc->sc_bulkout_buffer = malloc(USCANNER_BUFFERSIZE, M_USBDEV, M_WAITOK); /* No need to check buffers for NULL since we have WAITOK */ sc->sc_bulkin_bufferlen = USCANNER_BUFFERSIZE; sc->sc_bulkout_bufferlen = USCANNER_BUFFERSIZE; /* We have decided on which endpoints to use, now open the pipes */ if (sc->sc_bulkin_pipe == NULL) { err = usbd_open_pipe(sc->sc_iface, sc->sc_bulkin, USBD_EXCLUSIVE_USE, &sc->sc_bulkin_pipe); if (err) { printf("%s: cannot open bulk-in pipe (addr %d)\n", device_xname(sc->sc_dev), sc->sc_bulkin); uscanner_do_close(sc); return (EIO); } } if (sc->sc_bulkout_pipe == NULL) { err = usbd_open_pipe(sc->sc_iface, sc->sc_bulkout, USBD_EXCLUSIVE_USE, &sc->sc_bulkout_pipe); if (err) { printf("%s: cannot open bulk-out pipe (addr %d)\n", device_xname(sc->sc_dev), sc->sc_bulkout); uscanner_do_close(sc); return (EIO); } } sc->sc_bulkin_xfer = usbd_alloc_xfer(sc->sc_udev); if (sc->sc_bulkin_xfer == NULL) { uscanner_do_close(sc); return (ENOMEM); } sc->sc_bulkout_xfer = usbd_alloc_xfer(sc->sc_udev); if (sc->sc_bulkout_xfer == NULL) { uscanner_do_close(sc); return (ENOMEM); } return (0); /* success */ }
usbd_status umsm_umass_changemode(struct umsm_softc *sc) { #define UMASS_CMD_REZERO_UNIT 0x01 #define UMASS_CMD_START_STOP 0x1b #define UMASS_CMDPARAM_EJECT 0x02 #define UMASS_SERVICE_ACTION_OUT 0x9f usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; struct usbd_xfer *xfer; struct usbd_pipe *cmdpipe; usbd_status err; u_int32_t n; void *bufp; int target_ep, i; struct umass_bbb_cbw cbw; static int dCBWTag = 0x12345678; USETDW(cbw.dCBWSignature, CBWSIGNATURE); USETDW(cbw.dCBWTag, dCBWTag); cbw.bCBWLUN = 0; cbw.bCDBLength= 6; bzero(cbw.CBWCDB, sizeof(cbw.CBWCDB)); switch (sc->sc_flag) { case DEV_UMASS1: USETDW(cbw.dCBWDataTransferLength, 0x0); cbw.bCBWFlags = CBWFLAGS_OUT; cbw.CBWCDB[0] = UMASS_CMD_REZERO_UNIT; cbw.CBWCDB[1] = 0x0; /* target LUN: 0 */ break; case DEV_UMASS2: USETDW(cbw.dCBWDataTransferLength, 0x1); cbw.bCBWFlags = CBWFLAGS_IN; cbw.CBWCDB[0] = UMASS_CMD_REZERO_UNIT; cbw.CBWCDB[1] = 0x0; /* target LUN: 0 */ break; case DEV_UMASS3: /* longcheer */ USETDW(cbw.dCBWDataTransferLength, 0x80); cbw.bCBWFlags = CBWFLAGS_IN; cbw.CBWCDB[0] = 0x06; cbw.CBWCDB[1] = 0xf5; cbw.CBWCDB[2] = 0x04; cbw.CBWCDB[3] = 0x02; cbw.CBWCDB[4] = 0x52; cbw.CBWCDB[5] = 0x70; break; case DEV_UMASS4: USETDW(cbw.dCBWDataTransferLength, 0x0); cbw.bCBWFlags = CBWFLAGS_OUT; cbw.CBWCDB[0] = UMASS_CMD_START_STOP; cbw.CBWCDB[1] = 0x00; /* target LUN: 0 */ cbw.CBWCDB[4] = UMASS_CMDPARAM_EJECT; break; case DEV_UMASS5: cbw.bCBWFlags = CBWFLAGS_OUT; cbw.CBWCDB[0] = 0x11; cbw.CBWCDB[1] = 0x06; break; case DEV_UMASS6: /* ZTE */ USETDW(cbw.dCBWDataTransferLength, 0x20); cbw.bCBWFlags = CBWFLAGS_IN; cbw.bCDBLength= 12; cbw.CBWCDB[0] = 0x85; cbw.CBWCDB[1] = 0x01; cbw.CBWCDB[2] = 0x01; cbw.CBWCDB[3] = 0x01; cbw.CBWCDB[4] = 0x18; cbw.CBWCDB[5] = 0x01; cbw.CBWCDB[6] = 0x01; cbw.CBWCDB[7] = 0x01; cbw.CBWCDB[8] = 0x01; cbw.CBWCDB[9] = 0x01; break; case DEV_UMASS7: /* ZTE */ USETDW(cbw.dCBWDataTransferLength, 0xc0); cbw.bCBWFlags = CBWFLAGS_IN; cbw.CBWCDB[0] = UMASS_SERVICE_ACTION_OUT; cbw.CBWCDB[1] = 0x03; break; case DEV_UMASS8: USETDW(cbw.dCBWDataTransferLength, 0x0); cbw.bCBWFlags = CBWFLAGS_OUT; cbw.CBWCDB[0] = 0xf0; cbw.CBWCDB[1] = 0x01; cbw.CBWCDB[2] = 0x03; break; default: DPRINTF(("%s: unknown device type.\n", sc->sc_dev.dv_xname)); break; } /* get command endpoint address */ id = usbd_get_interface_descriptor(sc->sc_iface); for (i = 0; i < id->bNumEndpoints; i++) { ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i); if (ed == NULL) { return (USBD_IOERROR); } if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) target_ep = ed->bEndpointAddress; } /* open command endppoint */ err = usbd_open_pipe(sc->sc_iface, target_ep, USBD_EXCLUSIVE_USE, &cmdpipe); if (err) { DPRINTF(("%s: open pipe for modem change cmd failed: %s\n", sc->sc_dev.dv_xname, usbd_errstr(err))); return (err); } xfer = usbd_alloc_xfer(sc->sc_udev); if (xfer == NULL) { usbd_close_pipe(cmdpipe); return (USBD_NOMEM); } else { bufp = usbd_alloc_buffer(xfer, UMASS_BBB_CBW_SIZE); if (bufp == NULL) err = USBD_NOMEM; else { n = UMASS_BBB_CBW_SIZE; memcpy(bufp, &cbw, UMASS_BBB_CBW_SIZE); usbd_setup_xfer(xfer, cmdpipe, 0, bufp, n, USBD_NO_COPY | USBD_SYNCHRONOUS, 0, NULL); err = usbd_transfer(xfer); if (err) { usbd_clear_endpoint_stall(cmdpipe); DPRINTF(("%s: send error:%s", __func__, usbd_errstr(err))); } } usbd_close_pipe(cmdpipe); usbd_free_buffer(xfer); usbd_free_xfer(xfer); } return (err); }