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); }
static void pconsstart(struct tty *tp) { struct clist *cl; int s, len; uint8_t buf[OFBURSTLEN]; s = spltty(); if (tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP)) { splx(s); return; } tp->t_state |= TS_BUSY; splx(s); cl = &tp->t_outq; len = q_to_b(cl, buf, OFBURSTLEN); prom_putstr(buf, len); s = spltty(); tp->t_state &= ~TS_BUSY; if (ttypull(tp)) { tp->t_state |= TS_TIMEOUT; callout_schedule(&tp->t_rstrt_ch, 1); } splx(s); }
static void biconsdev_output(struct tty *tp) { int s, n; char buf[OBUFSIZ]; s = spltty(); if (tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP)) { splx(s); return; } tp->t_state |= TS_BUSY; splx(s); n = q_to_b(&tp->t_outq, buf, sizeof(buf)); bicons_putn(buf, n); s = spltty(); tp->t_state &= ~TS_BUSY; /* Come back if there's more to do */ if (ttypull(tp)) { tp->t_state |= TS_TIMEOUT; callout_schedule(&tp->t_rstrt_ch, 1); } splx(s); }
static void kdstart(struct tty *tp) { int s1, s2; s1 = splsoftclock(); s2 = spltty(); if (tp->t_state & (TS_BUSY|TS_TTSTOP|TS_TIMEOUT)) goto out; if (ttypull(tp)) { tp->t_state |= TS_BUSY; if ((s1 & PSR_PIL) == 0) { /* called at level zero - update screen now. */ splx(s2); kd_putfb(tp); s2 = spltty(); tp->t_state &= ~TS_BUSY; } else { /* called at interrupt level - do it later */ callout_schedule(&tp->t_rstrt_ch, 0); } } out: splx(s2); splx(s1); }
void dzstart(struct tty *tp) { struct dz_softc *sc; struct clist *cl; int unit, s; unit = DZ_I2C(minor(tp->t_dev)); sc = device_lookup_private(&dz_cd, unit); s = spltty(); if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) { splx(s); return; } cl = &tp->t_outq; ttypull(tp); if (cl->c_cc == 0) { splx(s); return; } tp->t_state |= TS_BUSY; /* was idle, get it started */ dzxint(sc,USI_TXRDY); 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; }
/* * czttystart: * * Start or restart transmission. */ static void czttystart(struct tty *tp) { struct cztty_softc *sc = CZTTY_SOFTC(tp->t_dev); int s; s = spltty(); if (ISSET(tp->t_state, TS_BUSY | TS_TIMEOUT | TS_TTSTOP)) goto out; if (!ttypull(tp)) goto out; cztty_transmit(sc, tp); out: splx(s); }
/* * Start transmission */ qvstart(register struct tty *tp) { register int unit, c; register struct tty *tp0; int s; unit = minor(tp->t_dev); #ifdef CONS_HACK tp0 = &qv_tty[(unit&0xfc)+QVPCONS]; #endif unit = QVCHAN(unit); s = spl5(); /* * If it's currently active, or delaying, no need to do anything. */ if (tp->t_state&(TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) goto out; /* * Display chars until the queue is empty, if the second subchannel * is open direct them there. Drop characters from subchannels other * than 0 on the floor. */ while( tp->t_outq.c_cc ) { c = getc(&tp->t_outq); if (unit == QVKEYBOARD) #ifdef CONS_HACK if( tp0->t_state & TS_ISOPEN ){ (*tp0->t_linesw->l_rint)(c, tp0); } else #endif qvputchar( c & 0xff ); } /* * Position the cursor to the next character location. */ qv_pos_cur( qv_scn->col*8, qv_scn->row*15 ); /* * If there are sleepers, and output has drained below low * water mark, wake up the sleepers. */ ttypull(tp); tp->t_state &= ~TS_BUSY; out: splx(s); }
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; }
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; }
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 dlstart(struct tty *tp) { struct dl_softc *sc = device_lookup_private(&dl_cd, minor(tp->t_dev)); int s = spltty(); if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) goto out; if (!ttypull(tp)) goto out; if (DL_READ_WORD(DL_UBA_XCSR) & DL_XCSR_TX_READY) { tp->t_state |= TS_BUSY; DL_WRITE_BYTE(DL_UBA_XBUFL, getc(&tp->t_outq)); } out: splx(s); return; }
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); }
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); }
/* * 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 itestart(struct tty *tp) { struct clist *rbp; struct ite_softc *ip; u_char buf[ITEBURST]; int s, len; ip = getitesp(tp->t_dev); KDASSERT(tp); s = spltty(); { if (tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP)) goto out; tp->t_state |= TS_BUSY; rbp = &tp->t_outq; len = q_to_b(rbp, buf, ITEBURST); } splx(s); /* Here is a really good place to implement pre/jumpscroll() */ ite_putstr(buf, len, tp->t_dev); s = spltty(); { tp->t_state &= ~TS_BUSY; /* we have characters remaining. */ if (ttypull(tp)) { tp->t_state |= TS_TIMEOUT; callout_schedule(&tp->t_rstrt_ch, 1); } } out: splx(s); }
void xencons_start(struct tty *tp) { struct clist *cl; int s; s = spltty(); if (tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP)) goto out; tp->t_state |= TS_BUSY; splx(s); /* * We need to do this outside spl since it could be fairly * expensive and we don't want our serial ports to overflow. */ cl = &tp->t_outq; if (xendomain_is_dom0()) { int len, r; u_char buf[XENCONS_BURST+1]; len = q_to_b(cl, buf, XENCONS_BURST); while (len > 0) { r = HYPERVISOR_console_io(CONSOLEIO_write, len, buf); if (r <= 0) break; len -= r; } } else { XENCONS_RING_IDX cons, prod, len; #define XNC_OUT (xencons_interface->out) cons = xencons_interface->out_cons; prod = xencons_interface->out_prod; xen_rmb(); while (prod != cons + sizeof(xencons_interface->out)) { if (MASK_XENCONS_IDX(prod, XNC_OUT) < MASK_XENCONS_IDX(cons, XNC_OUT)) { len = MASK_XENCONS_IDX(cons, XNC_OUT) - MASK_XENCONS_IDX(prod, XNC_OUT); } else { len = sizeof(XNC_OUT) - MASK_XENCONS_IDX(prod, XNC_OUT); } len = q_to_b(cl, __UNVOLATILE( &XNC_OUT[MASK_XENCONS_IDX(prod, XNC_OUT)]), len); if (len == 0) break; prod = prod + len; } xen_wmb(); xencons_interface->out_prod = prod; xen_wmb(); hypervisor_notify_via_evtchn(xen_start_info.console.domU.evtchn); #undef XNC_OUT } s = spltty(); tp->t_state &= ~TS_BUSY; if (ttypull(tp)) { tp->t_state |= TS_TIMEOUT; callout_schedule(&tp->t_rstrt_ch, 1); } out: splx(s); }