Module Name: src Committed By: dyoung Date: Thu Nov 12 20:37:09 UTC 2009
Modified Files: src/sys/dev/ic: com.c comvar.h Log Message: Move the code in com_activate() to com_detach(), where it always belonged. Remove com_activate(). Consolidate information about the console on com(4) in a new struct comcons_info. Support detachment & re-attachment of a system console on com(4). Re-attachment is somehow incomplete. Ideally, if some other device could take over as console, it would, but we're not quite there, yet. To generate a diff of this commit: cvs rdiff -u -r1.288 -r1.289 src/sys/dev/ic/com.c cvs rdiff -u -r1.66 -r1.67 src/sys/dev/ic/comvar.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/ic/com.c diff -u src/sys/dev/ic/com.c:1.288 src/sys/dev/ic/com.c:1.289 --- src/sys/dev/ic/com.c:1.288 Wed May 6 07:27:42 2009 +++ src/sys/dev/ic/com.c Thu Nov 12 20:37:09 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: com.c,v 1.288 2009/05/06 07:27:42 cegger Exp $ */ +/* $NetBSD: com.c,v 1.289 2009/11/12 20:37:09 dyoung Exp $ */ /*- * Copyright (c) 1998, 1999, 2004, 2008 The NetBSD Foundation, Inc. @@ -66,7 +66,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: com.c,v 1.288 2009/05/06 07:27:42 cegger Exp $"); +__KERNEL_RCSID(0, "$NetBSD: com.c,v 1.289 2009/11/12 20:37:09 dyoung Exp $"); #include "opt_com.h" #include "opt_ddb.h" @@ -173,10 +173,17 @@ void com_iflush(struct com_softc *); int com_common_getc(dev_t, struct com_regs *); -void com_common_putc(dev_t, struct com_regs *, int); +static void com_common_putc(dev_t, struct com_regs *, int); int cominit(struct com_regs *, int, int, int, tcflag_t); +#if 0 +static int comcngetc_detached(dev_t); +static void comcnputc_detached(dev_t, int); +#endif + +static int comcnreattach(void); + int comcngetc(dev_t); void comcnputc(dev_t, int); void comcnpollc(dev_t, int); @@ -200,6 +207,24 @@ dev_type_tty(comtty); dev_type_poll(compoll); +static struct comcons_info comcons_info; + +#if 0 +static struct consdev comcons_detached = { + NULL, NULL, comcngetc_detached, comcnputc_detached, comcnpollc, + NULL, NULL, NULL, NODEV, CN_NULL +}; +#endif + +/* + * Following are all routines needed for COM to act as console + */ +static struct consdev comcons = { + NULL, NULL, comcngetc, comcnputc, comcnpollc, NULL, NULL, NULL, + NODEV, CN_NORMAL +}; + + const struct cdevsw com_cdevsw = { comopen, comclose, comread, comwrite, comioctl, comstop, comtty, compoll, nommap, ttykqfilter, D_TTY @@ -215,10 +240,7 @@ u_int com_rbuf_hiwat = (COM_RING_SIZE * 1) / 4; u_int com_rbuf_lowat = (COM_RING_SIZE * 3) / 4; -static struct com_regs comconsregs; static int comconsattached; -static int comconsrate; -static tcflag_t comconscflag; static struct cnm_state com_cnm_state; #ifdef KGDB @@ -383,10 +405,15 @@ CSR_WRITE_1(regsp, COM_REG_IER, sc->sc_ier); - if (regsp->cr_iot == comconsregs.cr_iot && - regsp->cr_iobase == comconsregs.cr_iobase) { + if (regsp->cr_iot == comcons_info.regs.cr_iot && + regsp->cr_iobase == comcons_info.regs.cr_iobase) { comconsattached = 1; + if (cn_tab == NULL && comcnreattach() != 0) { + printf("can't re-init serial console @%zx\n", + (size_t)comcons_info.regs.cr_iobase); + } + /* Make sure the console is always "hardwired". */ delay(10000); /* wait for output to finish */ SET(sc->sc_hwflags, COM_HW_CONSOLE); @@ -605,15 +632,42 @@ com_enable_debugport(sc); } +#if 0 +static int +comcngetc_detached(dev_t dev) +{ + return 0; +} + +static void +comcnputc_detached(dev_t dev, int c) +{ +} +#endif + int com_detach(device_t self, int flags) { struct com_softc *sc = device_private(self); int maj, mn; - if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) + if (ISSET(sc->sc_hwflags, COM_HW_KGDB)) + return EBUSY; + + if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE) && + (flags & DETACH_SHUTDOWN) != 0) return EBUSY; + if (sc->disable != NULL && sc->enabled != 0) { + (*sc->disable)(sc); + sc->enabled = 0; + } + + if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) { + comconsattached = 0; + cn_tab = NULL; + } + /* locate the major number */ maj = cdevsw_lookup_major(&com_cdevsw); @@ -655,33 +709,6 @@ return (0); } -int -com_activate(device_t self, enum devact act) -{ - struct com_softc *sc = device_private(self); - int rv = 0; - - 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; - } - - return (rv); -} - void com_shutdown(struct com_softc *sc) { @@ -811,8 +838,8 @@ * sticky bits from TIOCSFLAGS. */ if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) { - t.c_ospeed = comconsrate; - t.c_cflag = comconscflag; + t.c_ospeed = comcons_info.rate; + t.c_cflag = comcons_info.cflag; } else { t.c_ospeed = TTYDEF_SPEED; t.c_cflag = TTYDEF_CFLAG; @@ -2110,7 +2137,7 @@ return (c); } -void +static void com_common_putc(dev_t dev, struct com_regs *regsp, int c) { int s = splserial(); @@ -2210,24 +2237,15 @@ return (0); } -/* - * Following are all routines needed for COM to act as console - */ -struct consdev comcons = { - NULL, NULL, comcngetc, comcnputc, comcnpollc, NULL, NULL, NULL, - NODEV, CN_NORMAL -}; - - int comcnattach1(struct com_regs *regsp, int rate, int frequency, int type, tcflag_t cflag) { int res; - comconsregs = *regsp; + comcons_info.regs = *regsp; - res = cominit(&comconsregs, rate, frequency, type, cflag); + res = cominit(&comcons_info.regs, rate, frequency, type, cflag); if (res) return (res); @@ -2235,8 +2253,10 @@ cn_init_magic(&com_cnm_state); cn_set_magic("\047\001"); /* default magic is BREAK */ - comconsrate = rate; - comconscflag = cflag; + comcons_info.frequency = frequency; + comcons_info.type = type; + comcons_info.rate = rate; + comcons_info.cflag = cflag; return (0); } @@ -2258,11 +2278,18 @@ return comcnattach1(®s, rate, frequency, type, cflag); } +static int +comcnreattach(void) +{ + return comcnattach1(&comcons_info.regs, comcons_info.rate, + comcons_info.frequency, comcons_info.type, comcons_info.cflag); +} + int comcngetc(dev_t dev) { - return (com_common_getc(dev, &comconsregs)); + return (com_common_getc(dev, &comcons_info.regs)); } /* @@ -2272,7 +2299,7 @@ comcnputc(dev_t dev, int c) { - com_common_putc(dev, &comconsregs, c); + com_common_putc(dev, &comcons_info.regs, c); } void @@ -2288,13 +2315,13 @@ { int res; - if (regsp->cr_iot == comconsregs.cr_iot && - regsp->cr_iobase == comconsregs.cr_iobase) { + if (regsp->cr_iot == comcons_info.regs.cr_iot && + regsp->cr_iobase == comcons_info.regs.cr_iobase) { #if !defined(DDB) return (EBUSY); /* cannot share with console */ #else comkgdbregs = *regsp; - comkgdbregs.cr_ioh = comconsregs.cr_ioh; + comkgdbregs.cr_ioh = comcons_info.regs.cr_ioh; #endif } else { comkgdbregs = *regsp; @@ -2357,8 +2384,9 @@ bus_space_handle_t help; if (!comconsattached && - iot == comconsregs.cr_iot && iobase == comconsregs.cr_iobase) - help = comconsregs.cr_ioh; + iot == comcons_info.regs.cr_iot && + iobase == comcons_info.regs.cr_iobase) + help = comcons_info.regs.cr_ioh; #ifdef KGDB else if (!com_kgdb_attached && iot == comkgdbregs.cr_iot && iobase == comkgdbregs.cr_iobase) @@ -2393,6 +2421,11 @@ { struct com_softc *sc = device_private(self); +#if 0 + if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE) && cn_tab == &comcons) + cn_tab = &comcons_suspend; +#endif + CSR_WRITE_1(&sc->sc_regs, COM_REG_IER, 0); (void)CSR_READ_1(&sc->sc_regs, COM_REG_IIR); Index: src/sys/dev/ic/comvar.h diff -u src/sys/dev/ic/comvar.h:1.66 src/sys/dev/ic/comvar.h:1.67 --- src/sys/dev/ic/comvar.h:1.66 Wed May 27 23:01:07 2009 +++ src/sys/dev/ic/comvar.h Thu Nov 12 20:37:09 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: comvar.h,v 1.66 2009/05/27 23:01:07 rjs Exp $ */ +/* $NetBSD: comvar.h,v 1.67 2009/11/12 20:37:09 dyoung Exp $ */ /* * Copyright (c) 1996 Christopher G. Demetriou. All rights reserved. @@ -144,6 +144,14 @@ #endif +struct comcons_info { + struct com_regs regs; + int rate; + int frequency; + int type; + tcflag_t cflag; +}; + struct com_softc { device_t sc_dev; void *sc_si;