summaryrefslogtreecommitdiff
path: root/sys/dev/ic/com.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/ic/com.c')
-rw-r--r--sys/dev/ic/com.c355
1 files changed, 81 insertions, 274 deletions
diff --git a/sys/dev/ic/com.c b/sys/dev/ic/com.c
index c8e1857a235..f4800147c52 100644
--- a/sys/dev/ic/com.c
+++ b/sys/dev/ic/com.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: com.c,v 1.45 1999/07/26 12:31:43 niklas Exp $ */
+/* $OpenBSD: com.c,v 1.46 1999/07/26 15:09:00 niklas Exp $ */
/* $NetBSD: com.c,v 1.82.4.1 1996/06/02 09:08:00 mrg Exp $ */
/*-
@@ -96,12 +96,6 @@ struct cfattach com_isa_ca = {
};
#endif
-#if NCOM_ISAPNP
-struct cfattach com_isapnp_ca = {
- sizeof(struct com_softc), comprobe, comattach
-};
-#endif
-
#if NCOM_COMMULTI
struct cfattach com_commulti_ca = {
sizeof(struct com_softc), comprobe, comattach
@@ -124,7 +118,6 @@ int comdefaultrate = TTYDEF_SPEED;
int comconsaddr;
int comconsinit;
int comconsattached;
-int comconsrate;
bus_space_tag_t comconsiot;
bus_space_handle_t comconsioh;
tcflag_t comconscflag = TTYDEF_CFLAG;
@@ -134,16 +127,11 @@ int comsopen = 0;
int comevents = 0;
#ifdef KGDB
-#include <sys/kgdb.h>
-
-static int com_kgdb_addr;
-static bus_space_tag_t com_kgdb_iot;
-static bus_space_handle_t com_kgdb_ioh;
-static int com_kgdb_attached;
-
-int com_kgdb_getc __P((void *));
-void com_kgdb_putc __P((void *, int));
-#endif /* KGDB */
+#include <machine/remote-sl.h>
+extern int kgdb_dev;
+extern int kgdb_rate;
+extern int kgdb_debug_init;
+#endif
#define DEVUNIT(x) (minor(x) & 0x7f)
#define DEVCUA(x) (minor(x) & 0x80)
@@ -154,23 +142,21 @@ void com_kgdb_putc __P((void *, int));
#define ISSET(t, f) ((t) & (f))
int
-comspeed(speed, frequency)
- long speed, frequency;
+comspeed(speed)
+ long speed;
{
#define divrnd(n, q) (((n)*2/(q)+1)/2) /* divide and round off */
int x, err;
-#if 0
if (speed == 0)
return 0;
-#endif
- if (speed <= 0)
+ if (speed < 0)
return -1;
- x = divrnd((frequency / 16), speed);
+ x = divrnd((COM_FREQ / 16), speed);
if (x <= 0)
return -1;
- err = divrnd((frequency / 16) * 1000, speed * x) - 1000;
+ err = divrnd((COM_FREQ / 16) * 1000, speed * x) - 1000;
if (err < 0)
err = -err;
if (err > COM_TOLERANCE)
@@ -358,7 +344,6 @@ comattach(parent, self, aux)
*/
sc->sc_hwflags = 0;
sc->sc_swflags = 0;
- sc->sc_frequency = COM_FREQ;
#if NCOM_ISA
if (IS_ISA(parent)) {
struct isa_attach_args *ia = aux;
@@ -563,55 +548,30 @@ comattach(parent, self, aux)
}
#ifdef KGDB
- /*
- * Allow kgdb to "take over" this port. If this is
- * the kgdb device, it has exclusive use.
- */
- if (iot == com_kgdb_iot && iobase == com_kgdb_addr &&
- !ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) {
- com_kgdb_attached = 1;
-
- SET(sc->sc_hwflags, COM_HW_KGDB);
- printf("%s: kgdb\n", sc->sc_dev.dv_xname);
+ if (kgdb_dev == makedev(commajor, unit)) {
+ if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE))
+ kgdb_dev = -1; /* can't debug over console port */
+ else {
+ cominit(iot, ioh, kgdb_rate);
+ if (kgdb_debug_init) {
+ /*
+ * Print prefix of device name,
+ * let kgdb_connect print the rest.
+ */
+ printf("%s: ", sc->sc_dev.dv_xname);
+ kgdb_connect(1);
+ } else
+ printf("%s: kgdb enabled\n",
+ sc->sc_dev.dv_xname);
+ }
}
#endif
/* XXX maybe move up some? */
if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE))
printf("%s: console\n", sc->sc_dev.dv_xname);
-
-#ifdef DDB
- if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE))
- com_enable_debugport(sc);
-#endif
-
-#ifdef KGDB
- /*
- * Allow kgdb to "take over" this port. If this is
- * the kgdb device, it has exclusive use.
- */
- if (ISSET(sc->sc_hwflags, COM_HW_KGDB))
- com_enable_debugport(sc);
-#endif
}
-#if defined(DDB) || defined(KGDB)
-void
-com_enable_debugport(sc)
- struct com_softc *sc;
-{
- int s;
-
- /* Turn on line break interrupt, set carrier. */
- s = splhigh();
- sc->sc_ier = IER_ERXRDY;
- bus_space_write_1(sc->sc_iot, sc->sc_ioh, com_ier, sc->sc_ier);
- SET(sc->sc_mcr, MCR_DTR | MCR_RTS);
- bus_space_write_1(sc->sc_iot, sc->sc_ioh, com_mcr, sc->sc_mcr);
- splx(s);
-}
-#endif
-
int
comopen(dev, flag, mode, p)
dev_t dev;
@@ -632,14 +592,6 @@ comopen(dev, flag, mode, p)
if (!sc)
return ENXIO;
-#ifdef KGDB
- /*
- * If this is the kgdb port, no other use is permitted.
- */
- if (ISSET(sc->sc_hwflags, COM_HW_KGDB))
- return (EBUSY);
-#endif
-
s = spltty();
if (!sc->sc_tty) {
tp = sc->sc_tty = ttymalloc();
@@ -1101,37 +1053,6 @@ comioctl(dev, cmd, data, flag, p)
return 0;
}
-u_char
-com_cflag2lcr(cflag)
- tcflag_t cflag;
-{
- u_char lcr = 0;
-
- switch (ISSET(cflag, CSIZE)) {
- case CS5:
- SET(lcr, LCR_5BITS);
- break;
- case CS6:
- SET(lcr, LCR_6BITS);
- break;
- case CS7:
- SET(lcr, LCR_7BITS);
- break;
- case CS8:
- SET(lcr, LCR_8BITS);
- break;
- }
- if (ISSET(cflag, PARENB)) {
- SET(lcr, LCR_PENAB);
- if (!ISSET(cflag, PARODD))
- SET(lcr, LCR_PEVEN);
- }
- if (ISSET(cflag, CSTOPB))
- SET(lcr, LCR_STOPB);
-
- return (lcr);
-}
-
int
comparam(tp, t)
struct tty *tp;
@@ -1140,7 +1061,7 @@ comparam(tp, t)
struct com_softc *sc = com_cd.cd_devs[DEVUNIT(tp->t_dev)];
bus_space_tag_t iot = sc->sc_iot;
bus_space_handle_t ioh = sc->sc_ioh;
- int ospeed = comspeed(t->c_ospeed, sc->sc_frequency);
+ int ospeed = comspeed(t->c_ospeed);
u_char lcr;
tcflag_t oldcflag;
int s;
@@ -1515,13 +1436,6 @@ comintr(arg)
}
#endif
data = 0;
-#ifdef KGDB
- if (ISSET(sc->sc_hwflags,
- COM_HW_KGDB)) {
- kgdb_connect(1);
- goto next;
- }
-#endif
}
if (p >= sc->sc_ibufend) {
sc->sc_floods++;
@@ -1538,7 +1452,7 @@ comintr(arg)
sc->sc_mcr);
}
}
-#if defined(DDB) || defined(KGDB)
+#ifdef DDB
next:
#endif
#ifdef COM_DEBUG
@@ -1682,113 +1596,54 @@ comcnprobe(cp)
#endif
}
-/*
- * The following functions are polled getc and putc routines, shared
- * by the console and kgdb glue.
- */
-
-int
-com_common_getc(iot, ioh)
- bus_space_tag_t iot;
- bus_space_handle_t ioh;
-{
- int s = splhigh();
- u_char stat, c;
-
- /* block until a character becomes available */
- while (!ISSET(stat = bus_space_read_1(iot, ioh, com_lsr), LSR_RXRDY))
- ;
-
- c = bus_space_read_1(iot, ioh, com_data);
- stat = bus_space_read_1(iot, ioh, com_iir);
- splx(s);
- return (c);
-}
-
-void
-com_common_putc(iot, ioh, c)
- bus_space_tag_t iot;
- bus_space_handle_t ioh;
- int c;
-{
- int s = splhigh();
- u_char stat;
- int timo;
-
- /* wait for any pending transmission to finish */
- timo = 50000;
- while (!ISSET(stat = bus_space_read_1(iot, ioh, com_lsr), LSR_TXRDY)
- && --timo)
- ;
-
- bus_space_write_1(iot, ioh, com_data, c);
- /* wait for this transmission to complete */
- timo = 1500000;
- while (!ISSET(stat = bus_space_read_1(iot, ioh, com_lsr), LSR_TXRDY)
- && --timo)
- ;
-
-#if 0 /* I don't think sooooo (pefo) */
- /* clear any interrupts generated by this transmission */
- stat = bus_space_read_1(iot, ioh, com_iir);
-#endif
- splx(s);
-}
-
-/*
- * Following are all routines needed for COM to act as console
- */
-
void
comcninit(cp)
struct consdev *cp;
{
- if (cominit(comconsiot, CONADDR, comdefaultrate, COM_FREQ,
- comconscflag, &comconsioh))
+ if (bus_space_map(comconsiot, CONADDR, COM_NPORTS, 0, &comconsioh))
panic("comcninit: mapping failed");
+ cominit(comconsiot, comconsioh, comdefaultrate);
comconsaddr = CONADDR;
comconsinit = 0;
}
-/*
- * Initialize UART to known state.
- */
-int
-cominit(iot, iobase, rate, frequency, cflag, iohp)
+void
+cominit(iot, ioh, rate)
bus_space_tag_t iot;
- int iobase;
- int rate, frequency;
- tcflag_t cflag;
- bus_space_handle_t *iohp;
-{
bus_space_handle_t ioh;
+ int rate;
+{
+ int s = splhigh();
+ u_char stat;
- if (bus_space_map(iot, iobase, COM_NPORTS, 0, &ioh))
- return (ENOMEM); /* ??? */
-
- bus_space_write_1(iot, ioh, com_lcr, LCR_EERS);
- bus_space_write_1(iot, ioh, com_efr, 0);
bus_space_write_1(iot, ioh, com_lcr, LCR_DLAB);
- rate = comspeed(rate, frequency);
+ rate = comspeed(comdefaultrate);
bus_space_write_1(iot, ioh, com_dlbl, rate);
bus_space_write_1(iot, ioh, com_dlbh, rate >> 8);
- bus_space_write_1(iot, ioh, com_lcr, com_cflag2lcr(cflag));
- bus_space_write_1(iot, ioh, com_mcr, 0);
- bus_space_write_1(iot, ioh, com_fifo,
- FIFO_ENABLE | FIFO_RCV_RST | FIFO_XMT_RST | FIFO_TRIGGER_1);
- bus_space_write_1(iot, ioh, com_ier, 0);
-
- *iohp = ioh;
- return (0);
+ bus_space_write_1(iot, ioh, com_lcr, LCR_8BITS);
+ bus_space_write_1(iot, ioh, com_ier, IER_ERXRDY | IER_ETXRDY);
+ bus_space_write_1(iot, ioh, com_fifo, FIFO_ENABLE | FIFO_RCV_RST | FIFO_XMT_RST | FIFO_TRIGGER_4);
+ stat = bus_space_read_1(iot, ioh, com_iir);
+ splx(s);
}
int
comcngetc(dev)
dev_t dev;
{
- return (com_common_getc(comconsiot, comconsioh));
+ int s = splhigh();
+ bus_space_tag_t iot = comconsiot;
+ bus_space_handle_t ioh = comconsioh;
+ u_char stat, c;
+
+ while (!ISSET(stat = bus_space_read_1(iot, ioh, com_lsr), LSR_RXRDY))
+ ;
+ c = bus_space_read_1(iot, ioh, com_data);
+ stat = bus_space_read_1(iot, ioh, com_iir);
+ splx(s);
+ return c;
}
/*
@@ -1799,7 +1654,33 @@ comcnputc(dev, c)
dev_t dev;
int c;
{
- com_common_putc(comconsiot, comconsioh, c);
+ int s = splhigh();
+ bus_space_tag_t iot = comconsiot;
+ bus_space_handle_t ioh = comconsioh;
+ u_char stat;
+ register int timo;
+
+#ifdef KGDB
+ if (dev != kgdb_dev)
+#endif
+ if (comconsinit == 0) {
+ cominit(iot, ioh, comdefaultrate);
+ comconsinit = 1;
+ }
+ /* wait for any pending transmission to finish */
+ timo = 50000;
+ while (!ISSET(stat = bus_space_read_1(iot, ioh, com_lsr), LSR_TXRDY) && --timo)
+ ;
+ bus_space_write_1(iot, ioh, com_data, c);
+ /* wait for this transmission to complete */
+ timo = 1500000;
+ while (!ISSET(stat = bus_space_read_1(iot, ioh, com_lsr), LSR_TXRDY) && --timo)
+ ;
+#if 0 /* I don't think sooooo (pefo) */
+ /* clear any interrupts generated by this transmission */
+ stat = bus_space_read_1(iot, ioh, com_iir);
+#endif
+ splx(s);
}
void
@@ -1809,77 +1690,3 @@ comcnpollc(dev, on)
{
}
-
-#ifdef KGDB
-int
-com_kgdb_attach(iot, iobase, rate, frequency, cflag)
- bus_space_tag_t iot;
- int iobase;
- int rate, frequency;
- tcflag_t cflag;
-{
- int res;
-
- if (iot == comconsiot && iobase == comconsaddr)
- return (EBUSY); /* cannot share with console */
-
- res = cominit(iot, iobase, rate, frequency, cflag, &com_kgdb_ioh);
- if (res)
- return (res);
-
- kgdb_attach(com_kgdb_getc, com_kgdb_putc, NULL);
- kgdb_dev = 123; /* unneeded, only to satisfy some tests */
-
- com_kgdb_iot = iot;
- com_kgdb_addr = iobase;
-
- return (0);
-}
-
-/* ARGSUSED */
-int
-com_kgdb_getc(arg)
- void *arg;
-{
-
- return (com_common_getc(com_kgdb_iot, com_kgdb_ioh));
-}
-
-/* ARGSUSED */
-void
-com_kgdb_putc(arg, c)
- void *arg;
- int c;
-{
-
- return (com_common_putc(com_kgdb_iot, com_kgdb_ioh, c));
-}
-#endif /* KGDB */
-
-/*
- * Helper function to identify the com ports used by
- * console or KGDB (and not yet autoconf attached)
- */
-int
-com_is_console(iot, iobase, ioh)
- bus_space_tag_t iot;
- int iobase;
- bus_space_handle_t *ioh;
-{
- bus_space_handle_t help;
-
- if (!comconsattached &&
- iot == comconsiot && iobase == comconsaddr)
- help = comconsioh;
-#ifdef KGDB
- else if (!com_kgdb_attached &&
- iot == com_kgdb_iot && iobase == com_kgdb_addr)
- help = com_kgdb_ioh;
-#endif
- else
- return (0);
-
- if (ioh)
- *ioh = help;
- return (1);
-}