static void rp_handle_port(struct rp_port *rp) { CHANNEL_t *cp; struct tty *tp; unsigned int IntMask, ChanStatus; if(!rp) return; cp = &rp->rp_channel; tp = rp->rp_tty; IntMask = sGetChanIntID(cp); IntMask = IntMask & rp->rp_intmask; ChanStatus = sGetChanStatus(cp); if(IntMask & RXF_TRIG) rp_do_receive(rp, tp, cp, ChanStatus); if(IntMask & DELTA_CD) { if(ChanStatus & CD_ACT) { (void)ttydisc_modem(tp, 1); } else { (void)ttydisc_modem(tp, 0); } } /* oldcts = rp->rp_cts; rp->rp_cts = ((ChanStatus & CTS_ACT) != 0); if(oldcts != rp->rp_cts) { printf("CTS change (now %s)... on port %d\n", rp->rp_cts ? "on" : "off", rp->rp_port); } */ }
static void nmdm_task_tty(void *arg, int pending __unused) { struct tty *tp, *otp; struct nmdmpart *np = arg; char c; tp = np->np_tty; tty_lock(tp); if (tty_gone(tp)) { tty_unlock(tp); return; } otp = np->np_other->np_tty; KASSERT(otp != NULL, ("NULL otp in nmdmstart")); KASSERT(otp != tp, ("NULL otp == tp nmdmstart")); if (np->np_other->np_dcd) { if (!tty_opened(tp)) { np->np_other->np_dcd = 0; ttydisc_modem(otp, 0); } } else { if (tty_opened(tp)) { np->np_other->np_dcd = 1; ttydisc_modem(otp, 1); } } /* This may happen when we are in detach process. */ if (tty_gone(otp)) { tty_unlock(otp); return; } while (ttydisc_rint_poll(otp) > 0) { if (np->np_rate && !np->np_quota) break; if (ttydisc_getc(tp, &c, 1) != 1) break; np->np_quota--; ttydisc_rint(otp, c, 0); } ttydisc_rint_done(otp); tty_unlock(tp); }
void uart_tty_intr(void *arg) { struct uart_softc *sc = arg; struct tty *tp; int c, err = 0, pend, sig, xc; if (sc->sc_leaving) return; pend = atomic_readandclear_32(&sc->sc_ttypend); if (!(pend & SER_INT_MASK)) return; tp = sc->sc_u.u_tty.tp; tty_lock(tp); if (pend & SER_INT_RXREADY) { while (!uart_rx_empty(sc) && !sc->sc_isquelch) { xc = uart_rx_peek(sc); c = xc & 0xff; if (xc & UART_STAT_FRAMERR) err |= TRE_FRAMING; if (xc & UART_STAT_OVERRUN) err |= TRE_OVERRUN; if (xc & UART_STAT_PARERR) err |= TRE_PARITY; if (ttydisc_rint(tp, c, err) != 0) { sc->sc_isquelch = 1; if ((tp->t_termios.c_cflag & CRTS_IFLOW) && !sc->sc_hwiflow) UART_SETSIG(sc, SER_DRTS); } else uart_rx_next(sc); } } if (pend & SER_INT_BREAK) ttydisc_rint(tp, 0, TRE_BREAK); if (pend & SER_INT_SIGCHG) { sig = pend & SER_INT_SIGMASK; if (sig & SER_DDCD) ttydisc_modem(tp, sig & SER_DCD); if (sig & SER_DCTS) uart_tty_outwakeup(tp); } if (pend & SER_INT_TXIDLE) uart_tty_outwakeup(tp); ttydisc_rint_done(tp); tty_unlock(tp); }
/* * Handle change of modem state */ static void si_modem_state(struct si_port *pp, struct tty *tp, int hi_ip) { /* if a modem dev */ mtx_assert(&Giant, MA_OWNED); if (hi_ip & IP_DCD) { if (!(pp->sp_last_hi_ip & IP_DCD)) { DPRINT((pp, DBG_INTR, "modem carr on%d\n")); (void)ttydisc_modem(tp, 1); } } else { if (pp->sp_last_hi_ip & IP_DCD) { DPRINT((pp, DBG_INTR, "modem carr off\n")); #if 0 /* XXX mpsafetty ttyld_modem used to tell us to shutdown the port or not */ if (ttydisc_modem(tp, 0)) (void) simodem(tp, 0, SER_DTR | SER_RTS); #else ttydisc_modem(tp, 0); #endif } } pp->sp_last_hi_ip = hi_ip; }
static void ucom_cfg_status_change(struct usb_proc_msg *_task) { struct ucom_cfg_task *task = (struct ucom_cfg_task *)_task; struct ucom_softc *sc = task->sc; struct tty *tp; uint8_t new_msr; uint8_t new_lsr; uint8_t onoff; tp = sc->sc_tty; mtx_assert(sc->sc_mtx, MA_OWNED); if (!(sc->sc_flag & UCOM_FLAG_LL_READY)) { return; } if (sc->sc_callback->ucom_cfg_get_status == NULL) { return; } /* get status */ new_msr = 0; new_lsr = 0; (sc->sc_callback->ucom_cfg_get_status) (sc, &new_lsr, &new_msr); if (!(sc->sc_flag & UCOM_FLAG_HL_READY)) { /* TTY device closed */ return; } onoff = ((sc->sc_msr ^ new_msr) & SER_DCD); sc->sc_msr = new_msr; sc->sc_lsr = new_lsr; if (onoff) { onoff = (sc->sc_msr & SER_DCD) ? 1 : 0; DPRINTF("DCD changed to %d\n", onoff); ttydisc_modem(tp, onoff); } }
static int nmdm_modem(struct tty *tp, int sigon, int sigoff) { struct nmdmpart *np = tty_softc(tp); int i = 0; if (sigon || sigoff) { if (sigon & SER_DTR) np->np_other->np_dcd = 1; if (sigoff & SER_DTR) np->np_other->np_dcd = 0; ttydisc_modem(np->np_other->np_tty, np->np_other->np_dcd); return (0); } else { if (np->np_dcd) i |= SER_DCD; if (np->np_other->np_dcd) i |= SER_DTR; return (i); } }
static void ucom_cfg_status_change(struct usb_proc_msg *_task) { struct ucom_cfg_task *task = (struct ucom_cfg_task *)_task; struct ucom_softc *sc = task->sc; struct tty *tp; uint8_t new_msr; uint8_t new_lsr; uint8_t msr_delta; uint8_t lsr_delta; tp = sc->sc_tty; UCOM_MTX_ASSERT(sc, MA_OWNED); if (!(sc->sc_flag & UCOM_FLAG_LL_READY)) { return; } if (sc->sc_callback->ucom_cfg_get_status == NULL) { return; } /* get status */ new_msr = 0; new_lsr = 0; (sc->sc_callback->ucom_cfg_get_status) (sc, &new_lsr, &new_msr); if (!(sc->sc_flag & UCOM_FLAG_HL_READY)) { /* TTY device closed */ return; } msr_delta = (sc->sc_msr ^ new_msr); lsr_delta = (sc->sc_lsr ^ new_lsr); sc->sc_msr = new_msr; sc->sc_lsr = new_lsr; /* * Time pulse counting support. Note that both CTS and DCD are * active-low signals. The status bit is high to indicate that * the signal on the line is low, which corresponds to a PPS * clear event. */ switch(ucom_pps_mode) { case 1: if ((sc->sc_pps.ppsparam.mode & PPS_CAPTUREBOTH) && (msr_delta & SER_CTS)) { pps_capture(&sc->sc_pps); pps_event(&sc->sc_pps, (sc->sc_msr & SER_CTS) ? PPS_CAPTURECLEAR : PPS_CAPTUREASSERT); } break; case 2: if ((sc->sc_pps.ppsparam.mode & PPS_CAPTUREBOTH) && (msr_delta & SER_DCD)) { pps_capture(&sc->sc_pps); pps_event(&sc->sc_pps, (sc->sc_msr & SER_DCD) ? PPS_CAPTURECLEAR : PPS_CAPTUREASSERT); } break; default: break; } if (msr_delta & SER_DCD) { int onoff = (sc->sc_msr & SER_DCD) ? 1 : 0; DPRINTF("DCD changed to %d\n", onoff); ttydisc_modem(tp, onoff); } if ((lsr_delta & ULSR_BI) && (sc->sc_lsr & ULSR_BI)) { DPRINTF("BREAK detected\n"); ttydisc_rint(tp, 0, TRE_BREAK); ttydisc_rint_done(tp); } if ((lsr_delta & ULSR_FE) && (sc->sc_lsr & ULSR_FE)) { DPRINTF("Frame error detected\n"); ttydisc_rint(tp, 0, TRE_FRAMING); ttydisc_rint_done(tp); } if ((lsr_delta & ULSR_PE) && (sc->sc_lsr & ULSR_PE)) { DPRINTF("Parity error detected\n"); ttydisc_rint(tp, 0, TRE_PARITY); ttydisc_rint_done(tp); } }
static void ucom_cfg_status_change(struct usb_proc_msg *_task) { struct ucom_cfg_task *task = (struct ucom_cfg_task *)_task; struct ucom_softc *sc = task->sc; struct tty *tp; uint8_t new_msr; uint8_t new_lsr; uint8_t onoff; uint8_t lsr_delta; tp = sc->sc_tty; UCOM_MTX_ASSERT(sc, MA_OWNED); if (!(sc->sc_flag & UCOM_FLAG_LL_READY)) { return; } if (sc->sc_callback->ucom_cfg_get_status == NULL) { return; } /* get status */ new_msr = 0; new_lsr = 0; (sc->sc_callback->ucom_cfg_get_status) (sc, &new_lsr, &new_msr); if (!(sc->sc_flag & UCOM_FLAG_HL_READY)) { /* TTY device closed */ return; } onoff = ((sc->sc_msr ^ new_msr) & SER_DCD); lsr_delta = (sc->sc_lsr ^ new_lsr); sc->sc_msr = new_msr; sc->sc_lsr = new_lsr; if (onoff) { onoff = (sc->sc_msr & SER_DCD) ? 1 : 0; DPRINTF("DCD changed to %d\n", onoff); ttydisc_modem(tp, onoff); } if ((lsr_delta & ULSR_BI) && (sc->sc_lsr & ULSR_BI)) { DPRINTF("BREAK detected\n"); ttydisc_rint(tp, 0, TRE_BREAK); ttydisc_rint_done(tp); } if ((lsr_delta & ULSR_FE) && (sc->sc_lsr & ULSR_FE)) { DPRINTF("Frame error detected\n"); ttydisc_rint(tp, 0, TRE_FRAMING); ttydisc_rint_done(tp); } if ((lsr_delta & ULSR_PE) && (sc->sc_lsr & ULSR_PE)) { DPRINTF("Parity error detected\n"); ttydisc_rint(tp, 0, TRE_PARITY); ttydisc_rint_done(tp); } }
static void ucom_cfg_status_change(struct usb_proc_msg *_task) { struct ucom_cfg_task *task = (struct ucom_cfg_task *)_task; struct ucom_softc *sc = task->sc; struct tty *tp; int onoff; uint8_t new_msr; uint8_t new_lsr; uint8_t msr_delta; uint8_t lsr_delta; uint8_t pps_signal; tp = sc->sc_tty; UCOM_MTX_ASSERT(sc, MA_OWNED); if (!(sc->sc_flag & UCOM_FLAG_LL_READY)) { return; } if (sc->sc_callback->ucom_cfg_get_status == NULL) { return; } /* get status */ new_msr = 0; new_lsr = 0; (sc->sc_callback->ucom_cfg_get_status) (sc, &new_lsr, &new_msr); if (!(sc->sc_flag & UCOM_FLAG_HL_READY)) { /* TTY device closed */ return; } msr_delta = (sc->sc_msr ^ new_msr); lsr_delta = (sc->sc_lsr ^ new_lsr); sc->sc_msr = new_msr; sc->sc_lsr = new_lsr; /* * Time pulse counting support. */ switch(ucom_pps_mode & UART_PPS_SIGNAL_MASK) { case UART_PPS_CTS: pps_signal = SER_CTS; break; case UART_PPS_DCD: pps_signal = SER_DCD; break; default: pps_signal = 0; break; } if ((sc->sc_pps.ppsparam.mode & PPS_CAPTUREBOTH) && (msr_delta & pps_signal)) { pps_capture(&sc->sc_pps); onoff = (sc->sc_msr & pps_signal) ? 1 : 0; if (ucom_pps_mode & UART_PPS_INVERT_PULSE) onoff = !onoff; pps_event(&sc->sc_pps, onoff ? PPS_CAPTUREASSERT : PPS_CAPTURECLEAR); } if (msr_delta & SER_DCD) { onoff = (sc->sc_msr & SER_DCD) ? 1 : 0; DPRINTF("DCD changed to %d\n", onoff); ttydisc_modem(tp, onoff); } if ((lsr_delta & ULSR_BI) && (sc->sc_lsr & ULSR_BI)) { DPRINTF("BREAK detected\n"); ttydisc_rint(tp, 0, TRE_BREAK); ttydisc_rint_done(tp); } if ((lsr_delta & ULSR_FE) && (sc->sc_lsr & ULSR_FE)) { DPRINTF("Frame error detected\n"); ttydisc_rint(tp, 0, TRE_FRAMING); ttydisc_rint_done(tp); } if ((lsr_delta & ULSR_PE) && (sc->sc_lsr & ULSR_PE)) { DPRINTF("Parity error detected\n"); ttydisc_rint(tp, 0, TRE_PARITY); ttydisc_rint_done(tp); } }