diff options
Diffstat (limited to 'drivers/char/snsc_event.c')
-rw-r--r-- | drivers/char/snsc_event.c | 37 |
1 files changed, 25 insertions, 12 deletions
diff --git a/drivers/char/snsc_event.c b/drivers/char/snsc_event.c index baaa365285fa..e234d50e142a 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) | |||
187 | static void | 187 | static void |
188 | scdrv_dispatch_event(char *event, int len) | 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 | 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 { |
@@ -271,7 +287,7 @@ scdrv_event_init(struct sysctl_data_s *scd) | |||
271 | { | 287 | { |
272 | int rv; | 288 | int rv; |
273 | 289 | ||
274 | event_sd = kmalloc(sizeof (struct subch_data_s), GFP_KERNEL); | 290 | event_sd = kzalloc(sizeof (struct subch_data_s), GFP_KERNEL); |
275 | if (event_sd == NULL) { | 291 | if (event_sd == NULL) { |
276 | printk(KERN_WARNING "%s: couldn't allocate subchannel info" | 292 | printk(KERN_WARNING "%s: couldn't allocate subchannel info" |
277 | " for event monitoring\n", __FUNCTION__); | 293 | " for event monitoring\n", __FUNCTION__); |
@@ -279,7 +295,6 @@ scdrv_event_init(struct sysctl_data_s *scd) | |||
279 | } | 295 | } |
280 | 296 | ||
281 | /* initialize subch_data_s fields */ | 297 | /* initialize subch_data_s fields */ |
282 | memset(event_sd, 0, sizeof (struct subch_data_s)); | ||
283 | event_sd->sd_nasid = scd->scd_nasid; | 298 | event_sd->sd_nasid = scd->scd_nasid; |
284 | spin_lock_init(&event_sd->sd_rlock); | 299 | spin_lock_init(&event_sd->sd_rlock); |
285 | 300 | ||
@@ -305,5 +320,3 @@ scdrv_event_init(struct sysctl_data_s *scd) | |||
305 | return; | 320 | return; |
306 | } | 321 | } |
307 | } | 322 | } |
308 | |||
309 | |||