aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/ipmi/ipmi_poweroff.c
diff options
context:
space:
mode:
authorCorey Minyard <cminyard@mvista.com>2008-04-29 04:01:02 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-29 11:06:14 -0400
commitbda4c30aa6f7dc1483f39ea1dfe37bcab8a96207 (patch)
tree760c538139c5b41ef54a27d62e5a8a1b01cf1c60 /drivers/char/ipmi/ipmi_poweroff.c
parent4ea18425436e7c72716b7f8d314775f399821195 (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.c20
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. */
102static atomic_t dummy_count = ATOMIC_INIT(0);
102static void dummy_smi_free(struct ipmi_smi_msg *msg) 103static void dummy_smi_free(struct ipmi_smi_msg *msg)
103{ 104{
105 atomic_dec(&dummy_count);
104} 106}
105static void dummy_recv_free(struct ipmi_recv_msg *msg) 107static void dummy_recv_free(struct ipmi_recv_msg *msg)
106{ 108{
109 atomic_dec(&dummy_count);
107} 110}
108static struct ipmi_smi_msg halt_smi_msg = 111static 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. */
156static int ipmi_request_in_rc_mode(ipmi_user_t user, 159static 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