Sun Jan 12 12:21:16 2014 UTC ()
Pull up following revision(s) (requested by tsutsui in ticket #1004):
	sys/arch/luna68k/dev/siotty.c: revision 1.35
	sys/arch/luna68k/dev/siotty.c: revision 1.36
	sys/arch/luna68k/dev/siotty.c: revision 1.37
	sys/arch/luna68k/dev/siotty.c: revision 1.38
	sys/arch/luna68k/dev/lunaws.c: revision 1.25
	sys/arch/luna68k/dev/lunaws.c: revision 1.26
	sys/arch/luna68k/dev/lunaws.c: revision 1.27
	sys/arch/luna68k/dev/siovar.h: revision 1.7
	sys/arch/luna68k/dev/siotty.c: revision 1.34
struct device * -> device_t, use device_xname()  (from chs@)
Whitespace cleanup.
Use softint(9) to pass received data into wskbd(9) and wsmouse(9) layers.
It might be problematic to call them from an interrupt handler at IPL_SERIAL.
Tab/space cleanup.
Use softint(9) properly to process TX/RX data between tty(4) layer.
It could cause possible locking issue to call tty(4) layer functions
from IPL_SERIAL interrupt handlers.
Changes details (mostly similar to com(4) and z8530tty(4)):
 - allocate RX buffer and put data and status into it in the interrupt handler
 - call t_linesw->l_rint from the software interrupt handler
 - set the only first byte in siottystart() and use t_outq buffer to send
   multiple TX data
 - call the next t_linesw->l_start on TX complete in the software interrupt
   handler
Also put more changes:
 - handle cnmagic(9) properly (now entering ddb(4) by console BREAK works)
 - allocate tty in the attach function as other drivers rather than first open
 - use proper variable types
Remove initialization of unused t_softc in struct tty (to make pullup easier).


(bouyer)
diff -r1.23.8.1 -r1.23.8.2 src/sys/arch/luna68k/dev/lunaws.c
diff -r1.33 -r1.33.4.1 src/sys/arch/luna68k/dev/siotty.c
diff -r1.6 -r1.6.8.1 src/sys/arch/luna68k/dev/siovar.h

cvs diff -r1.23.8.1 -r1.23.8.2 src/sys/arch/luna68k/dev/lunaws.c (expand / switch to context diff)
--- src/sys/arch/luna68k/dev/lunaws.c 2012/07/25 21:30:35 1.23.8.1
+++ src/sys/arch/luna68k/dev/lunaws.c 2014/01/12 12:21:16 1.23.8.2
@@ -1,4 +1,4 @@
-/* $NetBSD: lunaws.c,v 1.23.8.1 2012/07/25 21:30:35 martin Exp $ */
+/* $NetBSD: lunaws.c,v 1.23.8.2 2014/01/12 12:21:16 bouyer Exp $ */
 
 /*-
  * Copyright (c) 2000 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
 
 #include <sys/cdefs.h>			/* RCS ID & Copyright macro defns */
 
-__KERNEL_RCSID(0, "$NetBSD: lunaws.c,v 1.23.8.1 2012/07/25 21:30:35 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: lunaws.c,v 1.23.8.2 2014/01/12 12:21:16 bouyer Exp $");
 
 #include "wsmouse.h"
 
@@ -51,6 +51,10 @@
 
 #include "ioconf.h"
 
+#define OMKBD_RXQ_LEN		64
+#define OMKBD_RXQ_LEN_MASK	(OMKBD_RXQ_LEN - 1)
+#define OMKBD_NEXTRXQ(x)	(((x) + 1) & OMKBD_RXQ_LEN_MASK)
+
 static const uint8_t ch1_regs[6] = {
 	WR0_RSTINT,				/* Reset E/S Interrupt */
 	WR1_RXALLS,				/* Rx per char, No Tx */
@@ -64,12 +68,16 @@
 	device_t	sc_dev;
 	struct sioreg	*sc_ctl;
 	uint8_t		sc_wr[6];
-	struct device	*sc_wskbddev;
+	device_t	sc_wskbddev;
+	uint8_t		sc_rxq[OMKBD_RXQ_LEN];
+	u_int		sc_rxqhead;
+	u_int		sc_rxqtail;
 #if NWSMOUSE > 0
-	struct device	*sc_wsmousedev;
+	device_t	sc_wsmousedev;
 	int		sc_msreport;
-	int		buttons, dx, dy;
+	int		sc_msbuttons, sc_msdx, sc_msdy;
 #endif
+	void		*sc_si;
 };
 
 static void omkbd_input(void *, int);
@@ -111,6 +119,7 @@
 #endif
 
 static void wsintr(int);
+static void wssoftintr(void *);
 
 static int  wsmatch(device_t, cfdata_t, void *);
 static void wsattach(device_t, device_t, void *);
@@ -143,7 +152,7 @@
 	sc->sc_ctl = (struct sioreg *)scp->scp_ctl + 1;
 	memcpy(sc->sc_wr, ch1_regs, sizeof(ch1_regs));
 	scp->scp_intr[1] = wsintr;
-	
+
 	setsioreg(sc->sc_ctl, WR0, sc->sc_wr[WR0]);
 	setsioreg(sc->sc_ctl, WR4, sc->sc_wr[WR4]);
 	setsioreg(sc->sc_ctl, WR3, sc->sc_wr[WR3]);
@@ -153,6 +162,11 @@
 
 	syscnputc((dev_t)1, 0x20); /* keep quiet mouse */
 
+	sc->sc_rxqhead = 0;
+	sc->sc_rxqtail = 0;
+
+	sc->sc_si = softint_establish(SOFTINT_SERIAL, wssoftintr, sc);
+
 	aprint_normal("\n");
 
 	a.console = (args->hwflags == 1);
@@ -165,7 +179,7 @@
 	{
 	struct wsmousedev_attach_args b;
 	b.accessops = &omms_accessops;
-	b.accesscookie = (void *)sc;	
+	b.accesscookie = (void *)sc;
 	sc->sc_wsmousedev =
 	    config_found_ia(self, "wsmousedev", &b, wsmousedevprint);
 	sc->sc_msreport = 0;
@@ -179,7 +193,7 @@
 {
 	struct ws_softc *sc = device_lookup_private(&ws_cd, 0);
 	struct sioreg *sio = sc->sc_ctl;
-	u_int code;
+	uint8_t code;
 	int rr;
 
 	rr = getsiocsr(sio);
@@ -190,43 +204,10 @@
 				sio->sio_cmd = WR0_ERRRST;
 				continue;
 			}
-#if NWSMOUSE > 0
-			/*
-			 * if (code >= 0x80 && code <= 0x87), then
-			 * it's the first byte of 3 byte long mouse report
-			 * 	code[0] & 07 -> LMR button condition
-			 *	code[1], [2] -> x,y delta
-			 * otherwise, key press or release event.
-			 */
-			if (sc->sc_msreport == 0) {
-				if (code < 0x80 || code > 0x87) {
-					omkbd_input(sc, code);
-					continue;
-				}
-				code = (code & 07) ^ 07;
-				/* LMR->RML: wsevent counts 0 for leftmost */
-				sc->buttons = (code & 02);
-				if (code & 01)
-					sc->buttons |= 04;
-				if (code & 04)
-					sc->buttons |= 01;
-				sc->sc_msreport = 1;
-			} else if (sc->sc_msreport == 1) {
-				sc->dx = (signed char)code;
-				sc->sc_msreport = 2;
-			} else if (sc->sc_msreport == 2) {
-				sc->dy = (signed char)code;
-				wsmouse_input(sc->sc_wsmousedev,
-						sc->buttons,
-						sc->dx, sc->dy, 0, 0,
-						WSMOUSE_INPUT_DELTA);
-
-				sc->sc_msreport = 0;
-			}
-#else
-			omkbd_input(sc, code);
-#endif
+			sc->sc_rxq[sc->sc_rxqtail] = code;
+			sc->sc_rxqtail = OMKBD_NEXTRXQ(sc->sc_rxqtail);
 		} while ((rr = getsiocsr(sio)) & RR_RXRDY);
+		softint_schedule(sc->sc_si);
 	}
 	if (rr & RR_TXRDY)
 		sio->sio_cmd = WR0_RSTPEND;
@@ -234,6 +215,53 @@
 }
 
 static void
+wssoftintr(void *arg)
+{
+	struct ws_softc *sc = arg;
+	uint8_t code;
+
+	while (sc->sc_rxqhead != sc->sc_rxqtail) {
+		code = sc->sc_rxq[sc->sc_rxqhead];
+		sc->sc_rxqhead = OMKBD_NEXTRXQ(sc->sc_rxqhead);
+#if NWSMOUSE > 0
+		/*
+		 * if (code >= 0x80 && code <= 0x87), then
+		 * it's the first byte of 3 byte long mouse report
+		 *	code[0] & 07 -> LMR button condition
+		 *	code[1], [2] -> x,y delta
+		 * otherwise, key press or release event.
+		 */
+		if (sc->sc_msreport == 0) {
+			if (code < 0x80 || code > 0x87) {
+				omkbd_input(sc, code);
+				continue;
+			}
+			code = (code & 07) ^ 07;
+			/* LMR->RML: wsevent counts 0 for leftmost */
+			sc->sc_msbuttons = (code & 02);
+			if (code & 01)
+				sc->sc_msbuttons |= 04;
+			if (code & 04)
+				sc->sc_msbuttons |= 01;
+			sc->sc_msreport = 1;
+		} else if (sc->sc_msreport == 1) {
+			sc->sc_msdx = (int8_t)code;
+			sc->sc_msreport = 2;
+		} else if (sc->sc_msreport == 2) {
+			sc->sc_msdy = (int8_t)code;
+			wsmouse_input(sc->sc_wsmousedev,
+			    sc->sc_msbuttons, sc->sc_msdx, sc->sc_msdy, 0, 0,
+			    WSMOUSE_INPUT_DELTA);
+
+			sc->sc_msreport = 0;
+		}
+#else
+		omkbd_input(sc, code);
+#endif
+	}
+}
+
+static void
 omkbd_input(void *v, int data)
 {
 	struct ws_softc *sc = v;
@@ -241,7 +269,7 @@
 	int key;
 
 	if (omkbd_decode(v, data, &type, &key))
-		wskbd_input(sc->sc_wskbddev, type, key);	
+		wskbd_input(sc->sc_wskbddev, type, key);
 }
 
 static int
@@ -257,8 +285,8 @@
 
 static const keysym_t omkbd_keydesc_1[] = {
 /*  pos      command		normal		shifted */
-    KC(0x9), 			KS_Tab,
-    KC(0xa),  			KS_Control_L,
+    KC(0x9),			KS_Tab,
+    KC(0xa),			KS_Control_L,
     KC(0xb),			KS_Mode_switch,	/* Kana */
     KC(0xc),			KS_Shift_R,
     KC(0xd),			KS_Shift_L,
@@ -281,7 +309,7 @@
     KC(0x1f),			KS_KP_Down,
  /* KC(0x20),			KS_f11, */
  /* KC(0x21),			KS_f12, */
-    KC(0x22),  			KS_1,		KS_exclam,
+    KC(0x22),			KS_1,		KS_exclam,
     KC(0x23),			KS_2,		KS_quotedbl,
     KC(0x24),			KS_3,		KS_numbersign,
     KC(0x25),			KS_4,		KS_dollar,

cvs diff -r1.33 -r1.33.4.1 src/sys/arch/luna68k/dev/siotty.c (expand / switch to context diff)
--- src/sys/arch/luna68k/dev/siotty.c 2011/11/26 04:40:50 1.33
+++ src/sys/arch/luna68k/dev/siotty.c 2014/01/12 12:21:16 1.33.4.1
@@ -1,4 +1,4 @@
-/* $NetBSD: siotty.c,v 1.33 2011/11/26 04:40:50 tsutsui Exp $ */
+/* $NetBSD: siotty.c,v 1.33.4.1 2014/01/12 12:21:16 bouyer Exp $ */
 
 /*-
  * Copyright (c) 2000 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
 
 #include <sys/cdefs.h>			/* RCS ID & Copyright macro defns */
 
-__KERNEL_RCSID(0, "$NetBSD: siotty.c,v 1.33 2011/11/26 04:40:50 tsutsui Exp $");
+__KERNEL_RCSID(0, "$NetBSD: siotty.c,v 1.33.4.1 2014/01/12 12:21:16 bouyer Exp $");
 
 #include "opt_ddb.h"
 
@@ -47,6 +47,7 @@
 #include <sys/fcntl.h>
 #include <dev/cons.h>
 #include <sys/kauth.h>
+#include <sys/kmem.h>
 
 #include <machine/cpu.h>
 
@@ -59,7 +60,7 @@
 
 static const uint8_t ch0_regs[6] = {
 	WR0_RSTINT,				/* reset E/S interrupt */
-	WR1_RXALLS | WR1_TXENBL,	 	/* Rx per char, Tx */
+	WR1_RXALLS | WR1_TXENBL,		/* Rx per char, Tx */
 	0,					/* */
 	WR3_RX8BIT | WR3_RXENBL,		/* Rx */
 	WR4_BAUD96 | WR4_STOP1,			/* Tx/Rx */
@@ -77,14 +78,38 @@
 	device_t	sc_dev;
 	struct tty	*sc_tty;
 	struct sioreg	*sc_ctl;
-	u_int 		sc_flags;
+	u_int		sc_flags;
 	uint8_t		sc_wr[6];
+	void		*sc_si;		/* software interrupt handler */
+	u_int		sc_hwflags;
+#define	SIOTTY_HW_CONSOLE	0x0001
+
+	uint8_t		*sc_rbuf;
+	uint8_t		*sc_rbufend;
+	uint8_t	* volatile sc_rbget;
+	uint8_t	* volatile sc_rbput;
+	volatile u_int	sc_rbavail;
+
+	uint8_t		*sc_tba;
+	u_int		sc_tbc;
+
+	bool		sc_rx_ready;
+	bool		sc_tx_busy;
+	bool		sc_tx_done;
 };
 
+#define	SIOTTY_RING_SIZE	2048
+u_int siotty_rbuf_size = SIOTTY_RING_SIZE;
+
+static struct cnm_state	siotty_cnm_state;
+
 #include "siotty.h"
 static void siostart(struct tty *);
 static int  sioparam(struct tty *, struct termios *);
 static void siottyintr(int);
+static void siottysoft(void *);
+static void siotty_rxsoft(struct siotty_softc *, struct tty *);
+static void siotty_txsoft(struct siotty_softc *, struct tty *);
 static int  siomctl(struct siotty_softc *, int, int);
 
 static int  siotty_match(device_t, cfdata_t, void *);
@@ -107,7 +132,7 @@
 	siostop, siotty, siopoll, nommap, ttykqfilter, D_TTY
 };
 
-static int 
+static int
 siotty_match(device_t parent, cfdata_t cf, void *aux)
 {
 	struct sio_attach_args *args = aux;
@@ -117,19 +142,22 @@
 	return 1;
 }
 
-static void 
-siotty_attach(struct device *parent, struct device *self, void *aux)
+static void
+siotty_attach(device_t parent, device_t self, void *aux)
 {
 	struct sio_softc *scp = device_private(parent);
 	struct siotty_softc *sc = device_private(self);
 	struct sio_attach_args *args = aux;
+	struct tty *tp;
 
 	sc->sc_dev = self;
 	sc->sc_ctl = (struct sioreg *)scp->scp_ctl + args->channel;
 	memcpy(sc->sc_wr, ch0_regs, sizeof(ch0_regs));
 	scp->scp_intr[args->channel] = siottyintr;
+	if (args->hwflags == 1)
+		sc->sc_hwflags |= SIOTTY_HW_CONSOLE;
 
-	if (args->hwflags == 1) {
+	if ((sc->sc_hwflags & SIOTTY_HW_CONSOLE) != 0) {
 		aprint_normal(" (console)");
 		sc->sc_flags = TIOCFLAG_SOFTCAR;
 	} else {
@@ -145,6 +173,27 @@
 	setsioreg(sc->sc_ctl, WR1, sc->sc_wr[WR1]); /* now interrupt driven */
 
 	aprint_normal("\n");
+
+	sc->sc_rbuf = kmem_alloc(siotty_rbuf_size * 2, KM_NOSLEEP);
+	if (sc->sc_rbuf == NULL) {
+		aprint_error_dev(self, "unable to allocate ring buffer\n");
+		return;
+	}
+	sc->sc_rbufend = sc->sc_rbuf + (siotty_rbuf_size * 2);
+	sc->sc_rbput = sc->sc_rbget = sc->sc_rbuf;
+	sc->sc_rbavail = siotty_rbuf_size;
+
+	tp = tty_alloc();
+	tp->t_oproc = siostart;
+	tp->t_param = sioparam;
+	tp->t_hwiflow = NULL /* XXX siohwiflow XXX */;
+	if ((sc->sc_hwflags & SIOTTY_HW_CONSOLE) != 0)
+		tp->t_dev = cn_tab->cn_dev;
+	sc->sc_tty = tp;
+
+	tty_attach(tp);
+
+	sc->sc_si = softint_establish(SOFTINT_SERIAL, siottysoft, sc);
 }
 
 /*--------------------  low level routine --------------------*/
@@ -154,53 +203,141 @@
 {
 	struct siotty_softc *sc;
 	struct sioreg *sio;
-	struct tty *tp;
-	unsigned int code;
-	int rr;
+	uint8_t *put, *end;
+	uint8_t c;
+	uint16_t rr;
+	int cc;
 
 	sc = device_lookup_private(&siotty_cd, chan);
 	if (sc == NULL)
 		return;
 
-	tp = sc->sc_tty;
+	end = sc->sc_rbufend;
+	put = sc->sc_rbput;
+	cc = sc->sc_rbavail;
+
 	sio = sc->sc_ctl;
 	rr = getsiocsr(sio);
+	if ((rr & RR_BREAK) != 0) {
+		sio->sio_cmd = WR0_RSTINT;
+		cn_check_magic(sc->sc_tty->t_dev, CNC_BREAK, siotty_cnm_state);
+	}
 	if (rr & RR_RXRDY) {
 		do {
-			code = sio->sio_data;
-			if (rr & (RR_FRAMING | RR_OVERRUN | RR_PARITY)) {
-				sio->sio_cmd = WR0_ERRRST;
-				if (sio->sio_stat & RR_FRAMING)
-					code |= TTY_FE;
-				else if (sio->sio_stat & RR_PARITY)
-					code |= TTY_PE;
+			if (cc > 0) {
+				c = sio->sio_data;
+				cn_check_magic(sc->sc_tty->t_dev, c,
+				    siotty_cnm_state);
+				put[0] = c;
+				put[1] = rr & 0xff;
+				put += 2;
+				if (put >= end)
+					put = sc->sc_rbuf;
+				cc--;
 			}
-			if (tp == NULL || (tp->t_state & TS_ISOPEN) == 0)
-				continue;
-#if 0 && defined(DDB) /* ?!?! fails to resume ?!?! */
-			if ((rr & RR_BREAK) && tp->t_dev == cn_tab->cn_dev) {
-				cpu_Debugger();
-				return;
-			}
-#endif
-			(*tp->t_linesw->l_rint)(code, tp);
+			if ((rr & (RR_FRAMING | RR_OVERRUN | RR_PARITY)) != 0)
+				sio->sio_cmd = WR0_ERRRST;
+
+			sc->sc_rbput = put;
+			sc->sc_rbavail = cc;
+			sc->sc_rx_ready = true;
 		} while ((rr = getsiocsr(sio)) & RR_RXRDY);
 	}
 	if (rr & RR_TXRDY) {
 		sio->sio_cmd = WR0_RSTPEND;
-		if (tp != NULL) {
-			tp->t_state &= ~(TS_BUSY|TS_FLUSH);
-			(*tp->t_linesw->l_start)(tp);
+		if (sc->sc_tbc > 0) {
+			sio->sio_data = *sc->sc_tba;
+			sc->sc_tba++;
+			sc->sc_tbc--;
+		} else {
+			if (sc->sc_tx_busy) {
+				sc->sc_tx_busy = false;
+				sc->sc_tx_done = true;
+			}
 		}
 	}
+	softint_schedule(sc->sc_si);
 }
 
 static void
+siottysoft(void *arg)
+{
+	struct siotty_softc *sc;
+	struct tty *tp;
+
+	sc = arg;
+	tp = sc->sc_tty;
+
+	if (sc->sc_rx_ready) {
+		sc->sc_rx_ready = false;
+		siotty_rxsoft(sc, tp);
+	}
+	if (sc->sc_tx_done) {
+		sc->sc_tx_done = false;
+		siotty_txsoft(sc, tp);
+	}
+}
+
+static void
+siotty_rxsoft(struct siotty_softc *sc, struct tty *tp)
+{
+	uint8_t *get, *end;
+	u_int cc, scc;
+	unsigned int code;
+	uint8_t stat;
+	int s;
+
+	end = sc->sc_rbufend;
+	get = sc->sc_rbget;
+	scc = cc = siotty_rbuf_size - sc->sc_rbavail;
+
+	if (cc == siotty_rbuf_size) {
+		printf("%s: rx buffer overflow\n", device_xname(sc->sc_dev));
+	}
+
+	while (cc > 0) {
+		code = get[0];
+		stat = get[1];
+		if ((stat & RR_FRAMING) != 0)
+			code |= TTY_FE;
+		else if ((stat & RR_PARITY) != 0)
+			code |= TTY_PE;
+
+		(*tp->t_linesw->l_rint)(code, tp);
+		get += 2;
+		if (get >= end)
+			get = sc->sc_rbuf;
+		cc--;
+	}
+
+	if (cc != scc) {
+		s = splserial();
+		sc->sc_rbget = get;
+		sc->sc_rbavail += scc - cc;
+		splx(s);
+	}
+}
+
+static void
+siotty_txsoft(struct siotty_softc *sc, struct tty *tp)
+{
+
+	tp->t_state &= ~TS_BUSY;
+	if ((tp->t_state & TS_FLUSH) != 0)
+		tp->t_state &= ~TS_FLUSH;
+	else
+		ndflush(&tp->t_outq, (int)(sc->sc_tba - tp->t_outq.c_cf));
+	(*tp->t_linesw->l_start)(tp);
+}
+
+static void
 siostart(struct tty *tp)
 {
 	struct siotty_softc *sc;
-	int s, c;
- 
+	int s;
+	uint8_t *tba;
+	int tbc;
+
 	sc = device_lookup_private(&siotty_cd, minor(tp->t_dev));
 	s = splserial();
 	if (tp->t_state & (TS_BUSY|TS_TIMEOUT|TS_TTSTOP))
@@ -208,11 +345,17 @@
 	if (!ttypull(tp))
 		goto out;
 	tp->t_state |= TS_BUSY;
-	while (getsiocsr(sc->sc_ctl) & RR_TXRDY) {
-		if ((c = getc(&tp->t_outq)) == -1)
-			break;
-		sc->sc_ctl->sio_data = c;
-	}
+
+	tba = tp->t_outq.c_cf;
+	tbc = ndqb(&tp->t_outq, 0);
+
+	sc->sc_tba = tba;
+	sc->sc_tbc = tbc;
+	sc->sc_tx_busy = true;
+
+	sc->sc_ctl->sio_data = *sc->sc_tba;
+	sc->sc_tba++;
+	sc->sc_tbc--;
 out:
 	splx(s);
 }
@@ -222,14 +365,14 @@
 {
 	int s;
 
-        s = splserial();
-        if (TS_BUSY == (tp->t_state & (TS_BUSY|TS_TTSTOP))) {
-                /*
-                 * Device is transmitting; must stop it.
-                 */
+	s = splserial();
+	if (TS_BUSY == (tp->t_state & (TS_BUSY|TS_TTSTOP))) {
+		/*
+		 * Device is transmitting; must stop it.
+		 */
 		tp->t_state |= TS_FLUSH;
-        }
-        splx(s);
+	}
+	splx(s);
 }
 
 static int
@@ -279,7 +422,7 @@
 		if ((tp->t_cflag & PARODD) == 0)
 			wr4 |= WR4_EPARITY;
 	}
-	wr4 |= (tp->t_cflag & CSTOPB) ? WR4_STOP2 : WR4_STOP1;	
+	wr4 |= (tp->t_cflag & CSTOPB) ? WR4_STOP2 : WR4_STOP1;
 	sc->sc_wr[WR4] = wr4;
 
 	s = splserial();
@@ -294,7 +437,9 @@
 static int
 siomctl(struct siotty_softc *sc, int control, int op)
 {
-	int val, s, wr5, rr;
+	int val, s;
+	uint8_t wr5;
+	uint16_t rr;
 
 	val = 0;
 	if (control & TIOCM_BREAK)
@@ -331,7 +476,7 @@
 	sc->sc_wr[WR5] = wr5;
 	setsioreg(sc->sc_ctl, WR5, wr5);
 	val = 0;
-  done:
+ done:
 	splx(s);
 	return val;
 }
@@ -344,19 +489,13 @@
 	struct siotty_softc *sc;
 	struct tty *tp;
 	int error;
+	int s;
 
 	sc = device_lookup_private(&siotty_cd, minor(dev));
 	if (sc == NULL)
 		return ENXIO;
-	if ((tp = sc->sc_tty) == NULL) {
-		tp = sc->sc_tty = tty_alloc();
-		tty_attach(tp);
-	}
 
-	tp->t_oproc = siostart;
-	tp->t_param = sioparam;
-	tp->t_hwiflow = NULL /* XXX siohwiflow XXX */;
-	tp->t_dev = dev;
+	tp = sc->sc_tty;
 
 	if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp))
 		return EBUSY;
@@ -364,6 +503,7 @@
 	if ((tp->t_state & TS_ISOPEN) == 0 && tp->t_wopen == 0) {
 		struct termios t;
 
+		tp->t_dev = dev;
 		t.c_ispeed = t.c_ospeed = TTYDEF_SPEED;
 		t.c_cflag = TTYDEF_CFLAG;
 		tp->t_ospeed = 0; /* force register update */
@@ -375,7 +515,6 @@
 		ttsetwater(tp);
 		/* raise RTS and DTR here; but, DTR lead is not wired */
 		/* then check DCD condition; but, DCD lead is not wired */
-		tp->t_state |= TS_CARR_ON; /* assume detected all the time */
 #if 0
 		if ((sc->sc_flags & TIOCFLAG_SOFTCAR)
 		    || (tp->t_cflag & MDMBUF)
@@ -383,7 +522,14 @@
 			tp->t_state |= TS_CARR_ON;
 		else
 			tp->t_state &= ~TS_CARR_ON;
+#else
+		tp->t_state |= TS_CARR_ON; /* assume detected all the time */
 #endif
+
+		s = splserial();
+		sc->sc_rbput = sc->sc_rbget = sc->sc_rbuf;
+		sc->sc_rbavail = siotty_rbuf_size;
+		splx(s);
 	}
 
 	error = ttyopen(tp, 0, (flag & O_NONBLOCK));
@@ -391,7 +537,7 @@
 		return error;
 	return (*tp->t_linesw->l_open)(dev, tp);
 }
- 
+
 int
 sioclose(dev_t dev, int flag, int mode, struct lwp *l)
 {
@@ -414,24 +560,24 @@
 	splx(s);
 	return ttyclose(tp);
 }
- 
+
 int
 sioread(dev_t dev, struct uio *uio, int flag)
 {
 	struct siotty_softc *sc;
 	struct tty *tp;
- 
+
 	sc = device_lookup_private(&siotty_cd, minor(dev));
 	tp = sc->sc_tty;
 	return (*tp->t_linesw->l_read)(tp, uio, flag);
 }
- 
+
 int
 siowrite(dev_t dev, struct uio *uio, int flag)
 {
 	struct siotty_softc *sc;
 	struct tty *tp;
- 
+
 	sc = device_lookup_private(&siotty_cd, minor(dev));
 	tp = sc->sc_tty;
 	return (*tp->t_linesw->l_write)(tp, uio, flag);
@@ -442,7 +588,7 @@
 {
 	struct siotty_softc *sc;
 	struct tty *tp;
- 
+
 	sc = device_lookup_private(&siotty_cd, minor(dev));
 	tp = sc->sc_tty;
 	return ((*tp->t_linesw->l_poll)(tp, events, l));
@@ -508,7 +654,7 @@
 siotty(dev_t dev)
 {
 	struct siotty_softc *sc;
- 
+
 	sc = device_lookup_private(&siotty_cd, minor(dev));
 	return sc->sc_tty;
 }
@@ -524,7 +670,7 @@
 	sio->sio_cmd = val;		/* DELAY(); */
 }
 
-/* EXPORT */ int
+/* EXPORT */ uint16_t
 getsiocsr(struct sioreg *sio)
 {
 	int val;
@@ -567,6 +713,8 @@
 	syscons.cn_dev = makedev(cdevsw_lookup_major(&siotty_cdevsw),
 				 channel);
 	cn_tab = &syscons;
+	cn_init_magic(&siotty_cnm_state);
+	cn_set_magic("\047\001");
 
 	setsioreg(sio, WR0, WR0_CHANRST);
 	setsioreg(sio, WR2A, WR2_VEC86 | WR2_INTR_1);

cvs diff -r1.6 -r1.6.8.1 src/sys/arch/luna68k/dev/siovar.h (expand / switch to context diff)
--- src/sys/arch/luna68k/dev/siovar.h 2011/07/27 14:17:55 1.6
+++ src/sys/arch/luna68k/dev/siovar.h 2014/01/12 12:21:16 1.6.8.1
@@ -1,4 +1,4 @@
-/* $NetBSD: siovar.h,v 1.6 2011/07/27 14:17:55 tsutsui Exp $ */
+/* $NetBSD: siovar.h,v 1.6.8.1 2014/01/12 12:21:16 bouyer Exp $ */
 
 /*-
  * Copyright (c) 2000 The NetBSD Foundation, Inc.
@@ -48,5 +48,5 @@
 #define sio_stat sio_cmd
 };
 
-int  getsiocsr(struct sioreg *);
+uint16_t getsiocsr(struct sioreg *);
 void setsioreg(struct sioreg *, int, int);