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);
}
Esempio n. 2
0
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));
}
Esempio n. 3
0
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);
}
Esempio n. 5
0
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);
}
Esempio n. 6
0
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);
}
Esempio n. 7
0
File: uhid.c Progetto: MarginC/kame
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);
}
Esempio n. 8
0
File: uhid.c Progetto: MarginC/kame
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);
}
Esempio n. 9
0
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);
}
Esempio n. 10
0
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);
}
Esempio n. 11
0
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);
}
Esempio n. 12
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 = 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);
}
Esempio n. 13
0
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);
}
Esempio n. 14
0
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);
}
Esempio n. 15
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);
}
Esempio n. 16
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);
}
Esempio n. 17
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);
}
Esempio n. 18
0
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);
}
Esempio n. 19
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);
}
Esempio n. 20
0
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__));
}