示例#1
0
void
zskbd_softint(struct zs_chanstate *cs)
{
	struct zskbd_softc *sc = cs->cs_private;
	struct zskbd_devconfig *dc = sc->sc_dc;
	int rr0;

	/* handle pending transmissions */
	if (dc->txq_head != dc->txq_tail) {
		int s;

		s = splzs();
		while (dc->txq_head != dc->txq_tail) {
			rr0 = zs_read_csr(cs);
			if ((rr0 & ZSRR0_TX_READY) == 0)
				break;
			zs_write_data(cs, dc->txq[dc->txq_head]);
			dc->txq_head = (dc->txq_head + 1) & ~ZSKBD_TXQ_LEN;
		}
		splx(s);
	}

	/* handle incoming keystrokes/config */
	while (dc->rxq_head != dc->rxq_tail) {
		zskbd_process(cs, dc->rxq[dc->rxq_head]);
		dc->rxq_head = (dc->rxq_head + 1) & ~ZSKBD_RXQ_LEN;
	}
}
示例#2
0
/*
 * Polled output char.
 */
static void
zs_putc(int c)
{
	int s, rr0;

	s = splzs();
	/* Wait for transmitter to become ready. */
	do {
		rr0 = zs_read_csr(&zscn_cs);
	} while ((rr0 & ZSRR0_TX_READY) == 0);

	zs_write_data(&zscn_cs, c);
	splx(s);
}
示例#3
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);
}
示例#4
0
/* expects to be in splzs() */
int
zskbd_send(struct zs_chanstate *cs, uint8_t *c, u_int len)
{
	struct zskbd_softc     *sc = cs->cs_private;
	struct zskbd_devconfig *dc = sc->sc_dc;
	u_int i;
	int rr0;

	while (len != 0) {
		rr0 = zs_read_csr(cs);
		if ((rr0 & ZSRR0_TX_READY) == 0) {
			/*
			 * poll until whole transmission complete during
			 * autoconf
			 */
			if (cold) {
				for (i = 1000; i != 0; i--) {
					if ((rr0 & ZSRR0_TX_READY) != 0)
						break;
					delay(100);
				}
				if (i == 0)
					return EIO;
			} else
				break;
		}
		zs_write_data(cs, *c++);
		len--;
	}

	/*
	 * Enqueue any remaining bytes.
	 */
	while (len != 0) {
		dc->txq[dc->txq_tail] = *c++;
		dc->txq_tail = (dc->txq_tail + 1) & ~ZSKBD_TXQ_LEN;
		len--;
		cs->cs_softreq = 1;
	}

	return 0;
}
/* expects to be in splzs() */
static void
ewskbd_zsc_send(struct zs_chanstate *cs, uint8_t *c, u_int len)
{
	struct ewskbd_softc *sc;
	struct ewskbd_devconfig *dc;
	int i;

	sc = cs->cs_private;
	dc = sc->sc_dc;

	for (i = 0; i < len; i++) {
		if (dc->state & TX_READY) {
			zs_write_data(cs, c[i]);
			dc->state &= ~TX_READY;
		} else {
			dc->txq[dc->txq_tail] = c[i];
			dc->txq_tail = EWSKBD_NEXTTXQ(dc->txq_tail);
			cs->cs_softreq = 1;
		}
	}
}
static void
ewskbd_zsc_softint(struct zs_chanstate *cs)
{
	struct ewskbd_softc *sc;
	struct ewskbd_devconfig *dc;

	sc = cs->cs_private;
	dc = sc->sc_dc;

	/* handle pending transmissions */
	if (dc->txq_head != dc->txq_tail && (dc->state & TX_READY)) {
		int s;

		dc->state &= ~TX_READY;

		s = splzs();
		zs_write_data(cs, dc->txq[dc->txq_head]);
		splx(s);

		dc->txq_head = EWSKBD_NEXTTXQ(dc->txq_head);
	}

	/* don't bother if nobody is listening */
	if (!dc->enabled) {
		dc->rxq_head = dc->rxq_tail;
		return;
	}

	/* handle incoming keystrokes/config */
	while (dc->rxq_head != dc->rxq_tail) {
		uint8_t key = dc->rxq[dc->rxq_head];

		/* toss wskbd a bone */
		ewskbd_wskbd_input(cs, key);

		dc->rxq_head = EWSKBD_NEXTRXQ(dc->rxq_head);
	}
}
示例#7
0
/*
 * Transmitter Ready interrupt.
 * Called at splzs().
 */
void
zstty_txint(struct zs_chanstate *cs)
{
	struct zstty_softc *zst = cs->cs_private;
	int rr0;

	zs_write_csr(cs, ZSWR0_RESET_TXINT);

	/*
	 * If we've delayed a parameter change, do it now, and restart
	 * output.
	 */
	if (cs->cs_heldchange) {
		zs_loadchannelregs(cs);
		cs->cs_heldchange = 0;
		zst->zst_tbc = zst->zst_heldtbc;
		zst->zst_heldtbc = 0;
	}

	while (zst->zst_tbc > 0) {
		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++;
	}

	if (zst->zst_tbc == 0) {
		if (zst->zst_tx_busy) {
			zst->zst_tx_busy = 0;
			zst->zst_tx_done = 1;
			cs->cs_softreq = 1;
		}
	}
}