summaryrefslogtreecommitdiff
path: root/sys/dev/ic/com.c
diff options
context:
space:
mode:
authorNiklas Hallqvist <niklas@cvs.openbsd.org>1999-07-26 12:31:45 +0000
committerNiklas Hallqvist <niklas@cvs.openbsd.org>1999-07-26 12:31:45 +0000
commit5bb5cc058d123fb26a0d836a05f8ea92c6a381a3 (patch)
tree0fcd76d4e40685abd77ab014a905861d7d39f261 /sys/dev/ic/com.c
parent5fc5357816e696990c15bc4b5fe0042d5d46cfb1 (diff)
Remove obsolete detach code that has been dead for very long
Diffstat (limited to 'sys/dev/ic/com.c')
-rw-r--r--sys/dev/ic/com.c458
1 files changed, 285 insertions, 173 deletions
diff --git a/sys/dev/ic/com.c b/sys/dev/ic/com.c
index 7e492df0a98..c8e1857a235 100644
--- a/sys/dev/ic/com.c
+++ b/sys/dev/ic/com.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: com.c,v 1.44 1999/06/25 17:59:23 rees Exp $ */
+/* $OpenBSD: com.c,v 1.45 1999/07/26 12:31:43 niklas Exp $ */
/* $NetBSD: com.c,v 1.82.4.1 1996/06/02 09:08:00 mrg Exp $ */
/*-
@@ -87,7 +87,6 @@ static u_char tiocm_xxx2mcr __P((int));
*/
int comprobe __P((struct device *, void *, void *));
void comattach __P((struct device *, struct device *, void *));
-void comstart_pending __P((void *));
void compwroff __P((struct com_softc *));
void com_raisedtr __P((void *));
@@ -97,6 +96,12 @@ 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
@@ -119,6 +124,7 @@ 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;
@@ -128,11 +134,16 @@ int comsopen = 0;
int comevents = 0;
#ifdef KGDB
-#include <machine/remote-sl.h>
-extern int kgdb_dev;
-extern int kgdb_rate;
-extern int kgdb_debug_init;
-#endif
+#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 */
#define DEVUNIT(x) (minor(x) & 0x7f)
#define DEVCUA(x) (minor(x) & 0x80)
@@ -142,37 +153,24 @@ extern int kgdb_debug_init;
#define CLR(t, f) (t) &= ~(f)
#define ISSET(t, f) ((t) & (f))
-/*
- * must be called at spltty() or higher.
- */
-void
-com_absent_notify(sc)
- struct com_softc *sc;
-{
- struct tty *tp = sc->sc_tty;
-
- if (tp) {
- CLR(tp->t_state, TS_CARR_ON|TS_BUSY);
- ttyflush(tp, FREAD|FWRITE);
- }
-}
-
int
-comspeed(speed)
- long speed;
+comspeed(speed, frequency)
+ long speed, frequency;
{
#define divrnd(n, q) (((n)*2/(q)+1)/2) /* divide and round off */
int x, err;
+#if 0
if (speed == 0)
return 0;
- if (speed < 0)
+#endif
+ if (speed <= 0)
return -1;
- x = divrnd((COM_FREQ / 16), speed);
+ x = divrnd((frequency / 16), speed);
if (x <= 0)
return -1;
- err = divrnd((COM_FREQ / 16) * 1000, speed * x) - 1000;
+ err = divrnd((frequency / 16) * 1000, speed * x) - 1000;
if (err < 0)
err = -err;
if (err > COM_TOLERANCE)
@@ -358,14 +356,9 @@ comattach(parent, self, aux)
* XXX for commulti attach, with a helper function that contains
* XXX most of the interesting stuff.
*/
- if (ISSET(sc->sc_hwflags, COM_HW_REATTACH)) {
- int s;
- s = spltty();
- com_absent_notify(sc);
- splx(s);
- } else
- sc->sc_hwflags = 0;
+ 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;
@@ -570,29 +563,54 @@ comattach(parent, self, aux)
}
#ifdef KGDB
- 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);
- }
+ /*
+ * 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);
}
#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)
@@ -611,9 +629,17 @@ comopen(dev, flag, mode, p)
if (unit >= com_cd.cd_ndevs)
return ENXIO;
sc = com_cd.cd_devs[unit];
- if (!sc || ISSET(sc->sc_hwflags, COM_HW_ABSENT|COM_HW_ABSENT_PENDING))
+ 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();
@@ -831,16 +857,14 @@ comclose(dev, flag, mode, p)
(*linesw[tp->t_line].l_close)(tp, flag);
s = spltty();
- if (!ISSET(sc->sc_hwflags, COM_HW_ABSENT|COM_HW_ABSENT_PENDING)) {
- if (ISSET(tp->t_state, TS_WOPEN)) {
- /* tty device is waiting for carrier; drop dtr then re-raise */
- CLR(sc->sc_mcr, MCR_DTR | MCR_RTS);
- bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
- timeout(com_raisedtr, sc, hz * 2);
- } else {
- /* no one else waiting; turn off the uart */
- compwroff(sc);
- }
+ if (ISSET(tp->t_state, TS_WOPEN)) {
+ /* tty device is waiting for carrier; drop dtr then re-raise */
+ CLR(sc->sc_mcr, MCR_DTR | MCR_RTS);
+ bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
+ timeout(com_raisedtr, sc, hz * 2);
+ } else {
+ /* no one else waiting; turn off the uart */
+ compwroff(sc);
}
CLR(tp->t_state, TS_BUSY | TS_FLUSH);
if (--comsopen == 0)
@@ -848,13 +872,6 @@ comclose(dev, flag, mode, p)
sc->sc_cua = 0;
splx(s);
ttyclose(tp);
-#ifdef COM_DEBUG
- /* mark it ready for more use if reattached earlier */
- if (ISSET(sc->sc_hwflags, COM_HW_ABSENT_PENDING)) {
- printf("comclose pending cleared\n");
- }
-#endif
- CLR(sc->sc_hwflags, COM_HW_ABSENT_PENDING);
#ifdef notyet /* XXXX */
if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) {
@@ -926,13 +943,6 @@ comread(dev, uio, flag)
struct com_softc *sc = com_cd.cd_devs[DEVUNIT(dev)];
struct tty *tp = sc->sc_tty;
- if (ISSET(sc->sc_hwflags, COM_HW_ABSENT|COM_HW_ABSENT_PENDING)) {
- int s = spltty();
- com_absent_notify(sc);
- splx(s);
- return EIO;
- }
-
return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
}
@@ -945,13 +955,6 @@ comwrite(dev, uio, flag)
struct com_softc *sc = com_cd.cd_devs[DEVUNIT(dev)];
struct tty *tp = sc->sc_tty;
- if (ISSET(sc->sc_hwflags, COM_HW_ABSENT|COM_HW_ABSENT_PENDING)) {
- int s = spltty();
- com_absent_notify(sc);
- splx(s);
- return EIO;
- }
-
return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
}
@@ -993,13 +996,6 @@ comioctl(dev, cmd, data, flag, p)
bus_space_handle_t ioh = sc->sc_ioh;
int error;
- if (ISSET(sc->sc_hwflags, COM_HW_ABSENT|COM_HW_ABSENT_PENDING)) {
- int s = spltty();
- com_absent_notify(sc);
- splx(s);
- return EIO;
- }
-
error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
if (error >= 0)
return error;
@@ -1105,6 +1101,37 @@ 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;
@@ -1113,18 +1140,11 @@ 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);
+ int ospeed = comspeed(t->c_ospeed, sc->sc_frequency);
u_char lcr;
tcflag_t oldcflag;
int s;
- if (ISSET(sc->sc_hwflags, COM_HW_ABSENT|COM_HW_ABSENT_PENDING)) {
- int s = spltty();
- com_absent_notify(sc);
- splx(s);
- return EIO;
- }
-
/* check requested parameters */
if (ospeed < 0 || (t->c_ispeed && t->c_ispeed != t->c_ospeed))
return EINVAL;
@@ -1260,18 +1280,6 @@ comparam(tp, t)
}
void
-comstart_pending(arg)
- void *arg;
-{
- struct com_softc *sc = arg;
- int s;
-
- s = spltty();
- com_absent_notify(sc);
- splx(s);
-}
-
-void
comstart(tp)
struct tty *tp;
{
@@ -1281,16 +1289,6 @@ comstart(tp)
int s;
s = spltty();
- if (ISSET(sc->sc_hwflags, COM_HW_ABSENT|COM_HW_ABSENT_PENDING)) {
- /*
- * not quite good enough: if caller is ttywait() it will
- * go to sleep immediately, so hang out a bit and then
- * prod caller again.
- */
- com_absent_notify(sc);
- timeout(comstart_pending, sc, 1);
- goto out;
- }
if (ISSET(tp->t_state, TS_BUSY))
goto out;
if (ISSET(tp->t_state, TS_TIMEOUT | TS_TTSTOP) || sc->sc_halt > 0)
@@ -1476,7 +1474,7 @@ comintr(arg)
} iter[32];
#endif
- if (ISSET(sc->sc_hwflags, COM_HW_ABSENT) || !sc->sc_tty)
+ if (!sc->sc_tty)
return (0); /* can't do squat. */
#ifdef COM_DEBUG
@@ -1517,6 +1515,13 @@ 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++;
@@ -1533,7 +1538,7 @@ comintr(arg)
sc->sc_mcr);
}
}
-#ifdef DDB
+#if defined(DDB) || defined(KGDB)
next:
#endif
#ifdef COM_DEBUG
@@ -1677,54 +1682,113 @@ 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 (bus_space_map(comconsiot, CONADDR, COM_NPORTS, 0, &comconsioh))
+ if (cominit(comconsiot, CONADDR, comdefaultrate, COM_FREQ,
+ comconscflag, &comconsioh))
panic("comcninit: mapping failed");
- cominit(comconsiot, comconsioh, comdefaultrate);
comconsaddr = CONADDR;
comconsinit = 0;
}
-void
-cominit(iot, ioh, rate)
+/*
+ * Initialize UART to known state.
+ */
+int
+cominit(iot, iobase, rate, frequency, cflag, iohp)
bus_space_tag_t iot;
- bus_space_handle_t ioh;
- int rate;
+ int iobase;
+ int rate, frequency;
+ tcflag_t cflag;
+ bus_space_handle_t *iohp;
{
- int s = splhigh();
- u_char stat;
+ bus_space_handle_t ioh;
+ 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(comdefaultrate);
+ rate = comspeed(rate, frequency);
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, 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);
+ 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);
}
int
comcngetc(dev)
dev_t dev;
{
- 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;
+ return (com_common_getc(comconsiot, comconsioh));
}
/*
@@ -1735,33 +1799,7 @@ comcnputc(dev, c)
dev_t dev;
int 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);
+ com_common_putc(comconsiot, comconsioh, c);
}
void
@@ -1771,3 +1809,77 @@ 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);
+}