示例#1
0
文件: rp.c 项目: coyizumi/cs111
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);
	}
*/
}
示例#2
0
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);
}
示例#3
0
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);
}
示例#4
0
文件: si.c 项目: edgar-pek/PerspicuOS
/*
 * 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);
	}
}
示例#6
0
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);
	}
}
示例#7
0
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);
	}
}
示例#8
0
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);
	}
}
示例#9
0
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);
	}
}