diff options
author | Corey Minyard <minyard@acm.org> | 2006-03-31 05:30:41 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-03-31 15:18:54 -0500 |
commit | d6dfd1310d3562698fd7c3c086f6c239f96394ac (patch) | |
tree | ff6c77f2d2e8bcb5b765bdaa4198243e043031aa /drivers/char | |
parent | 8a3628d53fe5eb1d1401dd1ce16655182c1c5ffc (diff) |
[PATCH] IPMI: convert from semaphores to mutexes
Convert the remaining semaphores to mutexes in the IPMI driver. The
watchdog was using a semaphore as a real semaphore (for IPC), so the
conversion there required adding a completion.
Signed-off-by: Corey Minyard <minyard@acm.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/ipmi/ipmi_devintf.c | 18 | ||||
-rw-r--r-- | drivers/char/ipmi/ipmi_msghandler.c | 23 | ||||
-rw-r--r-- | drivers/char/ipmi/ipmi_si_intf.c | 24 | ||||
-rw-r--r-- | drivers/char/ipmi/ipmi_watchdog.c | 53 |
4 files changed, 63 insertions, 55 deletions
diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c index 932feedda262..e1c95374984c 100644 --- a/drivers/char/ipmi/ipmi_devintf.c +++ b/drivers/char/ipmi/ipmi_devintf.c | |||
@@ -42,7 +42,7 @@ | |||
42 | #include <linux/slab.h> | 42 | #include <linux/slab.h> |
43 | #include <linux/devfs_fs_kernel.h> | 43 | #include <linux/devfs_fs_kernel.h> |
44 | #include <linux/ipmi.h> | 44 | #include <linux/ipmi.h> |
45 | #include <asm/semaphore.h> | 45 | #include <linux/mutex.h> |
46 | #include <linux/init.h> | 46 | #include <linux/init.h> |
47 | #include <linux/device.h> | 47 | #include <linux/device.h> |
48 | #include <linux/compat.h> | 48 | #include <linux/compat.h> |
@@ -55,7 +55,7 @@ struct ipmi_file_private | |||
55 | struct file *file; | 55 | struct file *file; |
56 | struct fasync_struct *fasync_queue; | 56 | struct fasync_struct *fasync_queue; |
57 | wait_queue_head_t wait; | 57 | wait_queue_head_t wait; |
58 | struct semaphore recv_sem; | 58 | struct mutex recv_mutex; |
59 | int default_retries; | 59 | int default_retries; |
60 | unsigned int default_retry_time_ms; | 60 | unsigned int default_retry_time_ms; |
61 | }; | 61 | }; |
@@ -141,7 +141,7 @@ static int ipmi_open(struct inode *inode, struct file *file) | |||
141 | INIT_LIST_HEAD(&(priv->recv_msgs)); | 141 | INIT_LIST_HEAD(&(priv->recv_msgs)); |
142 | init_waitqueue_head(&priv->wait); | 142 | init_waitqueue_head(&priv->wait); |
143 | priv->fasync_queue = NULL; | 143 | priv->fasync_queue = NULL; |
144 | sema_init(&(priv->recv_sem), 1); | 144 | mutex_init(&priv->recv_mutex); |
145 | 145 | ||
146 | /* Use the low-level defaults. */ | 146 | /* Use the low-level defaults. */ |
147 | priv->default_retries = -1; | 147 | priv->default_retries = -1; |
@@ -285,15 +285,15 @@ static int ipmi_ioctl(struct inode *inode, | |||
285 | break; | 285 | break; |
286 | } | 286 | } |
287 | 287 | ||
288 | /* We claim a semaphore because we don't want two | 288 | /* We claim a mutex because we don't want two |
289 | users getting something from the queue at a time. | 289 | users getting something from the queue at a time. |
290 | Since we have to release the spinlock before we can | 290 | Since we have to release the spinlock before we can |
291 | copy the data to the user, it's possible another | 291 | copy the data to the user, it's possible another |
292 | user will grab something from the queue, too. Then | 292 | user will grab something from the queue, too. Then |
293 | the messages might get out of order if something | 293 | the messages might get out of order if something |
294 | fails and the message gets put back onto the | 294 | fails and the message gets put back onto the |
295 | queue. This semaphore prevents that problem. */ | 295 | queue. This mutex prevents that problem. */ |
296 | down(&(priv->recv_sem)); | 296 | mutex_lock(&priv->recv_mutex); |
297 | 297 | ||
298 | /* Grab the message off the list. */ | 298 | /* Grab the message off the list. */ |
299 | spin_lock_irqsave(&(priv->recv_msg_lock), flags); | 299 | spin_lock_irqsave(&(priv->recv_msg_lock), flags); |
@@ -352,7 +352,7 @@ static int ipmi_ioctl(struct inode *inode, | |||
352 | goto recv_putback_on_err; | 352 | goto recv_putback_on_err; |
353 | } | 353 | } |
354 | 354 | ||
355 | up(&(priv->recv_sem)); | 355 | mutex_unlock(&priv->recv_mutex); |
356 | ipmi_free_recv_msg(msg); | 356 | ipmi_free_recv_msg(msg); |
357 | break; | 357 | break; |
358 | 358 | ||
@@ -362,11 +362,11 @@ static int ipmi_ioctl(struct inode *inode, | |||
362 | spin_lock_irqsave(&(priv->recv_msg_lock), flags); | 362 | spin_lock_irqsave(&(priv->recv_msg_lock), flags); |
363 | list_add(entry, &(priv->recv_msgs)); | 363 | list_add(entry, &(priv->recv_msgs)); |
364 | spin_unlock_irqrestore(&(priv->recv_msg_lock), flags); | 364 | spin_unlock_irqrestore(&(priv->recv_msg_lock), flags); |
365 | up(&(priv->recv_sem)); | 365 | mutex_unlock(&priv->recv_mutex); |
366 | break; | 366 | break; |
367 | 367 | ||
368 | recv_err: | 368 | recv_err: |
369 | up(&(priv->recv_sem)); | 369 | mutex_unlock(&priv->recv_mutex); |
370 | break; | 370 | break; |
371 | } | 371 | } |
372 | 372 | ||
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index c0c862cce1c3..0ded046d5aa8 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <linux/sched.h> | 38 | #include <linux/sched.h> |
39 | #include <linux/poll.h> | 39 | #include <linux/poll.h> |
40 | #include <linux/spinlock.h> | 40 | #include <linux/spinlock.h> |
41 | #include <linux/mutex.h> | ||
41 | #include <linux/slab.h> | 42 | #include <linux/slab.h> |
42 | #include <linux/ipmi.h> | 43 | #include <linux/ipmi.h> |
43 | #include <linux/ipmi_smi.h> | 44 | #include <linux/ipmi_smi.h> |
@@ -234,7 +235,7 @@ struct ipmi_smi | |||
234 | 235 | ||
235 | /* The list of command receivers that are registered for commands | 236 | /* The list of command receivers that are registered for commands |
236 | on this interface. */ | 237 | on this interface. */ |
237 | struct semaphore cmd_rcvrs_lock; | 238 | struct mutex cmd_rcvrs_mutex; |
238 | struct list_head cmd_rcvrs; | 239 | struct list_head cmd_rcvrs; |
239 | 240 | ||
240 | /* Events that were queues because no one was there to receive | 241 | /* Events that were queues because no one was there to receive |
@@ -387,10 +388,10 @@ static void clean_up_interface_data(ipmi_smi_t intf) | |||
387 | 388 | ||
388 | /* Wholesale remove all the entries from the list in the | 389 | /* Wholesale remove all the entries from the list in the |
389 | * interface and wait for RCU to know that none are in use. */ | 390 | * interface and wait for RCU to know that none are in use. */ |
390 | down(&intf->cmd_rcvrs_lock); | 391 | mutex_lock(&intf->cmd_rcvrs_mutex); |
391 | list_add_rcu(&list, &intf->cmd_rcvrs); | 392 | list_add_rcu(&list, &intf->cmd_rcvrs); |
392 | list_del_rcu(&intf->cmd_rcvrs); | 393 | list_del_rcu(&intf->cmd_rcvrs); |
393 | up(&intf->cmd_rcvrs_lock); | 394 | mutex_unlock(&intf->cmd_rcvrs_mutex); |
394 | synchronize_rcu(); | 395 | synchronize_rcu(); |
395 | 396 | ||
396 | list_for_each_entry_safe(rcvr, rcvr2, &list, link) | 397 | list_for_each_entry_safe(rcvr, rcvr2, &list, link) |
@@ -846,7 +847,7 @@ int ipmi_destroy_user(ipmi_user_t user) | |||
846 | * since other things may be using it till we do | 847 | * since other things may be using it till we do |
847 | * synchronize_rcu()) then free everything in that list. | 848 | * synchronize_rcu()) then free everything in that list. |
848 | */ | 849 | */ |
849 | down(&intf->cmd_rcvrs_lock); | 850 | mutex_lock(&intf->cmd_rcvrs_mutex); |
850 | list_for_each_entry_rcu(rcvr, &intf->cmd_rcvrs, link) { | 851 | list_for_each_entry_rcu(rcvr, &intf->cmd_rcvrs, link) { |
851 | if (rcvr->user == user) { | 852 | if (rcvr->user == user) { |
852 | list_del_rcu(&rcvr->link); | 853 | list_del_rcu(&rcvr->link); |
@@ -854,7 +855,7 @@ int ipmi_destroy_user(ipmi_user_t user) | |||
854 | rcvrs = rcvr; | 855 | rcvrs = rcvr; |
855 | } | 856 | } |
856 | } | 857 | } |
857 | up(&intf->cmd_rcvrs_lock); | 858 | mutex_unlock(&intf->cmd_rcvrs_mutex); |
858 | synchronize_rcu(); | 859 | synchronize_rcu(); |
859 | while (rcvrs) { | 860 | while (rcvrs) { |
860 | rcvr = rcvrs; | 861 | rcvr = rcvrs; |
@@ -984,7 +985,7 @@ int ipmi_register_for_cmd(ipmi_user_t user, | |||
984 | rcvr->netfn = netfn; | 985 | rcvr->netfn = netfn; |
985 | rcvr->user = user; | 986 | rcvr->user = user; |
986 | 987 | ||
987 | down(&intf->cmd_rcvrs_lock); | 988 | mutex_lock(&intf->cmd_rcvrs_mutex); |
988 | /* Make sure the command/netfn is not already registered. */ | 989 | /* Make sure the command/netfn is not already registered. */ |
989 | entry = find_cmd_rcvr(intf, netfn, cmd); | 990 | entry = find_cmd_rcvr(intf, netfn, cmd); |
990 | if (entry) { | 991 | if (entry) { |
@@ -995,7 +996,7 @@ int ipmi_register_for_cmd(ipmi_user_t user, | |||
995 | list_add_rcu(&rcvr->link, &intf->cmd_rcvrs); | 996 | list_add_rcu(&rcvr->link, &intf->cmd_rcvrs); |
996 | 997 | ||
997 | out_unlock: | 998 | out_unlock: |
998 | up(&intf->cmd_rcvrs_lock); | 999 | mutex_unlock(&intf->cmd_rcvrs_mutex); |
999 | if (rv) | 1000 | if (rv) |
1000 | kfree(rcvr); | 1001 | kfree(rcvr); |
1001 | 1002 | ||
@@ -1009,17 +1010,17 @@ int ipmi_unregister_for_cmd(ipmi_user_t user, | |||
1009 | ipmi_smi_t intf = user->intf; | 1010 | ipmi_smi_t intf = user->intf; |
1010 | struct cmd_rcvr *rcvr; | 1011 | struct cmd_rcvr *rcvr; |
1011 | 1012 | ||
1012 | down(&intf->cmd_rcvrs_lock); | 1013 | mutex_lock(&intf->cmd_rcvrs_mutex); |
1013 | /* Make sure the command/netfn is not already registered. */ | 1014 | /* Make sure the command/netfn is not already registered. */ |
1014 | rcvr = find_cmd_rcvr(intf, netfn, cmd); | 1015 | rcvr = find_cmd_rcvr(intf, netfn, cmd); |
1015 | if ((rcvr) && (rcvr->user == user)) { | 1016 | if ((rcvr) && (rcvr->user == user)) { |
1016 | list_del_rcu(&rcvr->link); | 1017 | list_del_rcu(&rcvr->link); |
1017 | up(&intf->cmd_rcvrs_lock); | 1018 | mutex_unlock(&intf->cmd_rcvrs_mutex); |
1018 | synchronize_rcu(); | 1019 | synchronize_rcu(); |
1019 | kfree(rcvr); | 1020 | kfree(rcvr); |
1020 | return 0; | 1021 | return 0; |
1021 | } else { | 1022 | } else { |
1022 | up(&intf->cmd_rcvrs_lock); | 1023 | mutex_unlock(&intf->cmd_rcvrs_mutex); |
1023 | return -ENOENT; | 1024 | return -ENOENT; |
1024 | } | 1025 | } |
1025 | } | 1026 | } |
@@ -2365,7 +2366,7 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers, | |||
2365 | spin_lock_init(&intf->events_lock); | 2366 | spin_lock_init(&intf->events_lock); |
2366 | INIT_LIST_HEAD(&intf->waiting_events); | 2367 | INIT_LIST_HEAD(&intf->waiting_events); |
2367 | intf->waiting_events_count = 0; | 2368 | intf->waiting_events_count = 0; |
2368 | init_MUTEX(&intf->cmd_rcvrs_lock); | 2369 | mutex_init(&intf->cmd_rcvrs_mutex); |
2369 | INIT_LIST_HEAD(&intf->cmd_rcvrs); | 2370 | INIT_LIST_HEAD(&intf->cmd_rcvrs); |
2370 | init_waitqueue_head(&intf->waitq); | 2371 | init_waitqueue_head(&intf->waitq); |
2371 | 2372 | ||
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 2da5845a383a..a86c0f29953e 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c | |||
@@ -1014,7 +1014,7 @@ static struct ipmi_smi_handlers handlers = | |||
1014 | 1014 | ||
1015 | #define SI_MAX_PARMS 4 | 1015 | #define SI_MAX_PARMS 4 |
1016 | static LIST_HEAD(smi_infos); | 1016 | static LIST_HEAD(smi_infos); |
1017 | static DECLARE_MUTEX(smi_infos_lock); | 1017 | static DEFINE_MUTEX(smi_infos_lock); |
1018 | static int smi_num; /* Used to sequence the SMIs */ | 1018 | static int smi_num; /* Used to sequence the SMIs */ |
1019 | 1019 | ||
1020 | #define DEFAULT_REGSPACING 1 | 1020 | #define DEFAULT_REGSPACING 1 |
@@ -2276,7 +2276,7 @@ static int try_smi_init(struct smi_info *new_smi) | |||
2276 | new_smi->slave_addr, new_smi->irq); | 2276 | new_smi->slave_addr, new_smi->irq); |
2277 | } | 2277 | } |
2278 | 2278 | ||
2279 | down(&smi_infos_lock); | 2279 | mutex_lock(&smi_infos_lock); |
2280 | if (!is_new_interface(new_smi)) { | 2280 | if (!is_new_interface(new_smi)) { |
2281 | printk(KERN_WARNING "ipmi_si: duplicate interface\n"); | 2281 | printk(KERN_WARNING "ipmi_si: duplicate interface\n"); |
2282 | rv = -EBUSY; | 2282 | rv = -EBUSY; |
@@ -2432,7 +2432,7 @@ static int try_smi_init(struct smi_info *new_smi) | |||
2432 | 2432 | ||
2433 | list_add_tail(&new_smi->link, &smi_infos); | 2433 | list_add_tail(&new_smi->link, &smi_infos); |
2434 | 2434 | ||
2435 | up(&smi_infos_lock); | 2435 | mutex_unlock(&smi_infos_lock); |
2436 | 2436 | ||
2437 | printk(" IPMI %s interface initialized\n",si_to_str[new_smi->si_type]); | 2437 | printk(" IPMI %s interface initialized\n",si_to_str[new_smi->si_type]); |
2438 | 2438 | ||
@@ -2469,7 +2469,7 @@ static int try_smi_init(struct smi_info *new_smi) | |||
2469 | 2469 | ||
2470 | kfree(new_smi); | 2470 | kfree(new_smi); |
2471 | 2471 | ||
2472 | up(&smi_infos_lock); | 2472 | mutex_unlock(&smi_infos_lock); |
2473 | 2473 | ||
2474 | return rv; | 2474 | return rv; |
2475 | } | 2475 | } |
@@ -2527,26 +2527,26 @@ static __devinit int init_ipmi_si(void) | |||
2527 | #endif | 2527 | #endif |
2528 | 2528 | ||
2529 | if (si_trydefaults) { | 2529 | if (si_trydefaults) { |
2530 | down(&smi_infos_lock); | 2530 | mutex_lock(&smi_infos_lock); |
2531 | if (list_empty(&smi_infos)) { | 2531 | if (list_empty(&smi_infos)) { |
2532 | /* No BMC was found, try defaults. */ | 2532 | /* No BMC was found, try defaults. */ |
2533 | up(&smi_infos_lock); | 2533 | mutex_unlock(&smi_infos_lock); |
2534 | default_find_bmc(); | 2534 | default_find_bmc(); |
2535 | } else { | 2535 | } else { |
2536 | up(&smi_infos_lock); | 2536 | mutex_unlock(&smi_infos_lock); |
2537 | } | 2537 | } |
2538 | } | 2538 | } |
2539 | 2539 | ||
2540 | down(&smi_infos_lock); | 2540 | mutex_lock(&smi_infos_lock); |
2541 | if (list_empty(&smi_infos)) { | 2541 | if (list_empty(&smi_infos)) { |
2542 | up(&smi_infos_lock); | 2542 | mutex_unlock(&smi_infos_lock); |
2543 | #ifdef CONFIG_PCI | 2543 | #ifdef CONFIG_PCI |
2544 | pci_unregister_driver(&ipmi_pci_driver); | 2544 | pci_unregister_driver(&ipmi_pci_driver); |
2545 | #endif | 2545 | #endif |
2546 | printk("ipmi_si: Unable to find any System Interface(s)\n"); | 2546 | printk("ipmi_si: Unable to find any System Interface(s)\n"); |
2547 | return -ENODEV; | 2547 | return -ENODEV; |
2548 | } else { | 2548 | } else { |
2549 | up(&smi_infos_lock); | 2549 | mutex_unlock(&smi_infos_lock); |
2550 | return 0; | 2550 | return 0; |
2551 | } | 2551 | } |
2552 | } | 2552 | } |
@@ -2622,10 +2622,10 @@ static __exit void cleanup_ipmi_si(void) | |||
2622 | pci_unregister_driver(&ipmi_pci_driver); | 2622 | pci_unregister_driver(&ipmi_pci_driver); |
2623 | #endif | 2623 | #endif |
2624 | 2624 | ||
2625 | down(&smi_infos_lock); | 2625 | mutex_lock(&smi_infos_lock); |
2626 | list_for_each_entry_safe(e, tmp_e, &smi_infos, link) | 2626 | list_for_each_entry_safe(e, tmp_e, &smi_infos, link) |
2627 | cleanup_one_si(e); | 2627 | cleanup_one_si(e); |
2628 | up(&smi_infos_lock); | 2628 | mutex_unlock(&smi_infos_lock); |
2629 | 2629 | ||
2630 | driver_unregister(&ipmi_driver); | 2630 | driver_unregister(&ipmi_driver); |
2631 | } | 2631 | } |
diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c index 2872c9575528..2d11ddd99e55 100644 --- a/drivers/char/ipmi/ipmi_watchdog.c +++ b/drivers/char/ipmi/ipmi_watchdog.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #include <linux/watchdog.h> | 39 | #include <linux/watchdog.h> |
40 | #include <linux/miscdevice.h> | 40 | #include <linux/miscdevice.h> |
41 | #include <linux/init.h> | 41 | #include <linux/init.h> |
42 | #include <linux/completion.h> | ||
42 | #include <linux/rwsem.h> | 43 | #include <linux/rwsem.h> |
43 | #include <linux/errno.h> | 44 | #include <linux/errno.h> |
44 | #include <asm/uaccess.h> | 45 | #include <asm/uaccess.h> |
@@ -303,21 +304,22 @@ static int ipmi_heartbeat(void); | |||
303 | static void panic_halt_ipmi_heartbeat(void); | 304 | static void panic_halt_ipmi_heartbeat(void); |
304 | 305 | ||
305 | 306 | ||
306 | /* We use a semaphore to make sure that only one thing can send a set | 307 | /* We use a mutex to make sure that only one thing can send a set |
307 | timeout at one time, because we only have one copy of the data. | 308 | timeout at one time, because we only have one copy of the data. |
308 | The semaphore is claimed when the set_timeout is sent and freed | 309 | The mutex is claimed when the set_timeout is sent and freed |
309 | when both messages are free. */ | 310 | when both messages are free. */ |
310 | static atomic_t set_timeout_tofree = ATOMIC_INIT(0); | 311 | static atomic_t set_timeout_tofree = ATOMIC_INIT(0); |
311 | static DECLARE_MUTEX(set_timeout_lock); | 312 | static DEFINE_MUTEX(set_timeout_lock); |
313 | static DECLARE_COMPLETION(set_timeout_wait); | ||
312 | static void set_timeout_free_smi(struct ipmi_smi_msg *msg) | 314 | static void set_timeout_free_smi(struct ipmi_smi_msg *msg) |
313 | { | 315 | { |
314 | if (atomic_dec_and_test(&set_timeout_tofree)) | 316 | if (atomic_dec_and_test(&set_timeout_tofree)) |
315 | up(&set_timeout_lock); | 317 | complete(&set_timeout_wait); |
316 | } | 318 | } |
317 | static void set_timeout_free_recv(struct ipmi_recv_msg *msg) | 319 | static void set_timeout_free_recv(struct ipmi_recv_msg *msg) |
318 | { | 320 | { |
319 | if (atomic_dec_and_test(&set_timeout_tofree)) | 321 | if (atomic_dec_and_test(&set_timeout_tofree)) |
320 | up(&set_timeout_lock); | 322 | complete(&set_timeout_wait); |
321 | } | 323 | } |
322 | static struct ipmi_smi_msg set_timeout_smi_msg = | 324 | static struct ipmi_smi_msg set_timeout_smi_msg = |
323 | { | 325 | { |
@@ -399,7 +401,7 @@ static int ipmi_set_timeout(int do_heartbeat) | |||
399 | 401 | ||
400 | 402 | ||
401 | /* We can only send one of these at a time. */ | 403 | /* We can only send one of these at a time. */ |
402 | down(&set_timeout_lock); | 404 | mutex_lock(&set_timeout_lock); |
403 | 405 | ||
404 | atomic_set(&set_timeout_tofree, 2); | 406 | atomic_set(&set_timeout_tofree, 2); |
405 | 407 | ||
@@ -407,16 +409,21 @@ static int ipmi_set_timeout(int do_heartbeat) | |||
407 | &set_timeout_recv_msg, | 409 | &set_timeout_recv_msg, |
408 | &send_heartbeat_now); | 410 | &send_heartbeat_now); |
409 | if (rv) { | 411 | if (rv) { |
410 | up(&set_timeout_lock); | 412 | mutex_unlock(&set_timeout_lock); |
411 | } else { | 413 | goto out; |
412 | if ((do_heartbeat == IPMI_SET_TIMEOUT_FORCE_HB) | 414 | } |
413 | || ((send_heartbeat_now) | 415 | |
414 | && (do_heartbeat == IPMI_SET_TIMEOUT_HB_IF_NECESSARY))) | 416 | wait_for_completion(&set_timeout_wait); |
415 | { | 417 | |
416 | rv = ipmi_heartbeat(); | 418 | if ((do_heartbeat == IPMI_SET_TIMEOUT_FORCE_HB) |
417 | } | 419 | || ((send_heartbeat_now) |
420 | && (do_heartbeat == IPMI_SET_TIMEOUT_HB_IF_NECESSARY))) | ||
421 | { | ||
422 | rv = ipmi_heartbeat(); | ||
418 | } | 423 | } |
424 | mutex_unlock(&set_timeout_lock); | ||
419 | 425 | ||
426 | out: | ||
420 | return rv; | 427 | return rv; |
421 | } | 428 | } |
422 | 429 | ||
@@ -458,17 +465,17 @@ static void panic_halt_ipmi_set_timeout(void) | |||
458 | The semaphore is claimed when the set_timeout is sent and freed | 465 | The semaphore is claimed when the set_timeout is sent and freed |
459 | when both messages are free. */ | 466 | when both messages are free. */ |
460 | static atomic_t heartbeat_tofree = ATOMIC_INIT(0); | 467 | static atomic_t heartbeat_tofree = ATOMIC_INIT(0); |
461 | static DECLARE_MUTEX(heartbeat_lock); | 468 | static DEFINE_MUTEX(heartbeat_lock); |
462 | static DECLARE_MUTEX_LOCKED(heartbeat_wait_lock); | 469 | static DECLARE_COMPLETION(heartbeat_wait); |
463 | static void heartbeat_free_smi(struct ipmi_smi_msg *msg) | 470 | static void heartbeat_free_smi(struct ipmi_smi_msg *msg) |
464 | { | 471 | { |
465 | if (atomic_dec_and_test(&heartbeat_tofree)) | 472 | if (atomic_dec_and_test(&heartbeat_tofree)) |
466 | up(&heartbeat_wait_lock); | 473 | complete(&heartbeat_wait); |
467 | } | 474 | } |
468 | static void heartbeat_free_recv(struct ipmi_recv_msg *msg) | 475 | static void heartbeat_free_recv(struct ipmi_recv_msg *msg) |
469 | { | 476 | { |
470 | if (atomic_dec_and_test(&heartbeat_tofree)) | 477 | if (atomic_dec_and_test(&heartbeat_tofree)) |
471 | up(&heartbeat_wait_lock); | 478 | complete(&heartbeat_wait); |
472 | } | 479 | } |
473 | static struct ipmi_smi_msg heartbeat_smi_msg = | 480 | static struct ipmi_smi_msg heartbeat_smi_msg = |
474 | { | 481 | { |
@@ -511,14 +518,14 @@ static int ipmi_heartbeat(void) | |||
511 | return ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY); | 518 | return ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY); |
512 | } | 519 | } |
513 | 520 | ||
514 | down(&heartbeat_lock); | 521 | mutex_lock(&heartbeat_lock); |
515 | 522 | ||
516 | atomic_set(&heartbeat_tofree, 2); | 523 | atomic_set(&heartbeat_tofree, 2); |
517 | 524 | ||
518 | /* Don't reset the timer if we have the timer turned off, that | 525 | /* Don't reset the timer if we have the timer turned off, that |
519 | re-enables the watchdog. */ | 526 | re-enables the watchdog. */ |
520 | if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE) { | 527 | if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE) { |
521 | up(&heartbeat_lock); | 528 | mutex_unlock(&heartbeat_lock); |
522 | return 0; | 529 | return 0; |
523 | } | 530 | } |
524 | 531 | ||
@@ -539,14 +546,14 @@ static int ipmi_heartbeat(void) | |||
539 | &heartbeat_recv_msg, | 546 | &heartbeat_recv_msg, |
540 | 1); | 547 | 1); |
541 | if (rv) { | 548 | if (rv) { |
542 | up(&heartbeat_lock); | 549 | mutex_unlock(&heartbeat_lock); |
543 | printk(KERN_WARNING PFX "heartbeat failure: %d\n", | 550 | printk(KERN_WARNING PFX "heartbeat failure: %d\n", |
544 | rv); | 551 | rv); |
545 | return rv; | 552 | return rv; |
546 | } | 553 | } |
547 | 554 | ||
548 | /* Wait for the heartbeat to be sent. */ | 555 | /* Wait for the heartbeat to be sent. */ |
549 | down(&heartbeat_wait_lock); | 556 | wait_for_completion(&heartbeat_wait); |
550 | 557 | ||
551 | if (heartbeat_recv_msg.msg.data[0] != 0) { | 558 | if (heartbeat_recv_msg.msg.data[0] != 0) { |
552 | /* Got an error in the heartbeat response. It was already | 559 | /* Got an error in the heartbeat response. It was already |
@@ -555,7 +562,7 @@ static int ipmi_heartbeat(void) | |||
555 | rv = -EINVAL; | 562 | rv = -EINVAL; |
556 | } | 563 | } |
557 | 564 | ||
558 | up(&heartbeat_lock); | 565 | mutex_unlock(&heartbeat_lock); |
559 | 566 | ||
560 | return rv; | 567 | return rv; |
561 | } | 568 | } |