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); }
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); }
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); }
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); } }
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); }
/* * 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); }
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; }