Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 17 Apr 2003 16:31:22 -0700 (PDT)
From:      Alan Larson <alarson@switchanddata.com>
To:        FreeBSD-gnats-submit@FreeBSD.org
Subject:   kern/51110: halt -p doesn't if apm not enabled.
Message-ID:  <200304172331.h3HNVMx72167@ground1.paix.net>
Resent-Message-ID: <200304172340.h3HNeDA6055229@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         51110
>Category:       kern
>Synopsis:       halt -p doesn't if apm not enabled.
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Apr 17 16:40:13 PDT 2003
>Closed-Date:
>Last-Modified:
>Originator:     Alan Larson
>Release:        FreeBSD 4.8-RELEASE i386
>Organization:
>Environment:
All distributed release versions, from 4.3 to 4.8, probably more.


>Description:
  halt -p would halt the system, but not power down.  Power down
was known to work for windows 2k.  Investigation revealed that
apm_power_off() in apm.c was testing the softc to see if it was
active.

  It appears to be unnecessary for the apm to be active to issue
the bios call to power the machine down.

  A context diff of the correction is included.

  This is rather safe, since it calls apm_bioscall(), which calls
apm_check_function_supported() right at the start.

  (Since the only requirement in the present code to get through to
power off the system is that apm_softc.active be true, and that is
set true by the ioctl to enable apm (without further testing), it
seems quite safe to attempt the power off even if apm hasn't been
enabled.  The enabled state gives us no assurances that we can power
the system off.)




>How-To-Repeat:
How to repeat the problem:
	su		# many fun things start with this.
	apm -e 0	# only needed if it was already on.
	halt -p		# you did save your work first, didn't you?


>Fix:

Fix to the problem:
  The following diff should do it just fine.

*** apm.ccO	Fri Mar 22 14:09:17 2002
--- apm.cc	Fri Mar 22 14:15:10 2002
***************
*** 285,293 ****
  {
  	struct apm_softc *sc = &apm_softc;
  
! 	/* Not halting powering off, or not active */
! 	if (!(howto & RB_POWEROFF) || !apm_softc.active)
! 		return;
  	sc->bios.r.eax = (APM_BIOS << 8) | APM_SETPWSTATE;
  	sc->bios.r.ebx = PMDV_ALLDEV;
  	sc->bios.r.ecx = PMST_OFF;
--- 285,292 ----
  {
  	struct apm_softc *sc = &apm_softc;
  
! 	if (!(howto & RB_POWEROFF))	/* Powering off? */
! 		return;			/* no */
  	sc->bios.r.eax = (APM_BIOS << 8) | APM_SETPWSTATE;
  	sc->bios.r.ebx = PMDV_ALLDEV;
  	sc->bios.r.ecx = PMST_OFF;

>Release-Note:
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200304172331.h3HNVMx72167>