int uriowrite(dev_t dev, struct uio *uio, int flag) { struct urio_softc *sc; usbd_xfer_handle xfer; usbd_status err; void *bufp; u_int32_t n; int error = 0; sc = device_lookup_private(&urio_cd, URIOUNIT(dev)); DPRINTFN(5, ("uriowrite: unit=%d, len=%ld\n", URIOUNIT(dev), (long)uio->uio_resid)); if (sc->sc_dying) 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)); err = usbd_bulk_transfer(xfer, sc->sc_out_pipe, USBD_NO_COPY, URIO_RW_TIMEOUT, bufp, &n, "uriowr"); DPRINTFN(2, ("uriowrite: err=%d\n", err)); if (err) { if (err == USBD_INTERRUPTED) error = EINTR; else if (err == USBD_TIMEOUT) error = ETIMEDOUT; else error = EIO; break; } } usbd_free_xfer(xfer); if (--sc->sc_refcnt < 0) usb_detach_wakeupold(sc->sc_dev); DPRINTFN(5, ("uriowrite: done unit=%d, error=%d\n", URIOUNIT(dev), error)); return (error); }
int stuirda_write(void *h, struct uio *uio, int flag) { struct uirda_softc *sc = h; usbd_status err; u_int32_t n; int error = 0; DPRINTFN(1,("%s: sc=%p\n", __func__, sc)); if (sc->sc_dying) return (EIO); #ifdef DIAGNOSTIC if (sc->sc_wr_buf == NULL) return (EINVAL); #endif n = uio->uio_resid; if (n > sc->sc_params.maxsize) return (EINVAL); sc->sc_refcnt++; mutex_enter(&sc->sc_wr_buf_lk); sc->sc_wr_buf[0] = UIRDA_EB_NO_CHANGE | UIRDA_NO_SPEED; sc->sc_wr_buf[1] = 0; sc->sc_wr_buf[2] = 7; /* XXX turnaround - maximum for now */ if ((n > 0 && (n % 128) == 0 && (n % 512) != 0)) { sc->sc_wr_buf[1] = 1; } error = uiomove(sc->sc_wr_buf + STUIRDA_HEADER_SIZE, n, uio); if (!error) { DPRINTFN(1, ("uirdawrite: transfer %d bytes\n", n)); n += STUIRDA_HEADER_SIZE + sc->sc_wr_buf[1]; 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, "uirdawr"); DPRINTFN(2, ("uirdawrite: err=%d\n", err)); if (err) { if (err == USBD_INTERRUPTED) error = EINTR; else if (err == USBD_TIMEOUT) error = ETIMEDOUT; else error = EIO; } } mutex_exit(&sc->sc_wr_buf_lk); if (--sc->sc_refcnt < 0) usb_detach_wakeupold(sc->sc_dev); DPRINTFN(1,("%s: sc=%p done\n", __func__, sc)); return (error); }
int umass_atapi_attach(struct umass_softc *sc) { struct umass_scsipi_softc *scbus; scbus = umass_scsipi_setup(sc); scbus->sc_atapi_adapter.atapi_probe_device = umass_atapi_probe_device; scbus->sc_channel.chan_bustype = &umass_atapi_bustype; scbus->sc_channel.chan_ntargets = 2; scbus->sc_channel.chan_nluns = 1; scbus->sc_channel.chan_defquirks |= sc->sc_busquirks; DPRINTF(UDMASS_USB, ("%s: umass_attach_bus: ATAPI\n", device_xname(sc->sc_dev))); sc->sc_refcnt++; scbus->base.sc_child = config_found_ia(sc->sc_dev, "atapi", &scbus->sc_channel, atapiprint); if (--sc->sc_refcnt < 0) usb_detach_wakeupold(sc->sc_dev); return (0); }
int urioread(dev_t dev, struct uio *uio, int flag) { struct urio_softc *sc; usbd_xfer_handle xfer; usbd_status err; void *bufp; u_int32_t n, tn; int error = 0; sc = device_lookup_private(&urio_cd, URIOUNIT(dev)); DPRINTFN(5, ("urioread: %d\n", URIOUNIT(dev))); if (sc->sc_dying) 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) { DPRINTFN(1, ("urioread: start transfer %d bytes\n", n)); tn = n; err = usbd_bulk_transfer(xfer, sc->sc_in_pipe, USBD_NO_COPY, URIO_RW_TIMEOUT, bufp, &tn, "uriors"); if (err) { if (err == USBD_INTERRUPTED) error = EINTR; else if (err == USBD_TIMEOUT) error = ETIMEDOUT; else error = EIO; break; } DPRINTFN(1, ("urioread: got %d bytes\n", tn)); error = uiomove(bufp, tn, uio); if (error || tn < n) break; } usbd_free_xfer(xfer); if (--sc->sc_refcnt < 0) usb_detach_wakeupold(sc->sc_dev); return (error); }
Static void url_unlock_mii(struct url_softc *sc) { DPRINTFN(0xff, ("%s: %s: enter\n", device_xname(sc->sc_dev), __func__)); rw_exit(&sc->sc_mii_rwlock); if (--sc->sc_refcnt < 0) usb_detach_wakeupold(sc->sc_dev); }
/* ARGSUSED */ static int udsir_close(void *h, int flag, int mode, struct lwp *l) { struct udsir_softc *sc = h; DPRINTFN(0, ("%s: sc=%p\n", __func__, sc)); sc->sc_refcnt++; sc->sc_rd_readinprogress = 1; sc->sc_closing = 1; wakeup(&sc->sc_thread); while (sc->sc_thread != NULL) tsleep(&sc->sc_closing, PWAIT, "usircl", 0); if (sc->sc_rd_pipe != NULL) { usbd_abort_pipe(sc->sc_rd_pipe); } if (sc->sc_wr_pipe != NULL) { usbd_abort_pipe(sc->sc_wr_pipe); } if (sc->sc_rd_xfer != NULL) { usbd_destroy_xfer(sc->sc_rd_xfer); sc->sc_rd_xfer = NULL; sc->sc_rd_buf = NULL; } if (sc->sc_wr_xfer != NULL) { usbd_destroy_xfer(sc->sc_wr_xfer); sc->sc_wr_xfer = NULL; sc->sc_wr_buf = NULL; } if (sc->sc_rd_pipe != NULL) { usbd_close_pipe(sc->sc_rd_pipe); sc->sc_rd_pipe = NULL; } if (sc->sc_wr_pipe != NULL) { usbd_close_pipe(sc->sc_wr_pipe); sc->sc_wr_pipe = NULL; } if (sc->sc_ur_buf != NULL) { kmem_free(sc->sc_ur_buf, IRDA_MAX_FRAME_SIZE); sc->sc_ur_buf = NULL; } if (--sc->sc_refcnt < 0) usb_detach_wakeupold(sc->sc_dev); return 0; }
int uscannerwrite(dev_t dev, struct uio *uio, int flag) { struct uscanner_softc *sc; int error; sc = device_lookup_private(&uscanner_cd, USCANNERUNIT(dev)); sc->sc_refcnt++; error = uscanner_do_write(sc, uio, flag); if (--sc->sc_refcnt < 0) usb_detach_wakeupold(sc->sc_dev); return (error); }
int ucomioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l) { struct ucom_softc *sc = device_lookup_private(&ucom_cd, UCOMUNIT(dev)); int error; if (sc == NULL || sc->sc_dying) return (EIO); sc->sc_refcnt++; error = ucom_do_ioctl(sc, cmd, data, flag, l); if (--sc->sc_refcnt < 0) usb_detach_wakeupold(sc->sc_dev); return (error); }
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", device_xname(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", device_xname(sc->sc_dev), usbd_errstr(status)); if (status == USBD_STALLED) { sc->sc_refcnt++; usbd_clear_endpoint_stall_async(sc->sc_pipe_tx); if (--sc->sc_refcnt < 0) usb_detach_wakeupold(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 int url_send(struct url_softc *sc, struct mbuf *m, int idx) { int total_len; struct url_chain *c; usbd_status err; DPRINTF(("%s: %s: enter\n", device_xname(sc->sc_dev),__func__)); c = &sc->sc_cdata.url_tx_chain[idx]; /* Copy the mbuf data into a contiguous buffer */ m_copydata(m, 0, m->m_pkthdr.len, c->url_buf); c->url_mbuf = m; total_len = m->m_pkthdr.len; if (total_len < URL_MIN_FRAME_LEN) { memset(c->url_buf + total_len, 0, URL_MIN_FRAME_LEN - total_len); total_len = URL_MIN_FRAME_LEN; } usbd_setup_xfer(c->url_xfer, sc->sc_pipe_tx, c, c->url_buf, total_len, USBD_FORCE_SHORT_XFER | USBD_NO_COPY, URL_TX_TIMEOUT, url_txeof); /* Transmit */ sc->sc_refcnt++; err = usbd_transfer(c->url_xfer); if (--sc->sc_refcnt < 0) usb_detach_wakeupold(sc->sc_dev); if (err != USBD_IN_PROGRESS) { printf("%s: url_send error=%s\n", device_xname(sc->sc_dev), usbd_errstr(err)); /* Stop the interface */ usb_add_task(sc->sc_udev, &sc->sc_stop_task, USB_TASKQ_DRIVER); return (EIO); } DPRINTF(("%s: %s: send %d bytes\n", device_xname(sc->sc_dev), __func__, total_len)); sc->sc_cdata.url_tx_cnt++; return (0); }
int ucomwrite(dev_t dev, struct uio *uio, int flag) { struct ucom_softc *sc = device_lookup_private(&ucom_cd, UCOMUNIT(dev)); struct tty *tp; int error; if (sc == NULL || sc->sc_dying) return (EIO); tp = sc->sc_tty; sc->sc_refcnt++; error = ((*tp->t_linesw->l_write)(tp, uio, flag)); if (--sc->sc_refcnt < 0) usb_detach_wakeupold(sc->sc_dev); return (error); }
int ucompoll(dev_t dev, int events, struct lwp *l) { struct ucom_softc *sc; struct tty *tp; int revents; sc = device_lookup_private(&ucom_cd, UCOMUNIT(dev)); if (sc == NULL || sc->sc_dying) return (POLLHUP); tp = sc->sc_tty; sc->sc_refcnt++; revents = ((*tp->t_linesw->l_poll)(tp, events, l)); if (--sc->sc_refcnt < 0) usb_detach_wakeupold(sc->sc_dev); return (revents); }
int ucomclose(dev_t dev, int flag, int mode, struct lwp *l) { struct ucom_softc *sc = device_lookup_private(&ucom_cd, UCOMUNIT(dev)); struct tty *tp; int s; DPRINTF(("ucomclose: unit=%d\n", UCOMUNIT(dev))); if (sc == NULL) return 0; tp = sc->sc_tty; if (!ISSET(tp->t_state, TS_ISOPEN)) return (0); s = spltty(); sc->sc_refcnt++; (*tp->t_linesw->l_close)(tp, flag); ttyclose(tp); if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) { /* * Although we got a last close, the device may still be in * use; e.g. if this was the dialout node, and there are still * processes waiting for carrier on the non-dialout node. */ ucom_cleanup(sc); } if (sc->sc_methods->ucom_close != NULL) sc->sc_methods->ucom_close(sc->sc_parent, sc->sc_portno); if (--sc->sc_refcnt < 0) usb_detach_wakeupold(sc->sc_dev); splx(s); return (0); }
int umass_scsi_attach(struct umass_softc *sc) { struct umass_scsipi_softc *scbus; scbus = umass_scsipi_setup(sc); scbus->sc_channel.chan_bustype = &scsi_bustype; scbus->sc_channel.chan_ntargets = 2; scbus->sc_channel.chan_nluns = sc->maxlun + 1; scbus->sc_channel.chan_id = scbus->sc_channel.chan_ntargets - 1; DPRINTF(UDMASS_USB, ("%s: umass_attach_bus: SCSI\n", device_xname(sc->sc_dev))); sc->sc_refcnt++; scbus->base.sc_child = config_found_ia(sc->sc_dev, "scsi", &scbus->sc_channel, scsiprint); if (--sc->sc_refcnt < 0) usb_detach_wakeupold(sc->sc_dev); return (0); }
static void udsir_thread(void *arg) { struct udsir_softc *sc = arg; int error; DPRINTFN(20, ("%s: starting polling thread\n", __func__)); while (!sc->sc_closing) { if (!sc->sc_rd_readinprogress && !UDSIR_BLOCK_RX_DATA(sc)) udsir_periodic(sc); if (!sc->sc_closing) { error = tsleep(&sc->sc_thread, PWAIT, "udsir", hz / 10); if (error == EWOULDBLOCK && sc->sc_rd_expectdataticks > 0) /* * After a timeout decrement the tick * counter within which time we expect * data to arrive if we are receiving * data... */ sc->sc_rd_expectdataticks--; } } DPRINTFN(20, ("%s: exiting polling thread\n", __func__)); sc->sc_thread = NULL; wakeup(&sc->sc_closing); if (--sc->sc_refcnt < 0) usb_detach_wakeupold(sc->sc_dev); kthread_exit(0); }
/* read/write memory */ Static int url_mem(struct url_softc *sc, int cmd, int offset, void *buf, int len) { usb_device_request_t req; usbd_status err; if (sc == NULL) return (0); DPRINTFN(0x200, ("%s: %s: enter\n", device_xname(sc->sc_dev), __func__)); if (sc->sc_dying) return (0); if (cmd == URL_CMD_READMEM) req.bmRequestType = UT_READ_VENDOR_DEVICE; else req.bmRequestType = UT_WRITE_VENDOR_DEVICE; req.bRequest = URL_REQ_MEM; USETW(req.wValue, offset); USETW(req.wIndex, 0x0000); USETW(req.wLength, len); sc->sc_refcnt++; err = usbd_do_request(sc->sc_udev, &req, buf); if (--sc->sc_refcnt < 0) usb_detach_wakeupold(sc->sc_dev); if (err) { DPRINTF(("%s: url_mem(): %s failed. off=%04x, err=%d\n", device_xname(sc->sc_dev), cmd == URL_CMD_READMEM ? "read" : "write", offset, err)); } return (err); }
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", device_xname(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", device_xname(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, USBD_DEFAULT_INTERVAL); if (err) { printf("%s: open intr pipe failed: %s\n", device_xname(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", device_xname(sc->sc_dev), __func__)); } done: if (--sc->sc_refcnt < 0) usb_detach_wakeupold(sc->sc_dev); return (error); }
/* ARGSUSED */ static int udsir_write(void *h, struct uio *uio, int flag) { struct udsir_softc *sc = h; usbd_status err; uint32_t wrlen; int error, sirlength; uint8_t *wrbuf; int s; DPRINTFN(1, ("%s: sc=%p\n", __func__, sc)); if (sc->sc_dying) return EIO; #ifdef DIAGNOSTIC if (sc->sc_wr_buf == NULL) return EINVAL; #endif wrlen = uio->uio_resid; if (wrlen > sc->sc_wr_maxpsz) return EINVAL; sc->sc_refcnt++; if (!UDSIR_BLOCK_RX_DATA(sc)) { /* * If reads are not blocked, determine what action we * should potentially take... */ if (sc->sc_direction == udir_output) { /* * If the last operation was an output, wait for the * polling thread to check for incoming data. */ sc->sc_wr_stalewrite = 1; wakeup(&sc->sc_thread); } else if (!sc->sc_rd_readinprogress && (sc->sc_direction == udir_idle || sc->sc_direction == udir_input)) { /* If idle, check for input before outputting */ udsir_start_read(sc); } } s = splusb(); while (sc->sc_wr_stalewrite || (sc->sc_direction != udir_output && sc->sc_direction != udir_idle)) { DPRINTFN(5, ("%s: sc=%p stalewrite=%d direction=%d, " "calling tsleep()\n", __func__, sc, sc->sc_wr_stalewrite, sc->sc_direction)); error = tsleep(&sc->sc_wr_buf, PZERO | PCATCH, "usirwr", 0); if (sc->sc_dying) error = EIO; if (error) { splx(s); DPRINTFN(0, ("%s: tsleep() = %d\n", __func__, error)); goto ret; } } splx(s); wrbuf = sc->sc_wr_buf; sirlength = irda_sir_frame(wrbuf, MAX_UDSIR_OUTPUT_FRAME, uio, sc->sc_params.ebofs); if (sirlength < 0) error = -sirlength; else { uint32_t btlen; DPRINTFN(1, ("%s: transfer %u bytes\n", __func__, (unsigned int)wrlen)); btlen = sirlength; sc->sc_direction = udir_output; #ifdef UDSIR_DEBUG if (udsirdebug >= 20) udsir_dumpdata(wrbuf, btlen, __func__); #endif err = usbd_intr_transfer(sc->sc_wr_xfer, sc->sc_wr_pipe, USBD_FORCE_SHORT_XFER, UDSIR_WR_TIMEOUT, wrbuf, &btlen); DPRINTFN(2, ("%s: err=%d\n", __func__, err)); if (err != USBD_NORMAL_COMPLETION) { if (err == USBD_INTERRUPTED) error = EINTR; else if (err == USBD_TIMEOUT) error = ETIMEDOUT; else error = EIO; } else error = 0; } ret: if (--sc->sc_refcnt < 0) usb_detach_wakeupold(sc->sc_dev); DPRINTFN(1, ("%s: sc=%p done\n", __func__, sc)); return error; }
/* ARGSUSED */ static int udsir_read(void *h, struct uio *uio, int flag) { struct udsir_softc *sc = h; int s; int error; u_int uframelen; DPRINTFN(1, ("%s: sc=%p\n", __func__, sc)); if (sc->sc_dying) return EIO; #ifdef DIAGNOSTIC if (sc->sc_rd_buf == NULL) return EINVAL; #endif sc->sc_refcnt++; if (!sc->sc_rd_readinprogress && !UDSIR_BLOCK_RX_DATA(sc)) /* Possibly wake up polling thread */ wakeup(&sc->sc_thread); do { s = splusb(); while (sc->sc_ur_framelen == 0) { DPRINTFN(5, ("%s: calling tsleep()\n", __func__)); error = tsleep(&sc->sc_ur_framelen, PZERO | PCATCH, "usirrd", 0); if (sc->sc_dying) error = EIO; if (error) { splx(s); DPRINTFN(0, ("%s: tsleep() = %d\n", __func__, error)); goto ret; } } splx(s); uframelen = sc->sc_ur_framelen; DPRINTFN(1, ("%s: sc=%p framelen=%u, hdr=0x%02x\n", __func__, sc, uframelen, sc->sc_ur_buf[0])); if (uframelen > uio->uio_resid) error = EINVAL; else error = uiomove(sc->sc_ur_buf, uframelen, uio); sc->sc_ur_framelen = 0; if (deframe_rd_ur(sc) == 0 && uframelen > 0) { /* * Need to wait for another read to obtain a * complete frame... If we also obtained * actual data, wake up the possibly sleeping * thread immediately... */ wakeup(&sc->sc_thread); } } while (uframelen == 0); DPRINTFN(1, ("%s: return %d\n", __func__, error)); ret: if (--sc->sc_refcnt < 0) usb_detach_wakeupold(sc->sc_dev); return error; }
int urioioctl(dev_t dev, u_long cmd, void *addr, int flag, struct lwp *l) { struct urio_softc * sc; int unit = URIOUNIT(dev); struct urio_command *rcmd; int requesttype, len; struct iovec iov; struct uio uio; usb_device_request_t req; usbd_status err; int req_flags = 0; u_int32_t req_actlen = 0; void *ptr = NULL; int error = 0; sc = device_lookup_private(&urio_cd, unit); if (sc->sc_dying) return (EIO); rcmd = (struct urio_command *)addr; switch (cmd) { case URIO_RECV_COMMAND: requesttype = rcmd->requesttype | UT_READ_VENDOR_DEVICE; break; case URIO_SEND_COMMAND: requesttype = rcmd->requesttype | UT_WRITE_VENDOR_DEVICE; break; default: return (EINVAL); break; } if (!(flag & FWRITE)) return (EPERM); len = rcmd->length; DPRINTFN(1,("urio_ioctl: cmd=0x%08lx reqtype=0x%0x req=0x%0x " "value=0x%0x index=0x%0x len=0x%0x\n", cmd, requesttype, rcmd->request, rcmd->value, rcmd->index, len)); /* Send rio control message */ req.bmRequestType = requesttype; req.bRequest = rcmd->request; USETW(req.wValue, rcmd->value); USETW(req.wIndex, rcmd->index); USETW(req.wLength, len); if (len < 0 || len > 32767) return (EINVAL); if (len != 0) { iov.iov_base = (void *)rcmd->buffer; iov.iov_len = len; uio.uio_iov = &iov; uio.uio_iovcnt = 1; uio.uio_resid = len; uio.uio_offset = 0; uio.uio_rw = req.bmRequestType & UT_READ ? UIO_READ : UIO_WRITE; uio.uio_vmspace = l->l_proc->p_vmspace; ptr = malloc(len, M_TEMP, M_WAITOK); if (uio.uio_rw == UIO_WRITE) { error = uiomove(ptr, len, &uio); if (error) goto ret; } } sc->sc_refcnt++; err = usbd_do_request_flags(sc->sc_udev, &req, ptr, req_flags, &req_actlen, USBD_DEFAULT_TIMEOUT); if (--sc->sc_refcnt < 0) usb_detach_wakeupold(sc->sc_dev); if (err) { error = EIO; } else { if (len != 0 && uio.uio_rw == UIO_READ) error = uiomove(ptr, len, &uio); } ret: if (ptr != NULL) free(ptr, M_TEMP); 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", device_xname(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", device_xname(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_async(sc->sc_pipe_rx); if (--sc->sc_refcnt < 0) usb_detach_wakeupold(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", device_xname(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; } bpf_mtap(ifp, m); DPRINTF(("%s: %s: deliver %d\n", device_xname(sc->sc_dev), __func__, m->m_len)); (*(ifp)->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_wakeupold(sc->sc_dev); DPRINTF(("%s: %s: start rx\n", device_xname(sc->sc_dev), __func__)); }