diff options
author | Thomas Graichen <graichen@cvs.openbsd.org> | 1996-12-22 15:19:07 +0000 |
---|---|---|
committer | Thomas Graichen <graichen@cvs.openbsd.org> | 1996-12-22 15:19:07 +0000 |
commit | ca1c7fedd990e6b1e7244233df5a6a638f0e4e31 (patch) | |
tree | 20016b11dce3c72001f0e250c8f1a714ed64e546 /sys/arch/pmax/tc/scc.c | |
parent | de4c3561677938c64d13b1e5112686a88b0b47fe (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.c | 382 |
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; |