X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fchar%2Fsnsc_event.c;fp=drivers%2Fchar%2Fsnsc_event.c;h=baaa365285fa973776beddcb0ae5c09389ffbe65;hb=64ba3f394c830ec48a1c31b53dcae312c56f1604;hp=d12d4f629cec80ca1137fc4e0fc8ad0351f8bfa2;hpb=be1e6109ac94a859551f8e1774eb9a8469fe055c;p=linux-2.6.git diff --git a/drivers/char/snsc_event.c b/drivers/char/snsc_event.c index d12d4f629..baaa36528 100644 --- a/drivers/char/snsc_event.c +++ b/drivers/char/snsc_event.c @@ -5,7 +5,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2004-2006 Silicon Graphics, Inc. All rights reserved. + * Copyright (C) 2004 Silicon Graphics, Inc. All rights reserved. */ /* @@ -187,8 +187,7 @@ scdrv_event_severity(int code) static void scdrv_dispatch_event(char *event, int len) { - static int snsc_shutting_down = 0; - int code, esp_code, src, class; + int code, esp_code, src; char desc[CHUNKSIZE]; char *severity; @@ -200,27 +199,25 @@ scdrv_dispatch_event(char *event, int len) /* how urgent is the message? */ severity = scdrv_event_severity(code); - class = (code & EV_CLASS_MASK); - - if (class == EV_CLASS_PWRD_NOTIFY || code == ENV_PWRDN_PEND) { + if ((code & EV_CLASS_MASK) == EV_CLASS_PWRD_NOTIFY) { struct task_struct *p; - if (snsc_shutting_down) - return; - - snsc_shutting_down = 1; - - /* give a message for each type of event */ - if (class == EV_CLASS_PWRD_NOTIFY) - printk(KERN_NOTICE "Power off indication received." - " Sending SIGPWR to init...\n"); - else if (code == ENV_PWRDN_PEND) - printk(KERN_CRIT "WARNING: Shutting down the system" - " due to a critical environmental condition." - " Sending SIGPWR to init...\n"); - /* give a SIGPWR signal to init proc */ - kill_proc(1, SIGPWR, 0); + + /* first find init's task */ + read_lock(&tasklist_lock); + for_each_process(p) { + if (p->pid == 1) + break; + } + if (p) { /* we found init's task */ + printk(KERN_EMERG "Power off indication received. Initiating power fail sequence...\n"); + force_sig(SIGPWR, p); + } else { /* failed to find init's task - just give message(s) */ + printk(KERN_WARNING "Failed to find init proc to handle power off!\n"); + printk("%s|$(0x%x)%s\n", severity, esp_code, desc); + } + read_unlock(&tasklist_lock); } else { /* print to system log */ printk("%s|$(0x%x)%s\n", severity, esp_code, desc); @@ -274,7 +271,7 @@ scdrv_event_init(struct sysctl_data_s *scd) { int rv; - event_sd = kzalloc(sizeof (struct subch_data_s), GFP_KERNEL); + event_sd = kmalloc(sizeof (struct subch_data_s), GFP_KERNEL); if (event_sd == NULL) { printk(KERN_WARNING "%s: couldn't allocate subchannel info" " for event monitoring\n", __FUNCTION__); @@ -282,6 +279,7 @@ scdrv_event_init(struct sysctl_data_s *scd) } /* initialize subch_data_s fields */ + memset(event_sd, 0, sizeof (struct subch_data_s)); event_sd->sd_nasid = scd->scd_nasid; spin_lock_init(&event_sd->sd_rlock); @@ -297,7 +295,7 @@ scdrv_event_init(struct sysctl_data_s *scd) /* hook event subchannel up to the system controller interrupt */ rv = request_irq(SGI_UART_VECTOR, scdrv_event_interrupt, - IRQF_SHARED | IRQF_DISABLED, + SA_SHIRQ | SA_INTERRUPT, "system controller events", event_sd); if (rv) { printk(KERN_WARNING "%s: irq request failed (%d)\n", @@ -307,3 +305,5 @@ scdrv_event_init(struct sysctl_data_s *scd) return; } } + +