aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/ibmasm/ibmasmfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc/ibmasm/ibmasmfs.c')
-rw-r--r--drivers/misc/ibmasm/ibmasmfs.c34
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; 429out:
430 event_data->active = 0;
431 return ret;
414} 432}
415 433
416static ssize_t event_file_write(struct file *file, const char __user *buf, size_t count, loff_t *offset) 434static 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