Exemplo n.º 1
0
/*
 * Start output, after a stop.
 */
void
mtty_start(struct tty *tp)
{
    struct mtty_softc *ms = mtty_cd.cd_devs[MAGMA_CARD(tp->t_dev)];
    struct mtty_port *mp = &ms->ms_port[MAGMA_PORT(tp->t_dev)];
    int s;

    s = spltty();

    /* we only need to do something if we are not already busy
     * or delaying or stopped
     */
    if (!ISSET(tp->t_state, TS_TTSTOP | TS_TIMEOUT | TS_BUSY)) {

        /* if we are sleeping and output has drained below
         * low water mark, awaken
         */
        ttwakeupwr(tp);

        /* if something to send, start transmitting
         */
        if (tp->t_outq.c_cc) {
            mp->mp_txc = ndqb(&tp->t_outq, 0);
            mp->mp_txp = tp->t_outq.c_cf;
            SET(tp->t_state, TS_BUSY);
            cd1400_enable_transmitter(mp->mp_cd1400, mp->mp_channel);
        }
    }

    splx(s);
}
Exemplo n.º 2
0
void
dartstart(struct tty *tp)
{
	struct dartsoftc *sc;
	dev_t dev;
	int s;
	u_int port, chip;
	int c, tries;
	bus_addr_t ptaddr;

	if ((tp->t_state & TS_ISOPEN) == 0)
		return;

	dev = tp->t_dev;
	chip = DART_CHIP(dev);
	port = DART_PORT(dev);
	sc = (struct dartsoftc *)dart_cd.cd_devs[chip];
	ptaddr = port == A_PORT ? DART_A_BASE : DART_B_BASE;

	s = spltty();

	if (tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP))
		goto bail;

	ttwakeupwr(tp);
	if (tp->t_outq.c_cc == 0)
		goto bail;

	tp->t_state |= TS_BUSY;
	while (tp->t_outq.c_cc != 0) {

		/* load transmitter until it is full */
		for (tries = 10000; tries != 0; tries --)
			if (dart_read(sc, ptaddr + DART_SRA) & TXRDY)
				break;

		if (tries == 0) {
			timeout_add(&tp->t_rstrt_to, 1);
			tp->t_state |= TS_TIMEOUT;
			break;
		} else {
			c = getc(&tp->t_outq);

			dart_write(sc, ptaddr + DART_TBA, c & 0xff);

			sc->sc_sv_reg->sv_imr |=
			    port == A_PORT ? ITXRDYA : ITXRDYB;
			dart_write(sc, DART_IMR, sc->sc_sv_reg->sv_imr);
		}
	}
	tp->t_state &= ~TS_BUSY;

bail:
	splx(s);
}
Exemplo n.º 3
0
void
vioconstart(struct tty *tp)
{
	struct viocon_softc *sc = dev2sc(tp->t_dev);
	struct virtio_softc *vsc;
	struct viocon_port *vp = dev2port(tp->t_dev);
	struct virtqueue *vq;
	u_char *buf;
	int s, cnt, slot, ret, ndone;

	vsc = sc->sc_virtio;
	vq = vp->vp_tx;

	s = spltty();

	ndone = viocon_tx_drain(vp, vq);
	if (ISSET(tp->t_state, TS_BUSY)) {
		if (ndone > 0)
			CLR(tp->t_state, TS_BUSY);
		else
			goto out;
	}
	if (ISSET(tp->t_state, TS_TIMEOUT | TS_TTSTOP))
		goto out;

	if (tp->t_outq.c_cc == 0)
		goto out;
	ndone = 0;

	while (tp->t_outq.c_cc > 0) {
		ret = virtio_enqueue_prep(vq, &slot);
		if (ret == EAGAIN)
			break;
		KASSERT(ret == 0);
		ret = virtio_enqueue_reserve(vq, slot, 1);
		KASSERT(ret == 0);
		buf = vp->vp_tx_buf + slot * BUFSIZE;
		cnt = q_to_b(&tp->t_outq, buf, BUFSIZE);
		bus_dmamap_sync(vsc->sc_dmat, vp->vp_dmamap,
		    vp->vp_tx_buf - vp->vp_rx_buf + slot * BUFSIZE, cnt,
		    BUS_DMASYNC_PREWRITE);
		virtio_enqueue_p(vq, slot, vp->vp_dmamap,
		    vp->vp_tx_buf - vp->vp_rx_buf + slot * BUFSIZE, cnt, 1);
		virtio_enqueue_commit(vsc, vq, slot, 0);
		ndone++;
	}
	if (ret == EAGAIN)
		SET(tp->t_state, TS_BUSY);
	if (ndone > 0)
		virtio_notify(vsc, vq);
	ttwakeupwr(tp);
out:
	splx(s);
}
Exemplo n.º 4
0
void
vconsstart(struct tty *tp)
{
	int s;

	s = spltty();
	if (tp->t_state & (TS_TTSTOP | TS_BUSY)) {
		splx(s);
		return;
	}
	ttwakeupwr(tp);
	tp->t_state |= TS_BUSY;
	while (tp->t_outq.c_cc != 0)
		vcons_cnputc(tp->t_dev, getc(&tp->t_outq));
	tp->t_state &= ~TS_BUSY;
	splx(s);
}
Exemplo n.º 5
0
/*
 * Start or restart transmission.
 */
void
zsstart(struct tty *tp)
{
	struct zstty_softc *zst = zs_device_lookup(&zstty_cd, ZSUNIT(tp->t_dev));
	struct zs_chanstate *cs = zst->zst_cs;
	u_char *tba;
	int tbc, rr0;
	int s;

	s = spltty();
	if (ISSET(tp->t_state, TS_BUSY | TS_TIMEOUT | TS_TTSTOP))
		goto out;
	if (zst->zst_tx_stopped)
		goto out;

	ttwakeupwr(tp);
	if (tp->t_outq.c_cc == 0)
		goto out;

	/* Grab the first contiguous region of buffer space. */
	tba = tp->t_outq.c_cf;
	tbc = ndqb(&tp->t_outq, 0);

#if IPL_ZS != IPL_TTY
	(void)splzs();
#endif

	zst->zst_tba = tba;
	zst->zst_tbc = tbc;
	SET(tp->t_state, TS_BUSY);
	zst->zst_tx_busy = 1;

	do {
		rr0 = zs_read_csr(cs);
		if ((rr0 & ZSRR0_TX_READY) == 0)
			break;

		zs_write_data(cs, *zst->zst_tba);
		zst->zst_tbc--;
		zst->zst_tba++;
	} while (zst->zst_tbc > 0);

out:
	splx(s);
}
Exemplo n.º 6
0
int
ptcread(dev_t dev, struct uio *uio, int flag)
{
	struct pt_softc *pti = pt_softc[minor(dev)];
	struct tty *tp = pti->pt_tty;
	char buf[BUFSIZ];
	int error = 0, cc, bufcc = 0;

	/*
	 * We want to block until the slave
	 * is open, and there's something to read;
	 * but if we lost the slave or we're NBIO,
	 * then return the appropriate error instead.
	 */
	for (;;) {
		if (tp->t_state&TS_ISOPEN) {
			if (pti->pt_flags&PF_PKT && pti->pt_send) {
				error = ureadc((int)pti->pt_send, uio);
				if (error)
					return (error);
				if (pti->pt_send & TIOCPKT_IOCTL) {
					cc = MIN(uio->uio_resid,
						sizeof(tp->t_termios));
					error = uiomove(&tp->t_termios, cc, uio);
					if (error)
						return (error);
				}
				pti->pt_send = 0;
				return (0);
			}
			if (pti->pt_flags&PF_UCNTL && pti->pt_ucntl) {
				error = ureadc((int)pti->pt_ucntl, uio);
				if (error)
					return (error);
				pti->pt_ucntl = 0;
				return (0);
			}
			if (tp->t_outq.c_cc && (tp->t_state&TS_TTSTOP) == 0)
				break;
		}
		if ((tp->t_state&TS_CARR_ON) == 0)
			return (0);	/* EOF */
		if (flag & IO_NDELAY)
			return (EWOULDBLOCK);
		error = tsleep(&tp->t_outq.c_cf, TTIPRI | PCATCH,
		    ttyin, 0);
		if (error)
			return (error);
	}
	if (pti->pt_flags & (PF_PKT|PF_UCNTL))
		error = ureadc(0, uio);
	while (uio->uio_resid > 0 && error == 0) {
		cc = MIN(uio->uio_resid, BUFSIZ);
		cc = q_to_b(&tp->t_outq, buf, cc);
		if (cc > bufcc)
			bufcc = cc;
		if (cc <= 0)
			break;
		error = uiomove(buf, cc, uio);
	}
	ttwakeupwr(tp);
	if (bufcc)
		bzero(buf, bufcc);
	return (error);
}
Exemplo n.º 7
0
void
ucomstart(struct tty *tp)
{
	struct ucom_softc *sc = ucom_cd.cd_devs[UCOMUNIT(tp->t_dev)];
	usbd_status err;
	int s;
	u_char *data;
	int cnt;

	if (sc == NULL || usbd_is_dying(sc->sc_uparent))
		return;

	s = spltty();
	if (ISSET(tp->t_state, TS_BUSY | TS_TIMEOUT | TS_TTSTOP)) {
		DPRINTFN(4,("ucomstart: no go, state=0x%x\n", tp->t_state));
		goto out;
	}
	if (sc->sc_tx_stopped)
		goto out;

	ttwakeupwr(tp);
	if (tp->t_outq.c_cc == 0)
		goto out;

	/* Grab the first contiguous region of buffer space. */
	data = tp->t_outq.c_cf;
	cnt = ndqb(&tp->t_outq, 0);

	if (cnt == 0) {
		DPRINTF(("ucomstart: cnt==0\n"));
		goto out;
	}

	SET(tp->t_state, TS_BUSY);

	if (cnt > sc->sc_obufsize) {
		DPRINTF(("ucomstart: big buffer %d chars\n", cnt));
		cnt = sc->sc_obufsize;
	}
	if (sc->sc_methods->ucom_write != NULL)
		sc->sc_methods->ucom_write(sc->sc_parent, sc->sc_portno,
					   sc->sc_obuf, data, &cnt);
	else
		memcpy(sc->sc_obuf, data, cnt);

	DPRINTFN(4,("ucomstart: %d chars\n", cnt));
#ifdef DIAGNOSTIC
	if (sc->sc_oxfer == NULL) {
		printf("ucomstart: null oxfer\n");
		goto out;
	}
#endif
	if (sc->sc_bulkout_pipe != NULL) {
		usbd_setup_xfer(sc->sc_oxfer, sc->sc_bulkout_pipe,
		    (void *)sc, sc->sc_obuf, cnt,
		    USBD_NO_COPY, USBD_NO_TIMEOUT, ucomwritecb);
	} else {
		usbd_setup_xfer(sc->sc_oxfer, sc->sc_opipe,
		    (void *)sc, sc->sc_obuf, cnt,
		    USBD_NO_COPY, USBD_NO_TIMEOUT, ucomwritecb);
	}
	/* What can we do on error? */
	err = usbd_transfer(sc->sc_oxfer);
#ifdef DIAGNOSTIC
	if (err != USBD_IN_PROGRESS)
		printf("ucomstart: err=%s\n", usbd_errstr(err));
#endif

out:
	splx(s);
}