usbd_status uirda_start_read(struct uirda_softc *sc) { usbd_status err; DPRINTFN(1,("%s: sc=%p, size=%d\n", __func__, sc, sc->sc_params.maxsize + UIRDA_INPUT_HEADER_SIZE)); if (sc->sc_dying) return (USBD_IOERROR); if (sc->sc_rd_err) { sc->sc_rd_err = 0; DPRINTF(("uirda_start_read: clear stall\n")); usbd_clear_endpoint_stall(sc->sc_rd_pipe); } usbd_setup_xfer(sc->sc_rd_xfer, sc->sc_rd_pipe, sc, sc->sc_rd_buf, sc->sc_params.maxsize + sc->sc_hdszi, USBD_SHORT_XFER_OK | USBD_NO_COPY, USBD_NO_TIMEOUT, uirda_rd_cb); err = usbd_transfer(sc->sc_rd_xfer); if (err != USBD_IN_PROGRESS) { DPRINTF(("uirda_start_read: err=%d\n", err)); return (err); } return (USBD_NORMAL_COMPLETION); }
/* * End of sending */ static void lgue_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) { struct ifnet *ifp; struct lgue_softc *sc; usbd_status err; sc = priv; if (sc->lgue_dying) return; ifp = &sc->lgue_arpcom.ac_if; if (status != USBD_NORMAL_COMPLETION) { if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) return; if (status == USBD_STALLED) usbd_clear_endpoint_stall(sc->lgue_ep[LGUE_ENDPT_TX]); return; } usbd_get_xfer_status(sc->lgue_tx_xfer, NULL, NULL, NULL,&err); if (err) ifp->if_oerrors++; else ifp->if_opackets++; if (!STAILQ_EMPTY(&sc->lgue_tx_queue)) { lgue_start_schedule(ifp); } ifp->if_timer = 0; ifp->if_flags &= ~IFF_OACTIVE; }
usbd_status usbd_intr_transfer(usbd_xfer_handle xfer, usbd_pipe_handle pipe, u_int16_t flags, u_int32_t timeout, void *buf, u_int32_t *size, const char *lbl) { usbd_status err; USBHIST_FUNC(); USBHIST_CALLED(usbdebug); usbd_setup_xfer(xfer, pipe, 0, buf, *size, flags, timeout, NULL); DPRINTFN(1, ("usbd_intr_transfer: start transfer %d bytes\n", *size)); err = usbd_sync_transfer_sig(xfer); usbd_get_xfer_status(xfer, NULL, NULL, size, NULL); DPRINTFN(1,("usbd_intr_transfer: transferred %d\n", *size)); if (err) { DPRINTF(("usbd_intr_transfer: error=%d\n", err)); usbd_clear_endpoint_stall(pipe); } USBHIST_LOG(usbdebug, "<- done err %d", xfer, err, 0, 0); return (err); }
int uriowrite(dev_t dev, struct uio *uio, int flag) { struct urio_softc *sc; struct usbd_xfer *xfer; usbd_status err; void *bufp; u_int32_t n; int error = 0; sc = urio_cd.cd_devs[URIOUNIT(dev)]; DPRINTFN(5, ("uriowrite: unit=%d, len=%ld\n", URIOUNIT(dev), (long)uio->uio_resid)); if (usbd_is_dying(sc->sc_udev)) return (EIO); xfer = usbd_alloc_xfer(sc->sc_udev); if (xfer == NULL) return (ENOMEM); bufp = usbd_alloc_buffer(xfer, URIO_BSIZE); if (bufp == NULL) { usbd_free_xfer(xfer); return (ENOMEM); } sc->sc_refcnt++; while ((n = min(URIO_BSIZE, uio->uio_resid)) != 0) { error = uiomove(bufp, n, uio); if (error) break; DPRINTFN(1, ("uriowrite: transfer %d bytes\n", n)); usbd_setup_xfer(xfer, sc->sc_out_pipe, 0, bufp, n, USBD_NO_COPY | USBD_SYNCHRONOUS, URIO_RW_TIMEOUT, NULL); err = usbd_transfer(xfer); DPRINTFN(2, ("uriowrite: err=%d\n", err)); if (err) { usbd_clear_endpoint_stall(sc->sc_out_pipe); if (err == USBD_TIMEOUT) error = ETIMEDOUT; else error = EIO; break; } } usbd_free_xfer(xfer); if (--sc->sc_refcnt < 0) usb_detach_wakeup(&sc->sc_dev); DPRINTFN(5, ("uriowrite: done unit=%d, error=%d\n", URIOUNIT(dev), error)); return (error); }
/* * INTR arrived */ static void lgue_intreof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) { struct ifnet *ifp; struct lgue_softc *sc; sc = priv; if (sc->lgue_dying) return; ifp = &sc->lgue_arpcom.ac_if; lwkt_serialize_enter(ifp->if_serializer); if (status != USBD_NORMAL_COMPLETION) { if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) { lwkt_serialize_exit(ifp->if_serializer); return; } if_printf(ifp, "usb error on intr: %s\n", usbd_errstr(status)); if (status == USBD_STALLED) usbd_clear_endpoint_stall(sc->lgue_ep[LGUE_ENDPT_INTR]); lwkt_serialize_exit(ifp->if_serializer); return; } lgue_intrstart(ifp); lwkt_serialize_exit(ifp->if_serializer); }
/* * End of sending */ static void lgue_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) { struct ifnet *ifp; struct lgue_softc *sc; usbd_status err; sc = priv; if (sc->lgue_dying) return; ifp = &sc->lgue_arpcom.ac_if; if (status != USBD_NORMAL_COMPLETION) { if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) return; if (status == USBD_STALLED) usbd_clear_endpoint_stall(sc->lgue_ep[LGUE_ENDPT_TX]); return; } usbd_get_xfer_status(sc->lgue_tx_xfer, NULL, NULL, NULL,&err); if (err) IFNET_STAT_INC(ifp, oerrors, 1); else IFNET_STAT_INC(ifp, opackets, 1); if (!STAILQ_EMPTY(&sc->lgue_tx_queue)) { if_devstart_sched(ifp); } ifp->if_timer = 0; ifq_clr_oactive(&ifp->if_snd); }
usbd_status uhidev_write(struct uhidev_softc *sc, void *data, int len) { usbd_status error; DPRINTF(("uhidev_write: data=%p, len=%d\n", data, len)); if (sc->sc_opipe == NULL) return USBD_INVAL; #ifdef UHIDEV_DEBUG if (uhidevdebug > 50) { u_int32_t i; u_int8_t *d = data; DPRINTF(("uhidev_write: data =")); for (i = 0; i < len; i++) DPRINTF((" %02x", d[i])); DPRINTF(("\n")); } #endif usbd_setup_xfer(sc->sc_owxfer, sc->sc_opipe, 0, data, len, USBD_SYNCHRONOUS | USBD_CATCH, 0, NULL); error = usbd_transfer(sc->sc_owxfer); if (error) usbd_clear_endpoint_stall(sc->sc_opipe); return (error); }
usbd_status usbd_intr_transfer(usbd_xfer_handle xfer, usbd_pipe_handle pipe, u_int16_t flags, u_int32_t timeout, void *buf, u_int32_t *size, char *lbl) { usbd_status err; int s, error; usbd_setup_xfer(xfer, pipe, 0, buf, *size, flags, timeout, usbd_intr_transfer_cb); DPRINTFN(1, ("usbd_intr_transfer: start transfer %d bytes\n", *size)); s = splusb(); /* don't want callback until tsleep() */ err = usbd_transfer(xfer); if (err != USBD_IN_PROGRESS) { splx(s); return (err); } error = tsleep(xfer, PZERO | PCATCH, lbl, 0); splx(s); if (error) { DPRINTF(("usbd_intr_transfer: tsleep=%d\n", error)); usbd_abort_pipe(pipe); return (USBD_INTERRUPTED); } usbd_get_xfer_status(xfer, NULL, NULL, size, &err); DPRINTFN(1,("usbd_intr_transfer: transferred %d\n", *size)); if (err) { DPRINTF(("usbd_intr_transfer: error=%d\n", err)); usbd_clear_endpoint_stall(pipe); } return (err); }
/* * A frame has been uploaded: pass the resulting mbuf up to * the higher level protocols. */ static void lgue_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) { struct lgue_softc *sc; struct mbuf *m; struct ifnet *ifp; int total_len; sc = priv; if (sc->lgue_dying) return; ifp = &sc->lgue_arpcom.ac_if; total_len = 0; if (!(ifp->if_flags & IFF_RUNNING)) return; if (status != USBD_NORMAL_COMPLETION) { if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) return; if (usbd_ratecheck(&sc->lgue_rx_notice)) { if_printf(ifp, "usb error on rx:%s\n", usbd_errstr(status)); } if (status == USBD_STALLED) usbd_clear_endpoint_stall(sc->lgue_ep[LGUE_ENDPT_RX]); goto done; } usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL); if (total_len < sizeof(struct ether_header)) { IFNET_STAT_INC(ifp, ierrors, 1); goto done; } if (lgue_newbuf(sc, total_len, &m) == ENOBUFS) { IFNET_STAT_INC(ifp, ierrors, 1); return; } IFNET_STAT_INC(ifp, ipackets, 1); m_copyback(m, 0, total_len, sc->lgue_rx_buf); m->m_pkthdr.rcvif = ifp; m->m_pkthdr.len = m->m_len = total_len; usb_ether_input(m); lgue_rxstart(ifp); return; done: usbd_setup_xfer(sc->lgue_rx_xfer, sc->lgue_ep[LGUE_ENDPT_RX], sc, sc->lgue_rx_buf, LGUE_BUFSZ, USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, lgue_rxeof); usbd_transfer(sc->lgue_rx_xfer); }
Static void cdce_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) { struct ue_chain *c = priv; struct cdce_softc *sc = c->ue_sc; struct ifnet *ifp; usbd_status err; CDCE_LOCK(sc); ifp = GET_IFP(sc); if (sc->cdce_dying || !(ifp->if_flags & IFF_RUNNING)) { CDCE_UNLOCK(sc); return; } if (status != USBD_NORMAL_COMPLETION) { if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) { CDCE_UNLOCK(sc); return; } ifp->if_oerrors++; printf("%s: usb error on tx: %s\n", USBDEVNAME(sc->cdce_dev), usbd_errstr(status)); if (status == USBD_STALLED) usbd_clear_endpoint_stall(sc->cdce_bulkout_pipe); CDCE_UNLOCK(sc); return; } ifp->if_flags &= ~IFF_OACTIVE; usbd_get_xfer_status(c->ue_xfer, NULL, NULL, NULL, &err); if (c->ue_mbuf != NULL) { c->ue_mbuf->m_pkthdr.rcvif = ifp; usb_tx_done(c->ue_mbuf); c->ue_mbuf = NULL; } if (err) ifp->if_oerrors++; else ifp->if_opackets++; CDCE_UNLOCK(sc); return; }
Static void url_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) { struct url_chain *c = priv; struct url_softc *sc = c->url_sc; struct ifnet *ifp = GET_IFP(sc); int s; if (sc->sc_dying) return; s = splnet(); DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__)); ifp->if_timer = 0; ifp->if_flags &= ~IFF_OACTIVE; if (status != USBD_NORMAL_COMPLETION) { if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) { splx(s); return; } ifp->if_oerrors++; printf("%s: usb error on tx: %s\n", USBDEVNAME(sc->sc_dev), usbd_errstr(status)); if (status == USBD_STALLED) { sc->sc_refcnt++; usbd_clear_endpoint_stall(sc->sc_pipe_tx); if (--sc->sc_refcnt < 0) usb_detach_wakeup(USBDEV(sc->sc_dev)); } splx(s); return; } ifp->if_opackets++; m_freem(c->url_mbuf); c->url_mbuf = NULL; if (IFQ_IS_EMPTY(&ifp->if_snd) == 0) url_start(ifp); splx(s); }
Static void kue_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) { struct kue_chain *c = priv; struct kue_softc *sc = c->kue_sc; struct ifnet *ifp = GET_IFP(sc); int s; if (sc->kue_dying) return; s = splnet(); DPRINTFN(10,("%s: %s: enter status=%d\n", USBDEVNAME(sc->kue_dev), __func__, status)); ifp->if_timer = 0; ifp->if_flags &= ~IFF_OACTIVE; if (status != USBD_NORMAL_COMPLETION) { if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) { splx(s); return; } ifp->if_oerrors++; printf("%s: usb error on tx: %s\n", USBDEVNAME(sc->kue_dev), usbd_errstr(status)); if (status == USBD_STALLED) usbd_clear_endpoint_stall(sc->kue_ep[KUE_ENDPT_TX]); splx(s); return; } ifp->if_opackets++; m_freem(c->kue_mbuf); c->kue_mbuf = NULL; if (IFQ_IS_EMPTY(&ifp->if_snd) == 0) kue_start(ifp); splx(s); }
/*ARGSUSED*/ static void u3g_set(void *arg, int portno, int reg, int onoff) { struct u3g_softc *sc = arg; usb_device_request_t req; uint16_t mask, new_state; usbd_status err; if (sc->sc_dying) return; switch (reg) { case UCOM_SET_DTR: mask = U3G_OUTPIN_DTR; break; case UCOM_SET_RTS: mask = U3G_OUTPIN_RTS; break; default: return; } new_state = sc->sc_outpins & ~mask; if (onoff) new_state |= mask; if (new_state == sc->sc_outpins) return; sc->sc_outpins = new_state; req.bmRequestType = UT_WRITE_CLASS_INTERFACE; req.bRequest = U3G_SET_PIN; USETW(req.wValue, new_state); USETW(req.wIndex, sc->sc_ifaceno); USETW(req.wLength, 0); err = usbd_do_request(sc->sc_udev, &req, 0); if (err == USBD_STALLED) usbd_clear_endpoint_stall(sc->sc_udev->default_pipe); }
usbd_status usbd_bulk_transfer(struct usbd_xfer *xfer, struct usbd_pipe *pipe, uint16_t flags, uint32_t timeout, void *buf, uint32_t *size) { usbd_status err; USBHIST_FUNC(); USBHIST_CALLED(usbdebug); usbd_setup_xfer(xfer, 0, buf, *size, flags, timeout, NULL); DPRINTFN(1, "start transfer %d bytes", *size, 0, 0, 0); err = usbd_sync_transfer_sig(xfer); usbd_get_xfer_status(xfer, NULL, NULL, size, NULL); DPRINTFN(1, "transferred %d", *size, 0, 0, 0); if (err) { usbd_clear_endpoint_stall(pipe); } USBHIST_LOG(usbdebug, "<- done xfer %p err %d", xfer, err, 0, 0); return err; }
static usbd_status udsir_start_read(struct udsir_softc *sc) { usbd_status err; DPRINTFN(60, ("%s: sc=%p, size=%d\n", __func__, sc, sc->sc_rd_maxpsz)); if (sc->sc_dying) return USBD_IOERROR; if (UDSIR_BLOCK_RX_DATA(sc) || deframe_rd_ur(sc)) { /* * Can't start reading just yet. Since we aren't * going to start a read, have to switch direction to * idle. */ sc->sc_direction = udir_idle; return USBD_NORMAL_COMPLETION; } /* Starting a read... */ sc->sc_rd_readinprogress = 1; sc->sc_direction = udir_input; if (sc->sc_rd_err) { sc->sc_rd_err = 0; DPRINTFN(0, ("%s: clear stall\n", __func__)); usbd_clear_endpoint_stall(sc->sc_rd_pipe); } usbd_setup_xfer(sc->sc_rd_xfer, sc->sc_rd_pipe, sc, sc->sc_rd_buf, sc->sc_rd_maxpsz, USBD_SHORT_XFER_OK | USBD_NO_COPY, USBD_NO_TIMEOUT, udsir_rd_cb); err = usbd_transfer(sc->sc_rd_xfer); if (err != USBD_IN_PROGRESS) { DPRINTFN(0, ("%s: err=%d\n", __func__, (int)err)); return err; } return USBD_NORMAL_COMPLETION; }
int ugen_do_read(struct ugen_softc *sc, int endpt, struct uio *uio, int flag) { struct ugen_endpoint *sce = &sc->sc_endpoints[endpt][IN]; u_int32_t n, tn; char buf[UGEN_BBSIZE]; struct usbd_xfer *xfer; usbd_status err; int s; int flags, error = 0; u_char buffer[UGEN_CHUNK]; DPRINTFN(5, ("%s: ugenread: %d\n", sc->sc_dev.dv_xname, endpt)); if (usbd_is_dying(sc->sc_udev)) return (EIO); if (endpt == USB_CONTROL_ENDPOINT) return (ENODEV); #ifdef DIAGNOSTIC if (sce->edesc == NULL) { printf("ugenread: no edesc\n"); return (EIO); } if (sce->pipeh == NULL) { printf("ugenread: no pipe\n"); return (EIO); } #endif switch (sce->edesc->bmAttributes & UE_XFERTYPE) { case UE_INTERRUPT: /* Block until activity occurred. */ s = splusb(); while (sce->q.c_cc == 0) { if (flag & IO_NDELAY) { splx(s); return (EWOULDBLOCK); } sce->state |= UGEN_ASLP; DPRINTFN(5, ("ugenread: sleep on %p\n", sce)); error = tsleep(sce, PZERO | PCATCH, "ugenri", (sce->timeout * hz) / 1000); sce->state &= ~UGEN_ASLP; DPRINTFN(5, ("ugenread: woke, error=%d\n", error)); if (usbd_is_dying(sc->sc_udev)) error = EIO; if (error == EWOULDBLOCK) { /* timeout, return 0 */ error = 0; break; } if (error) break; } splx(s); /* Transfer as many chunks as possible. */ while (sce->q.c_cc > 0 && uio->uio_resid > 0 && !error) { n = min(sce->q.c_cc, uio->uio_resid); if (n > sizeof(buffer)) n = sizeof(buffer); /* Remove a small chunk from the input queue. */ q_to_b(&sce->q, buffer, n); DPRINTFN(5, ("ugenread: got %d chars\n", n)); /* Copy the data to the user process. */ error = uiomove(buffer, n, uio); if (error) break; } break; case UE_BULK: xfer = usbd_alloc_xfer(sc->sc_udev); if (xfer == 0) return (ENOMEM); flags = USBD_SYNCHRONOUS; if (sce->state & UGEN_SHORT_OK) flags |= USBD_SHORT_XFER_OK; if (sce->timeout == 0) flags |= USBD_CATCH; while ((n = min(UGEN_BBSIZE, uio->uio_resid)) != 0) { DPRINTFN(1, ("ugenread: start transfer %d bytes\n",n)); usbd_setup_xfer(xfer, sce->pipeh, 0, buf, n, flags, sce->timeout, NULL); err = usbd_transfer(xfer); if (err) { usbd_clear_endpoint_stall(sce->pipeh); if (err == USBD_INTERRUPTED) error = EINTR; else if (err == USBD_TIMEOUT) error = ETIMEDOUT; else error = EIO; break; } usbd_get_xfer_status(xfer, NULL, NULL, &tn, NULL); DPRINTFN(1, ("ugenread: got %d bytes\n", tn)); error = uiomove(buf, tn, uio); if (error || tn < n) break; } usbd_free_xfer(xfer); break; case UE_ISOCHRONOUS: s = splusb(); while (sce->cur == sce->fill) { if (flag & IO_NDELAY) { splx(s); return (EWOULDBLOCK); } sce->state |= UGEN_ASLP; DPRINTFN(5, ("ugenread: sleep on %p\n", sce)); error = tsleep(sce, PZERO | PCATCH, "ugenri", (sce->timeout * hz) / 1000); sce->state &= ~UGEN_ASLP; DPRINTFN(5, ("ugenread: woke, error=%d\n", error)); if (usbd_is_dying(sc->sc_udev)) error = EIO; if (error == EWOULDBLOCK) { /* timeout, return 0 */ error = 0; break; } if (error) break; } while (sce->cur != sce->fill && uio->uio_resid > 0 && !error) { if(sce->fill > sce->cur) n = min(sce->fill - sce->cur, uio->uio_resid); else n = min(sce->limit - sce->cur, uio->uio_resid); DPRINTFN(5, ("ugenread: isoc got %d chars\n", n)); /* Copy the data to the user process. */ error = uiomove(sce->cur, n, uio); if (error) break; sce->cur += n; if(sce->cur >= sce->limit) sce->cur = sce->ibuf; } splx(s); break; default: return (ENXIO); } return (error); }
int ugen_do_write(struct ugen_softc *sc, int endpt, struct uio *uio, int flag) { struct ugen_endpoint *sce = &sc->sc_endpoints[endpt][OUT]; u_int32_t n; int flags, error = 0; char buf[UGEN_BBSIZE]; struct usbd_xfer *xfer; usbd_status err; DPRINTFN(5, ("%s: ugenwrite: %d\n", sc->sc_dev.dv_xname, endpt)); if (usbd_is_dying(sc->sc_udev)) return (EIO); if (endpt == USB_CONTROL_ENDPOINT) return (ENODEV); #ifdef DIAGNOSTIC if (sce->edesc == NULL) { printf("ugenwrite: no edesc\n"); return (EIO); } if (sce->pipeh == NULL) { printf("ugenwrite: no pipe\n"); return (EIO); } #endif flags = USBD_SYNCHRONOUS; if (sce->timeout == 0) flags |= USBD_CATCH; switch (sce->edesc->bmAttributes & UE_XFERTYPE) { case UE_BULK: xfer = usbd_alloc_xfer(sc->sc_udev); if (xfer == 0) return (EIO); while ((n = min(UGEN_BBSIZE, uio->uio_resid)) != 0) { error = uiomove(buf, n, uio); if (error) break; DPRINTFN(1, ("ugenwrite: transfer %d bytes\n", n)); usbd_setup_xfer(xfer, sce->pipeh, 0, buf, n, flags, sce->timeout, NULL); err = usbd_transfer(xfer); if (err) { usbd_clear_endpoint_stall(sce->pipeh); if (err == USBD_INTERRUPTED) error = EINTR; else if (err == USBD_TIMEOUT) error = ETIMEDOUT; else error = EIO; break; } } usbd_free_xfer(xfer); break; case UE_INTERRUPT: xfer = usbd_alloc_xfer(sc->sc_udev); if (xfer == 0) return (EIO); while ((n = min(UGETW(sce->edesc->wMaxPacketSize), uio->uio_resid)) != 0) { error = uiomove(buf, n, uio); if (error) break; DPRINTFN(1, ("ugenwrite: transfer %d bytes\n", n)); usbd_setup_xfer(xfer, sce->pipeh, 0, buf, n, flags, sce->timeout, NULL); err = usbd_transfer(xfer); if (err) { usbd_clear_endpoint_stall(sce->pipeh); if (err == USBD_INTERRUPTED) error = EINTR; else if (err == USBD_TIMEOUT) error = ETIMEDOUT; else error = EIO; break; } } usbd_free_xfer(xfer); break; default: return (ENXIO); } return (error); }
int uirda_set_params(void *h, struct irda_params *p) { struct uirda_softc *sc = h; usbd_status err; int i; u_int8_t hdr; u_int32_t n; u_int mask; DPRINTF(("%s: sc=%p, speed=%d ebofs=%d maxsize=%d\n", __func__, sc, p->speed, p->ebofs, p->maxsize)); if (sc->sc_dying) return (EIO); hdr = 0; if (p->ebofs != sc->sc_params.ebofs) { /* round up ebofs */ mask = 1 /* sc->sc_irdadesc.bmAdditionalBOFs*/; DPRINTF(("u.s.p.: mask=0x%x, sc->ebofs=%d, p->ebofs=%d\n", mask, sc->sc_params.ebofs, p->ebofs)); for (i = 0; i < UIRDA_NEBOFS; i++) { DPRINTF(("u.s.p.: u_e[%d].mask=0x%x, count=%d\n", i, uirda_ebofs[i].mask, uirda_ebofs[i].count)); if ((mask & uirda_ebofs[i].mask) && uirda_ebofs[i].count >= p->ebofs) { hdr = uirda_ebofs[i].header; goto found1; } } for (i = 0; i < UIRDA_NEBOFS; i++) { DPRINTF(("u.s.p.: u_e[%d].mask=0x%x, count=%d\n", i, uirda_ebofs[i].mask, uirda_ebofs[i].count)); if ((mask & uirda_ebofs[i].mask)) { hdr = uirda_ebofs[i].header; goto found1; } } /* no good value found */ return (EINVAL); found1: DPRINTF(("uirda_set_params: ebofs hdr=0x%02x\n", hdr)); ; } if (hdr != 0 || p->speed != sc->sc_params.speed) { /* find speed */ mask = UGETW(sc->sc_irdadesc.wBaudRate); for (i = 0; i < UIRDA_NSPEEDS; i++) { if ((mask & uirda_speeds[i].mask) && uirda_speeds[i].speed == p->speed) { hdr |= uirda_speeds[i].header; goto found2; } } /* no good value found */ return (EINVAL); found2: DPRINTF(("uirda_set_params: speed hdr=0x%02x\n", hdr)); ; } if (p->maxsize != sc->sc_params.maxsize) { if (p->maxsize > IRDA_MAX_FRAME_SIZE) return (EINVAL); sc->sc_params.maxsize = p->maxsize; #if 0 DPRINTF(("%s: new buffers, old size=%d\n", __func__, sc->sc_params.maxsize)); if (p->maxsize > 10000 || p < 0) /* XXX */ return (EINVAL); /* Change the write buffer */ mutex_enter(&sc->sc_wr_buf_lk); if (sc->sc_wr_buf != NULL) usbd_free_buffer(sc->sc_wr_xfer); sc->sc_wr_buf = usbd_alloc_buffer(sc->sc_wr_xfer, p->maxsize+1); mutex_exit(&sc->sc_wr_buf_lk); if (sc->sc_wr_buf == NULL) return (ENOMEM); /* Change the read buffer */ mutex_enter(&sc->sc_rd_buf_lk); usbd_abort_pipe(sc->sc_rd_pipe); if (sc->sc_rd_buf != NULL) usbd_free_buffer(sc->sc_rd_xfer); sc->sc_rd_buf = usbd_alloc_buffer(sc->sc_rd_xfer, p->maxsize+1); sc->sc_rd_count = 0; if (sc->sc_rd_buf == NULL) { mutex_exit(&sc->sc_rd_buf_lk); return (ENOMEM); } sc->sc_params.maxsize = p->maxsize; err = uirda_start_read(sc); /* XXX check */ mutex_exit(&sc->sc_rd_buf_lk); #endif } if (hdr != 0 && hdr != sc->sc_wr_hdr) { /* * A change has occurred, transmit a 0 length frame with * the new settings. The 0 length frame is not sent to the * device. */ DPRINTF(("%s: sc=%p setting header 0x%02x\n", __func__, sc, hdr)); sc->sc_wr_hdr = hdr; mutex_enter(&sc->sc_wr_buf_lk); sc->sc_wr_buf[0] = hdr; n = UIRDA_OUTPUT_HEADER_SIZE; err = usbd_bulk_transfer(sc->sc_wr_xfer, sc->sc_wr_pipe, USBD_FORCE_SHORT_XFER | USBD_NO_COPY, UIRDA_WR_TIMEOUT, sc->sc_wr_buf, &n, "uirdast"); if (err) { aprint_error_dev(sc->sc_dev, "set failed, err=%d\n", err); usbd_clear_endpoint_stall(sc->sc_wr_pipe); } mutex_exit(&sc->sc_wr_buf_lk); } sc->sc_params = *p; return (0); }
Static void cdce_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) { struct ue_chain *c = priv; struct cdce_softc *sc = c->ue_sc; struct ifnet *ifp; struct mbuf *m; int total_len = 0; CDCE_LOCK(sc); ifp = GET_IFP(sc); if (sc->cdce_dying || !(ifp->if_flags & IFF_RUNNING)) { CDCE_UNLOCK(sc); return; } if (status != USBD_NORMAL_COMPLETION) { if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) { CDCE_UNLOCK(sc); return; } if (sc->cdce_rxeof_errors == 0) printf("%s: usb error on rx: %s\n", USBDEVNAME(sc->cdce_dev), usbd_errstr(status)); if (status == USBD_STALLED) usbd_clear_endpoint_stall(sc->cdce_bulkin_pipe); DELAY(sc->cdce_rxeof_errors * 10000); sc->cdce_rxeof_errors++; goto done; } sc->cdce_rxeof_errors = 0; usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL); if (sc->cdce_flags & CDCE_ZAURUS) total_len -= 4; /* Strip off CRC added by Zaurus */ m = c->ue_mbuf; if (total_len < sizeof(struct ether_header)) { ifp->if_ierrors++; goto done; } ifp->if_ipackets++; m->m_pkthdr.rcvif = (struct ifnet *)&sc->q; m->m_pkthdr.len = m->m_len = total_len; /* Put the packet on the special USB input queue. */ usb_ether_input(m); CDCE_UNLOCK(sc); return; done: /* Setup new transfer. */ 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); CDCE_UNLOCK(sc); return; }
int uriowrite(struct dev_write_args *ap) { cdev_t dev = ap->a_head.a_dev; struct uio *uio = ap->a_uio; #if (USBDI >= 1) struct urio_softc * sc; usbd_xfer_handle reqh; #else usbd_request_handle reqh; #endif int unit = URIOUNIT(dev); usbd_status r; char buf[URIO_BBSIZE]; u_int32_t n; int error = 0; sc = devclass_get_softc(urio_devclass, unit); DPRINTFN(5, ("uriowrite: %d\n", unit)); if (!sc->sc_opened) return EIO; #if (USBDI >= 1) sc->sc_refcnt++; reqh = usbd_alloc_xfer(sc->sc_udev); #else reqh = usbd_alloc_request(); #endif if (reqh == 0) return EIO; while ((n = szmin(URIO_BBSIZE, uio->uio_resid)) != 0) { error = uiomove(buf, n, uio); if (error) break; DPRINTFN(1, ("uriowrite: transfer %d bytes\n", n)); #if (USBDI >= 1) usbd_setup_xfer(reqh, sc->sc_pipeh_out, 0, buf, n, 0, RIO_RW_TIMEOUT, 0); #else r = usbd_setup_request(reqh, sc->sc_pipeh_out, 0, buf, n, 0, RIO_RW_TIMEOUT, 0); if (r != USBD_NORMAL_COMPLETION) { error = EIO; break; } #endif r = usbd_sync_transfer(reqh); if (r != USBD_NORMAL_COMPLETION) { DPRINTFN(1, ("uriowrite: error=%d\n", r)); usbd_clear_endpoint_stall(sc->sc_pipeh_out); error = EIO; break; } #if (USBDI >= 1) usbd_get_xfer_status(reqh, 0, 0, 0, 0); #endif } #if (USBDI >= 1) usbd_free_xfer(reqh); #else usbd_free_request(reqh); #endif return error; }
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); }
int uhid_do_read(struct uhid_softc *sc, struct uio *uio, int flag) { int s; int error = 0; size_t length; u_char buffer[UHID_CHUNK]; usbd_status err; DPRINTFN(1, ("uhidread\n")); if (sc->sc_state & UHID_IMMED) { DPRINTFN(1, ("uhidread immed\n")); err = usbd_get_report(sc->sc_iface, UHID_INPUT_REPORT, sc->sc_iid, buffer, sc->sc_isize); if (err) return (EIO); return (uiomove(buffer, sc->sc_isize, uio)); } s = splusb(); while (sc->sc_q.c_cc == 0) { if (flag & IO_NDELAY) { splx(s); return (EWOULDBLOCK); } sc->sc_state |= UHID_ASLP; DPRINTFN(5, ("uhidread: sleep on %p\n", &sc->sc_q)); error = tsleep(&sc->sc_q, PZERO | PCATCH, "uhidrea", 0); DPRINTFN(5, ("uhidread: woke, error=%d\n", error)); if (sc->sc_dying) error = EIO; if (error) { sc->sc_state &= ~UHID_ASLP; break; } if (sc->sc_state & UHID_NEEDCLEAR) { DPRINTFN(-1,("uhidread: clearing stall\n")); sc->sc_state &= ~UHID_NEEDCLEAR; usbd_clear_endpoint_stall(sc->sc_intrpipe); } } splx(s); /* Transfer as many chunks as possible. */ while (sc->sc_q.c_cc > 0 && uio->uio_resid > 0 && !error) { length = min(sc->sc_q.c_cc, uio->uio_resid); if (length > sizeof(buffer)) length = sizeof(buffer); /* Remove a small chunk from the input queue. */ (void) q_to_b(&sc->sc_q, buffer, length); DPRINTFN(5, ("uhidread: got %lu chars\n", (u_long)length)); /* Copy the data to the user process. */ if ((error = uiomove(buffer, length, uio)) != 0) break; } return (error); }
Static void url_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) { struct url_chain *c = priv; struct url_softc *sc = c->url_sc; struct ifnet *ifp = GET_IFP(sc); struct mbuf *m; u_int32_t total_len; url_rxhdr_t rxhdr; int s; DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev),__func__)); if (sc->sc_dying) return; if (status != USBD_NORMAL_COMPLETION) { if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) return; sc->sc_rx_errs++; if (usbd_ratecheck(&sc->sc_rx_notice)) { printf("%s: %u usb errors on rx: %s\n", USBDEVNAME(sc->sc_dev), sc->sc_rx_errs, usbd_errstr(status)); sc->sc_rx_errs = 0; } if (status == USBD_STALLED) { sc->sc_refcnt++; usbd_clear_endpoint_stall(sc->sc_pipe_rx); if (--sc->sc_refcnt < 0) usb_detach_wakeup(USBDEV(sc->sc_dev)); } goto done; } usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL); memcpy(mtod(c->url_mbuf, char *), c->url_buf, total_len); if (total_len <= ETHER_CRC_LEN) { ifp->if_ierrors++; goto done; } memcpy(&rxhdr, c->url_buf + total_len - ETHER_CRC_LEN, sizeof(rxhdr)); DPRINTF(("%s: RX Status: %dbytes%s%s%s%s packets\n", USBDEVNAME(sc->sc_dev), UGETW(rxhdr) & URL_RXHDR_BYTEC_MASK, UGETW(rxhdr) & URL_RXHDR_VALID_MASK ? ", Valid" : "", UGETW(rxhdr) & URL_RXHDR_RUNTPKT_MASK ? ", Runt" : "", UGETW(rxhdr) & URL_RXHDR_PHYPKT_MASK ? ", Physical match" : "", UGETW(rxhdr) & URL_RXHDR_MCASTPKT_MASK ? ", Multicast" : "")); if ((UGETW(rxhdr) & URL_RXHDR_VALID_MASK) == 0) { ifp->if_ierrors++; goto done; } ifp->if_ipackets++; total_len -= ETHER_CRC_LEN; m = c->url_mbuf; m->m_pkthdr.len = m->m_len = total_len; m->m_pkthdr.rcvif = ifp; s = splnet(); if (url_newbuf(sc, c, NULL) == ENOBUFS) { ifp->if_ierrors++; goto done1; } #if NBPFILTER > 0 if (ifp->if_bpf) BPF_MTAP(ifp, m); #endif DPRINTF(("%s: %s: deliver %d\n", USBDEVNAME(sc->sc_dev), __func__, m->m_len)); IF_INPUT(ifp, m); done1: splx(s); done: /* Setup new transfer */ usbd_setup_xfer(xfer, sc->sc_pipe_rx, c, c->url_buf, URL_BUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY, USBD_NO_TIMEOUT, url_rxeof); sc->sc_refcnt++; usbd_transfer(xfer); if (--sc->sc_refcnt < 0) usb_detach_wakeup(USBDEV(sc->sc_dev)); DPRINTF(("%s: %s: start rx\n", USBDEVNAME(sc->sc_dev), __func__)); }
/* * A frame has been uploaded: pass the resulting mbuf chain up to * the higher level protocols. */ Static void kue_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) { struct kue_chain *c = priv; struct kue_softc *sc = c->kue_sc; struct ifnet *ifp = GET_IFP(sc); struct mbuf *m; int total_len = 0; int s; DPRINTFN(10,("%s: %s: enter status=%d\n", USBDEVNAME(sc->kue_dev), __func__, status)); if (sc->kue_dying) return; if (!(ifp->if_flags & IFF_RUNNING)) return; if (status != USBD_NORMAL_COMPLETION) { if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) return; sc->kue_rx_errs++; if (usbd_ratecheck(&sc->kue_rx_notice)) { printf("%s: %u usb errors on rx: %s\n", USBDEVNAME(sc->kue_dev), sc->kue_rx_errs, usbd_errstr(status)); sc->kue_rx_errs = 0; } if (status == USBD_STALLED) usbd_clear_endpoint_stall(sc->kue_ep[KUE_ENDPT_RX]); goto done; } usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL); DPRINTFN(10,("%s: %s: total_len=%d len=%d\n", USBDEVNAME(sc->kue_dev), __func__, total_len, UGETW(mtod(c->kue_mbuf, u_int8_t *)))); if (total_len <= 1) goto done; m = c->kue_mbuf; /* copy data to mbuf */ memcpy(mtod(m, char *), c->kue_buf, total_len); /* No errors; receive the packet. */ total_len = UGETW(mtod(m, u_int8_t *)); m_adj(m, sizeof(u_int16_t)); if (total_len < sizeof(struct ether_header)) { ifp->if_ierrors++; goto done; } ifp->if_ipackets++; m->m_pkthdr.len = m->m_len = total_len; m->m_pkthdr.rcvif = ifp; s = splnet(); /* XXX ugly */ if (kue_newbuf(sc, c, NULL) == ENOBUFS) { ifp->if_ierrors++; goto done1; } #if NBPFILTER > 0 /* * Handle BPF listeners. Let the BPF user see the packet, but * don't pass it up to the ether_input() layer unless it's * a broadcast packet, multicast packet, matches our ethernet * address or the interface is in promiscuous mode. */ if (ifp->if_bpf) bpf_mtap(ifp->if_bpf, m); #endif DPRINTFN(10,("%s: %s: deliver %d\n", USBDEVNAME(sc->kue_dev), __func__, m->m_len)); IF_INPUT(ifp, m); done1: splx(s); done: /* Setup new transfer. */ 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); usbd_transfer(c->kue_xfer); DPRINTFN(10,("%s: %s: start rx\n", USBDEVNAME(sc->kue_dev), __func__)); }