+
+/*
+ * Following are all routines needed for COM to act as console
+ */
+#include "i386/i386/cons.h"
+
+comcnprobe(cp)
+ struct consdev *cp;
+{
+ int unit;
+
+ /* locate the major number */
+ for (commajor = 0; commajor < nchrdev; commajor++)
+ if (cdevsw[commajor].d_open == comopen)
+ break;
+
+ /* XXX: ick */
+ unit = CONUNIT;
+ com_addr[CONUNIT] = CONADDR;
+
+ /* make sure hardware exists? XXX */
+
+ /* initialize required fields */
+ cp->cn_dev = makedev(commajor, unit);
+ cp->cn_tp = &com_tty[unit];
+#ifdef COMCONSOLE
+ cp->cn_pri = CN_REMOTE; /* Force a serial port console */
+#else
+ cp->cn_pri = CN_NORMAL;
+#endif
+}
+
+comcninit(cp)
+ struct consdev *cp;
+{
+ int unit = UNIT(cp->cn_dev);
+
+ cominit(unit, comdefaultrate);
+ comconsole = unit;
+ comconsinit = 1;
+}
+
+cominit(unit, rate)
+ int unit, rate;
+{
+ register int com;
+ int s;
+ short stat;
+
+#ifdef lint
+ stat = unit; if (stat) return;
+#endif
+ com = com_addr[unit];
+ s = splhigh();
+ outb(com+com_cfcr, CFCR_DLAB);
+ rate = ttspeedtab(comdefaultrate, comspeedtab);
+ outb(com+com_data, rate & 0xFF);
+ outb(com+com_ier, rate >> 8);
+ outb(com+com_cfcr, CFCR_8BITS);
+ outb(com+com_ier, IER_ERXRDY | IER_ETXRDY);
+ outb(com+com_fifo, FIFO_ENABLE|FIFO_RCV_RST|FIFO_XMT_RST|FIFO_TRIGGER_14);
+ stat = inb(com+com_iir);
+ splx(s);
+}
+
+comcngetc(dev)
+{
+ register com = com_addr[UNIT(dev)];
+ short stat;
+ int c, s;
+
+#ifdef lint
+ stat = dev; if (stat) return(0);
+#endif
+ s = splhigh();
+ while (((stat = inb(com+com_lsr)) & LSR_RXRDY) == 0)
+ ;
+ c = inb(com+com_data);
+ stat = inb(com+com_iir);
+ splx(s);
+ return(c);
+}
+
+/*
+ * Console kernel output character routine.
+ */
+comcnputc(dev, c)
+ dev_t dev;
+ register int c;
+{
+ register com = com_addr[UNIT(dev)];
+ register int timo;
+ short stat;
+ int s = splhigh();
+
+#ifdef lint
+ stat = dev; if (stat) return;
+#endif
+#ifdef KGDB
+ if (dev != kgdb_dev)
+#endif
+ if (comconsinit == 0) {
+ (void) cominit(UNIT(dev), comdefaultrate);
+ comconsinit = 1;
+ }
+ /* wait for any pending transmission to finish */
+ timo = 50000;
+ while (((stat = inb(com+com_lsr)) & LSR_TXRDY) == 0 && --timo)
+ ;
+ outb(com+com_data, c);
+ /* wait for this transmission to complete */
+ timo = 1500000;
+ while (((stat = inb(com+com_lsr)) & LSR_TXRDY) == 0 && --timo)
+ ;
+ /* clear any interrupts generated by this transmission */
+ stat = inb(com+com_iir);
+ splx(s);
+}