int uirda_read(void *h, struct uio *uio, int flag) { struct uirda_softc *sc = h; usbd_status err; int s; int error; u_int n; 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++; do { s = splusb(); while (sc->sc_rd_count == 0) { DPRINTFN(5,("uirda_read: calling tsleep()\n")); error = tsleep(&sc->sc_rd_count, PZERO | PCATCH, "uirdrd", 0); if (sc->sc_dying) error = EIO; if (error) { splx(s); DPRINTF(("uirda_read: tsleep() = %d\n", error)); goto ret; } } splx(s); mutex_enter(&sc->sc_rd_buf_lk); n = sc->sc_rd_count - sc->sc_hdszi; DPRINTFN(1,("%s: sc=%p n=%u, hdr=0x%02x\n", __func__, sc, n, sc->sc_rd_buf[0])); if (n > uio->uio_resid) error = EINVAL; else error = uiomove(sc->sc_rd_buf + sc->sc_hdszi, n, uio); sc->sc_rd_count = 0; mutex_exit(&sc->sc_rd_buf_lk); err = uirda_start_read(sc); /* XXX check err */ } while (n == 0); DPRINTFN(1,("uirda_read: return %d\n", error)); ret: if (--sc->sc_refcnt < 0) usb_detach_wakeup(USBDEV(sc->sc_dev)); return (error); }
Static void ucom_unlock(struct ucom_softc *sc) { usb_lockmgr(&sc->sc_lock, LK_RELEASE, NULL, curproc); if (--sc->sc_refcnt < 0) usb_detach_wakeup(USBDEV(sc->sc_dev)); }
Static void url_unlock_mii(struct url_softc *sc) { DPRINTFN(0xff, ("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__)); usb_lockmgr(&sc->sc_mii_lock, LK_RELEASE, NULL, curproc); if (--sc->sc_refcnt < 0) usb_detach_wakeup(USBDEV(sc->sc_dev)); }
int uirda_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; error = uiomove(sc->sc_wr_buf + UIRDA_OUTPUT_HEADER_SIZE, n, uio); if (!error) { DPRINTFN(1, ("uirdawrite: transfer %d bytes\n", n)); 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, "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_wakeup(USBDEV(sc->sc_dev)); DPRINTFN(1,("%s: sc=%p done\n", __func__, sc)); return (error); }
int ucomioctl(dev_t dev, u_long cmd, caddr_t data, int flag, usb_proc_ptr p) { struct ucom_softc *sc = ucom_cd.cd_devs[UCOMUNIT(dev)]; int error; sc->sc_refcnt++; error = ucom_do_ioctl(sc, cmd, data, flag, p); if (--sc->sc_refcnt < 0) usb_detach_wakeup(USBDEV(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; sc->sc_refcnt++; error = ucom_do_ioctl(sc, cmd, data, flag, l); if (--sc->sc_refcnt < 0) usb_detach_wakeup(USBDEV(sc->sc_dev)); return (error); }
int uhidioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, usb_proc_ptr p) { struct uhid_softc *sc; int error; USB_GET_SC(uhid, UHIDUNIT(dev), sc); sc->sc_refcnt++; error = uhid_do_ioctl(sc, cmd, addr, flag, p); if (--sc->sc_refcnt < 0) usb_detach_wakeup(USBDEV(sc->sc_dev)); return (error); }
int uhidwrite(dev_t dev, struct uio *uio, int flag) { struct uhid_softc *sc; int error; USB_GET_SC(uhid, UHIDUNIT(dev), sc); sc->sc_refcnt++; error = uhid_do_write(sc, uio, flag); if (--sc->sc_refcnt < 0) usb_detach_wakeup(USBDEV(sc->sc_dev)); return (error); }
int uscannerwrite(dev_t dev, struct uio *uio, int flag) { struct uscanner_softc *sc; int error; USB_GET_SC(uscanner, USCANNERUNIT(dev), sc); sc->sc_refcnt++; error = uscanner_do_write(sc, uio, flag); if (--sc->sc_refcnt < 0) usb_detach_wakeup(USBDEV(sc->sc_dev)); return (error); }
int ucompoll(dev_t dev, int events, struct lwp *l) { struct ucom_softc *sc = device_lookup_private(&ucom_cd, UCOMUNIT(dev)); struct tty *tp = sc->sc_tty; int revents; if (sc->sc_dying) return (POLLHUP); sc->sc_refcnt++; revents = ((*tp->t_linesw->l_poll)(tp, events, l)); if (--sc->sc_refcnt < 0) usb_detach_wakeup(USBDEV(sc->sc_dev)); return (revents); }
int ucomwrite(dev_t dev, struct uio *uio, int flag) { struct ucom_softc *sc = ucom_cd.cd_devs[UCOMUNIT(dev)]; struct tty *tp = sc->sc_tty; int error; if (sc->sc_dying) return (EIO); sc->sc_refcnt++; error = (*LINESW(tp, l_write))(tp, uio, flag); if (--sc->sc_refcnt < 0) usb_detach_wakeup(USBDEV(sc->sc_dev)); return (error); }
int ucomwrite(dev_t dev, struct uio *uio, int flag) { struct ucom_softc *sc = device_lookup_private(&ucom_cd, UCOMUNIT(dev)); struct tty *tp = sc->sc_tty; int error; if (sc->sc_dying) return (EIO); sc->sc_refcnt++; error = ((*tp->t_linesw->l_write)(tp, uio, flag)); if (--sc->sc_refcnt < 0) usb_detach_wakeup(USBDEV(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", 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_async(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 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", USBDEVNAME(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) { bzero(c->url_buf + total_len, 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_wakeup(USBDEV(sc->sc_dev)); if (err != USBD_IN_PROGRESS) { printf("%s: url_send error=%s\n", USBDEVNAME(sc->sc_dev), usbd_errstr(err)); /* Stop the interface */ usb_add_task(sc->sc_udev, &sc->sc_stop_task); return (EIO); } DPRINTF(("%s: %s: send %d bytes\n", USBDEVNAME(sc->sc_dev), __func__, total_len)); sc->sc_cdata.url_tx_cnt++; return (0); }
static int ucomclose(dev_t dev, int flag, int mode, usb_proc_ptr p) { struct ucom_softc *sc; struct tty *tp; int s; USB_GET_SC(ucom, UCOMUNIT(dev), sc); tp = sc->sc_tty; DPRINTF(("%s: ucomclose: unit = %d\n", USBDEVNAME(sc->sc_dev), UCOMUNIT(dev))); if (!ISSET(tp->t_state, TS_ISOPEN)) goto quit; s = spltty(); (*linesw[tp->t_line].l_close)(tp, flag); disc_optim(tp, &tp->t_termios, sc); ttyclose(tp); splx(s); if (sc->sc_dying) goto quit; if (!ISSET(tp->t_state, TS_ISOPEN)) { /* * 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_callback->ucom_close != NULL) sc->sc_callback->ucom_close(sc->sc_parent, sc->sc_portno); quit: if (--sc->sc_refcnt < 0) usb_detach_wakeup(USBDEV(sc->sc_dev)); return (0); }
int ucom_detach(struct ucom_softc *sc) { struct tty *tp = sc->sc_tty; int s; DPRINTF(("ucom_detach: sc = %p, tp = %p\n", sc, sc->sc_tty)); sc->sc_dying = 1; if (sc->sc_bulkin_pipe != NULL) usbd_abort_pipe(sc->sc_bulkin_pipe); if (sc->sc_bulkout_pipe != NULL) usbd_abort_pipe(sc->sc_bulkout_pipe); if (tp != NULL) { if (tp->t_state & TS_ISOPEN) { device_printf(sc->sc_dev, "still open, forcing close\n"); (*linesw[tp->t_line].l_close)(tp, 0); tp->t_gen++; ttyclose(tp); ttwakeup(tp); ttwwakeup(tp); } } else { DPRINTF(("ucom_detach: no tty\n")); return (0); } s = splusb(); if (--sc->sc_refcnt >= 0) { /* Wait for processes to go away. */ usb_detach_wait(USBDEV(sc->sc_dev)); } splx(s); destroy_dev(sc->dev); return (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", USBDEVNAME(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_wakeup(USBDEV(sc->sc_dev)); if (err) { DPRINTF(("%s: url_mem(): %s failed. off=%04x, err=%d\n", USBDEVNAME(sc->sc_dev), cmd == URL_CMD_READMEM ? "read" : "write", offset, err)); } return (err); }
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 = sc->sc_tty; int s; DPRINTF(("ucomclose: unit=%d\n", UCOMUNIT(dev))); if (!ISSET(tp->t_state, TS_ISOPEN)) return (0); s = spltty(); sc->sc_refcnt++; CLR(tp->t_state, TS_BUSY); (*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_wakeup(USBDEV(sc->sc_dev)); splx(s); return (0); }
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); }
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_async(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->if_bpf, m, BPF_DIRECTION_IN); #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__)); }