Commit 28ff6b9b2fc01d2c2746c72ce8af1729344fae27

Authored by Aaron Young
Committed by Tony Luck
1 parent 3ee68c4af3

[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>

Showing 2 changed files with 28 additions and 9 deletions Side-by-side Diff

... ... @@ -5,7 +5,7 @@
5 5 * License. See the file "COPYING" in the main directory of this archive
6 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 /*
... ... @@ -69,6 +69,9 @@
69 69 #define EV_CLASS_TEST_FAULT 0x5000ul
70 70 #define EV_CLASS_TEST_WARNING 0x6000ul
71 71 #define EV_CLASS_PWRD_NOTIFY 0x8000ul
  72 +
  73 +/* ENV class codes */
  74 +#define ENV_PWRDN_PEND 0x4101ul
72 75  
73 76 #define EV_SEVERITY_POWER_STABLE 0x0000ul
74 77 #define EV_SEVERITY_POWER_LOW_WARNING 0x0100ul
drivers/char/snsc_event.c
... ... @@ -5,7 +5,7 @@
5 5 * License. See the file "COPYING" in the main directory of this archive
6 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 @@
187 187 static void
188 188 scdrv_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 192 char desc[CHUNKSIZE];
192 193 char *severity;
193 194  
194 195  
... ... @@ -199,9 +200,25 @@
199 200 /* how urgent is the message? */
200 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 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 222 /* give a SIGPWR signal to init proc */
206 223  
207 224 /* first find init's task */
208 225  
... ... @@ -210,12 +227,11 @@
210 227 if (p->pid == 1)
211 228 break;
212 229 }
213   - if (p) { /* we found init's task */
214   - printk(KERN_EMERG "Power off indication received. Initiating power fail sequence...\n");
  230 + if (p) {
215 231 force_sig(SIGPWR, p);
216   - } else { /* failed to find init's task - just give message(s) */
217   - printk(KERN_WARNING "Failed to find init proc to handle power off!\n");
218   - printk("%s|$(0x%x)%s\n", severity, esp_code, desc);
  232 + } else {
  233 + printk(KERN_ERR "Failed to signal init!\n");
  234 + snsc_shutting_down = 0; /* so can try again (?) */
219 235 }
220 236 read_unlock(&tasklist_lock);
221 237 } else {