/* * 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); }
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); }
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); }
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); }
/* * 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); }
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); }
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); }