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.c125
1 files changed, 27 insertions, 98 deletions
diff --git a/drivers/misc/ibmasm/ibmasmfs.c b/drivers/misc/ibmasm/ibmasmfs.c
index 866e867e68f2..5c550fcac2c4 100644
--- a/drivers/misc/ibmasm/ibmasmfs.c
+++ b/drivers/misc/ibmasm/ibmasmfs.c
@@ -37,9 +37,7 @@
37 * | |-- event 37 * | |-- event
38 * | |-- reverse_heartbeat 38 * | |-- reverse_heartbeat
39 * | `-- remote_video 39 * | `-- remote_video
40 * | |-- connected
41 * | |-- depth 40 * | |-- depth
42 * | |-- events
43 * | |-- height 41 * | |-- height
44 * | `-- width 42 * | `-- width
45 * . 43 * .
@@ -50,9 +48,7 @@
50 * |-- event 48 * |-- event
51 * |-- reverse_heartbeat 49 * |-- reverse_heartbeat
52 * `-- remote_video 50 * `-- remote_video
53 * |-- connected
54 * |-- depth 51 * |-- depth
55 * |-- events
56 * |-- height 52 * |-- height
57 * `-- width 53 * `-- width
58 * 54 *
@@ -75,14 +71,6 @@
75 * remote_video/width: control remote display settings 71 * remote_video/width: control remote display settings
76 * write: set value 72 * write: set value
77 * read: read value 73 * read: read value
78 *
79 * remote_video/connected
80 * read: return "1" if web browser VNC java applet is connected,
81 * "0" otherwise
82 *
83 * remote_video/events
84 * read: sleep until a remote mouse or keyboard event occurs, then return
85 * then event.
86 */ 74 */
87 75
88#include <linux/fs.h> 76#include <linux/fs.h>
@@ -333,7 +321,7 @@ static ssize_t command_file_write(struct file *file, const char __user *ubuff, s
333 if (command_data->command) 321 if (command_data->command)
334 return -EAGAIN; 322 return -EAGAIN;
335 323
336 cmd = ibmasm_new_command(count); 324 cmd = ibmasm_new_command(command_data->sp, count);
337 if (!cmd) 325 if (!cmd)
338 return -ENOMEM; 326 return -ENOMEM;
339 327
@@ -374,6 +362,7 @@ static int event_file_open(struct inode *inode, struct file *file)
374 ibmasm_event_reader_register(sp, &event_data->reader); 362 ibmasm_event_reader_register(sp, &event_data->reader);
375 363
376 event_data->sp = sp; 364 event_data->sp = sp;
365 event_data->active = 0;
377 file->private_data = event_data; 366 file->private_data = event_data;
378 return 0; 367 return 0;
379} 368}
@@ -391,7 +380,9 @@ static ssize_t event_file_read(struct file *file, char __user *buf, size_t count
391{ 380{
392 struct ibmasmfs_event_data *event_data = file->private_data; 381 struct ibmasmfs_event_data *event_data = file->private_data;
393 struct event_reader *reader = &event_data->reader; 382 struct event_reader *reader = &event_data->reader;
383 struct service_processor *sp = event_data->sp;
394 int ret; 384 int ret;
385 unsigned long flags;
395 386
396 if (*offset < 0) 387 if (*offset < 0)
397 return -EINVAL; 388 return -EINVAL;
@@ -400,17 +391,32 @@ static ssize_t event_file_read(struct file *file, char __user *buf, size_t count
400 if (*offset != 0) 391 if (*offset != 0)
401 return 0; 392 return 0;
402 393
403 ret = ibmasm_get_next_event(event_data->sp, reader); 394 spin_lock_irqsave(&sp->lock, flags);
395 if (event_data->active) {
396 spin_unlock_irqrestore(&sp->lock, flags);
397 return -EBUSY;
398 }
399 event_data->active = 1;
400 spin_unlock_irqrestore(&sp->lock, flags);
401
402 ret = ibmasm_get_next_event(sp, reader);
404 if (ret <= 0) 403 if (ret <= 0)
405 return ret; 404 goto out;
406 405
407 if (count < reader->data_size) 406 if (count < reader->data_size) {
408 return -EINVAL; 407 ret = -EINVAL;
408 goto out;
409 }
409 410
410 if (copy_to_user(buf, reader->data, reader->data_size)) 411 if (copy_to_user(buf, reader->data, reader->data_size)) {
411 return -EFAULT; 412 ret = -EFAULT;
413 goto out;
414 }
415 ret = reader->data_size;
412 416
413 return reader->data_size; 417out:
418 event_data->active = 0;
419 return ret;
414} 420}
415 421
416static ssize_t event_file_write(struct file *file, const char __user *buf, size_t count, loff_t *offset) 422static ssize_t event_file_write(struct file *file, const char __user *buf, size_t count, loff_t *offset)
@@ -424,7 +430,7 @@ static ssize_t event_file_write(struct file *file, const char __user *buf, size_
424 if (*offset != 0) 430 if (*offset != 0)
425 return 0; 431 return 0;
426 432
427 wake_up_interruptible(&event_data->reader.wait); 433 ibmasm_cancel_next_event(&event_data->reader);
428 return 0; 434 return 0;
429} 435}
430 436
@@ -575,75 +581,6 @@ static ssize_t remote_settings_file_write(struct file *file, const char __user *
575 return count; 581 return count;
576} 582}
577 583
578static int remote_event_file_open(struct inode *inode, struct file *file)
579{
580 struct service_processor *sp;
581 unsigned long flags;
582 struct remote_queue *q;
583
584 file->private_data = inode->u.generic_ip;
585 sp = file->private_data;
586 q = &sp->remote_queue;
587
588 /* allow only one event reader */
589 spin_lock_irqsave(&sp->lock, flags);
590 if (q->open) {
591 spin_unlock_irqrestore(&sp->lock, flags);
592 return -EBUSY;
593 }
594 q->open = 1;
595 spin_unlock_irqrestore(&sp->lock, flags);
596
597 enable_mouse_interrupts(sp);
598
599 return 0;
600}
601
602static int remote_event_file_close(struct inode *inode, struct file *file)
603{
604 struct service_processor *sp = file->private_data;
605
606 disable_mouse_interrupts(sp);
607 wake_up_interruptible(&sp->remote_queue.wait);
608 sp->remote_queue.open = 0;
609
610 return 0;
611}
612
613static ssize_t remote_event_file_read(struct file *file, char __user *buf, size_t count, loff_t *offset)
614{
615 struct service_processor *sp = file->private_data;
616 struct remote_queue *q = &sp->remote_queue;
617 size_t data_size;
618 struct remote_event *reader = q->reader;
619 size_t num_events;
620
621 if (*offset < 0)
622 return -EINVAL;
623 if (count == 0 || count > 1024)
624 return 0;
625 if (*offset != 0)
626 return 0;
627
628 if (wait_event_interruptible(q->wait, q->reader != q->writer))
629 return -ERESTARTSYS;
630
631 /* only get multiples of struct remote_event */
632 num_events = min((count/sizeof(struct remote_event)), ibmasm_events_available(q));
633 if (!num_events)
634 return 0;
635
636 data_size = num_events * sizeof(struct remote_event);
637
638 if (copy_to_user(buf, reader, data_size))
639 return -EFAULT;
640
641 ibmasm_advance_reader(q, num_events);
642
643 return data_size;
644}
645
646
647static struct file_operations command_fops = { 584static struct file_operations command_fops = {
648 .open = command_file_open, 585 .open = command_file_open,
649 .release = command_file_close, 586 .release = command_file_close,
@@ -672,12 +609,6 @@ static struct file_operations remote_settings_fops = {
672 .write = remote_settings_file_write, 609 .write = remote_settings_file_write,
673}; 610};
674 611
675static struct file_operations remote_event_fops = {
676 .open = remote_event_file_open,
677 .release = remote_event_file_close,
678 .read = remote_event_file_read,
679};
680
681 612
682static void ibmasmfs_create_files (struct super_block *sb, struct dentry *root) 613static void ibmasmfs_create_files (struct super_block *sb, struct dentry *root)
683{ 614{
@@ -703,7 +634,5 @@ static void ibmasmfs_create_files (struct super_block *sb, struct dentry *root)
703 ibmasmfs_create_file(sb, remote_dir, "width", &remote_settings_fops, (void *)display_width(sp), S_IRUSR|S_IWUSR); 634 ibmasmfs_create_file(sb, remote_dir, "width", &remote_settings_fops, (void *)display_width(sp), S_IRUSR|S_IWUSR);
704 ibmasmfs_create_file(sb, remote_dir, "height", &remote_settings_fops, (void *)display_height(sp), S_IRUSR|S_IWUSR); 635 ibmasmfs_create_file(sb, remote_dir, "height", &remote_settings_fops, (void *)display_height(sp), S_IRUSR|S_IWUSR);
705 ibmasmfs_create_file(sb, remote_dir, "depth", &remote_settings_fops, (void *)display_depth(sp), S_IRUSR|S_IWUSR); 636 ibmasmfs_create_file(sb, remote_dir, "depth", &remote_settings_fops, (void *)display_depth(sp), S_IRUSR|S_IWUSR);
706 ibmasmfs_create_file(sb, remote_dir, "connected", &remote_settings_fops, (void *)vnc_status(sp), S_IRUSR);
707 ibmasmfs_create_file(sb, remote_dir, "events", &remote_event_fops, (void *)sp, S_IRUSR);
708 } 637 }
709} 638}