summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/i386/isa/pccom.c80
-rw-r--r--sys/arch/i386/isa/pccomvar.h9
-rw-r--r--sys/dev/ic/com.c94
-rw-r--r--sys/dev/ic/comvar.h9
-rw-r--r--sys/dev/pcmcia/com_pcmcia.c54
5 files changed, 225 insertions, 21 deletions
diff --git a/sys/arch/i386/isa/pccom.c b/sys/arch/i386/isa/pccom.c
index 4d54d805279..03c6645059e 100644
--- a/sys/arch/i386/isa/pccom.c
+++ b/sys/arch/i386/isa/pccom.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pccom.c,v 1.31 1999/07/26 12:31:44 niklas Exp $ */
+/* $OpenBSD: pccom.c,v 1.32 1999/08/08 01:34:15 niklas Exp $ */
/* $NetBSD: com.c,v 1.82.4.1 1996/06/02 09:08:00 mrg Exp $ */
/*
@@ -86,6 +86,7 @@
#include <sys/syslog.h>
#include <sys/types.h>
#include <sys/device.h>
+#include <sys/vnode.h>
#include <machine/bus.h>
#include <machine/intr.h>
@@ -668,6 +669,83 @@ comattach(parent, self, aux)
/* XXX maybe move up some? */
if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE))
printf("%s: console\n", sc->sc_dev.dv_xname);
+
+ /*
+ * If there are no enable/disable functions, assume the device
+ * is always enabled.
+ */
+#ifdef notyet
+ if (!sc->enable)
+#endif
+ sc->enabled = 1;
+}
+
+int
+com_detach(self, flags)
+ struct device *self;
+ int flags;
+{
+ struct com_softc *sc = (struct com_softc *)self;
+ int maj, mn;
+
+ /* locate the major number */
+ for (maj = 0; maj < nchrdev; maj++)
+ if (cdevsw[maj].d_open == comopen)
+ break;
+
+ /* Nuke the vnodes for any open instances. */
+ mn = self->dv_unit;
+ vdevgone(maj, mn, mn, VCHR);
+
+ /* XXX a symbolic constant for the cua bit would be nicer. */
+ mn |= 0x80;
+ vdevgone(maj, mn, mn, VCHR);
+
+ /* Detach and free the tty. */
+ if (sc->sc_tty) {
+ tty_detach(sc->sc_tty);
+ ttyfree(sc->sc_tty);
+ }
+
+ untimeout(com_raisedtr, sc);
+ untimeout(comdiag, sc);
+
+ return (0);
+}
+
+int
+com_activate(self, act)
+ struct device *self;
+ enum devact act;
+{
+ struct com_softc *sc = (struct com_softc *)self;
+ int s, rv = 0;
+
+ /* XXX splserial, when we get that. */
+ s = spltty();
+ switch (act) {
+ case DVACT_ACTIVATE:
+ rv = EOPNOTSUPP;
+ break;
+
+ case DVACT_DEACTIVATE:
+#ifdef notyet
+ if (sc->sc_hwflags & (COM_HW_CONSOLE|COM_HW_KGDB)) {
+#else
+ if (sc->sc_hwflags & (COM_HW_CONSOLE)) {
+#endif
+ rv = EBUSY;
+ break;
+ }
+
+ if (sc->disable != NULL && sc->enabled != 0) {
+ (*sc->disable)(sc);
+ sc->enabled = 0;
+ }
+ break;
+ }
+ splx(s);
+ return (rv);
}
int
diff --git a/sys/arch/i386/isa/pccomvar.h b/sys/arch/i386/isa/pccomvar.h
index 5aa03ef8cb5..d3734c8499e 100644
--- a/sys/arch/i386/isa/pccomvar.h
+++ b/sys/arch/i386/isa/pccomvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pccomvar.h,v 1.7 1999/07/26 12:31:44 niklas Exp $ */
+/* $OpenBSD: pccomvar.h,v 1.8 1999/08/08 01:34:15 niklas Exp $ */
/* $NetBSD: comvar.h,v 1.5 1996/05/05 19:50:47 christos Exp $ */
/*
@@ -99,11 +99,18 @@ struct com_softc {
u_char sc_rxbuf[RBUFSIZE];
u_char *sc_tba;
int sc_tbc;
+
+ /* power management hooks */
+ int (*enable) __P((struct com_softc *));
+ void (*disable) __P((struct com_softc *));
+ int enabled;
};
int comprobe1 __P((bus_space_tag_t, bus_space_handle_t));
void cominit __P((bus_space_tag_t, bus_space_handle_t, int));
int comintr __P((void *));
+int com_detach __P((struct device *, int));
+int com_activate __P((struct device *, enum devact));
#ifdef COM_HAYESP
int comprobeHAYESP __P((bus_space_handle_t hayespioh, struct com_softc *sc));
diff --git a/sys/dev/ic/com.c b/sys/dev/ic/com.c
index 19c1ea929fd..8d4ba06e42c 100644
--- a/sys/dev/ic/com.c
+++ b/sys/dev/ic/com.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: com.c,v 1.47 1999/07/26 15:27:22 niklas Exp $ */
+/* $OpenBSD: com.c,v 1.48 1999/08/08 01:34:14 niklas Exp $ */
/* $NetBSD: com.c,v 1.82.4.1 1996/06/02 09:08:00 mrg Exp $ */
/*-
@@ -56,6 +56,7 @@
#include <sys/syslog.h>
#include <sys/types.h>
#include <sys/device.h>
+#include <sys/vnode.h>
#ifdef DDB
#include <ddb/db_var.h>
#endif
@@ -597,9 +598,100 @@ comattach(parent, self, aux)
/* XXX maybe move up some? */
if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE))
printf("%s: console\n", sc->sc_dev.dv_xname);
+
+ /*
+ * If there are no enable/disable functions, assume the device
+ * is always enabled.
+ */
+ if (!sc->enable)
+ sc->enabled = 1;
+}
+
+int
+com_detach(self, flags)
+ struct device *self;
+ int flags;
+{
+ struct com_softc *sc = (struct com_softc *)self;
+ int maj, mn;
+
+ /* locate the major number */
+ for (maj = 0; maj < nchrdev; maj++)
+ if (cdevsw[maj].d_open == comopen)
+ break;
+
+ /* Nuke the vnodes for any open instances. */
+ mn = self->dv_unit;
+ vdevgone(maj, mn, mn, VCHR);
+
+ /* XXX a symbolic constant for the cua bit would be nicer. */
+ mn |= 0x80;
+ vdevgone(maj, mn, mn, VCHR);
+
+ /* Free the receive buffer. */
+ free(sc->sc_rbuf, M_DEVBUF);
+
+ /* Detach and free the tty. */
+ if (sc->sc_tty) {
+ tty_detach(sc->sc_tty);
+ ttyfree(sc->sc_tty);
+ }
+
+ untimeout(compoll, NULL);
+ untimeout(com_raisedtr, sc);
+ untimeout(comdiag, sc);
+
+ return (0);
}
int
+com_activate(self, act)
+ struct device *self;
+ enum devact act;
+{
+ struct com_softc *sc = (struct com_softc *)self;
+ int s, rv = 0;
+
+ s = splserial();
+ switch (act) {
+ case DVACT_ACTIVATE:
+ rv = EOPNOTSUPP;
+ break;
+
+ case DVACT_DEACTIVATE:
+ if (sc->sc_hwflags & (COM_HW_CONSOLE|COM_HW_KGDB)) {
+ rv = EBUSY;
+ break;
+ }
+
+ if (sc->disable != NULL && sc->enabled != 0) {
+ (*sc->disable)(sc);
+ sc->enabled = 0;
+ }
+ break;
+ }
+ splx(s);
+ return (rv);
+}
+
+#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;
int flag, mode;
diff --git a/sys/dev/ic/comvar.h b/sys/dev/ic/comvar.h
index c16521b2958..f9afe3acc7c 100644
--- a/sys/dev/ic/comvar.h
+++ b/sys/dev/ic/comvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: comvar.h,v 1.13 1999/07/26 15:09:00 niklas Exp $ */
+/* $OpenBSD: comvar.h,v 1.14 1999/08/08 01:34:15 niklas Exp $ */
/* $NetBSD: comvar.h,v 1.5 1996/05/05 19:50:47 christos Exp $ */
/*
@@ -127,11 +127,18 @@ struct com_softc {
u_char *sc_ibuf, *sc_ibufp, *sc_ibufhigh, *sc_ibufend;
u_char sc_ibufs[2][COM_IBUFSIZE];
+
+ /* power management hooks */
+ int (*enable) __P((struct com_softc *));
+ void (*disable) __P((struct com_softc *));
+ int enabled;
};
int comprobe1 __P((bus_space_tag_t, bus_space_handle_t));
void cominit __P((bus_space_tag_t, bus_space_handle_t, int));
int comintr __P((void *));
+int com_detach __P((struct device *, int));
+int com_activate __P((struct device *, enum devact));
#ifdef COM_HAYESP
int comprobeHAYESP __P((bus_space_handle_t hayespioh, struct com_softc *sc));
diff --git a/sys/dev/pcmcia/com_pcmcia.c b/sys/dev/pcmcia/com_pcmcia.c
index 0e232bde99f..9dcf0a47891 100644
--- a/sys/dev/pcmcia/com_pcmcia.c
+++ b/sys/dev/pcmcia/com_pcmcia.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: com_pcmcia.c,v 1.15 1999/07/26 06:22:57 deraadt Exp $ */
+/* $OpenBSD: com_pcmcia.c,v 1.16 1999/08/08 01:34:15 niklas Exp $ */
/* $NetBSD: com_pcmcia.c,v 1.15 1998/08/22 17:47:58 msaitoh Exp $ */
/*-
@@ -96,21 +96,22 @@
#include <dev/isa/isavar.h>
-#include <dev/ic/comreg.h>
+#include "com.h"
#ifdef i386
+#include "pccom.h"
+#endif
+
+#include <dev/ic/comreg.h>
+#if NPCCOM > 0
#include <i386/isa/pccomvar.h>
-#else
+#endif
+#if NCOM > 0
#include <dev/ic/comvar.h>
#endif
#include <dev/ic/ns16550reg.h>
#include <dev/isa/isareg.h>
-#include "com.h"
-#ifdef i386
-#include "pccom.h"
-#endif
-
#define com_lcr com_cfcr
#define SET(t, f) (t) |= (f)
@@ -131,6 +132,7 @@ static struct com_dev *com_dev_match __P((struct pcmcia_card *));
int com_pcmcia_match __P((struct device *, void *, void *));
void com_pcmcia_attach __P((struct device *, struct device *, void *));
+int com_pcmcia_detach __P((struct device *, int));
void com_pcmcia_cleanup __P((void *));
int com_pcmcia_enable __P((struct com_softc *));
@@ -152,11 +154,13 @@ struct com_pcmcia_softc {
#if NCOM_PCMCIA
struct cfattach com_pcmcia_ca = {
- sizeof(struct com_pcmcia_softc), com_pcmcia_match, com_pcmcia_attach
+ sizeof(struct com_pcmcia_softc), com_pcmcia_match, com_pcmcia_attach,
+ com_pcmcia_detach, com_activate
};
#elif NPCCOM_PCMCIA
struct cfattach pccom_pcmcia_ca = {
- sizeof(struct com_pcmcia_softc), com_pcmcia_match, com_pcmcia_attach
+ sizeof(struct com_pcmcia_softc), com_pcmcia_match, com_pcmcia_attach,
+ com_pcmcia_detach, com_activate
};
#endif
@@ -256,8 +260,7 @@ retry:
if (!pcmcia_io_alloc(pa->pf,
autoalloc ? 0 : cfe->iospace[0].start,
- cfe->iospace[0].length, (1 << cfe->iomask),
- &psc->sc_pcioh)) {
+ cfe->iospace[0].length, COM_NPORTS, &psc->sc_pcioh)) {
goto found;
}
}
@@ -278,9 +281,7 @@ found:
if (com_pcmcia_enable1(sc))
printf(": function enable failed\n");
-#ifdef notyet
sc->enabled = 1;
-#endif
/* map in the io space */
@@ -294,14 +295,14 @@ found:
printf(" port 0x%lx/%d", psc->sc_pcioh.addr, psc->sc_pcioh.size);
sc->sc_iobase = -1;
-#ifdef notyet
- sc->sc_frequency = COM_FREQ;
-
sc->enable = com_pcmcia_enable;
sc->disable = com_pcmcia_disable;
printf(": serial device");
+#ifdef notyet
+ sc->sc_frequency = COM_FREQ;
+
com_attach_subr(sc);
#endif
/* establish the interrupt. */
@@ -319,6 +320,25 @@ found:
}
int
+com_pcmcia_detach(dev, flags)
+ struct device *dev;
+ int flags;
+{
+ struct com_pcmcia_softc *psc = (struct com_pcmcia_softc *)dev;
+ int error;
+
+ /* Release all resources. */
+ error = com_detach(dev, flags);
+ if (error)
+ return (error);
+
+ pcmcia_io_unmap(psc->sc_pf, psc->sc_io_window);
+ pcmcia_io_free(psc->sc_pf, &psc->sc_pcioh);
+
+ return (0);
+}
+
+int
com_pcmcia_enable(sc)
struct com_softc *sc;
{