Port-i386 archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

my serial-console i386 systems will not reboot after halt with a keypress



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



Home | Main Index | Thread Index | Old Index