diff options
| author | Gleb Natapov <glebn@voltaire.com> | 2005-07-27 17:40:00 -0400 |
|---|---|---|
| committer | Roland Dreier <roland@eddore.topspincom.com> | 2005-07-27 17:40:00 -0400 |
| commit | abdf119b4dad015803819c3d046d20cfbd393e87 (patch) | |
| tree | 9d0372a7f4a71886696a5d7b6f7583790e1c8d22 /drivers | |
| parent | 42b1806d5cfc93bf8c3d7fa6e9e79e4ec860c678 (diff) | |
[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')
| -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 { | |||
| 61 | int fd; | 61 | int fd; |
| 62 | int is_async; | 62 | int is_async; |
| 63 | wait_queue_head_t poll_wait; | 63 | wait_queue_head_t poll_wait; |
| 64 | struct fasync_struct *async_queue; | ||
| 64 | struct list_head event_list; | 65 | struct list_head event_list; |
| 65 | }; | 66 | }; |
| 66 | 67 | ||
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) | |||
| 257 | spin_unlock_irq(&file->lock); | 257 | spin_unlock_irq(&file->lock); |
| 258 | } | 258 | } |
| 259 | 259 | ||
| 260 | static int ib_uverbs_event_fasync(int fd, struct file *filp, int on) | ||
| 261 | { | ||
| 262 | struct ib_uverbs_event_file *file = filp->private_data; | ||
| 263 | |||
| 264 | return fasync_helper(fd, filp, on, &file->async_queue); | ||
| 265 | } | ||
| 266 | |||
| 260 | static int ib_uverbs_event_close(struct inode *inode, struct file *filp) | 267 | static int ib_uverbs_event_close(struct inode *inode, struct file *filp) |
| 261 | { | 268 | { |
| 262 | struct ib_uverbs_event_file *file = filp->private_data; | 269 | struct ib_uverbs_event_file *file = filp->private_data; |
| 263 | 270 | ||
| 264 | ib_uverbs_event_release(file); | 271 | ib_uverbs_event_release(file); |
| 272 | ib_uverbs_event_fasync(-1, filp, 0); | ||
| 265 | kref_put(&file->uverbs_file->ref, ib_uverbs_release_file); | 273 | kref_put(&file->uverbs_file->ref, ib_uverbs_release_file); |
| 266 | 274 | ||
| 267 | return 0; | 275 | return 0; |
| @@ -276,7 +284,8 @@ static struct file_operations uverbs_event_fops = { | |||
| 276 | */ | 284 | */ |
| 277 | .read = ib_uverbs_event_read, | 285 | .read = ib_uverbs_event_read, |
| 278 | .poll = ib_uverbs_event_poll, | 286 | .poll = ib_uverbs_event_poll, |
| 279 | .release = ib_uverbs_event_close | 287 | .release = ib_uverbs_event_close, |
| 288 | .fasync = ib_uverbs_event_fasync | ||
| 280 | }; | 289 | }; |
| 281 | 290 | ||
| 282 | void ib_uverbs_comp_handler(struct ib_cq *cq, void *cq_context) | 291 | 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) | |||
| 296 | spin_unlock_irqrestore(&file->comp_file[0].lock, flags); | 305 | spin_unlock_irqrestore(&file->comp_file[0].lock, flags); |
| 297 | 306 | ||
| 298 | wake_up_interruptible(&file->comp_file[0].poll_wait); | 307 | wake_up_interruptible(&file->comp_file[0].poll_wait); |
| 308 | kill_fasync(&file->comp_file[0].async_queue, SIGIO, POLL_IN); | ||
| 299 | } | 309 | } |
| 300 | 310 | ||
| 301 | static void ib_uverbs_async_handler(struct ib_uverbs_file *file, | 311 | 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, | |||
| 316 | spin_unlock_irqrestore(&file->async_file.lock, flags); | 326 | spin_unlock_irqrestore(&file->async_file.lock, flags); |
| 317 | 327 | ||
| 318 | wake_up_interruptible(&file->async_file.poll_wait); | 328 | wake_up_interruptible(&file->async_file.poll_wait); |
| 329 | kill_fasync(&file->async_file.async_queue, SIGIO, POLL_IN); | ||
| 319 | } | 330 | } |
| 320 | 331 | ||
| 321 | void ib_uverbs_cq_event_handler(struct ib_event *event, void *context_ptr) | 332 | 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, | |||
| 350 | INIT_LIST_HEAD(&file->event_list); | 361 | INIT_LIST_HEAD(&file->event_list); |
| 351 | init_waitqueue_head(&file->poll_wait); | 362 | init_waitqueue_head(&file->poll_wait); |
| 352 | file->uverbs_file = uverbs_file; | 363 | file->uverbs_file = uverbs_file; |
| 364 | file->async_queue = NULL; | ||
| 353 | 365 | ||
| 354 | file->fd = get_unused_fd(); | 366 | file->fd = get_unused_fd(); |
| 355 | if (file->fd < 0) | 367 | if (file->fd < 0) |
