diff options
author | David Altobelli <david.altobelli@hp.com> | 2009-08-17 19:08:01 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-09-15 12:50:48 -0400 |
commit | 4a351471df352474956f1fdc7bc4e7cf6836503a (patch) | |
tree | 974bc0732bf0fc1054421a2cfdf99ca694a7c747 /drivers/misc | |
parent | 9f7048412163d8f8175ba01063f3db02d42cc6a7 (diff) |
hpilo: add poll f_op
Add poll handler to hpilo, to allow applications a low overhead method
of waiting for data.
Signed-off-by: David Altobelli <david.altobelli@hp.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/misc')
-rw-r--r-- | drivers/misc/hpilo.c | 42 |
1 files changed, 41 insertions, 1 deletions
diff --git a/drivers/misc/hpilo.c b/drivers/misc/hpilo.c index 9a370d5acf87..1ad27c6abcca 100644 --- a/drivers/misc/hpilo.c +++ b/drivers/misc/hpilo.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/uaccess.h> | 23 | #include <linux/uaccess.h> |
24 | #include <linux/io.h> | 24 | #include <linux/io.h> |
25 | #include <linux/wait.h> | 25 | #include <linux/wait.h> |
26 | #include <linux/poll.h> | ||
26 | #include "hpilo.h" | 27 | #include "hpilo.h" |
27 | 28 | ||
28 | static struct class *ilo_class; | 29 | static struct class *ilo_class; |
@@ -102,6 +103,22 @@ static int fifo_dequeue(struct ilo_hwinfo *hw, char *fifobar, int *entry) | |||
102 | return ret; | 103 | return ret; |
103 | } | 104 | } |
104 | 105 | ||
106 | static int fifo_check_recv(struct ilo_hwinfo *hw, char *fifobar) | ||
107 | { | ||
108 | struct fifo *fifo_q = FIFOBARTOHANDLE(fifobar); | ||
109 | unsigned long flags; | ||
110 | int ret = 0; | ||
111 | u64 c; | ||
112 | |||
113 | spin_lock_irqsave(&hw->fifo_lock, flags); | ||
114 | c = fifo_q->fifobar[fifo_q->head & fifo_q->imask]; | ||
115 | if (c & ENTRY_MASK_C) | ||
116 | ret = 1; | ||
117 | spin_unlock_irqrestore(&hw->fifo_lock, flags); | ||
118 | |||
119 | return ret; | ||
120 | } | ||
121 | |||
105 | static int ilo_pkt_enqueue(struct ilo_hwinfo *hw, struct ccb *ccb, | 122 | static int ilo_pkt_enqueue(struct ilo_hwinfo *hw, struct ccb *ccb, |
106 | int dir, int id, int len) | 123 | int dir, int id, int len) |
107 | { | 124 | { |
@@ -146,6 +163,13 @@ static int ilo_pkt_dequeue(struct ilo_hwinfo *hw, struct ccb *ccb, | |||
146 | return ret; | 163 | return ret; |
147 | } | 164 | } |
148 | 165 | ||
166 | static int ilo_pkt_recv(struct ilo_hwinfo *hw, struct ccb *ccb) | ||
167 | { | ||
168 | char *fifobar = ccb->ccb_u3.recv_fifobar; | ||
169 | |||
170 | return fifo_check_recv(hw, fifobar); | ||
171 | } | ||
172 | |||
149 | static inline void doorbell_set(struct ccb *ccb) | 173 | static inline void doorbell_set(struct ccb *ccb) |
150 | { | 174 | { |
151 | iowrite8(1, ccb->ccb_u5.db_base); | 175 | iowrite8(1, ccb->ccb_u5.db_base); |
@@ -486,6 +510,21 @@ static ssize_t ilo_write(struct file *fp, const char __user *buf, | |||
486 | return err ? -EFAULT : len; | 510 | return err ? -EFAULT : len; |
487 | } | 511 | } |
488 | 512 | ||
513 | static unsigned int ilo_poll(struct file *fp, poll_table *wait) | ||
514 | { | ||
515 | struct ccb_data *data = fp->private_data; | ||
516 | struct ccb *driver_ccb = &data->driver_ccb; | ||
517 | |||
518 | poll_wait(fp, &data->ccb_waitq, wait); | ||
519 | |||
520 | if (is_channel_reset(driver_ccb)) | ||
521 | return POLLERR; | ||
522 | else if (ilo_pkt_recv(data->ilo_hw, driver_ccb)) | ||
523 | return POLLIN | POLLRDNORM; | ||
524 | |||
525 | return 0; | ||
526 | } | ||
527 | |||
489 | static int ilo_close(struct inode *ip, struct file *fp) | 528 | static int ilo_close(struct inode *ip, struct file *fp) |
490 | { | 529 | { |
491 | int slot; | 530 | int slot; |
@@ -595,6 +634,7 @@ static const struct file_operations ilo_fops = { | |||
595 | .owner = THIS_MODULE, | 634 | .owner = THIS_MODULE, |
596 | .read = ilo_read, | 635 | .read = ilo_read, |
597 | .write = ilo_write, | 636 | .write = ilo_write, |
637 | .poll = ilo_poll, | ||
598 | .open = ilo_open, | 638 | .open = ilo_open, |
599 | .release = ilo_close, | 639 | .release = ilo_close, |
600 | }; | 640 | }; |
@@ -835,7 +875,7 @@ static void __exit ilo_exit(void) | |||
835 | class_destroy(ilo_class); | 875 | class_destroy(ilo_class); |
836 | } | 876 | } |
837 | 877 | ||
838 | MODULE_VERSION("1.1"); | 878 | MODULE_VERSION("1.2"); |
839 | MODULE_ALIAS(ILO_NAME); | 879 | MODULE_ALIAS(ILO_NAME); |
840 | MODULE_DESCRIPTION(ILO_NAME); | 880 | MODULE_DESCRIPTION(ILO_NAME); |
841 | MODULE_AUTHOR("David Altobelli <david.altobelli@hp.com>"); | 881 | MODULE_AUTHOR("David Altobelli <david.altobelli@hp.com>"); |