Subject: Re: port-i386/36578: system may not actually halt if serial console is on a slow device
To: None <port-i386-maintainer@netbsd.org, gnats-admin@netbsd.org,>
From: Greg A. Woods <woods@planix.com>
List: netbsd-bugs
Date: 06/30/2007 00:20:02
The following reply was made to PR port-i386/36578; it has been noted by GNATS.

From: "Greg A. Woods" <woods@planix.com>
To: NetBSD GNATS <gnats-bugs@NetBSD.org>
Cc: 
Subject: Re: port-i386/36578: system may not actually halt if serial console is on a slow device
Date: Fri, 29 Jun 2007 20:16:32 -0400

 Of course one must ignore XON too, as it's very likely to follow XOFF:
 
 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.586.2.4
 diff -u -r1.586.2.4 machdep.c
 --- sys/arch/i386/i386/machdep.c	20 Apr 2007 20:31:25 -0000	1.586.2.4
 +++ sys/arch/i386/i386/machdep.c	30 Jun 2007 00:13:32 -0000
 @@ -870,6 +870,7 @@
  void
  cpu_reboot(int howto, char *bootstr)
  {
 +	int keyval = 0;
  
  	if (cold) {
  		howto |= RB_HALT;
 @@ -888,7 +889,7 @@
  			resettodr();
  	}
  
 -	/* Disable interrupts. */
 +	/* block interrupts. */
  	splhigh();
  
  	/* Do a dump if requested. */
 @@ -921,17 +922,16 @@
  		apm_set_powstate(NULL, APM_DEV_ALLDEVS, APM_SYS_OFF);
  		printf("WARNING: APM powerdown failed!\n");
  		/*
 -		 * RB_POWERDOWN implies RB_HALT... fall into it...
 +		 * RB_POWERDOWN includes RB_HALT... fall into it...
  		 */
  #endif
  	}
  
  	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--) {
 @@ -944,21 +944,51 @@
  		}
  #endif
  
 -		cnpollc(1);	/* for proper keyboard command handling */
 -		if (cngetc() == 0) {
 -			/* no console attached, so just hlt */
 -			for(;;) {
 -				__asm volatile("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 ((keyval = cngetc()) == 0) {
 +				/* no console attached, so just hlt */
 +				printf("\nCannot read from the console, calling the HLT instruction.\n\n");
 +				for (;;) {
 +					__asm volatile("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...\n\n");
 +
 +	for (;;) {
 +		__asm volatile("hlt");
 +	}
  	/*NOTREACHED*/
  }
  
 
 
 -- 
 						Greg A. Woods
 
 H:+1 416 218-0098 W:+1 416 489-5852 x122 VE3TCP RoboHack <woods@robohack.ca>
 Planix, Inc. <woods@planix.com>       Secrets of the Weird <woods@weird.com>