APM poweroff under Linux 2.4.7 / 2.4.2 RH 7.1
Subsystems (3)
Dear all,
I have an Athlon on an ASUS A7V133.
This machine powers off perfectly using a stock RedHat 7.1 kernel (2.4.2). However, it refuses to power off with 2.4.7, with all APM options set correctly (including power off in real mode).
Now for the funny part: copying the 2.4.2 apm.c to the 2.4.7 and recompiling yielded a working poweroff. So *something* has been broken between 2.4.2 and 2.4.7 with APM poweroff. :-)
Signature · 3 lines
David Monniaux http://www.di.ens.fr/~monniaux Laboratoire d'informatique de l'École Normale Supérieure, Paris, France
Hi David,
Quoted 9 lines · On 6 Aug 2001 23:03:35 +0200 David Monniaux wrote:
I have an Athlon on an ASUS A7V133.
This machine powers off perfectly using a stock RedHat 7.1 kernel (2.4.2). However, it refuses to power off with 2.4.7, with all APM options set correctly (including power off in real mode).Now for the funny part: copying the 2.4.2
apm.cto the 2.4.7 and recompiling yielded a working poweroff. So *something* has been broken between 2.4.2 and 2.4.7 with APM poweroff. :-)
So, is this a pristine 2.4.2? Or is it a RH patched one? I have just looked at the differences in arch/i386/kernel/apm.c between 2.4.2 and 2.4.7. The only differences are in comments and to allow one more kernel command line option. i.e. there is nothing that should make APM behave differently.
Could you send me a diff between the two versions of apm.c, please?
Cheers,
Stephen Rothwell
IBM Linux Technology Centre, Canberra
Hi Stephen.
Quoted 11 lines
Quoted 10 lines
I have an Athlon on an ASUS A7V133.
This machine powers off perfectly using a stock RedHat 7.1 kernel (2.4.2). However, it refuses to power off with 2.4.7, with all APM options set correctly (including power off in real mode).
Now for the funny part: copying the 2.4.2
apm.cto the 2.4.7 and recompiling yielded a working poweroff. So *something* has been broken between 2.4.2 and 2.4.7 with APM poweroff. :-)
Quoted 7 lines
So, is this a pristine 2.4.2? Or is it a RH patched one? I have just looked at the differences in
arch/i386/kernel/apm.cbetween 2.4.2 and 2.4.7. The only differences are in comments and to allow one more kernel command line option. i.e. there is nothing that should make APM behave differently.Could you send me a diff between the two versions of
apm.c, please?
I have to admit that your comments made me wonder exactly what patches RedHat have applied to the kernel and, as I have the 7.1 CD's to hand, I put the 7.1 source CD in my drive and installed the relevant source RPM therefrom. There are 227 patches listed therein, which is way too many IMHO, and some of them clearly need to be considered for the generic kernel.
Of the many patches theein, the enclosed TWO are the only ones that touch apm.c so they are the patches you may need to consider. I'd certainly be interested in your comments thereon.
Best wishes from Riley.
Documentation/sysrq.txt +41 -0
@@ -126,14 +126,55 @@ boot script. Oh, and by the way, you exit 'showkey' by not typing anything for ten seconds. +* I want to add SysRQ key events to a module, how does it work? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +In order to register a basic function with the table, you must first include +the header 'include/linux/sysrq.h', this will define everything else you need. +Next, you must create a sysrq_key_op struct, and populate it with A) the key +handler function you will use, B) a help_msg string, that will print when SysRQ +prints help, and C) an action_msg string, that will print right before your +handler is called. Your handler must conform to the protoype in 'sysrq.h'. + +After the sysrq_key_op is created, you can call the macro +REGISTER_SYSRQ_KEY(int key, struct sysrq_key_op *op_p) that is defined in +sysrq.h, this will register the operation pointed to by 'op_p' at table +key 'key', if that slot in the table is blank. At module unload time, you must +call the macro UNREGISTER_SYSRQ_KEY(int key, struct sysrq_key_op *op_p), which +will remove the key op pointed to by 'op_p' from the key 'key', if and only if +it is currently registered in that slot. This is in case the slot has been +overwritten since you registered it. + +The Magic SysRQ system works by registering key operations against a key op +lookup table, which is defined in 'drivers/char/sysrq.c'. This key table has +a number of operations registered into it at compile time, but is mutable, +and 4 functions are exported for interface to it: __sysrq_lock_table, +__sysrq_unlock_table, __sysrq_get_key_op, and __sysrq_put_key_op. The +functions __sysrq_swap_key_ops and __sysrq_swap_key_ops_nolock are defined +in the header itself, and the REGISTER and UNREGISTER macros are built fromi +these. More complex (and dangerous!) manipulations of the table are possible +using these functions, but you must be careful to always lock the table before +you read or write from it, and to unlock it again when you are done. (And of +course, to never ever leave an invalid pointer in the table). Null pointers in +the table are always safe :) + +If for some reason you feel the need to call the handle_sysrq function from +within a function called by handle_sysrq, you must be aware that you are in +a lock (you are also in an interupt handler, which means don't sleep!), so +you must call __handle_sysrq_nolock instead. + * I have more questions, who can I ask? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ You may feel free to send email to [email protected], and I will respond as soon as possible. -Myrdraal +And I'll answer any questions about the registration system you got, also +responding as soon as possible. + -Crutcher + * Credits ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Written by Mydraal <[email protected]> Updated by Adam Sulmicki <[email protected]> Updated by Jeremy M. Dolan <[email protected]> 2001/01/28 10:15:59 +Added to by Crutcher Dunnavant <[email protected]>
arch/i386/kernel/apm.c +26 -5
@@ -166,6 +166,11 @@* * [This document is available from Microsoft at: * http://www.microsoft.com/hwdev/busbios/amp_12.htm] +* +* (c) 2000 Crutcher Dunnavant <[email protected]> +* changed to use the sysrq-register hack for registering +* the power off function called by magic sysrq +* based upon discusions in irc://irc.openprojects.net/#kernelnewbies */ #include <linux/config.h>
@@ -191,12 +196,11 @@#include <asm/uaccess.h> #include <asm/desc.h> +#include <linux/sysrq.h> +extern unsigned long get_cmos_time (void );extern void machine_real_restart (unsigned char *,int ); -#ifdef CONFIG_MAGIC_SYSRQ -extern void (*sysrq_power_off)(void ); -#endif #if defined(CONFIG_APM_DISPLAY_BLANK ) && defined(CONFIG_VT )extern int (*console_blank_hook)(int );#endif
@@ -673,6 +677,23 @@#endif } +#ifdef CONFIG_MAGIC_SYSRQ +/* +* Magic sysrq key and handler for the power off function +*/ + +void handle_poweroff (int key,struct pt_regs *pt_regs, +struct kbd_struct *kbd,struct tty_struct *tty) { +apm_power_off (); +} +struct sysrq_key_op sysrq_poweroff_op = { + handler: handle_poweroff, + help_msg:"Off" , + action_msg:"Power Off\n" +}; +#endif + +#ifdef CONFIG_APM_DO_ENABLE static int apm_enable_power_management (int enable) {
@@ -1528,7 +1549,7 @@if (power_off) pm_power_off = apm_power_off;#ifdef CONFIG_MAGIC_SYSRQ - sysrq_power_off = apm_power_off; +REGISTER_SYSRQ_KEY ('o' ,&sysrq_poweroff_op);#endif if (smp_num_cpus ==1 ) {#if defined(CONFIG_APM_DISPLAY_BLANK ) && defined(CONFIG_VT )
@@ -1727,7 +1748,7 @@misc_deregister (&apm_device);remove_proc_entry ("apm" ,NULL );#ifdef CONFIG_MAGIC_SYSRQ - sysrq_power_off =NULL ; +UNREGISTER_SYSRQ_KEY ('o' ,&sysrq_poweroff_op);#endif if (power_off) pm_power_off =NULL ;
drivers/char/sysrq.c +335 -122
520 lines not on this page · raw message
include/linux/sysrq.h +57 -1
75 lines not on this page · raw message
kernel/ksyms.c +14 -0
@@ -7,6 +7,10 @@* - External symbol table support added (December 1994) * - Versions on symbols added (December 1994) * by Bjorn Ekwall <[email protected]> +* +* Added sysrq interface for dynamic sysrq (2000) +* Crutcher Dunnavant <[email protected]> +* */ #define __KERNEL_SYSCALLS__
@@ -47,6 +51,7 @@#include <linux/brlock.h> #include <linux/fs.h> #include <linux/tty.h> +#include <linux/sysrq.h> #include <asm/checksum.h> #include <linux/unistd.h>
@@ -559,3 +564,12 @@EXPORT_SYMBOL (tasklist_lock);EXPORT_SYMBOL (pidhash); + +/* dynamic sysrq registration */ +EXPORT_SYMBOL (handle_sysrq); +EXPORT_SYMBOL (__handle_sysrq_nolock); +EXPORT_SYMBOL (__sysrq_lock_table); +EXPORT_SYMBOL (__sysrq_unlock_table); +EXPORT_SYMBOL (__sysrq_get_key_op); +EXPORT_SYMBOL (__sysrq_put_key_op); +
arch/i386/kernel/apm.c renamed from arch/i386/kernel/apm.c.org +7 -1
@@ -343,6 +343,7 @@#else static int power_off =1 ;#endif +static int realmode_power_off =0 ;static int exit_kapmd;static int kapmd_running;
@@ -663,7 +664,10 @@ }#endif #ifdef CONFIG_APM_REAL_MODE_POWER_OFF -machine_real_restart (po_bios_call,sizeof (po_bios_call)); +if (realmode_power_off) +machine_real_restart (po_bios_call,sizeof (po_bios_call)); +else + (void )apm_set_power_state (APM_STATE_OFF );#else (void )apm_set_power_state (APM_STATE_OFF );#endif
@@ -1548,6 +1552,8 @@while ((str !=NULL ) && (*str !='\0' )) {if (strncmp (str,"off" ,3 ) ==0 ) apm_disabled =1 ; +if (strncmp (str,"realmode" ,8 ) ==0 ) + realmode_power_off =1 ;if (strncmp (str,"on" ,2 ) ==0 ) apm_disabled =0 ; invert = (strncmp (str,"no-" ,3 ) ==0 );
Quoted 4 lines
I put the 7.1 source CD in my drive and installed the relevant source RPM therefrom. There are 227 patches listed therein, which is way too many IMHO, and some of them clearly need to be considered for the generic kernel.
Most of them have been in -ac since the early days (the RH 2.4.2 is closer to 2.4.3-ac than 2.4.2 in truth) and pushed on to Linus long ago
Hi Alan.
Quoted 8 lines
Quoted 4 lines
I put the 7.1 source CD in my drive and installed the relevant source RPM therefrom. There are 227 patches listed therein, which is way too many IMHO, and some of them clearly need to be considered for the generic kernel.
Most of them have been in -ac since the early days (the RH 2.4.2 is closer to 2.4.3-ac than 2.4.2 in truth) and pushed on to Linus long ago
I guessed as much! However, it appears from the question being asked that some of them never made it into the latest 2.4 kernel, and specifically one of the two that I enclosed with that email, if the complainant's comments and Stephen's replies are both accurate.
Best wishes from Riley.
Hi Riley,
Quoted 4 lines · On Thu, 9 Aug 2001 08:34:51 +0100 (BST) Riley Williams <[email protected]> wrote:
Of the many patches theein, the enclosed TWO are the only ones that touch
apm.cso they are the patches you may need to consider. I'd certainly be interested in your comments thereon.
I have seen both these patches. The first is not relevant (it just changes how we register a sysreq key). The second has the effect of NOT using the real mode power off code unless both CONFIG_APM_REAL_MODE_POWER_OFF was set at kerne configure time AND "apm=realmode" was specified on the kernel command line at boot time.
So those having trouble powering off with 2.4.[78] when the Red Hat kernel did power off, should try building their kernels with CONFIG_APM_REAL_MODE_POWER_OFF NOT selected.
Cheers,
Stephen Rothwell
IBM OzLabs - Linux Technology Centre