/* * Status Change interrupt. * Called at splzs(). */ void zstty_stint(struct zs_chanstate *cs, int force) { struct zstty_softc *zst = cs->cs_private; struct tty *tp = zst->zst_tty; uint8_t rr0, delta; rr0 = zs_read_csr(cs); zs_write_csr(cs, ZSWR0_RESET_STATUS); /* * Check here for console break, so that we can abort * even when interrupts are locking up the machine. */ if ((zst->zst_hwflags & ZS_HWFLAG_CONSOLE_INPUT) && ISSET(rr0, ZSRR0_BREAK) && DB_CONSOLE) zs_abort(cs); if (!force) delta = rr0 ^ cs->cs_rr0; else delta = cs->cs_rr0_mask; ttytstamp(tp, cs->cs_rr0 & ZSRR0_CTS, rr0 & ZSRR0_CTS, cs->cs_rr0 & ZSRR0_DCD, rr0 & ZSRR0_DCD); cs->cs_rr0 = rr0; if (ISSET(delta, cs->cs_rr0_mask)) { SET(cs->cs_rr0_delta, delta); /* * Stop output immediately if we lose the output * flow control signal or carrier detect. */ if (ISSET(~rr0, cs->cs_rr0_mask)) { zst->zst_tbc = 0; zst->zst_heldtbc = 0; } zst->zst_st_check = 1; cs->cs_softreq = 1; } }
void ucom_status_change(struct ucom_softc *sc) { struct tty *tp = sc->sc_tty; u_char old_msr; if (sc->sc_methods->ucom_get_status != NULL) { old_msr = sc->sc_msr; sc->sc_methods->ucom_get_status(sc->sc_parent, sc->sc_portno, &sc->sc_lsr, &sc->sc_msr); ttytstamp(tp, old_msr & UMSR_CTS, sc->sc_msr & UMSR_CTS, old_msr & UMSR_DCD, sc->sc_msr & UMSR_DCD); if (ISSET((sc->sc_msr ^ old_msr), UMSR_DCD)) (*LINESW(tp, l_modem))(tp, ISSET(sc->sc_msr, UMSR_DCD)); } else { sc->sc_lsr = 0; sc->sc_msr = 0; } }
int sxiuart_intr(void *arg) { struct sxiuart_softc *sc = arg; bus_space_tag_t iot = sc->sc_iot; bus_space_handle_t ioh = sc->sc_ioh; struct tty *tp; uint32_t cnt; uint8_t c, iir, lsr, msr, delta; uint8_t *p; iir = bus_space_read_1(iot, ioh, SXIUART_IIR); if ((iir & IIR_IMASK) == IIR_BUSY) { (void)bus_space_read_1(iot, ioh, SXIUART_USR); return (0); } if (ISSET(iir, IIR_NOPEND)) return (0); if (sc->sc_tty == NULL) return (0); tp = sc->sc_tty; cnt = 0; loop: lsr = bus_space_read_1(iot, ioh, SXIUART_LSR); if (ISSET(lsr, LSR_RXRDY)) { if (cnt == 0) { p = sc->sc_ibufp; softintr_schedule(sc->sc_si); } cnt++; c = bus_space_read_1(iot, ioh, SXIUART_RBR); if (ISSET(lsr, LSR_BI)) { #if defined(DDB) if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) { if (db_console) Debugger(); goto loop; } #endif c = 0; } if (p >= sc->sc_ibufend) { sc->sc_floods++; if (sc->sc_errors++ == 0) timeout_add_sec(&sc->sc_diag_tmo, 60); } else { *p++ = c; *p++ = lsr; if (p == sc->sc_ibufhigh && ISSET(tp->t_cflag, CRTSCTS)) { /* XXX */ CLR(sc->sc_mcr, MCR_RTS); bus_space_write_1(iot, ioh, SXIUART_MCR, sc->sc_mcr); } } goto loop; } else if (cnt > 0) sc->sc_ibufp = p; msr = bus_space_read_1(iot, ioh, SXIUART_MSR); if (msr != sc->sc_msr) { delta = msr ^ sc->sc_msr; ttytstamp(tp, sc->sc_msr & MSR_CTS, msr & MSR_CTS, sc->sc_msr & MSR_DCD, msr & MSR_DCD); sc->sc_msr = msr; if (ISSET(delta, MSR_DCD)) { if (!ISSET(sc->sc_swflags, COM_SW_SOFTCAR) && (*linesw[tp->t_line].l_modem)(tp, ISSET(msr, MSR_DCD)) == 0) { CLR(sc->sc_mcr, sc->sc_dtr); bus_space_write_1(iot, ioh, SXIUART_MCR, sc->sc_mcr); } } if (ISSET(delta & msr, MSR_CTS) && ISSET(tp->t_cflag, CRTSCTS)) (*linesw[tp->t_line].l_start)(tp); } if (ISSET(tp->t_state, TS_BUSY) && ISSET(lsr, LSR_TXRDY)) { CLR(tp->t_state, TS_BUSY | TS_FLUSH); if (sc->sc_halt > 0) wakeup(&tp->t_outq); (*linesw[tp->t_line].l_start)(tp); } iir = bus_space_read_1(iot, ioh, SXIUART_IIR); if (ISSET(iir, IIR_NOPEND)) goto done; cnt = 0; goto loop; done: return (1); }