示例#1
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);
}
示例#2
0
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);
}
示例#3
0
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);
}
示例#4
0
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);
}
示例#5
0
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);
}
示例#6
0
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);
}
示例#7
0
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;
}
示例#8
0
/*
 * 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);
}
示例#9
0
/*
 * 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);
}
示例#10
0
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;
}
示例#12
0
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;
}
示例#13
0
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;
}
示例#14
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);
}
示例#16
0
文件: gtmpsc.c 项目: ryo/netbsd-src
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(&gtmpsc_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);
}
示例#17
0
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);
}
示例#18
0
/*
 * 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);
}
示例#19
0
文件: ite.c 项目: lacombar/netbsd-alc
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);
}
示例#20
0
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);
}