Subject: dca/dcm console support changes
To: None <port-hp300@NetBSD.ORG>
From: Jason Thorpe <thorpej@SJ.Xenotropic.COM>
List: port-hp300
Date: 12/30/1995 11:43:43
Hi folks...

Attached below are the diffs I promised.  They compile, and should work, 
but I'd appreciate a sanity check by someone with serial consoles.

BTW, it's likely that I'll be making more changes to the console stuff in 
general in the near future.  Keep your eyes open :-)

These are diffs against NetBSD-current as of yesterday.  If need-be, I 
can put up a GENERIC kernel.  Let me know...

Thanks...

------------------------------------------------------------------------------
Jason R. Thorpe                                         thorpej@Xenotropic.COM

           Just me and my collection of obsolete computer gear(s).

-----cut here-----
Index: dca.c
===================================================================
RCS file: /usr/og/devsrc/netbsd/src/sys/arch/hp300/dev/dca.c,v
retrieving revision 1.1.1.1
diff -c -r1.1.1.1 dca.c
*** dca.c	1995/12/19 17:23:53	1.1.1.1
--- dca.c	1995/12/30 18:48:09
***************
*** 62,71 ****
  #include <sys/kernel.h>
  #include <sys/syslog.h>
  
  #include <hp300/dev/device.h>
  #include <hp300/dev/dcareg.h>
- 
- #include <machine/cpu.h>
  #include <hp300/hp300/isr.h>
  
  int	dcamatch();
--- 62,73 ----
  #include <sys/kernel.h>
  #include <sys/syslog.h>
  
+ #include <machine/cpu.h>
+ 
+ #include <dev/cons.h>
+ 
  #include <hp300/dev/device.h>
  #include <hp300/dev/dcareg.h>
  #include <hp300/hp300/isr.h>
  
  int	dcamatch();
***************
*** 94,109 ****
  void	dcastart();
  int	dcaparam(), dcaintr();
  int	ndca = NDCA;
- #ifdef DCACONSOLE
- int	dcaconsole = DCACONSOLE;
- #else
- int	dcaconsole = -1;
- #endif
- int	dcaconsinit;
  int	dcadefaultrate = TTYDEF_SPEED;
  int	dcamajor;
  int	dcafastservice;
  
  struct speedtab dcaspeedtab[] = {
  	0,	0,
  	50,	DCABRD(50),
--- 96,118 ----
  void	dcastart();
  int	dcaparam(), dcaintr();
  int	ndca = NDCA;
  int	dcadefaultrate = TTYDEF_SPEED;
  int	dcamajor;
  int	dcafastservice;
  
+ /*
+  * Stuff for DCA console support.  This could probably be done a little
+  * better.
+  */
+ static	struct dcadevice *dca_cn = NULL;	/* pointer to hardware */
+ static	int dca_lastcnpri = CN_DEAD;		/* XXX last priority */
+ static	int dcaconsinit;			/* has been initialized */
+ #ifdef DCACONSOLE
+ static	int dcaconsole = DCACONSOLE;
+ #else
+ static	int dcaconsole = -1;
+ #endif
+ 
  struct speedtab dcaspeedtab[] = {
  	0,	0,
  	50,	DCABRD(50),
***************
*** 141,146 ****
--- 150,157 ----
  long	dcamintcount[16];
  #endif
  
+ void	dcainit __P((struct dcadevice *, int));
+ 
  int
  dcamatch(hd)
  	register struct hp_device *hd;
***************
*** 216,222 ****
  		if (dcaconsole == unit)
  			kgdb_dev = NODEV; /* can't debug over console port */
  		else {
! 			(void) dcainit(sc, kgdb_rate);
  			dcaconsinit = 1;	/* don't re-init in dcaputc */
  			if (kgdb_debug_init) {
  				/*
--- 227,233 ----
  		if (dcaconsole == unit)
  			kgdb_dev = NODEV; /* can't debug over console port */
  		else {
! 			dcainit(dca, kgdb_rate);
  			dcaconsinit = 1;	/* don't re-init in dcaputc */
  			if (kgdb_debug_init) {
  				/*
***************
*** 270,276 ****
  		 * The card might be left in an inconsistent state
  		 * if card memory is read inadvertently.
  		 */
! 		dcainit(sc, dcadefaultrate);
  
  		tp->t_state |= TS_WOPEN;
  		ttychars(tp);
--- 281,287 ----
  		 * The card might be left in an inconsistent state
  		 * if card memory is read inadvertently.
  		 */
! 		dcainit(dca, dcadefaultrate);
  
  		tp->t_state |= TS_WOPEN;
  		ttychars(tp);
***************
*** 846,861 ****
  	return (bits);
  }
  
  /*
   * Following are all routines needed for DCA to act as console
   */
- #include <dev/cons.h>
  
  void
  dcacnprobe(cp)
  	struct consdev *cp;
  {
! 	struct dca_softc *sc;
  	int unit;
  
  	/* locate the major number */
--- 857,898 ----
  	return (bits);
  }
  
+ void
+ dcainit(dca, rate)
+ 	struct dcadevice *dca;
+ 	int rate;
+ {
+ 	int s;
+ 	short stat;
+ 
+ 	s = splhigh();
+ 
+ 	dca->dca_reset = 0xFF;
+ 	DELAY(100);
+ 	dca->dca_ic = IC_IE;
+ 
+ 	dca->dca_cfcr = CFCR_DLAB;
+ 	rate = ttspeedtab(rate, dcaspeedtab);
+ 	dca->dca_data = rate & 0xFF;
+ 	dca->dca_ier = rate >> 8;
+ 	dca->dca_cfcr = CFCR_8BITS;
+ 	dca->dca_ier = IER_ERXRDY | IER_ETXRDY;
+ 	dca->dca_fifo = FIFO_ENABLE|FIFO_RCV_RST|FIFO_XMT_RST|FIFO_TRIGGER_14;
+ 	dca->dca_mcr |= MCR_IEN;
+ 	DELAY(100);
+ 	stat = dca->dca_iir;
+ 	splx(s);
+ }
+ 
  /*
   * Following are all routines needed for DCA to act as console
   */
  
  void
  dcacnprobe(cp)
  	struct consdev *cp;
  {
! 	struct dcadevice *dca;
  	int unit;
  
  	/* locate the major number */
***************
*** 865,876 ****
  
  	/* XXX: ick */
  	unit = CONUNIT;
- 	sc = &dca_softc[unit];
  
! 	sc->sc_dca = (struct dcadevice *) sctova(CONSCODE);
  
  	/* make sure hardware exists */
! 	if (badaddr((short *)sc->sc_dca)) {
  		cp->cn_pri = CN_DEAD;
  		return;
  	}
--- 902,912 ----
  
  	/* XXX: ick */
  	unit = CONUNIT;
  
! 	dca = (struct dcadevice *)sctova(CONSCODE);
  
  	/* make sure hardware exists */
! 	if (badaddr((short *)dca)) {
  		cp->cn_pri = CN_DEAD;
  		return;
  	}
***************
*** 878,884 ****
  	/* initialize required fields */
  	cp->cn_dev = makedev(dcamajor, unit);
  
! 	switch (sc->sc_dca->dca_id) {
  	case DCAID0:
  	case DCAID1:
  		cp->cn_pri = CN_NORMAL;
--- 914,920 ----
  	/* initialize required fields */
  	cp->cn_dev = makedev(dcamajor, unit);
  
! 	switch (dca->dca_id) {
  	case DCAID0:
  	case DCAID1:
  		cp->cn_pri = CN_NORMAL;
***************
*** 897,902 ****
--- 933,949 ----
  	 */
  	if (dcaconsole == unit)
  		cp->cn_pri = CN_REMOTE;
+ 
+ 	/*
+ 	 * If our priority is higher than the currently-remembered
+ 	 * DCA, stash our priority and address, for the benefit of
+ 	 * dcacninit().
+ 	 */
+ 	if (cp->cn_pri > dca_lastcnpri) {
+ 		dca_lastcnpri = cp->cn_pri;
+ 		dca_cn = dca;
+ 	}
+ 
  #ifdef KGDB
  	if (major(kgdb_dev) == 1)			/* XXX */
  		kgdb_dev = makedev(dcamajor, minor(kgdb_dev));
***************
*** 908,968 ****
  	struct consdev *cp;
  {
  	int unit = DCAUNIT(cp->cn_dev);
- 	struct dca_softc *sc = &dca_softc[unit];
  
! 	dcainit(sc, dcadefaultrate);
  	dcaconsole = unit;
  	dcaconsinit = 1;
  }
  
! dcainit(sc, rate)
! 	struct dca_softc *sc;
! 	int rate;
! {
! 	struct dcadevice *dca = sc->sc_dca;
! 	int s;
! 	short stat;
! 
! #ifdef lint
! 	stat = sc->sc_hd->hp_unit; if (stat) return;
! #endif
! 
! 	s = splhigh();
! 
! 	dca->dca_reset = 0xFF;
! 	DELAY(100);
! 	dca->dca_ic = IC_IE;
! 
! 	dca->dca_cfcr = CFCR_DLAB;
! 	rate = ttspeedtab(rate, dcaspeedtab);
! 	dca->dca_data = rate & 0xFF;
! 	dca->dca_ier = rate >> 8;
! 	dca->dca_cfcr = CFCR_8BITS;
! 	dca->dca_ier = IER_ERXRDY | IER_ETXRDY;
! 	dca->dca_fifo = FIFO_ENABLE|FIFO_RCV_RST|FIFO_XMT_RST|FIFO_TRIGGER_14;
! 	dca->dca_mcr |= MCR_IEN;
! 	DELAY(100);
! 	stat = dca->dca_iir;
! 	splx(s);
! }
! 
  int
  dcacngetc(dev)
  	dev_t dev;
  {
- 	struct dca_softc *sc = &dca_softc[DCAUNIT(dev)];
- 	struct dcadevice *dca = sc->sc_dca;
  	u_char stat;
  	int c, s;
  
  #ifdef lint
  	stat = dev; if (stat) return (0);
  #endif
  	s = splhigh();
! 	while (((stat = dca->dca_lsr) & LSR_RXRDY) == 0)
  		;
! 	c = dca->dca_data;
! 	stat = dca->dca_iir;
  	splx(s);
  	return (c);
  }
--- 955,989 ----
  	struct consdev *cp;
  {
  	int unit = DCAUNIT(cp->cn_dev);
  
! 	dcainit(dca_cn, dcadefaultrate);
  	dcaconsole = unit;
  	dcaconsinit = 1;
  }
  
! /* ARGSUSED */
  int
  dcacngetc(dev)
  	dev_t dev;
  {
  	u_char stat;
  	int c, s;
  
  #ifdef lint
  	stat = dev; if (stat) return (0);
  #endif
+ 
+ 	/*
+ 	 * NOTE: This assumes that DCAUNIT(dev) == dcaconsole.  If
+ 	 * it doesn't, well, you lose.  (It's also extremely unlikely
+ 	 * that will ever not be the case.)
+ 	 */
+ 
  	s = splhigh();
! 	while (((stat = dca_cn->dca_lsr) & LSR_RXRDY) == 0)
  		;
! 	c = dca_cn->dca_data;
! 	stat = dca_cn->dca_iir;
  	splx(s);
  	return (c);
  }
***************
*** 970,982 ****
  /*
   * Console kernel output character routine.
   */
  void
  dcacnputc(dev, c)
  	dev_t dev;
  	register int c;
  {
- 	struct dca_softc *sc = &dca_softc[DCAUNIT(dev)];
- 	struct dcadevice *dca = sc->sc_dca;
  	int timo;
  	u_char stat;
  	int s = splhigh();
--- 991,1002 ----
  /*
   * Console kernel output character routine.
   */
+ /* ARGSUSED */
  void
  dcacnputc(dev, c)
  	dev_t dev;
  	register int c;
  {
  	int timo;
  	u_char stat;
  	int s = splhigh();
***************
*** 984,1009 ****
  #ifdef lint
  	stat = dev; if (stat) return;
  #endif
  	if (dcaconsinit == 0) {
! 		(void) dcainit(sc, dcadefaultrate);
  		dcaconsinit = 1;
  	}
  	/* wait for any pending transmission to finish */
  	timo = 50000;
! 	while (((stat = dca->dca_lsr) & LSR_TXRDY) == 0 && --timo)
  		;
! 	dca->dca_data = c;
  	/* wait for this transmission to complete */
  	timo = 1500000;
! 	while (((stat = dca->dca_lsr) & LSR_TXRDY) == 0 && --timo)
  		;
! 	/*
! 	 * If the "normal" interface was busy transfering a character
! 	 * we must let our interrupt through to keep things moving.
! 	 * Otherwise, we clear the interrupt that we have caused.
! 	 */
! 	if ((sc->sc_tty->t_state & TS_BUSY) == 0)
! 		stat = dca->dca_iir;
  	splx(s);
  }
! #endif
--- 1004,1031 ----
  #ifdef lint
  	stat = dev; if (stat) return;
  #endif
+ 
+ 	/*
+ 	 * NOTE: This assumes that DCAUNIT(dev) == dcaconsole.  If
+ 	 * it doesn't, well, you lose.  (It's also extremely unlikely
+ 	 * that will ever not be the case.)
+ 	 */
+ 
  	if (dcaconsinit == 0) {
! 		dcainit(dca_cn, dcadefaultrate);
  		dcaconsinit = 1;
  	}
  	/* wait for any pending transmission to finish */
  	timo = 50000;
! 	while (((stat = dca_cn->dca_lsr) & LSR_TXRDY) == 0 && --timo)
  		;
! 	dca_cn->dca_data = c;
  	/* wait for this transmission to complete */
  	timo = 1500000;
! 	while (((stat = dca_cn->dca_lsr) & LSR_TXRDY) == 0 && --timo)
  		;
! 	/* clear any interrupts generated by this transmission */
! 	stat = dca_cn->dca_iir;
  	splx(s);
  }
! #endif /* NDCA > 0 */
Index: dcareg.h
===================================================================
RCS file: /usr/og/devsrc/netbsd/src/sys/arch/hp300/dev/dcareg.h,v
retrieving revision 1.1.1.1
diff -c -r1.1.1.1 dcareg.h
*** dcareg.h	1995/12/19 17:23:53	1.1.1.1
--- dcareg.h	1995/12/30 05:59:10
***************
*** 174,187 ****
  #define	MSR_DDSR	0x02
  #define	MSR_DCTS	0x01
  
- #ifdef hp300
  /* WARNING: Serial console is assumed to be at SC9 */
  #define CONSCODE	(9)
- #endif
- #ifdef hp700
- /* hardwired port addresses */
- #define PORT1		((struct dcadevice *)CORE_RS232_1)
- #define PORT2		((struct dcadevice *)CORE_RS232_2)
- #define CONPORT		PORT1
- #endif
  #define CONUNIT		(0)
--- 174,179 ----
Index: dcm.c
===================================================================
RCS file: /usr/og/devsrc/netbsd/src/sys/arch/hp300/dev/dcm.c,v
retrieving revision 1.1.1.2
diff -c -r1.1.1.2 dcm.c
*** dcm.c	1995/12/30 07:42:06	1.1.1.2
--- dcm.c	1995/12/30 18:38:34
***************
*** 68,73 ****
--- 68,75 ----
  
  #include <machine/cpu.h>
  
+ #include <dev/cons.h>
+ 
  #include <hp300/dev/device.h>
  #include <hp300/dev/dcmreg.h>
  #include <hp300/hp300/isr.h>
***************
*** 122,135 ****
  };
  
  /*
!  * Console support
   */
  #ifdef DCMCONSOLE
! int	dcmconsole = DCMCONSOLE;
  #else
! int	dcmconsole = -1;
  #endif
! int	dcmconsinit;
  int	dcmdefaultrate = DEFAULT_BAUD_RATE;
  int	dcmconbrdbusy = 0;
  int	dcmmajor;
--- 124,141 ----
  };
  
  /*
!  * Stuff for DCM console support.  This could probably be done a little
!  * better.
   */
+ static	struct dcmdevice *dcm_cn = NULL;	/* pointer to hardware */
+ static	int dcm_lastcnpri = CN_DEAD;		/* XXX last priority */
+ static	int dcmconsinit;			/* has been initialized */
  #ifdef DCMCONSOLE
! static	int dcmconsole = DCMCONSOLE;
  #else
! static	int dcmconsole = -1;
  #endif
! 
  int	dcmdefaultrate = DEFAULT_BAUD_RATE;
  int	dcmconbrdbusy = 0;
  int	dcmmajor;
***************
*** 249,254 ****
--- 255,262 ----
  #endif
  } dcm_softc[NDCM];
  
+ void	dcminit __P((struct dcmdevice *, int, int));
+ 
  int
  dcmmatch(hd)
  	register struct hp_device *hd;
***************
*** 377,383 ****
  		 * by the corresponding code in dcmcnprobe.
  		 */
  		else {
! 			(void) dcminit(kgdb_dev, kgdb_rate);
  			if (kgdb_debug_init) {
  				printf("%s port %d: ", sc->sc_hd->hp_xname,
  				    DCMPORT(DCMUNIT(kgdb_dev)));
--- 385,392 ----
  		 * by the corresponding code in dcmcnprobe.
  		 */
  		else {
! 			dcminit(dcm, DCMPORT(DCMUNIT(kgdb_dev)),
! 			    kgdb_rate);
  			if (kgdb_debug_init) {
  				printf("%s port %d: ", sc->sc_hd->hp_xname,
  				    DCMPORT(DCMUNIT(kgdb_dev)));
***************
*** 431,437 ****
  		 * The card might be left in an inconsistent state
  		 * if the card memory is read inadvertently.
  		 */
! 		dcminit(dev, dcmdefaultrate);
  
  		tp->t_state |= TS_WOPEN;
  		ttychars(tp);
--- 440,446 ----
  		 * The card might be left in an inconsistent state
  		 * if the card memory is read inadvertently.
  		 */
! 		dcminit(sc->sc_dcm, port, dcmdefaultrate);
  
  		tp->t_state |= TS_WOPEN;
  		ttychars(tp);
***************
*** 1328,1343 ****
  	SEM_UNLOCK(dcm);
  }
  
  /*
   * Following are all routines needed for DCM to act as console
   */
- #include <dev/cons.h>
  
  void
  dcmcnprobe(cp)
  	struct consdev *cp;
  {
! 	struct dcm_softc *sc;
  	struct dcmdevice *dcm;
  	struct hp_hw *hw;
  	int unit;
--- 1337,1386 ----
  	SEM_UNLOCK(dcm);
  }
  
+ void
+ dcminit(dcm, port, rate)
+ 	struct dcmdevice *dcm;
+ 	int port, rate;
+ {
+ 	int s, mode;
+ 
+ 	mode = LC_8BITS | LC_1STOP;
+ 
+ 	s = splhigh();
+ 
+ 	/*
+ 	 * Wait for transmitter buffer to empty.
+ 	 */
+ 	while (dcm->dcm_thead[port].ptr != dcm->dcm_ttail[port].ptr)
+ 		DELAY(DCM_USPERCH(rate));
+ 
+ 	/*
+ 	 * Make changes known to hardware.
+ 	 */
+ 	dcm->dcm_data[port].dcm_baud = ttspeedtab(rate, dcmspeedtab);
+ 	dcm->dcm_data[port].dcm_conf = mode;
+ 	SEM_LOCK(dcm);
+ 	dcm->dcm_cmdtab[port].dcm_data |= CT_CON;
+ 	dcm->dcm_cr |= (1 << port);
+ 	SEM_UNLOCK(dcm);
+ 
+ 	/*
+ 	 * Delay for config change to take place. Weighted by baud.
+ 	 * XXX why do we do this?
+ 	 */
+ 	DELAY(16 * DCM_USPERCH(rate));
+ 	splx(s);
+ }
+ 
  /*
   * Following are all routines needed for DCM to act as console
   */
  
  void
  dcmcnprobe(cp)
  	struct consdev *cp;
  {
! 	struct dcm_softc *sc;	/* XXX thorpej */
  	struct dcmdevice *dcm;
  	struct hp_hw *hw;
  	int unit;
***************
*** 1348,1353 ****
--- 1391,1397 ----
  			break;
  
  	/*
+ 	 * XXX FIX ME!
  	 * Implicitly assigns the lowest select code DCM card found to be
  	 * logical unit 0 (actually CONUNIT).  If your config file does
  	 * anything different, you're screwed.
***************
*** 1361,1368 ****
  	}
  
  	unit = CONUNIT;
! 	sc = &dcm_softc[DCMBOARD(CONUNIT)];
! 	dcm = sc->sc_dcm = (struct dcmdevice *)hw->hw_kva;
  
  	/* initialize required fields */
  	cp->cn_dev = makedev(dcmmajor, unit);
--- 1405,1411 ----
  	}
  
  	unit = CONUNIT;
! 	dcm = (struct dcmdevice *)hw->hw_kva;
  
  	/* initialize required fields */
  	cp->cn_dev = makedev(dcmmajor, unit);
***************
*** 1385,1390 ****
--- 1428,1444 ----
  	 */
  	if (dcmconsole == unit)
  		cp->cn_pri = CN_REMOTE;
+ 
+ 	/*
+ 	 * If our priority is higher than the currently-remembered
+ 	 * DCM, stash our priority and address, for the benefit of
+ 	 * dcmcninit().
+ 	 */
+ 	if (cp->cn_pri > dcm_lastcnpri) {
+ 		dcm_lastcnpri = cp->cn_pri;
+ 		dcm_cn = dcm;
+ 	}
+ 
  #ifdef KGDB_CHEAT
  	/*
  	 * This doesn't currently work, at least not with ite consoles;
***************
*** 1392,1398 ****
  	 */
  	if (major(kgdb_dev) == dcmmajor &&
  	    DCMBOARD(DCMUNIT(kgdb_dev)) == DCMBOARD(unit)) {
! 		(void) dcminit(kgdb_dev, kgdb_rate);
  		if (kgdb_debug_init) {
  			/*
  			 * We assume that console is ready for us...
--- 1446,1452 ----
  	 */
  	if (major(kgdb_dev) == dcmmajor &&
  	    DCMBOARD(DCMUNIT(kgdb_dev)) == DCMBOARD(unit)) {
! 		dcminit(dcm_cn, DCMPORT(DCMUNIT(kgdb_dev)), kgdb_rate);
  		if (kgdb_debug_init) {
  			/*
  			 * We assume that console is ready for us...
***************
*** 1411,1487 ****
  dcmcninit(cp)
  	struct consdev *cp;
  {
  
! 	dcminit(cp->cn_dev, dcmdefaultrate);
  	dcmconsinit = 1;
  	dcmconsole = DCMUNIT(cp->cn_dev);
  }
  
- dcminit(dev, rate)
- 	dev_t dev;
- 	int rate;
- {
- 	struct dcm_softc *sc;
- 	struct dcmdevice *dcm;
- 	int s, mode, unit, board, port;
- 
- 	unit = DCMUNIT(dev);
- 	board = DCMBOARD(unit);
- 	port = DCMPORT(unit);
- 
- 	sc = &dcm_softc[board];
- 	dcm = sc->sc_dcm;
- 
- 	mode = LC_8BITS | LC_1STOP;
- 
- 	s = splhigh();
- 
- 	/*
- 	 * Wait for transmitter buffer to empty.
- 	 */
- 	while (dcm->dcm_thead[port].ptr != dcm->dcm_ttail[port].ptr)
- 		DELAY(DCM_USPERCH(rate));
- 
- 	/*
- 	 * Make changes known to hardware.
- 	 */
- 	dcm->dcm_data[port].dcm_baud = ttspeedtab(rate, dcmspeedtab);
- 	dcm->dcm_data[port].dcm_conf = mode;
- 	SEM_LOCK(dcm);
- 	dcm->dcm_cmdtab[port].dcm_data |= CT_CON;
- 	dcm->dcm_cr |= (1 << port);
- 	SEM_UNLOCK(dcm);
- 
- 	/*
- 	 * Delay for config change to take place. Weighted by baud.
- 	 * XXX why do we do this?
- 	 */
- 	DELAY(16 * DCM_USPERCH(rate));
- 	splx(s);
- }
- 
  int
  dcmcngetc(dev)
  	dev_t dev;
  {
- 	struct dcm_softc *sc;
- 	struct dcmdevice *dcm;
  	struct dcmrfifo *fifo;
  	struct dcmpreg *pp;
  	u_int head;
! 	int s, c, stat, unit, board, port;
  
  	unit = DCMUNIT(dev);
- 	board = DCMBOARD(unit);
  	port = DCMPORT(unit);
  
! 	sc = &dcm_softc[board];
! 	dcm = sc->sc_dcm;
! 	pp = dcm_preg(dcm, port);
  
  	s = splhigh();
  	head = pp->r_head & RX_MASK;
! 	fifo = &dcm->dcm_rfifos[3-port][head>>1];
  	while (head == (pp->r_tail & RX_MASK))
  		;
  	/*
--- 1465,1501 ----
  dcmcninit(cp)
  	struct consdev *cp;
  {
+ 	int unit = DCMUNIT(cp->cn_dev);
+ 	int port = DCMPORT(unit);
  
! 	dcminit(dcm_cn, port, dcmdefaultrate);
  	dcmconsinit = 1;
  	dcmconsole = DCMUNIT(cp->cn_dev);
  }
  
  int
  dcmcngetc(dev)
  	dev_t dev;
  {
  	struct dcmrfifo *fifo;
  	struct dcmpreg *pp;
  	u_int head;
! 	int s, c, stat, unit, port;
  
  	unit = DCMUNIT(dev);
  	port = DCMPORT(unit);
  
! 	/*
! 	 * NOTE: This assumes that unit == dcmconsole.  If it doesn't,
! 	 * well, you lose.  (It's also extremely unlikely that will ever
! 	 * not be the case.)
! 	 */
! 
! 	pp = dcm_preg(dcm_cn, port);
  
  	s = splhigh();
  	head = pp->r_head & RX_MASK;
! 	fifo = &dcm_cn->dcm_rfifos[3-port][head>>1];
  	while (head == (pp->r_tail & RX_MASK))
  		;
  	/*
***************
*** 1489,1498 ****
  	 * interrupt through in case some other port on the board was
  	 * busy.  Otherwise we must clear the interrupt.
  	 */
! 	SEM_LOCK(dcm);
! 	if ((dcm->dcm_ic & IC_IE) == 0)
! 		stat = dcm->dcm_iir;
! 	SEM_UNLOCK(dcm);
  	c = fifo->data_char;
  	stat = fifo->data_stat;
  	pp->r_head = (head + 2) & RX_MASK;
--- 1503,1512 ----
  	 * interrupt through in case some other port on the board was
  	 * busy.  Otherwise we must clear the interrupt.
  	 */
! 	SEM_LOCK(dcm_cn);
! 	if ((dcm_cn->dcm_ic & IC_IE) == 0)
! 		stat = dcm_cn->dcm_iir;
! 	SEM_UNLOCK(dcm_cn);
  	c = fifo->data_char;
  	stat = fifo->data_stat;
  	pp->r_head = (head + 2) & RX_MASK;
***************
*** 1508,1544 ****
  	dev_t dev;
  	int c;
  {
- 	struct dcm_softc *sc;
- 	struct dcmdevice *dcm;
  	struct dcmpreg *pp;
  	unsigned tail;
! 	int s, unit, board, port, stat;
  
  	unit = DCMUNIT(dev);
- 	board = DCMBOARD(unit);
  	port = DCMPORT(unit);
  
! 	sc = &dcm_softc[board];
! 	dcm = sc->sc_dcm;
! 	pp = dcm_preg(dcm, port);
  
  	s = splhigh();
  #ifdef KGDB
  	if (dev != kgdb_dev)
  #endif
  	if (dcmconsinit == 0) {
! 		(void) dcminit(dev, dcmdefaultrate);
  		dcmconsinit = 1;
  	}
  	tail = pp->t_tail & TX_MASK;
  	while (tail != (pp->t_head & TX_MASK))
  		;
! 	dcm->dcm_tfifos[3-port][tail].data_char = c;
  	pp->t_tail = tail = (tail + 1) & TX_MASK;
! 	SEM_LOCK(dcm);
! 	dcm->dcm_cmdtab[port].dcm_data |= CT_TX;
! 	dcm->dcm_cr |= (1 << port);
! 	SEM_UNLOCK(dcm);
  	while (tail != (pp->t_head & TX_MASK))
  		;
  	/*
--- 1522,1559 ----
  	dev_t dev;
  	int c;
  {
  	struct dcmpreg *pp;
  	unsigned tail;
! 	int s, unit, port, stat;
  
  	unit = DCMUNIT(dev);
  	port = DCMPORT(unit);
  
! 	/*
! 	 * NOTE: This assumes that unit == dcmconsole.  If it doesn't,
! 	 * well, you lose.  (It's also extremely unlikely that will ever
! 	 * not be the case.)
! 	 */
! 
! 	pp = dcm_preg(dcm_cn, port);
  
  	s = splhigh();
  #ifdef KGDB
  	if (dev != kgdb_dev)
  #endif
  	if (dcmconsinit == 0) {
! 		dcminit(dcm_cn, port, dcmdefaultrate);
  		dcmconsinit = 1;
  	}
  	tail = pp->t_tail & TX_MASK;
  	while (tail != (pp->t_head & TX_MASK))
  		;
! 	dcm_cn->dcm_tfifos[3-port][tail].data_char = c;
  	pp->t_tail = tail = (tail + 1) & TX_MASK;
! 	SEM_LOCK(dcm_cn);
! 	dcm_cn->dcm_cmdtab[port].dcm_data |= CT_TX;
! 	dcm_cn->dcm_cr |= (1 << port);
! 	SEM_UNLOCK(dcm_cn);
  	while (tail != (pp->t_head & TX_MASK))
  		;
  	/*
***************
*** 1546,1556 ****
  	 * interrupt through in case some other port on the board
  	 * was busy.  Otherwise we must clear the interrupt.
  	 */
! 	if ((dcm->dcm_ic & IC_IE) == 0) {
! 		SEM_LOCK(dcm);
! 		stat = dcm->dcm_iir;
! 		SEM_UNLOCK(dcm);
  	}
  	splx(s);
  }
! #endif
--- 1561,1571 ----
  	 * interrupt through in case some other port on the board
  	 * was busy.  Otherwise we must clear the interrupt.
  	 */
! 	if ((dcm_cn->dcm_ic & IC_IE) == 0) {
! 		SEM_LOCK(dcm_cn);
! 		stat = dcm_cn->dcm_iir;
! 		SEM_UNLOCK(dcm_cn);
  	}
  	splx(s);
  }
! #endif /* NDCM > 0 */