diff options
author | Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> | 2006-02-21 18:45:45 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2006-03-23 17:35:13 -0500 |
commit | f7391f5325ea744f0632f7ef39a90085162743ac (patch) | |
tree | a7368b2ca639211743ba7fbc0dab7a9efaea02b7 /drivers/pci/hotplug/shpchp_ctrl.c | |
parent | 68c0b671491088d79611fa965bbf94b3bc0024a4 (diff) |
[PATCH] shpchp: event handling rework
The event handler of SHPCHP driver is unnecessarily very complex. In
addition, current event handler can only a fixed number of events at
the same time, and some of events would be lost if several number of
events happened at the same time.
This patch simplify the event handler by using 'work queue', and it
also fix the above-mentioned issue.
Signed-off-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
Signed-off-by: Kristen Carlson Accardi <kristen.c.accardi@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/pci/hotplug/shpchp_ctrl.c')
-rw-r--r-- | drivers/pci/hotplug/shpchp_ctrl.c | 313 |
1 files changed, 89 insertions, 224 deletions
diff --git a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c index b709328a4145..2411f3bd08da 100644 --- a/drivers/pci/hotplug/shpchp_ctrl.c +++ b/drivers/pci/hotplug/shpchp_ctrl.c | |||
@@ -32,44 +32,46 @@ | |||
32 | #include <linux/types.h> | 32 | #include <linux/types.h> |
33 | #include <linux/smp_lock.h> | 33 | #include <linux/smp_lock.h> |
34 | #include <linux/pci.h> | 34 | #include <linux/pci.h> |
35 | #include <linux/workqueue.h> | ||
35 | #include "../pci.h" | 36 | #include "../pci.h" |
36 | #include "shpchp.h" | 37 | #include "shpchp.h" |
37 | 38 | ||
38 | static void interrupt_event_handler(struct controller *ctrl); | 39 | static void interrupt_event_handler(void *data); |
39 | 40 | ||
40 | static struct semaphore event_semaphore; /* mutex for process loop (up if something to process) */ | 41 | static int queue_interrupt_event(struct slot *p_slot, u32 event_type) |
41 | static struct semaphore event_exit; /* guard ensure thread has exited before calling it quits */ | 42 | { |
42 | static int event_finished; | 43 | struct event_info *info; |
43 | static unsigned long pushbutton_pending; /* = 0 */ | 44 | |
45 | info = kmalloc(sizeof(*info), GFP_ATOMIC); | ||
46 | if (!info) | ||
47 | return -ENOMEM; | ||
48 | |||
49 | info->event_type = event_type; | ||
50 | info->p_slot = p_slot; | ||
51 | INIT_WORK(&info->work, interrupt_event_handler, info); | ||
52 | |||
53 | queue_work(shpchp_wq, &info->work); | ||
54 | |||
55 | return 0; | ||
56 | } | ||
44 | 57 | ||
45 | u8 shpchp_handle_attention_button(u8 hp_slot, void *inst_id) | 58 | u8 shpchp_handle_attention_button(u8 hp_slot, void *inst_id) |
46 | { | 59 | { |
47 | struct controller *ctrl = (struct controller *) inst_id; | 60 | struct controller *ctrl = (struct controller *) inst_id; |
48 | struct slot *p_slot; | 61 | struct slot *p_slot; |
49 | u8 rc = 0; | 62 | u32 event_type; |
50 | u8 getstatus; | ||
51 | struct event_info *taskInfo; | ||
52 | 63 | ||
53 | /* Attention Button Change */ | 64 | /* Attention Button Change */ |
54 | dbg("shpchp: Attention button interrupt received.\n"); | 65 | dbg("shpchp: Attention button interrupt received.\n"); |
55 | 66 | ||
56 | /* This is the structure that tells the worker thread what to do */ | ||
57 | taskInfo = &(ctrl->event_queue[ctrl->next_event]); | ||
58 | p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); | 67 | p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); |
59 | |||
60 | p_slot->hpc_ops->get_adapter_status(p_slot, &(p_slot->presence_save)); | 68 | p_slot->hpc_ops->get_adapter_status(p_slot, &(p_slot->presence_save)); |
61 | p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); | ||
62 | |||
63 | ctrl->next_event = (ctrl->next_event + 1) % 10; | ||
64 | taskInfo->hp_slot = hp_slot; | ||
65 | |||
66 | rc++; | ||
67 | 69 | ||
68 | /* | 70 | /* |
69 | * Button pressed - See if need to TAKE ACTION!!! | 71 | * Button pressed - See if need to TAKE ACTION!!! |
70 | */ | 72 | */ |
71 | info("Button pressed on Slot(%d)\n", ctrl->first_slot + hp_slot); | 73 | info("Button pressed on Slot(%d)\n", ctrl->first_slot + hp_slot); |
72 | taskInfo->event_type = INT_BUTTON_PRESS; | 74 | event_type = INT_BUTTON_PRESS; |
73 | 75 | ||
74 | if ((p_slot->state == BLINKINGON_STATE) | 76 | if ((p_slot->state == BLINKINGON_STATE) |
75 | || (p_slot->state == BLINKINGOFF_STATE)) { | 77 | || (p_slot->state == BLINKINGOFF_STATE)) { |
@@ -77,7 +79,7 @@ u8 shpchp_handle_attention_button(u8 hp_slot, void *inst_id) | |||
77 | * attention again before the 5 sec. limit expires to cancel hot-add | 79 | * attention again before the 5 sec. limit expires to cancel hot-add |
78 | * or hot-remove | 80 | * or hot-remove |
79 | */ | 81 | */ |
80 | taskInfo->event_type = INT_BUTTON_CANCEL; | 82 | event_type = INT_BUTTON_CANCEL; |
81 | info("Button cancel on Slot(%d)\n", ctrl->first_slot + hp_slot); | 83 | info("Button cancel on Slot(%d)\n", ctrl->first_slot + hp_slot); |
82 | } else if ((p_slot->state == POWERON_STATE) | 84 | } else if ((p_slot->state == POWERON_STATE) |
83 | || (p_slot->state == POWEROFF_STATE)) { | 85 | || (p_slot->state == POWEROFF_STATE)) { |
@@ -85,12 +87,11 @@ u8 shpchp_handle_attention_button(u8 hp_slot, void *inst_id) | |||
85 | * means that the previous attention button action to hot-add or | 87 | * means that the previous attention button action to hot-add or |
86 | * hot-remove is undergoing | 88 | * hot-remove is undergoing |
87 | */ | 89 | */ |
88 | taskInfo->event_type = INT_BUTTON_IGNORE; | 90 | event_type = INT_BUTTON_IGNORE; |
89 | info("Button ignore on Slot(%d)\n", ctrl->first_slot + hp_slot); | 91 | info("Button ignore on Slot(%d)\n", ctrl->first_slot + hp_slot); |
90 | } | 92 | } |
91 | 93 | ||
92 | if (rc) | 94 | queue_interrupt_event(p_slot, event_type); |
93 | up(&event_semaphore); /* signal event thread that new event is posted */ | ||
94 | 95 | ||
95 | return 0; | 96 | return 0; |
96 | 97 | ||
@@ -100,21 +101,12 @@ u8 shpchp_handle_switch_change(u8 hp_slot, void *inst_id) | |||
100 | { | 101 | { |
101 | struct controller *ctrl = (struct controller *) inst_id; | 102 | struct controller *ctrl = (struct controller *) inst_id; |
102 | struct slot *p_slot; | 103 | struct slot *p_slot; |
103 | u8 rc = 0; | ||
104 | u8 getstatus; | 104 | u8 getstatus; |
105 | struct event_info *taskInfo; | 105 | u32 event_type; |
106 | 106 | ||
107 | /* Switch Change */ | 107 | /* Switch Change */ |
108 | dbg("shpchp: Switch interrupt received.\n"); | 108 | dbg("shpchp: Switch interrupt received.\n"); |
109 | 109 | ||
110 | /* This is the structure that tells the worker thread | ||
111 | * what to do | ||
112 | */ | ||
113 | taskInfo = &(ctrl->event_queue[ctrl->next_event]); | ||
114 | ctrl->next_event = (ctrl->next_event + 1) % 10; | ||
115 | taskInfo->hp_slot = hp_slot; | ||
116 | |||
117 | rc++; | ||
118 | p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); | 110 | p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); |
119 | p_slot->hpc_ops->get_adapter_status(p_slot, &(p_slot->presence_save)); | 111 | p_slot->hpc_ops->get_adapter_status(p_slot, &(p_slot->presence_save)); |
120 | p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); | 112 | p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); |
@@ -126,9 +118,9 @@ u8 shpchp_handle_switch_change(u8 hp_slot, void *inst_id) | |||
126 | * Switch opened | 118 | * Switch opened |
127 | */ | 119 | */ |
128 | info("Latch open on Slot(%d)\n", ctrl->first_slot + hp_slot); | 120 | info("Latch open on Slot(%d)\n", ctrl->first_slot + hp_slot); |
129 | taskInfo->event_type = INT_SWITCH_OPEN; | 121 | event_type = INT_SWITCH_OPEN; |
130 | if (p_slot->pwr_save && p_slot->presence_save) { | 122 | if (p_slot->pwr_save && p_slot->presence_save) { |
131 | taskInfo->event_type = INT_POWER_FAULT; | 123 | event_type = INT_POWER_FAULT; |
132 | err("Surprise Removal of card\n"); | 124 | err("Surprise Removal of card\n"); |
133 | } | 125 | } |
134 | } else { | 126 | } else { |
@@ -136,34 +128,23 @@ u8 shpchp_handle_switch_change(u8 hp_slot, void *inst_id) | |||
136 | * Switch closed | 128 | * Switch closed |
137 | */ | 129 | */ |
138 | info("Latch close on Slot(%d)\n", ctrl->first_slot + hp_slot); | 130 | info("Latch close on Slot(%d)\n", ctrl->first_slot + hp_slot); |
139 | taskInfo->event_type = INT_SWITCH_CLOSE; | 131 | event_type = INT_SWITCH_CLOSE; |
140 | } | 132 | } |
141 | 133 | ||
142 | if (rc) | 134 | queue_interrupt_event(p_slot, event_type); |
143 | up(&event_semaphore); /* signal event thread that new event is posted */ | ||
144 | 135 | ||
145 | return rc; | 136 | return 1; |
146 | } | 137 | } |
147 | 138 | ||
148 | u8 shpchp_handle_presence_change(u8 hp_slot, void *inst_id) | 139 | u8 shpchp_handle_presence_change(u8 hp_slot, void *inst_id) |
149 | { | 140 | { |
150 | struct controller *ctrl = (struct controller *) inst_id; | 141 | struct controller *ctrl = (struct controller *) inst_id; |
151 | struct slot *p_slot; | 142 | struct slot *p_slot; |
152 | u8 rc = 0; | 143 | u32 event_type; |
153 | /*u8 temp_byte;*/ | ||
154 | struct event_info *taskInfo; | ||
155 | 144 | ||
156 | /* Presence Change */ | 145 | /* Presence Change */ |
157 | dbg("shpchp: Presence/Notify input change.\n"); | 146 | dbg("shpchp: Presence/Notify input change.\n"); |
158 | 147 | ||
159 | /* This is the structure that tells the worker thread | ||
160 | * what to do | ||
161 | */ | ||
162 | taskInfo = &(ctrl->event_queue[ctrl->next_event]); | ||
163 | ctrl->next_event = (ctrl->next_event + 1) % 10; | ||
164 | taskInfo->hp_slot = hp_slot; | ||
165 | |||
166 | rc++; | ||
167 | p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); | 148 | p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); |
168 | 149 | ||
169 | /* | 150 | /* |
@@ -175,39 +156,29 @@ u8 shpchp_handle_presence_change(u8 hp_slot, void *inst_id) | |||
175 | * Card Present | 156 | * Card Present |
176 | */ | 157 | */ |
177 | info("Card present on Slot(%d)\n", ctrl->first_slot + hp_slot); | 158 | info("Card present on Slot(%d)\n", ctrl->first_slot + hp_slot); |
178 | taskInfo->event_type = INT_PRESENCE_ON; | 159 | event_type = INT_PRESENCE_ON; |
179 | } else { | 160 | } else { |
180 | /* | 161 | /* |
181 | * Not Present | 162 | * Not Present |
182 | */ | 163 | */ |
183 | info("Card not present on Slot(%d)\n", ctrl->first_slot + hp_slot); | 164 | info("Card not present on Slot(%d)\n", ctrl->first_slot + hp_slot); |
184 | taskInfo->event_type = INT_PRESENCE_OFF; | 165 | event_type = INT_PRESENCE_OFF; |
185 | } | 166 | } |
186 | 167 | ||
187 | if (rc) | 168 | queue_interrupt_event(p_slot, event_type); |
188 | up(&event_semaphore); /* signal event thread that new event is posted */ | ||
189 | 169 | ||
190 | return rc; | 170 | return 1; |
191 | } | 171 | } |
192 | 172 | ||
193 | u8 shpchp_handle_power_fault(u8 hp_slot, void *inst_id) | 173 | u8 shpchp_handle_power_fault(u8 hp_slot, void *inst_id) |
194 | { | 174 | { |
195 | struct controller *ctrl = (struct controller *) inst_id; | 175 | struct controller *ctrl = (struct controller *) inst_id; |
196 | struct slot *p_slot; | 176 | struct slot *p_slot; |
197 | u8 rc = 0; | 177 | u32 event_type; |
198 | struct event_info *taskInfo; | ||
199 | 178 | ||
200 | /* Power fault */ | 179 | /* Power fault */ |
201 | dbg("shpchp: Power fault interrupt received.\n"); | 180 | dbg("shpchp: Power fault interrupt received.\n"); |
202 | 181 | ||
203 | /* This is the structure that tells the worker thread | ||
204 | * what to do | ||
205 | */ | ||
206 | taskInfo = &(ctrl->event_queue[ctrl->next_event]); | ||
207 | ctrl->next_event = (ctrl->next_event + 1) % 10; | ||
208 | taskInfo->hp_slot = hp_slot; | ||
209 | |||
210 | rc++; | ||
211 | p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); | 182 | p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); |
212 | 183 | ||
213 | if ( !(p_slot->hpc_ops->query_power_fault(p_slot))) { | 184 | if ( !(p_slot->hpc_ops->query_power_fault(p_slot))) { |
@@ -216,21 +187,21 @@ u8 shpchp_handle_power_fault(u8 hp_slot, void *inst_id) | |||
216 | */ | 187 | */ |
217 | info("Power fault cleared on Slot(%d)\n", ctrl->first_slot + hp_slot); | 188 | info("Power fault cleared on Slot(%d)\n", ctrl->first_slot + hp_slot); |
218 | p_slot->status = 0x00; | 189 | p_slot->status = 0x00; |
219 | taskInfo->event_type = INT_POWER_FAULT_CLEAR; | 190 | event_type = INT_POWER_FAULT_CLEAR; |
220 | } else { | 191 | } else { |
221 | /* | 192 | /* |
222 | * Power fault | 193 | * Power fault |
223 | */ | 194 | */ |
224 | info("Power fault on Slot(%d)\n", ctrl->first_slot + hp_slot); | 195 | info("Power fault on Slot(%d)\n", ctrl->first_slot + hp_slot); |
225 | taskInfo->event_type = INT_POWER_FAULT; | 196 | event_type = INT_POWER_FAULT; |
226 | /* set power fault status for this board */ | 197 | /* set power fault status for this board */ |
227 | p_slot->status = 0xFF; | 198 | p_slot->status = 0xFF; |
228 | info("power fault bit %x set\n", hp_slot); | 199 | info("power fault bit %x set\n", hp_slot); |
229 | } | 200 | } |
230 | if (rc) | ||
231 | up(&event_semaphore); /* signal event thread that new event is posted */ | ||
232 | 201 | ||
233 | return rc; | 202 | queue_interrupt_event(p_slot, event_type); |
203 | |||
204 | return 1; | ||
234 | } | 205 | } |
235 | 206 | ||
236 | /* The following routines constitute the bulk of the | 207 | /* The following routines constitute the bulk of the |
@@ -521,14 +492,6 @@ static int remove_board(struct slot *p_slot) | |||
521 | } | 492 | } |
522 | 493 | ||
523 | 494 | ||
524 | static void pushbutton_helper_thread (unsigned long data) | ||
525 | { | ||
526 | pushbutton_pending = data; | ||
527 | |||
528 | up(&event_semaphore); | ||
529 | } | ||
530 | |||
531 | |||
532 | /** | 495 | /** |
533 | * shpchp_pushbutton_thread | 496 | * shpchp_pushbutton_thread |
534 | * | 497 | * |
@@ -536,90 +499,24 @@ static void pushbutton_helper_thread (unsigned long data) | |||
536 | * Handles all pending events and exits. | 499 | * Handles all pending events and exits. |
537 | * | 500 | * |
538 | */ | 501 | */ |
539 | static void shpchp_pushbutton_thread (unsigned long slot) | 502 | void shpchp_pushbutton_thread(void *data) |
540 | { | 503 | { |
541 | struct slot *p_slot = (struct slot *) slot; | 504 | struct slot *p_slot = data; |
542 | u8 getstatus; | 505 | u8 getstatus; |
543 | |||
544 | pushbutton_pending = 0; | ||
545 | |||
546 | if (!p_slot) { | ||
547 | dbg("%s: Error! slot NULL\n", __FUNCTION__); | ||
548 | return; | ||
549 | } | ||
550 | 506 | ||
551 | p_slot->hpc_ops->get_power_status(p_slot, &getstatus); | 507 | p_slot->hpc_ops->get_power_status(p_slot, &getstatus); |
552 | if (getstatus) { | 508 | if (getstatus) { |
553 | p_slot->state = POWEROFF_STATE; | 509 | p_slot->state = POWEROFF_STATE; |
554 | |||
555 | shpchp_disable_slot(p_slot); | 510 | shpchp_disable_slot(p_slot); |
556 | p_slot->state = STATIC_STATE; | 511 | p_slot->state = STATIC_STATE; |
557 | } else { | 512 | } else { |
558 | p_slot->state = POWERON_STATE; | 513 | p_slot->state = POWERON_STATE; |
559 | |||
560 | if (shpchp_enable_slot(p_slot)) | 514 | if (shpchp_enable_slot(p_slot)) |
561 | p_slot->hpc_ops->green_led_off(p_slot); | 515 | p_slot->hpc_ops->green_led_off(p_slot); |
562 | |||
563 | p_slot->state = STATIC_STATE; | 516 | p_slot->state = STATIC_STATE; |
564 | } | 517 | } |
565 | |||
566 | return; | ||
567 | } | ||
568 | |||
569 | |||
570 | /* this is the main worker thread */ | ||
571 | static int event_thread(void* data) | ||
572 | { | ||
573 | struct controller *ctrl; | ||
574 | lock_kernel(); | ||
575 | daemonize("shpchpd_event"); | ||
576 | unlock_kernel(); | ||
577 | |||
578 | while (1) { | ||
579 | dbg("!!!!event_thread sleeping\n"); | ||
580 | down_interruptible (&event_semaphore); | ||
581 | dbg("event_thread woken finished = %d\n", event_finished); | ||
582 | if (event_finished || signal_pending(current)) | ||
583 | break; | ||
584 | /* Do stuff here */ | ||
585 | if (pushbutton_pending) | ||
586 | shpchp_pushbutton_thread(pushbutton_pending); | ||
587 | else | ||
588 | list_for_each_entry(ctrl, &shpchp_ctrl_list, ctrl_list) | ||
589 | interrupt_event_handler(ctrl); | ||
590 | } | ||
591 | dbg("event_thread signals exit\n"); | ||
592 | up(&event_exit); | ||
593 | return 0; | ||
594 | } | ||
595 | |||
596 | int shpchp_event_start_thread (void) | ||
597 | { | ||
598 | int pid; | ||
599 | |||
600 | /* initialize our semaphores */ | ||
601 | init_MUTEX_LOCKED(&event_exit); | ||
602 | event_finished=0; | ||
603 | |||
604 | init_MUTEX_LOCKED(&event_semaphore); | ||
605 | pid = kernel_thread(event_thread, NULL, 0); | ||
606 | |||
607 | if (pid < 0) { | ||
608 | err ("Can't start up our event thread\n"); | ||
609 | return -1; | ||
610 | } | ||
611 | return 0; | ||
612 | } | ||
613 | |||
614 | |||
615 | void shpchp_event_stop_thread (void) | ||
616 | { | ||
617 | event_finished = 1; | ||
618 | up(&event_semaphore); | ||
619 | down(&event_exit); | ||
620 | } | 518 | } |
621 | 519 | ||
622 | |||
623 | static int update_slot_info (struct slot *slot) | 520 | static int update_slot_info (struct slot *slot) |
624 | { | 521 | { |
625 | struct hotplug_slot_info *info; | 522 | struct hotplug_slot_info *info; |
@@ -639,91 +536,59 @@ static int update_slot_info (struct slot *slot) | |||
639 | return result; | 536 | return result; |
640 | } | 537 | } |
641 | 538 | ||
642 | static void interrupt_event_handler(struct controller *ctrl) | 539 | static void interrupt_event_handler(void *data) |
643 | { | 540 | { |
644 | int loop = 0; | 541 | struct event_info *info = data; |
645 | int change = 1; | 542 | struct slot *p_slot = info->p_slot; |
646 | u8 hp_slot; | ||
647 | u8 getstatus; | 543 | u8 getstatus; |
648 | struct slot *p_slot; | ||
649 | 544 | ||
650 | while (change) { | 545 | switch (info->event_type) { |
651 | change = 0; | 546 | case INT_BUTTON_CANCEL: |
652 | 547 | dbg("%s: button cancel\n", __FUNCTION__); | |
653 | for (loop = 0; loop < 10; loop++) { | 548 | cancel_delayed_work(&p_slot->work); |
654 | if (ctrl->event_queue[loop].event_type != 0) { | 549 | switch (p_slot->state) { |
655 | dbg("%s:loop %x event_type %x\n", __FUNCTION__, loop, | 550 | case BLINKINGOFF_STATE: |
656 | ctrl->event_queue[loop].event_type); | 551 | p_slot->hpc_ops->green_led_on(p_slot); |
657 | hp_slot = ctrl->event_queue[loop].hp_slot; | 552 | p_slot->hpc_ops->set_attention_status(p_slot, 0); |
658 | 553 | break; | |
659 | p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); | 554 | case BLINKINGON_STATE: |
660 | 555 | p_slot->hpc_ops->green_led_off(p_slot); | |
661 | if (ctrl->event_queue[loop].event_type == INT_BUTTON_CANCEL) { | 556 | p_slot->hpc_ops->set_attention_status(p_slot, 0); |
662 | dbg("%s: button cancel\n", __FUNCTION__); | 557 | break; |
663 | del_timer(&p_slot->task_event); | 558 | default: |
664 | 559 | warn("Not a valid state\n"); | |
665 | switch (p_slot->state) { | 560 | return; |
666 | case BLINKINGOFF_STATE: | 561 | } |
667 | p_slot->hpc_ops->green_led_on(p_slot); | 562 | info(msg_button_cancel, p_slot->number); |
668 | p_slot->hpc_ops->set_attention_status(p_slot, 0); | 563 | p_slot->state = STATIC_STATE; |
669 | break; | 564 | break; |
670 | case BLINKINGON_STATE: | 565 | case INT_BUTTON_PRESS: |
671 | p_slot->hpc_ops->green_led_off(p_slot); | 566 | dbg("%s: Button pressed\n", __FUNCTION__); |
672 | p_slot->hpc_ops->set_attention_status(p_slot, 0); | 567 | p_slot->hpc_ops->get_power_status(p_slot, &getstatus); |
673 | break; | 568 | if (getstatus) { |
674 | default: | 569 | p_slot->state = BLINKINGOFF_STATE; |
675 | warn("Not a valid state\n"); | 570 | info(msg_button_off, p_slot->number); |
676 | return; | 571 | } else { |
677 | } | 572 | p_slot->state = BLINKINGON_STATE; |
678 | info(msg_button_cancel, p_slot->number); | 573 | info(msg_button_on, p_slot->number); |
679 | p_slot->state = STATIC_STATE; | 574 | } |
680 | } else if (ctrl->event_queue[loop].event_type == INT_BUTTON_PRESS) { | 575 | /* blink green LED and turn off amber */ |
681 | /* Button Pressed (No action on 1st press...) */ | 576 | p_slot->hpc_ops->green_led_blink(p_slot); |
682 | dbg("%s: Button pressed\n", __FUNCTION__); | 577 | p_slot->hpc_ops->set_attention_status(p_slot, 0); |
683 | |||
684 | p_slot->hpc_ops->get_power_status(p_slot, &getstatus); | ||
685 | if (getstatus) { | ||
686 | /* slot is on */ | ||
687 | dbg("%s: slot is on\n", __FUNCTION__); | ||
688 | p_slot->state = BLINKINGOFF_STATE; | ||
689 | info(msg_button_off, p_slot->number); | ||
690 | } else { | ||
691 | /* slot is off */ | ||
692 | dbg("%s: slot is off\n", __FUNCTION__); | ||
693 | p_slot->state = BLINKINGON_STATE; | ||
694 | info(msg_button_on, p_slot->number); | ||
695 | } | ||
696 | |||
697 | /* blink green LED and turn off amber */ | ||
698 | p_slot->hpc_ops->green_led_blink(p_slot); | ||
699 | p_slot->hpc_ops->set_attention_status(p_slot, 0); | ||
700 | |||
701 | init_timer(&p_slot->task_event); | ||
702 | p_slot->task_event.expires = jiffies + 5 * HZ; /* 5 second delay */ | ||
703 | p_slot->task_event.function = (void (*)(unsigned long)) pushbutton_helper_thread; | ||
704 | p_slot->task_event.data = (unsigned long) p_slot; | ||
705 | |||
706 | dbg("%s: add_timer p_slot = %p\n", __FUNCTION__,(void *) p_slot); | ||
707 | add_timer(&p_slot->task_event); | ||
708 | } else if (ctrl->event_queue[loop].event_type == INT_POWER_FAULT) { | ||
709 | /***********POWER FAULT********************/ | ||
710 | dbg("%s: power fault\n", __FUNCTION__); | ||
711 | p_slot->hpc_ops->set_attention_status(p_slot, 1); | ||
712 | p_slot->hpc_ops->green_led_off(p_slot); | ||
713 | } else { | ||
714 | /* refresh notification */ | ||
715 | if (p_slot) | ||
716 | update_slot_info(p_slot); | ||
717 | } | ||
718 | |||
719 | ctrl->event_queue[loop].event_type = 0; | ||
720 | 578 | ||
721 | change = 1; | 579 | queue_delayed_work(shpchp_wq, &p_slot->work, 5*HZ); |
722 | } | 580 | break; |
723 | } /* End of FOR loop */ | 581 | case INT_POWER_FAULT: |
582 | dbg("%s: power fault\n", __FUNCTION__); | ||
583 | p_slot->hpc_ops->set_attention_status(p_slot, 1); | ||
584 | p_slot->hpc_ops->green_led_off(p_slot); | ||
585 | break; | ||
586 | default: | ||
587 | update_slot_info(p_slot); | ||
588 | break; | ||
724 | } | 589 | } |
725 | 590 | ||
726 | return; | 591 | kfree(info); |
727 | } | 592 | } |
728 | 593 | ||
729 | 594 | ||