diff options
author | Corey Minyard <cminyard@mvista.com> | 2008-04-29 04:01:02 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-29 11:06:14 -0400 |
commit | bda4c30aa6f7dc1483f39ea1dfe37bcab8a96207 (patch) | |
tree | 760c538139c5b41ef54a27d62e5a8a1b01cf1c60 /drivers/char/ipmi/ipmi_poweroff.c | |
parent | 4ea18425436e7c72716b7f8d314775f399821195 (diff) |
ipmi: run to completion fixes
The "run_to_completion" mode was somewhat broken. Locks need to be avoided in
run_to_completion mode, and it shouldn't be used by normal users, just
internally for panic situations.
This patch removes locks in run_to_completion mode and removes the user call
for setting the mode. The only user was the poweroff code, but it was easily
converted to use the polling interface.
[akpm@linux-foundation.org: coding-style fixes]
Signed-off-by: Corey Minyard <cminyard@mvista.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/char/ipmi/ipmi_poweroff.c')
-rw-r--r-- | drivers/char/ipmi/ipmi_poweroff.c | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/drivers/char/ipmi/ipmi_poweroff.c b/drivers/char/ipmi/ipmi_poweroff.c index b86186de7f07..b065a53d1ca8 100644 --- a/drivers/char/ipmi/ipmi_poweroff.c +++ b/drivers/char/ipmi/ipmi_poweroff.c | |||
@@ -99,11 +99,14 @@ static unsigned char ipmi_version; | |||
99 | allocate them, since we may be in a panic situation. The whole | 99 | allocate them, since we may be in a panic situation. The whole |
100 | thing is single-threaded, anyway, so multiple messages are not | 100 | thing is single-threaded, anyway, so multiple messages are not |
101 | required. */ | 101 | required. */ |
102 | static atomic_t dummy_count = ATOMIC_INIT(0); | ||
102 | static void dummy_smi_free(struct ipmi_smi_msg *msg) | 103 | static void dummy_smi_free(struct ipmi_smi_msg *msg) |
103 | { | 104 | { |
105 | atomic_dec(&dummy_count); | ||
104 | } | 106 | } |
105 | static void dummy_recv_free(struct ipmi_recv_msg *msg) | 107 | static void dummy_recv_free(struct ipmi_recv_msg *msg) |
106 | { | 108 | { |
109 | atomic_dec(&dummy_count); | ||
107 | } | 110 | } |
108 | static struct ipmi_smi_msg halt_smi_msg = | 111 | static struct ipmi_smi_msg halt_smi_msg = |
109 | { | 112 | { |
@@ -152,17 +155,28 @@ static int ipmi_request_wait_for_response(ipmi_user_t user, | |||
152 | return halt_recv_msg.msg.data[0]; | 155 | return halt_recv_msg.msg.data[0]; |
153 | } | 156 | } |
154 | 157 | ||
155 | /* We are in run-to-completion mode, no completion is desired. */ | 158 | /* Wait for message to complete, spinning. */ |
156 | static int ipmi_request_in_rc_mode(ipmi_user_t user, | 159 | static int ipmi_request_in_rc_mode(ipmi_user_t user, |
157 | struct ipmi_addr *addr, | 160 | struct ipmi_addr *addr, |
158 | struct kernel_ipmi_msg *send_msg) | 161 | struct kernel_ipmi_msg *send_msg) |
159 | { | 162 | { |
160 | int rv; | 163 | int rv; |
161 | 164 | ||
165 | atomic_set(&dummy_count, 2); | ||
162 | rv = ipmi_request_supply_msgs(user, addr, 0, send_msg, NULL, | 166 | rv = ipmi_request_supply_msgs(user, addr, 0, send_msg, NULL, |
163 | &halt_smi_msg, &halt_recv_msg, 0); | 167 | &halt_smi_msg, &halt_recv_msg, 0); |
164 | if (rv) | 168 | if (rv) { |
169 | atomic_set(&dummy_count, 0); | ||
165 | return rv; | 170 | return rv; |
171 | } | ||
172 | |||
173 | /* | ||
174 | * Spin until our message is done. | ||
175 | */ | ||
176 | while (atomic_read(&dummy_count) > 0) { | ||
177 | ipmi_poll_interface(user); | ||
178 | cpu_relax(); | ||
179 | } | ||
166 | 180 | ||
167 | return halt_recv_msg.msg.data[0]; | 181 | return halt_recv_msg.msg.data[0]; |
168 | } | 182 | } |
@@ -531,9 +545,7 @@ static void ipmi_poweroff_function (void) | |||
531 | return; | 545 | return; |
532 | 546 | ||
533 | /* Use run-to-completion mode, since interrupts may be off. */ | 547 | /* Use run-to-completion mode, since interrupts may be off. */ |
534 | ipmi_user_set_run_to_completion(ipmi_user, 1); | ||
535 | specific_poweroff_func(ipmi_user); | 548 | specific_poweroff_func(ipmi_user); |
536 | ipmi_user_set_run_to_completion(ipmi_user, 0); | ||
537 | } | 549 | } |
538 | 550 | ||
539 | /* Wait for an IPMI interface to be installed, the first one installed | 551 | /* Wait for an IPMI interface to be installed, the first one installed |