diff options
author | Max Asbock <masbock@us.ibm.com> | 2005-06-21 20:16:33 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-06-21 22:07:34 -0400 |
commit | b8acb808468a88a188d7c5aba3681c583a5785f9 (patch) | |
tree | 7a4e5367e05cc52bc8008baaa8c35ed05989ec60 /drivers/misc/ibmasm/ibmasmfs.c | |
parent | f5ccc842318efcd7c05dee3203dfdbbafae47bd6 (diff) |
[PATCH] ibmasm driver: correctly wake up sleeping threads
Due to my incomplete understanding of the wait_event_interruptible() function
threads waiting for service processor events were not woken up. This patch
fixes that problem.
Signed-off-by: Max Asbock <masbock@us.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/misc/ibmasm/ibmasmfs.c')
-rw-r--r-- | drivers/misc/ibmasm/ibmasmfs.c | 34 |
1 files changed, 26 insertions, 8 deletions
diff --git a/drivers/misc/ibmasm/ibmasmfs.c b/drivers/misc/ibmasm/ibmasmfs.c index 866e867e68f2..c87ef7d82b70 100644 --- a/drivers/misc/ibmasm/ibmasmfs.c +++ b/drivers/misc/ibmasm/ibmasmfs.c | |||
@@ -374,6 +374,7 @@ static int event_file_open(struct inode *inode, struct file *file) | |||
374 | ibmasm_event_reader_register(sp, &event_data->reader); | 374 | ibmasm_event_reader_register(sp, &event_data->reader); |
375 | 375 | ||
376 | event_data->sp = sp; | 376 | event_data->sp = sp; |
377 | event_data->active = 0; | ||
377 | file->private_data = event_data; | 378 | file->private_data = event_data; |
378 | return 0; | 379 | return 0; |
379 | } | 380 | } |
@@ -391,7 +392,9 @@ static ssize_t event_file_read(struct file *file, char __user *buf, size_t count | |||
391 | { | 392 | { |
392 | struct ibmasmfs_event_data *event_data = file->private_data; | 393 | struct ibmasmfs_event_data *event_data = file->private_data; |
393 | struct event_reader *reader = &event_data->reader; | 394 | struct event_reader *reader = &event_data->reader; |
395 | struct service_processor *sp = event_data->sp; | ||
394 | int ret; | 396 | int ret; |
397 | unsigned long flags; | ||
395 | 398 | ||
396 | if (*offset < 0) | 399 | if (*offset < 0) |
397 | return -EINVAL; | 400 | return -EINVAL; |
@@ -400,17 +403,32 @@ static ssize_t event_file_read(struct file *file, char __user *buf, size_t count | |||
400 | if (*offset != 0) | 403 | if (*offset != 0) |
401 | return 0; | 404 | return 0; |
402 | 405 | ||
403 | ret = ibmasm_get_next_event(event_data->sp, reader); | 406 | spin_lock_irqsave(&sp->lock, flags); |
407 | if (event_data->active) { | ||
408 | spin_unlock_irqrestore(&sp->lock, flags); | ||
409 | return -EBUSY; | ||
410 | } | ||
411 | event_data->active = 1; | ||
412 | spin_unlock_irqrestore(&sp->lock, flags); | ||
413 | |||
414 | ret = ibmasm_get_next_event(sp, reader); | ||
404 | if (ret <= 0) | 415 | if (ret <= 0) |
405 | return ret; | 416 | goto out; |
406 | 417 | ||
407 | if (count < reader->data_size) | 418 | if (count < reader->data_size) { |
408 | return -EINVAL; | 419 | ret = -EINVAL; |
420 | goto out; | ||
421 | } | ||
409 | 422 | ||
410 | if (copy_to_user(buf, reader->data, reader->data_size)) | 423 | if (copy_to_user(buf, reader->data, reader->data_size)) { |
411 | return -EFAULT; | 424 | ret = -EFAULT; |
425 | goto out; | ||
426 | } | ||
427 | ret = reader->data_size; | ||
412 | 428 | ||
413 | return reader->data_size; | 429 | out: |
430 | event_data->active = 0; | ||
431 | return ret; | ||
414 | } | 432 | } |
415 | 433 | ||
416 | static ssize_t event_file_write(struct file *file, const char __user *buf, size_t count, loff_t *offset) | 434 | static ssize_t event_file_write(struct file *file, const char __user *buf, size_t count, loff_t *offset) |
@@ -424,7 +442,7 @@ static ssize_t event_file_write(struct file *file, const char __user *buf, size_ | |||
424 | if (*offset != 0) | 442 | if (*offset != 0) |
425 | return 0; | 443 | return 0; |
426 | 444 | ||
427 | wake_up_interruptible(&event_data->reader.wait); | 445 | ibmasm_cancel_next_event(&event_data->reader); |
428 | return 0; | 446 | return 0; |
429 | } | 447 | } |
430 | 448 | ||