From 102a0743326a03cd1a1202ceda21e175b7d3575c Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Tue, 20 Feb 2024 01:20:52 +0000 Subject: [PATCH] add new system file --- kernel/drivers/input/evdev.c | 33 +++++++++++++-------------------- 1 files changed, 13 insertions(+), 20 deletions(-) diff --git a/kernel/drivers/input/evdev.c b/kernel/drivers/input/evdev.c index 05c617b..95f9069 100644 --- a/kernel/drivers/input/evdev.c +++ b/kernel/drivers/input/evdev.c @@ -1,11 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Event char devices, giving access to raw input device events. * * Copyright (c) 1999-2002 Vojtech Pavlik - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt @@ -31,7 +28,6 @@ struct evdev { int open; struct input_handle handle; - wait_queue_head_t wait; struct evdev_client __rcu *grab; struct list_head client_list; spinlock_t client_lock; /* protects client_list */ @@ -46,6 +42,7 @@ unsigned int tail; unsigned int packet_head; /* [future] position of the first element of next packet */ spinlock_t buffer_lock; /* protects access to buffer, head and tail */ + wait_queue_head_t wait; struct fasync_struct *fasync; struct evdev *evdev; struct list_head node; @@ -248,7 +245,6 @@ const struct input_value *vals, unsigned int count, ktime_t *ev_time) { - struct evdev *evdev = client->evdev; const struct input_value *v; struct input_event event; struct timespec64 ts; @@ -285,7 +281,8 @@ spin_unlock(&client->buffer_lock); if (wakeup) - wake_up_interruptible(&evdev->wait); + wake_up_interruptible_poll(&client->wait, + EPOLLIN | EPOLLOUT | EPOLLRDNORM | EPOLLWRNORM); } /* @@ -428,11 +425,11 @@ struct evdev_client *client; spin_lock(&evdev->client_lock); - list_for_each_entry(client, &evdev->client_list, node) + list_for_each_entry(client, &evdev->client_list, node) { kill_fasync(&client->fasync, SIGIO, POLL_HUP); + wake_up_interruptible_poll(&client->wait, EPOLLHUP | EPOLLERR); + } spin_unlock(&evdev->client_lock); - - wake_up_interruptible(&evdev->wait); } static int evdev_release(struct inode *inode, struct file *file) @@ -474,17 +471,14 @@ { struct evdev *evdev = container_of(inode->i_cdev, struct evdev, cdev); unsigned int bufsize = evdev_compute_buffer_size(evdev->handle.dev); - unsigned int size = sizeof(struct evdev_client) + - bufsize * sizeof(struct input_event); struct evdev_client *client; int error; - client = kzalloc(size, GFP_KERNEL | __GFP_NOWARN); - if (!client) - client = vzalloc(size); + client = kvzalloc(struct_size(client, buffer, bufsize), GFP_KERNEL); if (!client) return -ENOMEM; + init_waitqueue_head(&client->wait); client->bufsize = bufsize; spin_lock_init(&client->buffer_lock); client->evdev = evdev; @@ -495,7 +489,7 @@ goto err_free_client; file->private_data = client; - nonseekable_open(inode, file); + stream_open(inode, file); return 0; @@ -601,7 +595,7 @@ break; if (!(file->f_flags & O_NONBLOCK)) { - error = wait_event_interruptible(evdev->wait, + error = wait_event_interruptible(client->wait, client->packet_head != client->tail || !evdev->exist || client->revoked); if (error) @@ -619,7 +613,7 @@ struct evdev *evdev = client->evdev; __poll_t mask; - poll_wait(file, &evdev->wait, wait); + poll_wait(file, &client->wait, wait); if (evdev->exist && !client->revoked) mask = EPOLLOUT | EPOLLWRNORM; @@ -952,7 +946,7 @@ client->revoked = true; evdev_ungrab(evdev, client); input_flush_device(&evdev->handle, file); - wake_up_interruptible(&evdev->wait); + wake_up_interruptible_poll(&client->wait, EPOLLHUP | EPOLLERR); return 0; } @@ -1364,7 +1358,6 @@ INIT_LIST_HEAD(&evdev->client_list); spin_lock_init(&evdev->client_lock); mutex_init(&evdev->mutex); - init_waitqueue_head(&evdev->wait); evdev->exist = true; dev_no = minor; -- Gitblit v1.6.2