aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
authorAaron Young <ayoung@google.engr.sgi.com>2006-01-23 12:00:51 -0500
committerTony Luck <tony.luck@intel.com>2006-01-26 16:32:26 -0500
commit28ff6b9b2fc01d2c2746c72ce8af1729344fae27 (patch)
tree6209aa2a6416cc7c363ad8c8efef2e15ca7b9b59 /drivers/char
parent3ee68c4af3fd7228c1be63254b9f884614f9ebb2 (diff)
[IA64-SGI] Handle SC env. powerdown events
Handle system controller power down pending events on SN systems. This allows the system to gracefully shutdown before the system controller removes power due to an adverse environmental condition. Signed-off-by: Aaron Young <ayoung@sgi.com> Signed-off-by: Tony Luck <tony.luck@intel.com>
Diffstat (limited to 'drivers/char')
-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 a9efc13cc85..8a98169b60c 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 baaa365285f..a4fa507eed9 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 {