aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/char/snsc.h5
-rw-r--r--drivers/char/snsc_event.c32
2 files changed, 28 insertions, 9 deletions
diff --git a/drivers/char/snsc.h b/drivers/char/snsc.h
index a9efc13cc858..8a98169b60c1 100644
--- a/drivers/char/snsc.h
+++ b/drivers/char/snsc.h
@@ -5,7 +5,7 @@
5 * License. See the file "COPYING" in the main directory of this archive 5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details. 6 * for more details.
7 * 7 *
8 * Copyright (C) 2004 Silicon Graphics, Inc. All rights reserved. 8 * Copyright (C) 2004-2006 Silicon Graphics, Inc. All rights reserved.
9 */ 9 */
10 10
11/* 11/*
@@ -70,6 +70,9 @@ struct sysctl_data_s {
70#define EV_CLASS_TEST_WARNING 0x6000ul 70#define EV_CLASS_TEST_WARNING 0x6000ul
71#define EV_CLASS_PWRD_NOTIFY 0x8000ul 71#define EV_CLASS_PWRD_NOTIFY 0x8000ul
72 72
73/* ENV class codes */
74#define ENV_PWRDN_PEND 0x4101ul
75
73#define EV_SEVERITY_POWER_STABLE 0x0000ul 76#define EV_SEVERITY_POWER_STABLE 0x0000ul
74#define EV_SEVERITY_POWER_LOW_WARNING 0x0100ul 77#define EV_SEVERITY_POWER_LOW_WARNING 0x0100ul
75#define EV_SEVERITY_POWER_HIGH_WARNING 0x0200ul 78#define EV_SEVERITY_POWER_HIGH_WARNING 0x0200ul
diff --git a/drivers/char/snsc_event.c b/drivers/char/snsc_event.c
index baaa365285fa..a4fa507eed9e 100644
--- a/drivers/char/snsc_event.c
+++ b/drivers/char/snsc_event.c
@@ -5,7 +5,7 @@
5 * License. See the file "COPYING" in the main directory of this archive 5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details. 6 * for more details.
7 * 7 *
8 * Copyright (C) 2004 Silicon Graphics, Inc. All rights reserved. 8 * Copyright (C) 2004-2006 Silicon Graphics, Inc. All rights reserved.
9 */ 9 */
10 10
11/* 11/*
@@ -187,7 +187,8 @@ scdrv_event_severity(int code)
187static void 187static void
188scdrv_dispatch_event(char *event, int len) 188scdrv_dispatch_event(char *event, int len)
189{ 189{
190 int code, esp_code, src; 190 static int snsc_shutting_down = 0;
191 int code, esp_code, src, class;
191 char desc[CHUNKSIZE]; 192 char desc[CHUNKSIZE];
192 char *severity; 193 char *severity;
193 194
@@ -199,9 +200,25 @@ scdrv_dispatch_event(char *event, int len)
199 /* how urgent is the message? */ 200 /* how urgent is the message? */
200 severity = scdrv_event_severity(code); 201 severity = scdrv_event_severity(code);
201 202
202 if ((code & EV_CLASS_MASK) == EV_CLASS_PWRD_NOTIFY) { 203 class = (code & EV_CLASS_MASK);
204
205 if (class == EV_CLASS_PWRD_NOTIFY || code == ENV_PWRDN_PEND) {
203 struct task_struct *p; 206 struct task_struct *p;
204 207
208 if (snsc_shutting_down)
209 return;
210
211 snsc_shutting_down = 1;
212
213 /* give a message for each type of event */
214 if (class == EV_CLASS_PWRD_NOTIFY)
215 printk(KERN_NOTICE "Power off indication received."
216 " Sending SIGPWR to init...\n");
217 else if (code == ENV_PWRDN_PEND)
218 printk(KERN_CRIT "WARNING: Shutting down the system"
219 " due to a critical environmental condition."
220 " Sending SIGPWR to init...\n");
221
205 /* give a SIGPWR signal to init proc */ 222 /* give a SIGPWR signal to init proc */
206 223
207 /* first find init's task */ 224 /* first find init's task */
@@ -210,12 +227,11 @@ scdrv_dispatch_event(char *event, int len)
210 if (p->pid == 1) 227 if (p->pid == 1)
211 break; 228 break;
212 } 229 }
213 if (p) { /* we found init's task */ 230 if (p) {
214 printk(KERN_EMERG "Power off indication received. Initiating power fail sequence...\n");
215 force_sig(SIGPWR, p); 231 force_sig(SIGPWR, p);
216 } else { /* failed to find init's task - just give message(s) */ 232 } else {
217 printk(KERN_WARNING "Failed to find init proc to handle power off!\n"); 233 printk(KERN_ERR "Failed to signal init!\n");
218 printk("%s|$(0x%x)%s\n", severity, esp_code, desc); 234 snsc_shutting_down = 0; /* so can try again (?) */
219 } 235 }
220 read_unlock(&tasklist_lock); 236 read_unlock(&tasklist_lock);
221 } else { 237 } else {