diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/i386/isa/pccom.c | 80 | ||||
-rw-r--r-- | sys/arch/i386/isa/pccomvar.h | 9 | ||||
-rw-r--r-- | sys/dev/ic/com.c | 94 | ||||
-rw-r--r-- | sys/dev/ic/comvar.h | 9 | ||||
-rw-r--r-- | sys/dev/pcmcia/com_pcmcia.c | 54 |
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; { |