svn commit: r243656 - in stable/9/sys: dev/usb/serial sys
Hans Petter Selasky
hselasky at FreeBSD.org
Wed Nov 28 18:10:05 UTC 2012
Author: hselasky
Date: Wed Nov 28 18:10:05 2012
New Revision: 243656
URL: http://svnweb.freebsd.org/changeset/base/243656
Log:
MFC r242619, r242695, r242702 and r242703:
Implement support for RTS (flow control).
Improve USB serial console support.
Implement a USB serial jitter buffer in receive direction.
Modified:
stable/9/sys/dev/usb/serial/usb_serial.c
stable/9/sys/dev/usb/serial/usb_serial.h
stable/9/sys/sys/param.h
Directory Properties:
stable/9/sys/ (props changed)
stable/9/sys/dev/ (props changed)
Modified: stable/9/sys/dev/usb/serial/usb_serial.c
==============================================================================
--- stable/9/sys/dev/usb/serial/usb_serial.c Wed Nov 28 17:55:18 2012 (r243655)
+++ stable/9/sys/dev/usb/serial/usb_serial.c Wed Nov 28 18:10:05 2012 (r243656)
@@ -162,6 +162,7 @@ static tsw_ioctl_t ucom_ioctl;
static tsw_modem_t ucom_modem;
static tsw_param_t ucom_param;
static tsw_outwakeup_t ucom_outwakeup;
+static tsw_inwakeup_t ucom_inwakeup;
static tsw_free_t ucom_free;
static struct ttydevsw ucom_class = {
@@ -169,6 +170,7 @@ static struct ttydevsw ucom_class = {
.tsw_open = ucom_open,
.tsw_close = ucom_close,
.tsw_outwakeup = ucom_outwakeup,
+ .tsw_inwakeup = ucom_inwakeup,
.tsw_ioctl = ucom_ioctl,
.tsw_param = ucom_param,
.tsw_modem = ucom_modem,
@@ -423,16 +425,13 @@ ucom_attach_tty(struct ucom_super_softc
if ((ucom_cons_softc == NULL) &&
(ssc->sc_unit == ucom_cons_unit) &&
(sc->sc_subunit == ucom_cons_subunit)) {
- struct termios t;
- DPRINTF("unit %d subunit %d is console", ssc->sc_unit, sc->sc_subunit);
+ DPRINTF("unit %d subunit %d is console",
+ ssc->sc_unit, sc->sc_subunit);
ucom_cons_softc = sc;
- memset(&t, 0, sizeof(t));
- t.c_ispeed = ucom_cons_baud;
- t.c_ospeed = t.c_ispeed;
- t.c_cflag = CS8;
+ tty_init_console(tp, ucom_cons_baud);
UCOM_MTX_LOCK(ucom_cons_softc);
ucom_cons_rx_low = 0;
@@ -441,7 +440,7 @@ ucom_attach_tty(struct ucom_super_softc
ucom_cons_tx_high = 0;
sc->sc_flag |= UCOM_FLAG_CONSOLE;
ucom_open(ucom_cons_softc->sc_tty);
- ucom_param(ucom_cons_softc->sc_tty, &t);
+ ucom_param(ucom_cons_softc->sc_tty, &tp->t_termios_init_in);
UCOM_MTX_UNLOCK(ucom_cons_softc);
}
@@ -716,6 +715,10 @@ ucom_open(struct tty *tp)
sc->sc_pls_set = 0;
sc->sc_pls_clr = 0;
+ /* reset jitter buffer */
+ sc->sc_jitterbuf_in = 0;
+ sc->sc_jitterbuf_out = 0;
+
ucom_queue_command(sc, ucom_cfg_open, NULL,
&sc->sc_open_task[0].hdr,
&sc->sc_open_task[1].hdr);
@@ -780,6 +783,46 @@ ucom_close(struct tty *tp)
}
}
+static void
+ucom_inwakeup(struct tty *tp)
+{
+ struct ucom_softc *sc = tty_softc(tp);
+ uint16_t pos;
+
+ if (sc == NULL)
+ return;
+
+ UCOM_MTX_ASSERT(sc, MA_OWNED);
+
+ DPRINTF("tp=%p\n", tp);
+
+ if (ttydisc_can_bypass(tp) != 0 ||
+ (sc->sc_flag & UCOM_FLAG_HL_READY) == 0) {
+ return;
+ }
+
+ pos = sc->sc_jitterbuf_out;
+
+ while (sc->sc_jitterbuf_in != pos) {
+ int c;
+
+ c = (char)sc->sc_jitterbuf[pos];
+
+ if (ttydisc_rint(tp, c, 0) == -1)
+ break;
+ pos++;
+ if (pos >= UCOM_JITTERBUF_SIZE)
+ pos -= UCOM_JITTERBUF_SIZE;
+ }
+
+ sc->sc_jitterbuf_out = pos;
+
+ /* clear RTS in async fashion */
+ if ((sc->sc_jitterbuf_in == pos) &&
+ (sc->sc_flag & UCOM_FLAG_RTS_IFLOW))
+ ucom_rts(sc, 0);
+}
+
static int
ucom_ioctl(struct tty *tp, u_long cmd, caddr_t data, struct thread *td)
{
@@ -1139,17 +1182,22 @@ ucom_param(struct tty *tp, struct termio
if (!(sc->sc_flag & UCOM_FLAG_HL_READY)) {
/* XXX the TTY layer should call "open()" first! */
-
+ /*
+ * Not quite: Its ordering is partly backwards, but
+ * some parameters must be set early in ttydev_open(),
+ * possibly before calling ttydevsw_open().
+ */
error = ucom_open(tp);
- if (error) {
+ if (error)
goto done;
- }
+
opened = 1;
}
DPRINTF("sc = %p\n", sc);
/* Check requested parameters. */
if (t->c_ispeed && (t->c_ispeed != t->c_ospeed)) {
+ /* XXX c_ospeed == 0 is perfectly valid. */
DPRINTF("mismatch ispeed and ospeed\n");
error = EINVAL;
goto done;
@@ -1360,6 +1408,11 @@ ucom_put_data(struct ucom_softc *sc, str
/* first check if we can pass the buffer directly */
if (ttydisc_can_bypass(tp)) {
+
+ /* clear any jitter buffer */
+ sc->sc_jitterbuf_in = 0;
+ sc->sc_jitterbuf_out = 0;
+
if (ttydisc_rint_bypass(tp, buf, cnt) != cnt) {
DPRINTF("tp=%p, data lost\n", tp);
}
@@ -1368,8 +1421,31 @@ ucom_put_data(struct ucom_softc *sc, str
/* need to loop */
for (cnt = 0; cnt != res.length; cnt++) {
- if (ttydisc_rint(tp, buf[cnt], 0) == -1) {
- /* XXX what should we do? */
+ if (sc->sc_jitterbuf_in != sc->sc_jitterbuf_out ||
+ ttydisc_rint(tp, buf[cnt], 0) == -1) {
+ uint16_t end;
+ uint16_t pos;
+
+ pos = sc->sc_jitterbuf_in;
+ end = sc->sc_jitterbuf_out +
+ UCOM_JITTERBUF_SIZE - 1;
+ if (end >= UCOM_JITTERBUF_SIZE)
+ end -= UCOM_JITTERBUF_SIZE;
+
+ for (; cnt != res.length; cnt++) {
+ if (pos == end)
+ break;
+ sc->sc_jitterbuf[pos] = buf[cnt];
+ pos++;
+ if (pos >= UCOM_JITTERBUF_SIZE)
+ pos -= UCOM_JITTERBUF_SIZE;
+ }
+
+ sc->sc_jitterbuf_in = pos;
+
+ /* set RTS in async fashion */
+ if (sc->sc_flag & UCOM_FLAG_RTS_IFLOW)
+ ucom_rts(sc, 1);
DPRINTF("tp=%p, lost %d "
"chars\n", tp, res.length - cnt);
Modified: stable/9/sys/dev/usb/serial/usb_serial.h
==============================================================================
--- stable/9/sys/dev/usb/serial/usb_serial.h Wed Nov 28 17:55:18 2012 (r243655)
+++ stable/9/sys/dev/usb/serial/usb_serial.h Wed Nov 28 18:10:05 2012 (r243656)
@@ -78,6 +78,7 @@
#define UCOM_MINVER 1
#define UCOM_PREFVER UCOM_MODVER
#define UCOM_MAXVER 1
+#define UCOM_JITTERBUF_SIZE 128 /* bytes */
struct usb_device;
struct ucom_softc;
@@ -169,6 +170,8 @@ struct ucom_softc {
struct mtx *sc_mtx;
void *sc_parent;
int sc_subunit;
+ uint16_t sc_jitterbuf_in;
+ uint16_t sc_jitterbuf_out;
uint16_t sc_portno;
uint16_t sc_flag;
#define UCOM_FLAG_RTS_IFLOW 0x01 /* use RTS input flow control */
@@ -191,6 +194,7 @@ struct ucom_softc {
#define UCOM_LS_RTS 0x02
#define UCOM_LS_BREAK 0x04
#define UCOM_LS_RING 0x08
+ uint8_t sc_jitterbuf[UCOM_JITTERBUF_SIZE];
};
#define UCOM_MTX_ASSERT(sc, what) mtx_assert((sc)->sc_mtx, what)
Modified: stable/9/sys/sys/param.h
==============================================================================
--- stable/9/sys/sys/param.h Wed Nov 28 17:55:18 2012 (r243655)
+++ stable/9/sys/sys/param.h Wed Nov 28 18:10:05 2012 (r243656)
@@ -58,7 +58,7 @@
* in the range 5 to 9.
*/
#undef __FreeBSD_version
-#define __FreeBSD_version 901501 /* Master, propagated to newvers */
+#define __FreeBSD_version 901502 /* Master, propagated to newvers */
/*
* __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,
More information about the svn-src-all
mailing list