Subject: Re: Fixed: Problems booting DECsystem 5000/200
To: None <port-pmax@netbsd.org>
From: Izumi Tsutsui <tsutsui@ceres.dti.ne.jp>
List: port-pmax
Date: 11/11/2000 22:35:26
In <200010011734.e91HY2D00519@mirage.ceres.dti.ne.jp>
I wrote:

> In <Pine.BSF.4.21.0010011230510.1071-100000@server.wes.mee.com>
> frederik@freddym.org wrote:
> 
> > The Problem was very easy to fix: I just attached a mouse to the system.
> > Oh man... Why can't NetBSD just say: "No mouse attached - I'm going to
> > hang now" :-).
> 
> This problem also occurs on my 5000/125.
> 
> The mouse is initialized in arch/pmax/tc/scc.c:scc_mouse_init().
> If keyboard/framebuffer are used as console, it calls lk_mouseinit()
> in arch/pmax/dev/lk201.c. But it uses sccPutc() to send command
> to the mouse, and sccPutc() will never return if transmitter
> is not ready.

The problem is not sccPutc(), but sccGetc().
lk_mouseinit() waits return from sccGetc() forever
if no mouse is connected.

The attached ugly patch fixes this..
---
Izumi Tsutsui
tsutsui@ceres.dti.ne.jp

Index: scc.c
===================================================================
RCS file: /cvs/cvsroot/syssrc/sys/arch/pmax/tc/scc.c,v
retrieving revision 1.65
diff -u -r1.65 scc.c
--- scc.c	2000/03/06 21:36:11	1.65
+++ scc.c	2000/11/11 13:29:51
@@ -224,6 +224,7 @@
 static int	sccmctl __P((dev_t, int, int));
 static int	cold_sccparam __P((struct tty *, struct termios *,
 		    struct scc_softc *sc));
+static int	sccGetc1 __P((dev_t));
 
 #ifdef SCC_DEBUG
 static void	rr __P((char *, scc_regmap_t *));
@@ -525,7 +526,7 @@
 		goto done;
 
 	DELAY(10000);
-	lk_mouseinit(ctty.t_dev, sccPutc, sccGetc);
+	lk_mouseinit(ctty.t_dev, sccPutc, sccGetc1);
 	DELAY(10000);
 
 done:
@@ -1425,6 +1426,53 @@
 		} else
 			DELAY(10);
 	}
+}
+
+/*
+ * Get a char off the appropriate line via. a busy wait loop with timeout.
+ */
+static int
+sccGetc1(dev)
+	dev_t dev;
+{
+	scc_regmap_t *regs;
+	int c, line;
+	u_char value;
+	int s, i;
+
+	line = SCCLINE(dev);
+	if (cold && scc_cons_addr) {
+		regs = scc_cons_addr;
+	} else {
+		struct scc_softc *sc;
+		sc = scc_cd.cd_devs[SCCUNIT(dev)];
+		regs = (scc_regmap_t *)sc->scc_pdma[line].p_addr;
+	}
+
+	if (!regs)
+		return (-1);
+	/*s = spltty(); */	/* XXX  why different spls? */
+	s = splhigh();
+	for (i = 0; i < 10000; i++) {
+		SCC_READ_REG(regs, line, SCC_RR0, value);
+		if (value & ZSRR0_RX_READY) {
+			SCC_READ_REG(regs, line, SCC_RR1, value);
+			SCC_READ_DATA(regs, line, c);
+			if (value & (ZSRR1_PE | ZSRR1_DO | ZSRR1_FE)) {
+				SCC_WRITE_REG(regs, line, SCC_WR0,
+				    ZSWR0_RESET_ERRORS);
+				SCC_WRITE_REG(regs, SCC_CHANNEL_A, SCC_WR0,
+				    ZSWR0_CLR_INTR);
+			} else {
+				SCC_WRITE_REG(regs, SCC_CHANNEL_A, SCC_WR0,
+				    ZSWR0_CLR_INTR);
+				splx(s);
+				return (c & 0xff);
+			}
+		} else
+			DELAY(10);
+	}
+	return (-1);
 }
 
 /*