static int kmoutput(struct tty *tp) { /* * FIXME - to be grokked...copied from m68k km.c. */ char buf[80]; char *cp; int cc = -1; while (tp->t_outq.c_cc > 0) { cc = ndqb(&tp->t_outq, 0); if (cc == 0) break; cc = min(cc, sizeof buf); (void) q_to_b(&tp->t_outq, (unsigned char *)buf, cc); for (cp = buf; cp < &buf[cc]; cp++) kmputc(tp->t_dev, *cp & 0x7f); } if (tp->t_outq.c_cc > 0) { timeout((timeout_fcn_t)kmtimeout, tp, hz); } tp->t_state &= ~TS_BUSY; (*linesw[tp->t_line].l_start)(tp); return 0; }
static int kmoutput( struct tty *tp) { /* * FIXME - to be grokked...copied from m68k km.c. */ char buf[80]; char *cp; int cc = -1; extern int hz; while (tp->t_outq.c_cc > 0) { cc = ndqb(&tp->t_outq, 0); if (cc == 0) break; cc = min(cc, sizeof buf); (void) q_to_b(&tp->t_outq, buf, cc); for (cp = buf; cp < &buf[cc]; cp++) { kmputc(*cp & 0x7f); } } if (tp->t_outq.c_cc > 0) { timeout((timeout_fcn_t)kmtimeout, tp, hz); } tp->t_state &= ~TS_BUSY; ttwwakeup(tp); return 0; }
static void clmpcc_start(struct tty *tp) { struct clmpcc_softc *sc = device_lookup_private(&clmpcc_cd, CLMPCCUNIT(tp->t_dev)); struct clmpcc_chan *ch = &sc->sc_chans[CLMPCCCHAN(tp->t_dev)]; u_int oldch; int s; s = spltty(); if ( ISCLR(tp->t_state, TS_TTSTOP | TS_TIMEOUT | TS_BUSY) ) { ttypull(tp); if ( ISSET(ch->ch_flags, CLMPCC_FLG_START_BREAK | CLMPCC_FLG_END_BREAK) || tp->t_outq.c_cc > 0 ) { if ( ISCLR(ch->ch_flags, CLMPCC_FLG_START_BREAK | CLMPCC_FLG_END_BREAK) ) { ch->ch_obuf_addr = tp->t_outq.c_cf; ch->ch_obuf_size = ndqb(&tp->t_outq, 0); } /* Enable TX empty interrupts */ oldch = clmpcc_select_channel(ch->ch_sc, ch->ch_car); clmpcc_wrreg(ch->ch_sc, CLMPCC_REG_IER, clmpcc_rdreg(ch->ch_sc, CLMPCC_REG_IER) | CLMPCC_IER_TX_EMPTY); clmpcc_select_channel(ch->ch_sc, oldch); SET(tp->t_state, TS_BUSY); } } splx(s); }
/* * kmoutput * * Locks: Assumes tp is locked on entry, remains locked on exit * * Notes: Called from kmstart() and kmtimeout(); kmtimeout() is a * timer initiated by this routine to deal with pending * output not yet flushed (output is flushed at a maximum * of sizeof(buf) charatcers at a time before dropping into * the timeout code). */ static int kmoutput(struct tty *tp) { char buf[80]; /* buffer; limits output per call */ char *cp; int cc = -1; /* While there is data available to be output... */ while (tp->t_outq.c_cc > 0) { cc = ndqb(&tp->t_outq, 0); if (cc == 0) break; /* * attempt to output as many characters as are available, * up to the available transfer buffer size. */ cc = min(cc, sizeof buf); /* copy the output queue contents to the buffer */ (void) q_to_b(&tp->t_outq, (unsigned char *)buf, cc); for (cp = buf; cp < &buf[cc]; cp++) { /* output the buffer one charatcer at a time */ kmputc(tp->t_dev, *cp & 0x7f); } } if (tp->t_outq.c_cc > 0) { timeout((timeout_fcn_t)kmtimeout, tp, hz); } tp->t_state &= ~TS_BUSY; (*linesw[tp->t_line].l_start)(tp); return 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); }
static void ucomstart(struct tty *tp) { struct ucom_softc *sc = device_lookup_private(&ucom_cd, UCOMUNIT(tp->t_dev)); struct ucom_buffer *ub; int s; u_char *data; int cnt; if (sc->sc_dying) 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; if (!ttypull(tp)) 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; } ub = SIMPLEQ_FIRST(&sc->sc_obuff_free); KASSERT(ub != NULL); SIMPLEQ_REMOVE_HEAD(&sc->sc_obuff_free, ub_link); if (SIMPLEQ_FIRST(&sc->sc_obuff_free) == NULL) SET(tp->t_state, TS_BUSY); if (cnt > sc->sc_obufsize) cnt = sc->sc_obufsize; if (sc->sc_methods->ucom_write != NULL) sc->sc_methods->ucom_write(sc->sc_parent, sc->sc_portno, ub->ub_data, data, &cnt); else memcpy(ub->ub_data, data, cnt); ub->ub_len = cnt; ub->ub_index = 0; SIMPLEQ_INSERT_TAIL(&sc->sc_obuff_full, ub, ub_link); softint_schedule(sc->sc_si); out: splx(s); }
void sacomstart(struct tty *tp) { struct sacom_softc *sc = device_lookup_private(&sacom_cd, COMUNIT(tp->t_dev)); bus_space_tag_t iot = sc->sc_iot; bus_space_handle_t ioh = sc->sc_ioh; int s; if (COM_ISALIVE(sc) == 0) return; s = spltty(); if (ISSET(tp->t_state, TS_BUSY | TS_TIMEOUT | TS_TTSTOP)) goto out; if (!ttypull(tp)) goto out; /* Grab the first contiguous region of buffer space. */ { u_char *tba; int tbc; tba = tp->t_outq.c_cf; tbc = ndqb(&tp->t_outq, 0); (void)splserial(); COM_LOCK(sc); sc->sc_tba = tba; sc->sc_tbc = tbc; } SET(tp->t_state, TS_BUSY); sc->sc_tx_busy = 1; /* Enable transmit completion interrupts if necessary. */ if (!ISSET(sc->sc_cr3, CR3_TIE)) { SET(sc->sc_cr3, CR3_TIE); bus_space_write_4(iot, ioh, SACOM_CR3, sc->sc_cr3); } /* Output the first chunk of the contiguous buffer. */ sacom_filltx(sc); COM_UNLOCK(sc); out: splx(s); return; }
void sscomstart(struct tty *tp) { struct sscom_softc *sc = device_lookup_private(&sscom_cd, SSCOMUNIT(tp->t_dev)); int s; if (SSCOM_ISALIVE(sc) == 0) return; s = spltty(); if (ISSET(tp->t_state, TS_BUSY | TS_TIMEOUT | TS_TTSTOP)) goto out; if (sc->sc_tx_stopped) goto out; if (!ttypull(tp)) goto out; /* Grab the first contiguous region of buffer space. */ { u_char *tba; int tbc; tba = tp->t_outq.c_cf; tbc = ndqb(&tp->t_outq, 0); (void)splserial(); SSCOM_LOCK(sc); sc->sc_tba = tba; sc->sc_tbc = tbc; } SET(tp->t_state, TS_BUSY); sc->sc_tx_busy = 1; /* Output the first chunk of the contiguous buffer. */ sscom_output_chunk(sc); /* Enable transmit completion interrupts if necessary. */ if ((sc->sc_hwflags & SSCOM_HW_TXINT) == 0) sscom_enable_txint(sc); SSCOM_UNLOCK(sc); out: splx(s); return; }
/* * cztty_transmit() * * Look at the tty for this port and start sending. */ static int cztty_transmit(struct cztty_softc *sc, struct tty *tp) { struct cz_softc *cz = CZTTY_CZ(sc); u_int move, get, put, size, address; #ifdef HOSTRAMCODE int error, done = 0; #else int done = 0; #endif size = CZTTY_BUF_READ(sc, BUFCTL_TX_BUFSIZE); get = CZTTY_BUF_READ(sc, BUFCTL_TX_GET); put = CZTTY_BUF_READ(sc, BUFCTL_TX_PUT); address = CZTTY_BUF_READ(sc, BUFCTL_TX_BUFADDR); while ((tp->t_outq.c_cc > 0) && ((move = TX_MOVEABLE(get, put, size)))){ #ifdef HOSTRAMCODE if (0) { move = min(tp->t_outq.c_cc, move); error = q_to_b(&tp->t_outq, 0, move); if (error != move) { printf("%s: channel %d: error moving to " "transmit buf\n", device_xname(cz->cz_dev), sc->sc_channel); move = error; } } else { #endif move = min(ndqb(&tp->t_outq, 0), move); bus_space_write_region_1(cz->cz_win_st, cz->cz_win_sh, address + put, tp->t_outq.c_cf, move); ndflush(&tp->t_outq, move); #ifdef HOSTRAMCODE } #endif put = ((put + move) % size); done = 1; } if (done) { CZTTY_BUF_WRITE(sc, BUFCTL_TX_PUT, put); } return (done); }
static void at91dbgu_start(struct tty *tp) { struct at91dbgu_softc *sc = device_lookup_private(&at91dbgu_cd, COMUNIT(tp->t_dev)); int s; if (COM_ISALIVE(sc) == 0) return; s = spltty(); if (ISSET(tp->t_state, TS_BUSY | TS_TIMEOUT | TS_TTSTOP)) goto out; if (sc->sc_tx_stopped) goto out; if (!ttypull(tp)) goto out; /* Grab the first contiguous region of buffer space. */ { u_char *tba; int tbc; tba = tp->t_outq.c_cf; tbc = ndqb(&tp->t_outq, 0); (void)splserial(); sc->sc_tba = tba; sc->sc_tbc = tbc; } SET(tp->t_state, TS_BUSY); sc->sc_tx_busy = 1; /* Output the first chunk of the contiguous buffer. */ at91dbgu_filltx(sc); SET(sc->sc_ier, DBGU_INT_TXRDY); DBGUREG(DBGU_IER) = DBGU_INT_TXRDY; out: splx(s); return; }
static void at91usart_start(struct tty *tp) { struct at91usart_softc *sc = device_lookup_private(&at91usart_cd, COMUNIT(tp->t_dev)); int s; if (COM_ISALIVE(sc) == 0) { DPRINTFN(5, ("%s: %s / COM_ISALIVE == 0\n", device_xname(sc->sc_dev), __FUNCTION__)); return; } s = spltty(); if (ISSET(tp->t_state, TS_BUSY | TS_TIMEOUT | TS_TTSTOP)) { DPRINTFN(5, ("%s: %s: TS_BUSY || TS_TIMEOUT || TS_TTSTOP\n", device_xname(sc->sc_dev), __FUNCTION__)); goto out; } if (!ttypull(tp)) goto out; /* Grab the first contiguous region of buffer space. */ { u_char *tba; int tbc; tba = tp->t_outq.c_cf; tbc = ndqb(&tp->t_outq, 0); sc->sc_tba = tba; sc->sc_tbc = tbc; } SET(tp->t_state, TS_BUSY); /* Output the first chunk of the contiguous buffer. */ at91usart_filltx(sc); at91usart_writereg(sc, US_IER, sc->sc_ier); DPRINTFN(5, ("%s: %s, ier=%08x (csr=%08x)\n", device_xname(sc->sc_dev), __FUNCTION__, sc->sc_ier, at91usart_readreg(sc, US_CSR))); out: splx(s); return; }
/* * 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); }
/* * kmoutput * * Locks: Assumes tp is locked on entry, remains locked on exit * * Notes: Called from kmstart() and kmtimeout(); kmtimeout() is a * timer initiated by this routine to deal with pending * output not yet flushed (output is flushed at a maximum * of sizeof(buf) charatcers at a time before dropping into * the timeout code). */ static int kmoutput(struct tty *tp) { unsigned char buf[80]; /* buffer; limits output per call */ unsigned char *cp; int cc = -1; /* * While there is data available to be output... */ while (tp->t_outq.c_cc > 0) { cc = ndqb(&tp->t_outq, 0); if (cc == 0) break; /* * attempt to output as many characters as are available, * up to the available transfer buffer size. */ cc = min(cc, sizeof(buf)); /* * copy the output queue contents to the buffer */ (void) q_to_b(&tp->t_outq, buf, cc); for (cp = buf; cp < &buf[cc]; cp++) { /* * output the buffer one charatcer at a time */ kmputc(tp->t_dev, *cp & 0x7f); } } /* * XXX This is likely not necessary, as the tty output queue is not * XXX writeable while we hold the tty_lock(). */ if (tp->t_outq.c_cc > 0) { timeout(kmtimeout, tp, hz); } tp->t_state &= ~TS_BUSY; /* * Start the output processing for the line discipline */ (*linesw[tp->t_line].l_start) (tp); return 0; }
void uart_start(struct tty *tp) { int s,i,cnt; s = spltty(); if (tp->t_state & (TS_TTSTOP | TS_BUSY)) goto out; ttypull(tp); tp->t_state |= TS_BUSY; while (tp->t_outq.c_cc != 0) { cnt = ndqb(&tp->t_outq, 0); for (i=0; i<cnt; i++) uart_cnputc(0,tp->t_outq.c_cf[i]); ndflush(&tp->t_outq, cnt); } tp->t_state &= ~TS_BUSY; out: splx(s); }
void arcbios_tty_start(struct tty *tp) { u_long count; int s; s = spltty(); if (tp->t_state & (TS_TTSTOP | TS_BUSY)) goto out; ttypull(tp); tp->t_state |= TS_BUSY; while (tp->t_outq.c_cc != 0) { arcbios_Write(ARCBIOS_STDOUT, tp->t_outq.c_cf, ndqb(&tp->t_outq, 0), &count); ndflush(&tp->t_outq, count); } tp->t_state &= ~TS_BUSY; out: splx(s); }
STATIC void gtmpscstart(struct tty *tp) { struct gtmpsc_softc *sc; unsigned char *tba; unsigned int unit; int s, tbc; unit = GTMPSCUNIT(tp->t_dev); sc = device_lookup_private(>mpsc_cd, unit); if (sc == NULL) return; s = spltty(); if (ISSET(tp->t_state, TS_TIMEOUT | TS_BUSY | TS_TTSTOP)) goto out; if (sc->sc_tx_stopped) goto out; if (!ttypull(tp)) goto out; /* Grab the first contiguous region of buffer space. */ tba = tp->t_outq.c_cf; tbc = ndqb(&tp->t_outq, 0); mutex_spin_enter(&sc->sc_lock); sc->sc_tba = tba; sc->sc_tbc = tbc; sdma_imask |= SDMA_INTR_TXBUF(sc->sc_unit); gt_sdma_imask(device_parent(sc->sc_dev), sdma_imask); SET(tp->t_state, TS_BUSY); sc->sc_tx_busy = 1; gtmpsc_write(sc); mutex_spin_exit(&sc->sc_lock); out: splx(s); }
/* * Start output, after a stop. */ void mtty_start(struct tty *tp) { struct mtty_softc *ms = device_lookup_private(&mtty_cd, 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 (ttypull(tp)) { 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 stty_start(struct tty *tp) { struct stty_softc *stc = device_lookup_private(&stty_cd, SPIF_CARD(tp->t_dev)); struct stty_port *sp = &stc->sc_port[SPIF_PORT(tp->t_dev)]; struct spif_softc *sc = sp->sp_sc; int s; s = spltty(); if (!ISSET(tp->t_state, TS_TTSTOP | TS_TIMEOUT | TS_BUSY)) { if (ttypull(tp)) { sp->sp_txc = ndqb(&tp->t_outq, 0); sp->sp_txp = tp->t_outq.c_cf; SET(tp->t_state, TS_BUSY); STC_WRITE(sc, STC_CAR, sp->sp_channel); STC_WRITE(sc, STC_SRER, STC_READ(sc, STC_SRER) | CD180_SRER_TXD); } } splx(s); }
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); }