diff options
author | Gleb Natapov <glebn@voltaire.com> | 2005-07-27 23:40:00 +0200 |
---|---|---|
committer | Roland Dreier <roland@eddore.topspincom.com> | 2005-07-27 23:40:00 +0200 |
commit | abdf119b4dad015803819c3d046d20cfbd393e87 (patch) | |
tree | 9d0372a7f4a71886696a5d7b6f7583790e1c8d22 /drivers/infiniband | |
parent | [IB/mthca]: Fix error CQ entry handling on mem-free HCAs (diff) | |
download | linux-abdf119b4dad015803819c3d046d20cfbd393e87.tar.xz linux-abdf119b4dad015803819c3d046d20cfbd393e87.zip |
[IB/uverbs]: Add O_ASYNC support
Add support for O_ASYNC notifications on userspace verbs
completion and asynchronous event file descriptors.
Signed-off-by: Gleb Natapov <glebn@voltaire.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r-- | drivers/infiniband/core/uverbs.h | 1 | ||||
-rw-r--r-- | drivers/infiniband/core/uverbs_main.c | 14 |
2 files changed, 14 insertions, 1 deletions
diff --git a/drivers/infiniband/core/uverbs.h b/drivers/infiniband/core/uverbs.h index 57347f1e82c1..7696022f9a4e 100644 --- a/drivers/infiniband/core/uverbs.h +++ b/drivers/infiniband/core/uverbs.h @@ -61,6 +61,7 @@ struct ib_uverbs_event_file { int fd; int is_async; wait_queue_head_t poll_wait; + struct fasync_struct *async_queue; struct list_head event_list; }; diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c index fbbe03d8c901..eb99e693dec2 100644 --- a/drivers/infiniband/core/uverbs_main.c +++ b/drivers/infiniband/core/uverbs_main.c @@ -257,11 +257,19 @@ static void ib_uverbs_event_release(struct ib_uverbs_event_file *file) spin_unlock_irq(&file->lock); } +static int ib_uverbs_event_fasync(int fd, struct file *filp, int on) +{ + struct ib_uverbs_event_file *file = filp->private_data; + + return fasync_helper(fd, filp, on, &file->async_queue); +} + static int ib_uverbs_event_close(struct inode *inode, struct file *filp) { struct ib_uverbs_event_file *file = filp->private_data; ib_uverbs_event_release(file); + ib_uverbs_event_fasync(-1, filp, 0); kref_put(&file->uverbs_file->ref, ib_uverbs_release_file); return 0; @@ -276,7 +284,8 @@ static struct file_operations uverbs_event_fops = { */ .read = ib_uverbs_event_read, .poll = ib_uverbs_event_poll, - .release = ib_uverbs_event_close + .release = ib_uverbs_event_close, + .fasync = ib_uverbs_event_fasync }; void ib_uverbs_comp_handler(struct ib_cq *cq, void *cq_context) @@ -296,6 +305,7 @@ void ib_uverbs_comp_handler(struct ib_cq *cq, void *cq_context) spin_unlock_irqrestore(&file->comp_file[0].lock, flags); wake_up_interruptible(&file->comp_file[0].poll_wait); + kill_fasync(&file->comp_file[0].async_queue, SIGIO, POLL_IN); } static void ib_uverbs_async_handler(struct ib_uverbs_file *file, @@ -316,6 +326,7 @@ static void ib_uverbs_async_handler(struct ib_uverbs_file *file, spin_unlock_irqrestore(&file->async_file.lock, flags); wake_up_interruptible(&file->async_file.poll_wait); + kill_fasync(&file->async_file.async_queue, SIGIO, POLL_IN); } void ib_uverbs_cq_event_handler(struct ib_event *event, void *context_ptr) @@ -350,6 +361,7 @@ static int ib_uverbs_event_init(struct ib_uverbs_event_file *file, INIT_LIST_HEAD(&file->event_list); init_waitqueue_head(&file->poll_wait); file->uverbs_file = uverbs_file; + file->async_queue = NULL; file->fd = get_unused_fd(); if (file->fd < 0) |