| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Event char devices, giving access to raw input device events. |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright (c) 1999-2002 Vojtech Pavlik |
|---|
| 5 | | - * |
|---|
| 6 | | - * This program is free software; you can redistribute it and/or modify it |
|---|
| 7 | | - * under the terms of the GNU General Public License version 2 as published by |
|---|
| 8 | | - * the Free Software Foundation. |
|---|
| 9 | 6 | */ |
|---|
| 10 | 7 | |
|---|
| 11 | 8 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
|---|
| .. | .. |
|---|
| 31 | 28 | struct evdev { |
|---|
| 32 | 29 | int open; |
|---|
| 33 | 30 | struct input_handle handle; |
|---|
| 34 | | - wait_queue_head_t wait; |
|---|
| 35 | 31 | struct evdev_client __rcu *grab; |
|---|
| 36 | 32 | struct list_head client_list; |
|---|
| 37 | 33 | spinlock_t client_lock; /* protects client_list */ |
|---|
| .. | .. |
|---|
| 46 | 42 | unsigned int tail; |
|---|
| 47 | 43 | unsigned int packet_head; /* [future] position of the first element of next packet */ |
|---|
| 48 | 44 | spinlock_t buffer_lock; /* protects access to buffer, head and tail */ |
|---|
| 45 | + wait_queue_head_t wait; |
|---|
| 49 | 46 | struct fasync_struct *fasync; |
|---|
| 50 | 47 | struct evdev *evdev; |
|---|
| 51 | 48 | struct list_head node; |
|---|
| .. | .. |
|---|
| 248 | 245 | const struct input_value *vals, unsigned int count, |
|---|
| 249 | 246 | ktime_t *ev_time) |
|---|
| 250 | 247 | { |
|---|
| 251 | | - struct evdev *evdev = client->evdev; |
|---|
| 252 | 248 | const struct input_value *v; |
|---|
| 253 | 249 | struct input_event event; |
|---|
| 254 | 250 | struct timespec64 ts; |
|---|
| .. | .. |
|---|
| 285 | 281 | spin_unlock(&client->buffer_lock); |
|---|
| 286 | 282 | |
|---|
| 287 | 283 | if (wakeup) |
|---|
| 288 | | - wake_up_interruptible(&evdev->wait); |
|---|
| 284 | + wake_up_interruptible_poll(&client->wait, |
|---|
| 285 | + EPOLLIN | EPOLLOUT | EPOLLRDNORM | EPOLLWRNORM); |
|---|
| 289 | 286 | } |
|---|
| 290 | 287 | |
|---|
| 291 | 288 | /* |
|---|
| .. | .. |
|---|
| 428 | 425 | struct evdev_client *client; |
|---|
| 429 | 426 | |
|---|
| 430 | 427 | spin_lock(&evdev->client_lock); |
|---|
| 431 | | - list_for_each_entry(client, &evdev->client_list, node) |
|---|
| 428 | + list_for_each_entry(client, &evdev->client_list, node) { |
|---|
| 432 | 429 | kill_fasync(&client->fasync, SIGIO, POLL_HUP); |
|---|
| 430 | + wake_up_interruptible_poll(&client->wait, EPOLLHUP | EPOLLERR); |
|---|
| 431 | + } |
|---|
| 433 | 432 | spin_unlock(&evdev->client_lock); |
|---|
| 434 | | - |
|---|
| 435 | | - wake_up_interruptible(&evdev->wait); |
|---|
| 436 | 433 | } |
|---|
| 437 | 434 | |
|---|
| 438 | 435 | static int evdev_release(struct inode *inode, struct file *file) |
|---|
| .. | .. |
|---|
| 474 | 471 | { |
|---|
| 475 | 472 | struct evdev *evdev = container_of(inode->i_cdev, struct evdev, cdev); |
|---|
| 476 | 473 | unsigned int bufsize = evdev_compute_buffer_size(evdev->handle.dev); |
|---|
| 477 | | - unsigned int size = sizeof(struct evdev_client) + |
|---|
| 478 | | - bufsize * sizeof(struct input_event); |
|---|
| 479 | 474 | struct evdev_client *client; |
|---|
| 480 | 475 | int error; |
|---|
| 481 | 476 | |
|---|
| 482 | | - client = kzalloc(size, GFP_KERNEL | __GFP_NOWARN); |
|---|
| 483 | | - if (!client) |
|---|
| 484 | | - client = vzalloc(size); |
|---|
| 477 | + client = kvzalloc(struct_size(client, buffer, bufsize), GFP_KERNEL); |
|---|
| 485 | 478 | if (!client) |
|---|
| 486 | 479 | return -ENOMEM; |
|---|
| 487 | 480 | |
|---|
| 481 | + init_waitqueue_head(&client->wait); |
|---|
| 488 | 482 | client->bufsize = bufsize; |
|---|
| 489 | 483 | spin_lock_init(&client->buffer_lock); |
|---|
| 490 | 484 | client->evdev = evdev; |
|---|
| .. | .. |
|---|
| 495 | 489 | goto err_free_client; |
|---|
| 496 | 490 | |
|---|
| 497 | 491 | file->private_data = client; |
|---|
| 498 | | - nonseekable_open(inode, file); |
|---|
| 492 | + stream_open(inode, file); |
|---|
| 499 | 493 | |
|---|
| 500 | 494 | return 0; |
|---|
| 501 | 495 | |
|---|
| .. | .. |
|---|
| 601 | 595 | break; |
|---|
| 602 | 596 | |
|---|
| 603 | 597 | if (!(file->f_flags & O_NONBLOCK)) { |
|---|
| 604 | | - error = wait_event_interruptible(evdev->wait, |
|---|
| 598 | + error = wait_event_interruptible(client->wait, |
|---|
| 605 | 599 | client->packet_head != client->tail || |
|---|
| 606 | 600 | !evdev->exist || client->revoked); |
|---|
| 607 | 601 | if (error) |
|---|
| .. | .. |
|---|
| 619 | 613 | struct evdev *evdev = client->evdev; |
|---|
| 620 | 614 | __poll_t mask; |
|---|
| 621 | 615 | |
|---|
| 622 | | - poll_wait(file, &evdev->wait, wait); |
|---|
| 616 | + poll_wait(file, &client->wait, wait); |
|---|
| 623 | 617 | |
|---|
| 624 | 618 | if (evdev->exist && !client->revoked) |
|---|
| 625 | 619 | mask = EPOLLOUT | EPOLLWRNORM; |
|---|
| .. | .. |
|---|
| 952 | 946 | client->revoked = true; |
|---|
| 953 | 947 | evdev_ungrab(evdev, client); |
|---|
| 954 | 948 | input_flush_device(&evdev->handle, file); |
|---|
| 955 | | - wake_up_interruptible(&evdev->wait); |
|---|
| 949 | + wake_up_interruptible_poll(&client->wait, EPOLLHUP | EPOLLERR); |
|---|
| 956 | 950 | |
|---|
| 957 | 951 | return 0; |
|---|
| 958 | 952 | } |
|---|
| .. | .. |
|---|
| 1364 | 1358 | INIT_LIST_HEAD(&evdev->client_list); |
|---|
| 1365 | 1359 | spin_lock_init(&evdev->client_lock); |
|---|
| 1366 | 1360 | mutex_init(&evdev->mutex); |
|---|
| 1367 | | - init_waitqueue_head(&evdev->wait); |
|---|
| 1368 | 1361 | evdev->exist = true; |
|---|
| 1369 | 1362 | |
|---|
| 1370 | 1363 | dev_no = minor; |
|---|