The motivation for this patch comes from an issue on sparc64 but it applies to code that's used by any of the architectures that includes syscons so it would be good if this got some reasonable testing before it got committed. The issue crept in with the recent-ish devfs megapatches, and is caused by the same thing that caused some problems with other console drivers. You can't call make_dev() too soon in the boot process because it needs mutexes to be functional. So prospective console devices may need to procrastinate on the call to make_dev() on some architectures, depending on when it would be best for that architecture to call cninit() and when enough of the baseline hardware is set up that mutexes can become functional. This patch arranges for syscons(4) to wait longer than its console initialization routines before it calls make_dev(). If I don't get any feedback about this patch I'll commit it some time this weekend. I would appreciate it if other folks could give it a try before then. I've tested it on sparc64 and briefly on i386. I don't have access to anything else that can use syscons as its console driver, any other architecture machines I can get to use serial port consoles. This patch is for src/sys/dev/syscons/syscons.c Thanks... Index: syscons.c =================================================================== RCS file: /home/ncvs/src/sys/dev/syscons/syscons.c,v retrieving revision 1.417 diff -u -r1.417 syscons.c --- syscons.c 18 Mar 2004 21:07:54 -0000 1.417 +++ syscons.c 31 Mar 2004 08:02:48 -0000 _at__at_ -99,6 +99,8 _at__at_ static struct tty *sc_console_tty; static struct consdev *sc_consptr; static void *kernel_console_ts; +static scr_stat main_console; +static dev_t main_devs[MAXCONS]; static char init_done = COLD; static char shutdown_in_progress = FALSE; _at__at_ -151,6 +153,7 _at__at_ static int scparam(struct tty *tp, struct termios *t); static void scstart(struct tty *tp); static void scinit(int unit, int flags); +static scr_stat *sc_get_stat(dev_t devptr); #if !__alpha__ static void scterm(int unit, int flags); #endif _at__at_ -331,7 +334,7 _at__at_ sc = sc_get_softc(unit, flags & SC_KERNEL_CONSOLE); sc->config = flags; - scp = SC_STAT(sc->dev[0]); + scp = sc_get_stat(sc->dev[0]); if (sc_console == NULL) /* sc_console_unit < 0 */ sc_console = scp; _at__at_ -388,6 +391,9 _at__at_ dev = make_dev(&sc_cdevsw, vc + unit * MAXCONS, UID_ROOT, GID_WHEEL, 0600, "ttyv%r", vc + unit * MAXCONS); sc->dev[vc] = dev; + sc->dev[vc]->si_tty = ttymalloc(sc->dev[vc]->si_tty); + if (vc == 0 && sc->dev == main_devs) + SC_STAT(sc->dev[0]) = &main_console; } /* * The first vty already has struct tty and scr_stat initialized _at__at_ -497,7 +503,7 _at__at_ error = (*linesw[tp->t_line].l_open)(dev, tp); - scp = SC_STAT(dev); + scp = sc_get_stat(dev); if (scp == NULL) { scp = SC_STAT(dev) = alloc_scp(sc, SC_VTY(dev)); if (ISGRAPHSC(scp)) _at__at_ -519,7 +525,7 _at__at_ int s; if (SC_VTY(dev) != SC_CONSOLECTL) { - scp = SC_STAT(tp->t_dev); + scp = sc_get_stat(tp->t_dev); /* were we in the middle of the VT switching process? */ DPRINTF(5, ("sc%d: scclose(), ", scp->sc->unit)); s = spltty(); _at__at_ -682,7 +688,7 _at__at_ return error; #endif - scp = SC_STAT(tp->t_dev); + scp = sc_get_stat(tp->t_dev); /* assert(scp != NULL) */ /* scp is sc_console, if SC_VTY(dev) == SC_CONSOLECTL. */ sc = scp->sc; _at__at_ -1015,7 +1021,7 _at__at_ splx(s); if (error) return error; - scp = SC_STAT(SC_DEV(sc, i)); + scp = sc_get_stat(SC_DEV(sc, i)); if (scp == scp->sc->cur_scp) return 0; while ((error=tsleep(&scp->smode, PZERO|PCATCH, _at__at_ -1353,7 +1359,7 _at__at_ struct clist *rbp; int s, len; u_char buf[PCBURST]; - scr_stat *scp = SC_STAT(tp->t_dev); + scr_stat *scp = sc_get_stat(tp->t_dev); if (scp->status & SLKED || (scp == scp->sc->cur_scp && scp->sc->blink_in_progress)) _at__at_ -1417,7 +1423,7 _at__at_ sc_get_cons_priority(&unit, &flags); scinit(unit, flags | SC_KERNEL_CONSOLE); sc_console_unit = unit; - sc_console = SC_STAT(sc_get_softc(unit, SC_KERNEL_CONSOLE)->dev[0]); + sc_console = sc_get_stat(sc_get_softc(unit, SC_KERNEL_CONSOLE)->dev[0]); sc_consptr = cp; #endif /* !__alpha__ */ _at__at_ -1475,7 +1481,7 _at__at_ scinit(unit, flags | SC_KERNEL_CONSOLE); sc_console_unit = unit; sc_consptr = &consdev; - sc_console = SC_STAT(sc_get_softc(unit, SC_KERNEL_CONSOLE)->dev[0]); + sc_console = sc_get_stat(sc_get_softc(unit, SC_KERNEL_CONSOLE)->dev[0]); sprintf(consdev.cn_name, "ttyv%r", 0); cnadd(&consdev); } _at__at_ -2312,7 +2318,7 _at__at_ ++sc->switch_in_progress; sc->delayed_next_scr = 0; sc->old_scp = cur_scp; - sc->new_scp = SC_STAT(SC_DEV(sc, next_scr)); + sc->new_scp = sc_get_stat(SC_DEV(sc, next_scr)); if (sc->new_scp == sc->old_scp) { sc->switch_in_progress = 0; /* _at__at_ -2624,7 +2630,7 _at__at_ for (i = sc->first_vty; i < sc->first_vty + sc->vtys; ++i) { if ((dev = SC_DEV(sc, i)) == NODEV) continue; - if ((scp = SC_STAT(dev)) == NULL) + if ((scp = sc_get_stat(dev)) == NULL) continue; scp->dflt_curs_attr = sc->curs_attr; change_cursor_shape(scp, CONS_RESET_CURSOR, -1, -1); _at__at_ -2642,9 +2648,6 _at__at_ * static buffers for the console. This is less than ideal, * but is necessry evil for the time being. XXX */ - static scr_stat main_console; - static dev_t main_devs[MAXCONS]; - static struct tty main_tty; #ifdef PC98 static u_short sc_buffer[ROW*COL*2];/* XXX */ #else _at__at_ -2727,11 +2730,12 _at__at_ sc->first_vty = unit*MAXCONS; sc->vtys = MAXCONS; /* XXX: should be configurable */ if (flags & SC_KERNEL_CONSOLE) { + /* + * Set up devs structure but don't use it yet, calling make_dev() + * might panic kernel. Wait for sc_attach_unit() to actually + * create the devices. + */ sc->dev = main_devs; - sc->dev[0] = make_dev(&sc_cdevsw, unit * MAXCONS, - UID_ROOT, GID_WHEEL, 0600, "ttyv%r", unit * MAXCONS); - sc->dev[0]->si_tty = &main_tty; - ttyregister(&main_tty); scp = &main_console; init_scp(sc, sc->first_vty, scp); sc_vtb_init(&scp->vtb, VTB_MEMORY, scp->xsize, scp->ysize, _at__at_ -2748,8 +2752,8 _at__at_ UID_ROOT, GID_WHEEL, 0600, "ttyv%r", unit * MAXCONS); sc->dev[0]->si_tty = ttymalloc(sc->dev[0]->si_tty); scp = alloc_scp(sc, sc->first_vty); + SC_STAT(sc->dev[0]) = scp; } - SC_STAT(sc->dev[0]) = scp; sc->cur_scp = scp; #ifndef __sparc64__ _at__at_ -2879,7 +2883,7 _at__at_ vid_release(sc->adp, &sc->adapter); /* stop the terminal emulator, if any */ - scp = SC_STAT(sc->dev[0]); + scp = sc_get_stat(sc->dev[0]); if (scp->tsw) (*scp->tsw->te_term)(scp, &scp->ts); if (scp->ts != NULL) _at__at_ -3412,7 +3416,7 _at__at_ { scr_stat *scp; - scp = SC_STAT(dev); + scp = sc_get_stat(dev); if (scp != scp->sc->cur_scp) return -1; return (*vidsw[scp->sc->adapter]->mmap)(scp->sc->adp, offset, paddr, nprot); _at__at_ -3620,4 +3624,12 _at__at_ scp->sc->blink_in_progress--; timeout(blink_screen, scp, hz / 10); } +} + +static scr_stat * +sc_get_stat(dev_t devptr) +{ + if (devptr == NULL) + return (&main_console); + return (SC_STAT(devptr)); } -- Ken Smith - From there to here, from here to | kensmith_at_cse.buffalo.edu there, funny things are everywhere. | - Theodore Geisel |Received on Wed Mar 31 2004 - 07:59:12 UTC
This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:37:49 UTC