From owner-p4-projects@FreeBSD.ORG Wed Sep 3 02:46:08 2003 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 0B2E416A4C1; Wed, 3 Sep 2003 02:46:08 -0700 (PDT) Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 8E01416A4BF for ; Wed, 3 Sep 2003 02:46:07 -0700 (PDT) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 10B6A43FE9 for ; Wed, 3 Sep 2003 02:46:07 -0700 (PDT) (envelope-from marcel@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.12.6/8.12.6) with ESMTP id h839k60U068480 for ; Wed, 3 Sep 2003 02:46:06 -0700 (PDT) (envelope-from marcel@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.12.6/8.12.6/Submit) id h839k6VT068477 for perforce@freebsd.org; Wed, 3 Sep 2003 02:46:06 -0700 (PDT) Date: Wed, 3 Sep 2003 02:46:06 -0700 (PDT) Message-Id: <200309030946.h839k6VT068477@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to marcel@freebsd.org using -f From: Marcel Moolenaar To: Perforce Change Reviews Subject: PERFORCE change 37439 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 03 Sep 2003 09:46:08 -0000 http://perforce.freebsd.org/chv.cgi?CH=37439 Change 37439 by marcel@marcel_nfs on 2003/09/03 02:45:48 Implement flow control. Note that none of the hardware drivers report that they have hardware support for flow control, so it's all software based for now. The logic is there to set hardware flow control... Affected files ... .. //depot/projects/uart/dev/uart/uart_tty.c#12 edit Differences ... ==== //depot/projects/uart/dev/uart/uart_tty.c#12 (text+ko) ==== @@ -160,22 +160,36 @@ if (sc == NULL || sc->sc_leaving) return; - if (tp->t_state & TS_TBLOCK) - UART_SETSIG(sc, UART_SIG_DRTS); - else - UART_SETSIG(sc, UART_SIG_DRTS|UART_SIG_RTS); + /* + * Handle input flow control. Note that if we have hardware support, + * we don't do anything here. We continue to receive until our buffer + * is full. At that time we cannot empty the UART itself and it will + * de-assert RTS for us. In that situation we're completely stuffed. + * Without hardware support, we need to toggle RTS ourselves. + */ + if ((tp->t_cflag & CRTS_IFLOW) && !sc->sc_hwiflow) { + if ((tp->t_state & TS_TBLOCK) && + (sc->sc_hwsig & UART_SIG_RTS)) + UART_SETSIG(sc, UART_SIG_DRTS); + else if (!(tp->t_state & TS_TBLOCK) && + !(sc->sc_hwsig & UART_SIG_RTS)) + UART_SETSIG(sc, UART_SIG_DRTS|UART_SIG_RTS); + } + + if (tp->t_state & TS_TTSTOP) + return; + + if ((tp->t_state & TS_BUSY) || sc->sc_txbusy) + return; - if (tp->t_state & (TS_BUSY | TS_TIMEOUT | TS_TTSTOP)) { + if (tp->t_outq.c_cc == 0) { ttwwakeup(tp); return; } - if (tp->t_outq.c_cc > 0 && !sc->sc_txbusy) { - sc->sc_txdatasz = q_to_b(&tp->t_outq, sc->sc_txbuf, - sc->sc_txfifosz); - tp->t_state |= TS_BUSY; - UART_TRANSMIT(sc); - } + sc->sc_txdatasz = q_to_b(&tp->t_outq, sc->sc_txbuf, sc->sc_txfifosz); + tp->t_state |= TS_BUSY; + UART_TRANSMIT(sc); ttwwakeup(tp); } @@ -215,8 +229,17 @@ parity = UART_PARITY_NONE; UART_PARAM(sc, t->c_ospeed, databits, stopbits, parity); UART_SETSIG(sc, UART_SIG_DDTR | UART_SIG_DTR); - if ((t->c_cflag & CRTS_IFLOW) == 0) - UART_SETSIG(sc, UART_SIG_DRTS | UART_SIG_RTS); + /* Set input flow control state. */ + if (!sc->sc_hwiflow) { + if ((t->c_cflag & CRTS_IFLOW) && (tp->t_state & TS_TBLOCK)) + UART_SETSIG(sc, UART_SIG_DRTS); + else + UART_SETSIG(sc, UART_SIG_DRTS | UART_SIG_RTS); + } else + UART_IOCTL(sc, UART_IOCTL_IFLOW, (t->c_cflag & CRTS_IFLOW)); + /* Set output flow control state. */ + if (sc->sc_hwoflow) + UART_IOCTL(sc, UART_IOCTL_OFLOW, (t->c_cflag & CCTS_OFLOW)); ttsetwater(tp); return (0); } @@ -260,7 +283,7 @@ tp = sc->sc_u.u_tty.tp; if (pend & UART_IPEND_RXREADY) { - while (!uart_rx_empty(sc)) { + while (!uart_rx_empty(sc) && !(tp->t_state & TS_TBLOCK)) { xc = uart_rx_get(sc); c = xc & 0xff; if (xc & UART_STAT_FRAMERR) @@ -280,6 +303,14 @@ sig = pend & UART_IPEND_SIGMASK; if (sig & UART_SIG_DDCD) (*linesw[tp->t_line].l_modem)(tp, sig & UART_SIG_DCD); + if ((sig & UART_SIG_DCTS) && (tp->t_cflag & CCTS_OFLOW) && + !sc->sc_hwoflow) { + if (sig & UART_SIG_CTS) { + tp->t_state &= ~TS_TTSTOP; + (*linesw[tp->t_line].l_start)(tp); + } else + tp->t_state |= TS_TTSTOP; + } } if (pend & UART_IPEND_TXIDLE) {