Exemple #1
0
static int
zstty_cncheckc(struct zstty_softc *sc)
{
	uint8_t c;

	c = -1;
	zstty_cnopen(sc);
	if ((ZS_READ(sc, sc->sc_csr) & ZSRR0_RX_READY) != 0)
		c = ZS_READ(sc, sc->sc_data);
	zstty_cnclose(sc);
	return (c);
}
Exemple #2
0
static int
zstty_cngetc(struct zstty_softc *sc)
{
	uint8_t c;

	zstty_cnopen(sc);
	while ((ZS_READ(sc, sc->sc_csr) & ZSRR0_RX_READY) == 0)
		;
	c = ZS_READ(sc, sc->sc_data);
	zstty_cnclose(sc);
	return (c);
}
Exemple #3
0
static void
zstty_cnputc(struct zstty_softc *sc, int c)
{

	zstty_cnopen(sc);
	while ((ZS_READ(sc, sc->sc_csr) & ZSRR0_TX_READY) == 0)
		;
	ZS_WRITE(sc, sc->sc_data, c);
	zstty_cnclose(sc);
}
Exemple #4
0
static void
zstty_flush(struct zstty_softc *sc)
{
	uint8_t rr0;
	uint8_t rr1;
	uint8_t c;

	for (;;) {
		rr0 = ZS_READ(sc, sc->sc_csr);
		if ((rr0 & ZSRR0_RX_READY) == 0)
			break;

		rr1 = ZS_READ_REG(sc, 1);
		c = ZS_READ(sc, sc->sc_data);

		if (rr1 & (ZSRR1_FE | ZSRR1_DO | ZSRR1_PE))
			ZS_WRITE(sc, sc->sc_data, ZSWR0_RESET_ERRORS);
	}
}
Exemple #5
0
static int
zsrint(struct zs_chanstate *cs, struct zschan *zc)
{
	int c;

	/*
	 * First read the status, because read of the received char
	 * destroy the status of this char.
	 */
	c = ZS_READ(zc, 1);
	c |= (zc->zc_data << 8);

	/* clear receive error & interrupt condition */
	zc->zc_csr = ZSWR0_RESET_ERRORS;
	zc->zc_csr = ZSWR0_CLR_INTR;

	return ZRING_MAKE(ZRING_RINT, c);
}
Exemple #6
0
/*
 * Note that the rr3 value is shifted so the channel a status bits are in the
 * channel b bit positions, which makes the bit positions uniform for both
 * channels.
 */
static int
zstty_intr(struct zstty_softc *sc, uint8_t rr3)
{
	int needsoft;
	uint8_t rr0;
	uint8_t rr1;
	uint8_t c;
	int brk;

	ZSTTY_LOCK(sc);

	ZS_WRITE(sc, sc->sc_csr, ZSWR0_CLR_INTR);

	brk = 0;
	needsoft = 0;
	if ((rr3 & ZSRR3_IP_B_RX) != 0) {
		needsoft = 1;
		do {
			/*
			 * First read the status, because reading the received
			 * char destroys the status of this char.
			 */
			rr1 = ZS_READ_REG(sc, 1);
			c = ZS_READ(sc, sc->sc_data);

			if ((rr1 & (ZSRR1_FE | ZSRR1_DO | ZSRR1_PE)) != 0)
				ZS_WRITE(sc, sc->sc_csr, ZSWR0_RESET_ERRORS);
#if defined(DDB) && defined(ALT_BREAK_TO_DEBUGGER)
			if (sc->sc_console != 0)
				brk = db_alt_break(c, &sc->sc_alt_break_state);
#endif
			*sc->sc_iput++ = c;
			*sc->sc_iput++ = rr1;
			if (sc->sc_iput == sc->sc_ibuf + sizeof(sc->sc_ibuf))
				sc->sc_iput = sc->sc_ibuf;
		} while ((ZS_READ(sc, sc->sc_csr) & ZSRR0_RX_READY) != 0);
	}

	if ((rr3 & ZSRR3_IP_B_STAT) != 0) {
		rr0 = ZS_READ(sc, sc->sc_csr);
		ZS_WRITE(sc, sc->sc_csr, ZSWR0_RESET_STATUS);
#if defined(DDB) && defined(BREAK_TO_DEBUGGER)
		if (sc->sc_console != 0 && (rr0 & ZSRR0_BREAK) != 0)
			brk = 1;
#endif
		/* XXX do something about flow control */
	}

	if ((rr3 & ZSRR3_IP_B_TX) != 0) {
		/*
		 * If we've delayed a paramter change, do it now.
		 */
		if (sc->sc_preg_held) {
			sc->sc_preg_held = 0;
			zstty_load_regs(sc);
		}
		if (sc->sc_ocnt > 0) {
			ZS_WRITE(sc, sc->sc_data, *sc->sc_oget++);
			sc->sc_ocnt--;
		} else {
			/*
			 * Disable transmit completion interrupts if
			 * necessary.
			 */
			if ((sc->sc_preg[1] & ZSWR1_TIE) != 0) {
				sc->sc_preg[1] &= ~ZSWR1_TIE;
				sc->sc_creg[1] = sc->sc_preg[1];
				ZS_WRITE_REG(sc, 1, sc->sc_creg[1]);
			}
			sc->sc_tx_done = 1;
			sc->sc_tx_busy = 0;
			needsoft = 1;
		}
	}

	ZSTTY_UNLOCK(sc);

	if (brk != 0)
		breakpoint();

	return (needsoft);
}
Exemple #7
0
int
zshard(void *arg)
{
	struct zs_softc *sc;
	struct zs_chanstate *cs0, *cs1;
	struct zschan *zc;
	int intflags, v, i;
	uint8_t rr3;

	sc = arg;
	intflags = 0;
	cs0 = sc->sc_cs[0];
	cs1 = sc->sc_cs[1];

	do {
		intflags &= ~4;
		rr3 = ZS_READ(cs0->cs_zc, 3);
		if (rr3 & (ZSRR3_IP_A_RX | ZSRR3_IP_A_TX | ZSRR3_IP_A_STAT)) {
			intflags |= 4 | 2;
			zc = cs0->cs_zc;
			i  = cs0->cs_rbput;
			if ((rr3 & ZSRR3_IP_A_RX) != 0 &&
			    (v = zsrint(cs0, zc)) != 0) {
				cs0->cs_rbuf[i++ & ZLRB_RING_MASK] = v;
				intflags |= 1;
			}
			if ((rr3 & ZSRR3_IP_A_TX) != 0 &&
			    (v = zsxint(cs0, zc)) != 0) {
				cs0->cs_rbuf[i++ & ZLRB_RING_MASK] = v;
				intflags |= 1;
			}
			if ((rr3 & ZSRR3_IP_A_STAT) != 0 &&
			    (v = zssint(cs0, zc)) != 0) {
				cs0->cs_rbuf[i++ & ZLRB_RING_MASK] = v;
				intflags |= 1;
			}
			cs0->cs_rbput = i;
		}
		if (rr3 & (ZSRR3_IP_B_RX | ZSRR3_IP_B_TX | ZSRR3_IP_B_STAT)) {
			intflags |= 4 | 2;
			zc = cs1->cs_zc;
			i  = cs1->cs_rbput;
			if ((rr3 & ZSRR3_IP_B_RX) != 0 &&
			    (v = zsrint(cs1, zc)) != 0) {
				cs1->cs_rbuf[i++ & ZLRB_RING_MASK] = v;
				intflags |= 1;
			}
			if ((rr3 & ZSRR3_IP_B_TX) != 0 &&
			    (v = zsxint(cs1, zc)) != 0) {
				cs1->cs_rbuf[i++ & ZLRB_RING_MASK] = v;
				intflags |= 1;
			}
			if ((rr3 & ZSRR3_IP_B_STAT) != 0 &&
			    (v = zssint(cs1, zc)) != 0) {
				cs1->cs_rbuf[i++ & ZLRB_RING_MASK] = v;
				intflags |= 1;
			}
			cs1->cs_rbput = i;
		}
	} while (intflags & 4);

	if (intflags & 1)
		softint_schedule(sc->sc_sicookie);

	return intflags & 2;
}