summaryrefslogtreecommitdiff
path: root/sys/arch/pmax/tc/scc.c
diff options
context:
space:
mode:
authorThomas Graichen <graichen@cvs.openbsd.org>1996-12-22 15:19:07 +0000
committerThomas Graichen <graichen@cvs.openbsd.org>1996-12-22 15:19:07 +0000
commitca1c7fedd990e6b1e7244233df5a6a638f0e4e31 (patch)
tree20016b11dce3c72001f0e250c8f1a714ed64e546 /sys/arch/pmax/tc/scc.c
parentde4c3561677938c64d13b1e5112686a88b0b47fe (diff)
update the pmax stuff to NetBSD 961107 - this version i got somehow
compiled on my decstation 2100 (PLUTO) - but it will not fully work out of the box - but i want to bring it into the tree because i get my own pmax on 961228 - so that i have a good startpoint then :-) all the OpenBSD changes to the pmax tree will follow in the next commit
Diffstat (limited to 'sys/arch/pmax/tc/scc.c')
-rw-r--r--sys/arch/pmax/tc/scc.c382
1 files changed, 252 insertions, 130 deletions
diff --git a/sys/arch/pmax/tc/scc.c b/sys/arch/pmax/tc/scc.c
index 22fc8c3c562..ca487ab7e6a 100644
--- a/sys/arch/pmax/tc/scc.c
+++ b/sys/arch/pmax/tc/scc.c
@@ -1,7 +1,7 @@
-/* $NetBSD: scc.c,v 1.11.4.2 1996/06/16 17:13:16 mhitch Exp $ */
+/* $NetBSD: scc.c,v 1.18 1996/10/16 05:04:51 jonathan Exp $ */
/*
- * Copyright (c) 1991,1990,1989,1994,1995 Carnegie Mellon University
+ * Copyright (c) 1991,1990,1989,1994,1995,1996 Carnegie Mellon University
* All rights reserved.
*
* Author: Chris G. Demetriou and Jonathan Stone
@@ -62,7 +62,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * from: @(#)scc.c 8.2 (Berkeley) 11/30/93
+ * @(#)scc.c 8.2 (Berkeley) 11/30/93
*/
@@ -90,7 +90,7 @@
#include <sys/syslog.h>
#include <sys/device.h>
-#ifdef alpha
+#ifndef pmax
#include <dev/cons.h>
#endif
@@ -99,9 +99,10 @@
#include <pmax/dev/pdma.h>
#include <dev/ic/z8530reg.h>
#include <pmax/dev/lk201.h>
+#include <pmax/dev/lk201var.h>
#ifdef pmax
-#include <machine/machConst.h>
+#include <pmax/cpuregs.h> /* phys to uncached */
#include <pmax/pmax/cons.h>
#include <pmax/pmax/pmaxtype.h>
#include <pmax/pmax/maxine.h>
@@ -121,6 +122,8 @@
#include <dev/tc/tcvar.h>
#include <dev/tc/ioasicvar.h>
+#include <machine/conf.h>
+
extern void ttrstrt __P((void *));
#ifdef alpha
@@ -129,7 +132,9 @@ extern void ttrstrt __P((void *));
#endif
/*
- * rcons glass-tty console (as used on pmax and sparc) won't compile on Alphas.
+ * rcons glass-tty console (as used on pmax) needs lk-201 ASCII input
+ * support from the tty drivers. This is ugly and broken and won't
+ * compile on Alphas.
*/
#ifdef pmax
#define HAVE_RCONS
@@ -156,20 +161,20 @@ extern int pending_remcons;
*/
static inline int
-raster_console()
+raster_console(void)
{
return (cn_tab->cn_pri == CN_NORMAL || cn_tab->cn_pri == CN_INTERNAL);
}
-#define NSCCLINE (NSCC*2)
#define SCCUNIT(dev) (minor(dev) >> 1)
#define SCCLINE(dev) (minor(dev) & 0x1)
-struct tty *scc_tty[NSCCLINE];
-void (*sccDivertXInput)(); /* X windows keyboard input routine */
-void (*sccMouseEvent)(); /* X windows mouse motion event routine */
-void (*sccMouseButtons)(); /* X windows mouse buttons event routine */
+/* QVSS-compatible in-kernel X input event parser, pointer tracker */
+void (*sccDivertXInput) __P((int cc)); /* X windows keyboard input routine */
+void (*sccMouseEvent) __P((int)); /* X windows mouse motion event routine */
+void (*sccMouseButtons) __P((int)); /* X windows mouse buttons event routine */
+
#ifdef DEBUG
int debugChar;
#endif
@@ -184,7 +189,16 @@ struct scc_softc {
u_char wr5;
u_char wr14;
} scc_wreg[2];
+ struct tty *scc_tty[2];
int scc_softCAR;
+ int scc_flags[2];
+#define SCC_CHAN_NEEDSDELAY 0x01 /* sw must delay 1.6us between output*/
+#define SCC_CHAN_NOMODEM 0x02 /* don't touch modem ctl lines (may
+ be left floating or x-wired */
+#define SCC_CHAN_MODEM_CROSSED 0x04 /* modem lines wired to other channel*/
+#define SCC_CHAN_KBDLINE 0x08 /* XXX special-case keyboard lines */
+ int scc_unitflags; /* flags for both channels, e.g. */
+#define SCC_PREFERRED_CONSOLE 0x01
};
/*
@@ -209,15 +223,15 @@ struct speedtab sccspeedtab[] = {
{ 1800, 126, },
{ 2400, 94, },
{ 4800, 46, },
- { 7200, 30, }, /* 7.2 (an d14.4, 28.8, 57.6) non-POSSIX */
+ { 7200, 30, }, /* non-POSIX */
{ 9600, 22, },
{ 14400, 14, }, /* non-POSIX */
{ 19200, 10, },
{ 28800, 6, }, /* non-POSIX */
- { 38400, 4, }, /* all higher speeds are non-POSIX */
- { 57600, 2, },
- { 76800, 1, },
- { 115200, 0 },
+ { 38400, 4, }, /* non-POSIX */
+ { 57600, 2, }, /* non-POSIX */
+ { 76800, 1, }, /* non-POSIX, doesn't work reliably */
+ { 115200, 0 }, /* non-POSIX doesn't work reliably */
{ -1, -1, },
};
@@ -254,16 +268,17 @@ struct speedtab sccspeedtab[] = {
#endif
/* Definition of the driver for autoconfig. */
-int sccmatch __P((struct device * parent, void *cfdata, void *aux));
-void sccattach __P((struct device *parent, struct device *self, void *aux));
-extern struct cfdriver scc_cd;
+static int sccmatch __P((struct device * parent, void *cfdata,
+ void *aux));
+static void sccattach __P((struct device *parent, struct device *self,
+ void *aux));
struct cfattach scc_ca = {
- sizeof (struct scc_softc), sccmatch, sccattach
+ sizeof (struct scc_softc), sccmatch, sccattach,
};
struct cfdriver scc_cd = {
- NULL, "scc", DV_TTY
+ NULL, "scc", DV_TTY,
};
int sccGetc __P((dev_t));
@@ -272,56 +287,144 @@ void sccPollc __P((dev_t, int));
int sccparam __P((struct tty *, struct termios *));
void sccstart __P((struct tty *));
int sccmctl __P((dev_t, int, int));
+static int cold_sccparam __P((struct tty *, struct termios *,
+ struct scc_softc *sc));
+#ifdef SCC_DEBUG
+static void rr __P((char *, scc_regmap_t *));
+#endif
+
static void scc_modem_intr __P((dev_t));
static void sccreset __P((struct scc_softc *));
int sccintr __P((void *));
+#ifdef alpha
+void scc_alphaintr __P((int));
+#endif
-void scc_consinit __P((struct scc_softc *sc));
+/*
+ * console variables, for using serial console while still cold and
+ * autoconfig has not attached the scc device.
+ */
+extern int cold;
+scc_regmap_t *scc_cons_addr = 0;
+static struct scc_softc coldcons_softc;
+static struct consdev scccons = {
+ NULL, NULL, sccGetc, sccPutc, sccPollc, NODEV, 0
+};
+void scc_consinit __P((dev_t dev, scc_regmap_t *sccaddr));
-#ifdef alpha
-void scc_alphaintr __P((int));
+
+/*
+ * Set up a given unit as a serial console device.
+ * We need console output when cold, and before any device is configured.
+ * Should be callable when cold, to reset the chip and set parameters
+ * for a remote (serial) console or kgdb line.
+ * XXX
+ * As most DECstations only bring out one rs-232 lead from an SCC
+ * to the bulkhead, and use the other for mouse and keyboard, we
+ * only allow one unit per SCC to be console.
+ */
+void
+scc_consinit(dev, sccaddr)
+ dev_t dev;
+ scc_regmap_t *sccaddr;
+{
+ struct scc_softc *sc;
+ struct termios cterm;
+ struct tty ctty;
+ int s;
+
+ /* Save address in case we're cold. */
+ if (cold && scc_cons_addr == 0) {
+ scc_cons_addr = sccaddr;
+ sc = &coldcons_softc;
+ coldcons_softc.scc_pdma[0].p_addr = sccaddr;
+ coldcons_softc.scc_pdma[1].p_addr = sccaddr;
+ } else {
+ /* being called from sccattach() to reset console */
+ sc = scc_cd.cd_devs[SCCUNIT(dev)];
+ }
+
+ /* Reset chip. */
+ sccreset(sc);
+ /* XXX make sure sccreset() called only once for this chip? */
+
+ /* set console-line parameters */
+ s = spltty();
+ ctty.t_dev = dev;
+ scccons.cn_dev = dev;
+ cterm.c_cflag = CS8;
+#ifdef pmax
+ /* XXX -- why on pmax, not on Alpha? */
+ cterm.c_cflag |= CLOCAL;
#endif
+ cterm.c_ospeed = cterm.c_ispeed = 9600;
+ (void) cold_sccparam(&ctty, &cterm, sc);
+ *cn_tab = scccons;
+ DELAY(1000);
+ splx(s);
+}
+
+void
+scc_oconsinit(sc, dev)
+ struct scc_softc *sc;
+ dev_t dev;
+{
+ struct termios cterm;
+ struct tty ctty;
+ int s;
+
+ s = spltty();
+ ctty.t_dev = dev;
+ cterm.c_cflag = CS8;
+#ifdef pmax
+ /* XXX -- why on pmax, not on Alpha? */
+ cterm.c_cflag |= CLOCAL;
+#endif
+ cterm.c_ospeed = cterm.c_ispeed = 9600;
+ (void) sccparam(&ctty, &cterm);
+ DELAY(1000);
+ splx(s);
+}
/*
* Test to see if device is present.
* Return true if found.
*/
int
-sccmatch(parent, match, aux)
+sccmatch(parent, cfdata, aux)
struct device *parent;
- void *match;
+ void *cfdata;
void *aux;
{
- struct cfdata *cf = match;
+ struct cfdata *cf = cfdata;
struct ioasicdev_attach_args *d = aux;
void *sccaddr;
- if (parent->dv_cfdata->cf_driver == &ioasic_cd) {
- /* Make sure that we're looking for this type of device. */
- if (strncmp(d->iada_modname, "scc", TC_ROM_LLEN))
- return (0);
- }
- else {
+ if (parent->dv_cfdata->cf_driver != &ioasic_cd) {
#ifdef DIAGNOSTIC
printf("Cannot attach scc on %s\n", parent->dv_xname);
#endif
- return 0;
+ return (0);
}
-
- /* Don't over-run softc. */
+ /* Make sure that we're looking for this type of device. */
+ if ((strncmp(d->iada_modname, "z8530 ", TC_ROM_LLEN) != 0) &&
+ (strncmp(d->iada_modname, "scc", TC_ROM_LLEN)!= 0))
+ return (0);
+
+ /* XXX MATCH CFLOC */
if (cf->cf_unit >= NSCC)
return (0);
/* Get the address, and check it for validity. */
- sccaddr = (caddr_t)d->iada_addr;
-#ifdef alpha
- sccaddr = TC_DENSE_TO_SPARSE(sccaddr);
-#endif /*alpha*/
+ sccaddr = (void *)d->iada_addr;
+#ifdef SPARSE
+ sccaddr = (void *)TC_DENSE_TO_SPARSE((tc_addr_t)sccaddr);
+#endif
if (badaddr(sccaddr, 2))
return (0);
@@ -330,6 +433,10 @@ sccmatch(parent, match, aux)
}
#ifdef alpha
+/*
+ * Enable ioasic SCC interrupts and scc DMA engine interrupts.
+ * XXX does not really belong here.
+ */
void
scc_alphaintr(onoff)
int onoff;
@@ -351,7 +458,7 @@ scc_alphaintr(onoff)
IOASIC_CSR_DMAEN_T2 | IOASIC_CSR_DMAEN_R2);
#endif
}
- wbflush();
+ alpha_mb();
}
#endif /*alpha*/
@@ -383,9 +490,9 @@ sccattach(parent, self, aux)
#endif /* defined(DEBUG) && defined(HAVE_RCONS)*/
sccaddr = (void*)MACH_PHYS_TO_UNCACHED(d->iada_addr);
-#ifdef alpha
- sccaddr = TC_DENSE_TO_SPARSE(sccaddr);
-#endif /*alpha*/
+#ifdef SPARSE
+ sccaddr = (void *)TC_DENSE_TO_SPARSE((tc_addr_t)sccaddr);
+#endif
/* Register the interrupt handler. */
ioasic_intr_establish(parent, d->iada_cookie, TC_IPL_TTY,
@@ -417,18 +524,18 @@ sccattach(parent, self, aux)
/* init pseudo DMA structures */
for (cntr = 0; cntr < 2; cntr++) {
pdp->p_addr = (void *)sccaddr;
- tp = scc_tty[unit * 2 + cntr] = ttymalloc();
+ tp = sc->scc_tty[cntr] = ttymalloc();
if (cputype == DS_MAXINE || cntr == 0)
tty_attach(tp); /* XXX */
pdp->p_arg = (long)tp;
- pdp->p_fcn = (void (*)())0;
+ pdp->p_fcn = (void (*)__P((struct tty*)))0;
tp->t_dev = (dev_t)((unit << 1) | cntr);
pdp++;
}
/* What's the warning here? Defaulting to softCAR on line 2? */
- sc->scc_softCAR = flags | 0x2; /* XXX */
+ sc->scc_softCAR = flags | 0x2; /* XXX */
- /* reset chip */
+ /* reset chip, initialize register-copies in softc */
sccreset(sc);
/*
@@ -442,19 +549,15 @@ sccattach(parent, self, aux)
* wire up this driver as console ASAP.
*/
- static struct consdev scccons = {
- NULL, NULL, sccGetc, sccPutc, sccPollc, NODEV, 0
- };
-
-
/*XXX*/ /* test for correct unit */
DELAY(10000);
/*
* XXX PROM and NetBSD unit numbers swapped
* on kn03, maybe kmin?
+ * And what about maxine?
*/
- if (cn_tab->cn_dev == unit)
+ if (cn_tab->cn_dev == unit && cputype != DS_MAXINE)
return;
/*
@@ -462,10 +565,15 @@ sccattach(parent, self, aux)
* as console, now is the time to set up the scc
* driver as console.
*/
- scc_consinit(sc);
cn_tab = &scccons;
cn_tab->cn_dev = makedev(SCCDEV,
sc->sc_dv.dv_unit == 0 ? SCCCOMM2_PORT : SCCCOMM3_PORT);
+#ifdef notyet
+ scc_consinit(cn_tab->cn_dev, sccaddr);
+#else
+ scc_oconsinit(sc, cn_tab->cn_dev);
+#endif
+
printf(" (In sccattach: cn_dev = 0x%x)", cn_tab->cn_dev);
printf(" (Unit = %d)", unit);
printf(": console");
@@ -533,9 +641,6 @@ sccattach(parent, self, aux)
if ((cputype == ST_DEC_3000_500 && sc->sc_dv.dv_unit == 1) ||
(cputype == ST_DEC_3000_300 && sc->sc_dv.dv_unit == 0))
{
- static struct consdev scccons = {
- NULL, NULL, sccGetc, sccPutc, sccPollc, NODEV, 0
- };
cn_tab = &scccons;
cn_tab->cn_dev = makedev(SCCDEV, sc->sc_dv.dv_unit * 2);
@@ -549,37 +654,11 @@ sccattach(parent, self, aux)
printf("\n");
}
-/*
- * Set up a given unit as a serial console device.
- * XXX
- * As most DECstations only bring out one rs-232 lead from an SCC
- * to the bulkhead, and use the other for mouse and keyboard, we
- * only allow one unit per SCC to be console.
- */
-void
-scc_consinit(sc)
- struct scc_softc *sc;
-{
- struct termios cterm;
- struct tty ctty;
- int s;
-
- s = spltty();
- ctty.t_dev = makedev(SCCDEV,
- sc->sc_dv.dv_unit == 0 ? SCCCOMM2_PORT : SCCCOMM3_PORT);
- cterm.c_cflag = CS8;
-#ifdef pmax
- /* XXX -- why on pmax, not on Alpha? */
- cterm.c_cflag |= CLOCAL;
-#endif
- cterm.c_ospeed = cterm.c_ispeed = 9600;
- (void) sccparam(&ctty, &cterm);
- DELAY(1000);
- splx(s);
-}
/*
- * Reset the chip.
+ * Reset the chip and the softc state.
+ * Resetting clobbers chip state and copies of registers for both channels.
+ * The driver assumes this is only ever called once per unit.
*/
static void
sccreset(sc)
@@ -621,6 +700,10 @@ sccreset(sc)
SCC_WRITE_REG(regs, SCC_CHANNEL_B, ZSWR_IVEC, 0xf0);
SCC_WRITE_REG(regs, SCC_CHANNEL_A, SCC_WR9, ZSWR9_VECTOR_INCL_STAT);
+ /*
+ * Set softc copies of writable (write-only?) registers.
+ */
+
/* receive parameters and control */
sc->scc_wreg[SCC_CHANNEL_A].wr3 = 0;
sc->scc_wreg[SCC_CHANNEL_B].wr3 = 0;
@@ -670,10 +753,9 @@ sccopen(dev, flag, mode, p)
line = SCCLINE(dev);
if (sc->scc_pdma[line].p_addr == NULL)
return (ENXIO);
-
- tp = scc_tty[minor(dev)];
+ tp = sc->scc_tty[line];
if (tp == NULL) {
- tp = scc_tty[minor(dev)] = ttymalloc();
+ tp = sc->scc_tty[line] = ttymalloc();
tty_attach(tp);
}
tp->t_oproc = sccstart;
@@ -721,12 +803,12 @@ sccclose(dev, flag, mode, p)
int flag, mode;
struct proc *p;
{
- register struct scc_softc *sc = scc_cd.cd_devs[SCCUNIT(dev)];
+ register struct scc_softc *sc = scc_cd.cd_devs[SCCUNIT(dev)];
register struct tty *tp;
register int line;
- tp = scc_tty[minor(dev)];
line = SCCLINE(dev);
+ tp = sc->scc_tty[line];
if (sc->scc_wreg[line].wr5 & ZSWR5_BREAK) {
sc->scc_wreg[line].wr5 &= ~ZSWR5_BREAK;
ttyoutput(0, tp);
@@ -744,9 +826,11 @@ sccread(dev, uio, flag)
struct uio *uio;
int flag;
{
+ register struct scc_softc *sc;
register struct tty *tp;
- tp = scc_tty[minor(dev)];
+ sc = scc_cd.cd_devs[SCCUNIT(dev)]; /* XXX*/
+ tp = sc->scc_tty[SCCLINE(dev)];
return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
}
@@ -756,9 +840,11 @@ sccwrite(dev, uio, flag)
struct uio *uio;
int flag;
{
+ register struct scc_softc *sc;
register struct tty *tp;
- tp = scc_tty[minor(dev)];
+ sc = scc_cd.cd_devs[SCCUNIT(dev)]; /* XXX*/
+ tp = sc->scc_tty[SCCLINE(dev)];
return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
}
@@ -766,9 +852,13 @@ struct tty *
scctty(dev)
dev_t dev;
{
- /* What's the warning here? */
- struct tty *tp = scc_tty[minor(dev)]; /* XXX */
+ register struct scc_softc *sc;
+ register struct tty *tp;
+ register int unit = SCCUNIT(dev);
+ if ((unit >= scc_cd.cd_ndevs) || (sc = scc_cd.cd_devs[unit]) == 0)
+ return (0);
+ tp = sc->scc_tty[SCCLINE(dev)];
return (tp);
}
@@ -785,7 +875,9 @@ sccioctl(dev, cmd, data, flag, p)
register struct tty *tp;
int error, line;
- tp = scc_tty[minor(dev)];
+ line = SCCLINE(dev);
+ sc = scc_cd.cd_devs[SCCUNIT(dev)];
+ tp = sc->scc_tty[line];
error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
if (error >= 0)
return (error);
@@ -793,8 +885,6 @@ sccioctl(dev, cmd, data, flag, p)
if (error >= 0)
return (error);
- line = SCCLINE(dev);
- sc = scc_cd.cd_devs[SCCUNIT(dev)];
switch (cmd) {
case TIOCSBRK:
@@ -837,19 +927,39 @@ sccioctl(dev, cmd, data, flag, p)
return (0);
}
+/*
+ * Set line parameters -- tty t_param entry point.
+ */
int
sccparam(tp, t)
register struct tty *tp;
register struct termios *t;
{
register struct scc_softc *sc;
+
+ /* Extract the softc and call cold_sccparam to do all the work. */
+ sc = scc_cd.cd_devs[SCCUNIT(tp->t_dev)];
+ return cold_sccparam(tp, t, sc);
+}
+
+
+/*
+ * Do what sccparam() (t_param entry point) does, but callable when cold.
+ */
+static int
+cold_sccparam(tp, t, sc)
+ register struct tty *tp;
+ register struct termios *t;
+ register struct scc_softc *sc;
+{
register scc_regmap_t *regs;
register int line;
register u_char value, wvalue;
register int cflag = t->c_cflag;
int ospeed;
- if (t->c_ispeed && t->c_ispeed != t->c_ospeed)
+ /* Check arguments */
+ if (t->c_ispeed && t->c_ispeed != t->c_ospeed)
return (EINVAL);
ospeed = ttspeedtab(t->c_ospeed, sccspeedtab);
if (ospeed < 0)
@@ -882,7 +992,6 @@ sccparam(tp, t)
return (0);
}
- sc = scc_cd.cd_devs[SCCUNIT(tp->t_dev)];
line = SCCLINE(tp->t_dev);
regs = (scc_regmap_t *)sc->scc_pdma[line].p_addr;
@@ -990,30 +1099,32 @@ sccparam(tp, t)
value = ZSWR9_MASTER_IE | ZSWR9_VECTOR_INCL_STAT;
SCC_WRITE_REG(regs, line, SCC_WR9, value);
SCC_WRITE_REG(regs, line, SCC_WR1, sc->scc_wreg[line].wr1);
- wbflush();
+ tc_mb();
#ifdef alpha
- scc_alphaintr(1);
+ scc_alphaintr(1); /* XXX XXX XXX */
#endif /*alpha*/
return (0);
}
+
/*
* Check for interrupts from all devices.
*/
int
sccintr(xxxsc)
- void * xxxsc;
+ void *xxxsc;
{
register struct scc_softc *sc = (struct scc_softc *)xxxsc;
- register int unit = sc->sc_dv.dv_unit;
+ register int unit = (long)sc->sc_dv.dv_unit;
register scc_regmap_t *regs;
register struct tty *tp;
register struct pdma *dp;
register int cc, chan, rr1, rr2, rr3;
int overrun = 0;
+ rr1 = 0; /* shut up gcc -Wall */
regs = (scc_regmap_t *)sc->scc_pdma[0].p_addr;
unit <<= 1;
for (;;) {
@@ -1030,14 +1141,14 @@ sccintr(xxxsc)
if ((rr2 == SCC_RR2_A_XMIT_DONE) || (rr2 == SCC_RR2_B_XMIT_DONE)) {
chan = (rr2 == SCC_RR2_A_XMIT_DONE) ?
SCC_CHANNEL_A : SCC_CHANNEL_B;
- tp = scc_tty[unit | chan];
+ tp = sc->scc_tty[chan];
dp = &sc->scc_pdma[chan];
if (dp->p_mem < dp->p_end) {
SCC_WRITE_DATA(regs, chan, *dp->p_mem++);
#ifdef pmax /* Alpha handles the 1.6 msec settle time in hardware */
DELAY(2);
#endif
- wbflush();
+ tc_mb();
} else {
tp->t_state &= ~TS_BUSY;
if (tp->t_state & TS_FLUSH)
@@ -1058,7 +1169,7 @@ sccintr(xxxsc)
cc = sc->scc_wreg[chan].wr1 & ~ZSWR1_TIE;
SCC_WRITE_REG(regs, chan, SCC_WR1, cc);
sc->scc_wreg[chan].wr1 = cc;
- wbflush();
+ tc_mb();
}
}
} else if (rr2 == SCC_RR2_A_RECV_DONE ||
@@ -1068,7 +1179,7 @@ sccintr(xxxsc)
chan = SCC_CHANNEL_A;
else
chan = SCC_CHANNEL_B;
- tp = scc_tty[unit | chan];
+ tp = sc->scc_tty[chan];
SCC_READ_DATA(regs, chan, cc);
if (rr2 == SCC_RR2_A_RECV_SPECIAL ||
rr2 == SCC_RR2_B_RECV_SPECIAL) {
@@ -1084,7 +1195,8 @@ sccintr(xxxsc)
/*
* Keyboard needs special treatment.
*/
- if (tp == scc_tty[SCCKBD_PORT] && raster_console()) {
+ if (tp == scctty(makedev(SCCDEV, SCCKBD_PORT)) &&
+ raster_console()) {
#ifdef KADB
if (cc == LK_DO) {
spl0();
@@ -1106,10 +1218,13 @@ sccintr(xxxsc)
/*
* Now for mousey
*/
- } else if (tp == scc_tty[SCCMOUSE_PORT] && sccMouseButtons) {
+ } else if (tp == scctty(makedev(SCCDEV, SCCMOUSE_PORT)) &&
+ sccMouseButtons) {
+#ifdef HAVE_RCONS
/*XXX*/
mouseInput(cc);
continue;
+#endif
}
if (!(tp->t_state & TS_ISOPEN)) {
wakeup((caddr_t)&tp->t_rawq);
@@ -1162,7 +1277,7 @@ sccstart(tp)
if (tp->t_outq.c_cc == 0)
goto out;
/* handle console specially */
- if (tp == scc_tty[SCCKBD_PORT] && raster_console()) {
+ if (tp == scctty(makedev(SCCDEV,SCCKBD_PORT)) && raster_console()) {
while (tp->t_outq.c_cc > 0) {
cc = getc(&tp->t_outq) & 0x7f;
cnputc(cc);
@@ -1180,7 +1295,6 @@ sccstart(tp)
}
goto out;
}
-
cc = ndqb(&tp->t_outq, 0);
tp->t_state |= TS_BUSY;
@@ -1203,13 +1317,13 @@ sccstart(tp)
#ifdef DIAGNOSTIC
if (cc == 0)
panic("sccstart: No chars");
-#endif /* DIAGNOSTIC */
+#endif
SCC_WRITE_DATA(regs, chan, *dp->p_mem++);
#ifdef pmax /* Alpha handles the 1.6 msec settle time in hardware */
DELAY(2);
#endif
}
- wbflush();
+ tc_mb();
out:
splx(s);
}
@@ -1218,7 +1332,7 @@ out:
* Stop output on a line.
*/
/*ARGSUSED*/
-int
+void
sccstop(tp, flag)
register struct tty *tp;
int flag;
@@ -1236,8 +1350,6 @@ sccstop(tp, flag)
tp->t_state |= TS_FLUSH;
}
splx(s);
-
- return 0; /* XXX should be void */
}
int
@@ -1296,7 +1408,7 @@ sccmctl(dev, bits, how)
sc->scc_wreg[SCC_CHANNEL_A].wr5);
}
if ((mbits & DML_DTR) || (sc->scc_softCAR & (1 << line)))
- scc_tty[minor(dev)]->t_state |= TS_CARR_ON;
+ sc->scc_tty[line]->t_state |= TS_CARR_ON;
(void) splx(s);
return (mbits);
}
@@ -1315,9 +1427,9 @@ scc_modem_intr(dev)
register u_char value;
int s;
- sc = scc_cd.cd_devs[SCCUNIT(dev)];
- tp = scc_tty[minor(dev)];
chan = SCCLINE(dev);
+ sc = scc_cd.cd_devs[SCCUNIT(dev)];
+ tp = sc->scc_tty[chan];
regs = (scc_regmap_t *)sc->scc_pdma[chan].p_addr;
if (chan == SCC_CHANNEL_A)
return;
@@ -1330,7 +1442,8 @@ scc_modem_intr(dev)
}
/*
- * XXX Why doesn't the Alpha driver follow carrier-detect?
+ * The pmax driver follows carrier-detect. The Alpha does not.
+ * XXX Why doesn't the Alpha driver follow carrier-detect?
* (in the Alpha driver, this is an "#ifdef notdef").
* Is it related to console handling?
*/
@@ -1357,12 +1470,17 @@ sccGetc(dev)
register scc_regmap_t *regs;
register int c, line;
register u_char value;
- struct scc_softc *sc;
int s;
line = SCCLINE(dev);
- sc = scc_cd.cd_devs[SCCUNIT(dev)];
- regs = (scc_regmap_t *)sc->scc_pdma[line].p_addr;
+ if (cold && scc_cons_addr) {
+ regs = scc_cons_addr;
+ } else {
+ register struct scc_softc *sc;
+ sc = scc_cd.cd_devs[SCCUNIT(dev)];
+ regs = (scc_regmap_t *)sc->scc_pdma[line].p_addr;
+ }
+
if (!regs)
return (0);
#ifdef pmax
@@ -1403,7 +1521,6 @@ sccPutc(dev, c)
register scc_regmap_t *regs;
register int line;
register u_char value;
- struct scc_softc *sc;
int s;
#ifdef pmax
@@ -1412,8 +1529,13 @@ sccPutc(dev, c)
s = splhigh();
#endif
line = SCCLINE(dev);
- sc = scc_cd.cd_devs[SCCUNIT(dev)];
- regs = (scc_regmap_t *)sc->scc_pdma[line].p_addr;
+ if (cold && scc_cons_addr) {
+ regs = scc_cons_addr;
+ } else {
+ register struct scc_softc *sc;
+ sc = scc_cd.cd_devs[SCCUNIT(dev)];
+ regs = (scc_regmap_t *)sc->scc_pdma[line].p_addr;
+ }
/*
* Wait for transmitter to be not busy.
@@ -1429,7 +1551,7 @@ sccPutc(dev, c)
* Send the char.
*/
SCC_WRITE_DATA(regs, line, c);
- wbflush();
+ tc_mb();
splx(s);
return;