I've been having some trouble lately with getting my i386 systems with serial consoles to reboot after halt. I've made the following changes in an attempt to see if XON/XOFF flow control might be the problem and to provide further diagnostics and operator information. The following demonstrates what I see happening: historically# halt -q syncing disks... 6 done unmounting file systems... unmounting /kern (kernfs)...ok, unmounting /tmp (mfs:156)...ok, unmounting / (/dev/wd0a)...ok, done The operating system has halted. Please press any key to reboot. [halt sent] Cannot read from the console, calling the HLT instruction. RESET or power cycle the system to reboot. The "[halt sent]" is from conserver, after having pressed many keys. Index: sys/arch/i386/i386/machdep.c =================================================================== RCS file: /cvs/master/m-NetBSD/main/src/sys/arch/i386/i386/machdep.c,v retrieving revision 1.632 diff -u -r1.632 machdep.c --- sys/arch/i386/i386/machdep.c 29 Apr 2008 15:27:08 -0000 1.632 +++ sys/arch/i386/i386/machdep.c 30 Apr 2008 12:43:24 -0000 @@ -848,6 +848,7 @@ void cpu_reboot(int howto, char *bootstr) { + int keyval = 0; if (cold) { howto |= RB_HALT; @@ -855,6 +856,10 @@ } boothowto = howto; + /* + * XXX this bit, except for the "cold" check above, should be MI -- + * i.e. back in kern/kern_xxx.c:sys_reboot() + */ if ((howto & RB_NOSYNC) == 0 && waittime < 0) { waittime = 0; vfs_shutdown(); @@ -914,11 +919,10 @@ } if (howto & RB_HALT) { - printf("\n"); - printf("The operating system has halted.\n"); - printf("Please press any key to reboot.\n\n"); + printf("\nThe operating system has halted.\n" + "Please press any key to reboot.\n\n"); -#ifdef BEEP_ONHALT +#ifdef BEEP_ONHALT /* XXX could be: defined(BEEP_ONHALT_COUNT) && (BEEP_ONHALT_COUNT > 0) */ { int c; for (c = BEEP_ONHALT_COUNT; c > 0; c--) { @@ -931,21 +935,58 @@ } #endif - cnpollc(1); /* for proper keyboard command handling */ - if (cngetc() == 0) { - /* no console attached, so just hlt */ - for(;;) { - x86_hlt(); + cnpollc(1); /* for proper keyboard command handling without + * interrupts */ + /* + * ACK!!! The line discipline does _NOT_ get used from within + * the kernel for console I/O (though it probably should be). + * + * If any output above went out too fast for the device + * connected to a serial console then we'll read a <CTRL-S> + * here, and/or perhaps a <CTRL-Q>, and we'll just have to + * ignore them. + */ +#define ASCII_XON 0x11 +#define ASCII_XOFF 0x13 + while (keyval != ASCII_XOFF && keyval != ASCII_XON) { + if (cngetc() == 0) { + /* + * no console attached, or perhaps a BREAK + * condition caused a read error, so just + * invoke the HLT instruction and wait for the + * operator to push the reset (or power) + * button. + */ + printf("\nCannot read from the console, calling the HLT instruction.\n\n"); + printf("RESET or power cycle the system to reboot.\n\n"); + for(;;) { + x86_hlt(); + } + /*NOTREACHED*/ } +#ifdef DEBUG + else if (keyval == ASCII_XOFF && keyval != ASCII_XON) { + printf("(ignoring flow control char (0x%x)\n", keyval); + /* XXX even this could trigger another XOFF, sigh... */ + } +#endif } cnpollc(0); } +#ifdef DEBUG + if (keyval) + printf("(read key value 0x%x)\n\n", keyval); +#endif printf("rebooting...\n"); if (cpureset_delay > 0) delay(cpureset_delay * 1000); cpu_reset(); - for(;;) ; + printf("cpu_reset() returned, waiting for hardware to reset or be reset...\n\n"); + + for(;;) { + x86_hlt(); + } /*NOTREACHED*/ } -- Greg A. Woods Planix, Inc. <woods%planix.com@localhost> +1 416 489-5852 x122 http://www.planix.com/
Attachment:
pgpTbzTbQwGNu.pgp
Description: PGP signature