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 | |
| 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>
| -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>"); |
