^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Raw serio device providing access to a raw byte stream from underlying
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * serio port. Closely emulates behavior of pre-2.6 /dev/psaux device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (c) 2004 Dmitry Torokhov
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/kref.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/poll.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/serio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/major.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/miscdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/wait.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define DRIVER_DESC "Raw serio driver"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) MODULE_AUTHOR("Dmitry Torokhov <dtor@mail.ru>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) MODULE_DESCRIPTION(DRIVER_DESC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define SERIO_RAW_QUEUE_LEN 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) struct serio_raw {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) unsigned char queue[SERIO_RAW_QUEUE_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) unsigned int tail, head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) char name[16];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) struct kref kref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) struct serio *serio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) struct miscdevice dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) wait_queue_head_t wait;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) struct list_head client_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) struct list_head node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) bool dead;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) struct serio_raw_client {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) struct fasync_struct *fasync;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) struct serio_raw *serio_raw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) struct list_head node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) static DEFINE_MUTEX(serio_raw_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) static LIST_HEAD(serio_raw_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) /*********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * Interface with userspace (file operations) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) *********************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) static int serio_raw_fasync(int fd, struct file *file, int on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) struct serio_raw_client *client = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) return fasync_helper(fd, file, on, &client->fasync);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) static struct serio_raw *serio_raw_locate(int minor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) struct serio_raw *serio_raw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) list_for_each_entry(serio_raw, &serio_raw_list, node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) if (serio_raw->dev.minor == minor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) return serio_raw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) static int serio_raw_open(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) struct serio_raw *serio_raw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) struct serio_raw_client *client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) retval = mutex_lock_interruptible(&serio_raw_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) serio_raw = serio_raw_locate(iminor(inode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) if (!serio_raw) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) retval = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) if (serio_raw->dead) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) retval = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) client = kzalloc(sizeof(struct serio_raw_client), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) if (!client) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) retval = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) client->serio_raw = serio_raw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) file->private_data = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) kref_get(&serio_raw->kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) serio_pause_rx(serio_raw->serio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) list_add_tail(&client->node, &serio_raw->client_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) serio_continue_rx(serio_raw->serio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) mutex_unlock(&serio_raw_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) static void serio_raw_free(struct kref *kref)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) struct serio_raw *serio_raw =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) container_of(kref, struct serio_raw, kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) put_device(&serio_raw->serio->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) kfree(serio_raw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) static int serio_raw_release(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) struct serio_raw_client *client = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) struct serio_raw *serio_raw = client->serio_raw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) serio_pause_rx(serio_raw->serio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) list_del(&client->node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) serio_continue_rx(serio_raw->serio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) kfree(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) kref_put(&serio_raw->kref, serio_raw_free);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) static bool serio_raw_fetch_byte(struct serio_raw *serio_raw, char *c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) bool empty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) serio_pause_rx(serio_raw->serio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) empty = serio_raw->head == serio_raw->tail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) if (!empty) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) *c = serio_raw->queue[serio_raw->tail];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) serio_raw->tail = (serio_raw->tail + 1) % SERIO_RAW_QUEUE_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) serio_continue_rx(serio_raw->serio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) return !empty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) static ssize_t serio_raw_read(struct file *file, char __user *buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) struct serio_raw_client *client = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) struct serio_raw *serio_raw = client->serio_raw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) char c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) ssize_t read = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) if (serio_raw->dead)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) if (serio_raw->head == serio_raw->tail &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) (file->f_flags & O_NONBLOCK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) if (count == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) while (read < count && serio_raw_fetch_byte(serio_raw, &c)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) if (put_user(c, buffer++))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) read++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) if (read)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) if (!(file->f_flags & O_NONBLOCK)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) error = wait_event_interruptible(serio_raw->wait,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) serio_raw->head != serio_raw->tail ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) serio_raw->dead);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) return read;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) static ssize_t serio_raw_write(struct file *file, const char __user *buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) struct serio_raw_client *client = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) struct serio_raw *serio_raw = client->serio_raw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) int retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) unsigned char c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) retval = mutex_lock_interruptible(&serio_raw_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) if (serio_raw->dead) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) retval = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) if (count > 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) count = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) while (count--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) if (get_user(c, buffer++)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) retval = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) if (serio_write(serio_raw->serio, c)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) /* Either signal error or partial write */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) if (retval == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) retval = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) retval++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) mutex_unlock(&serio_raw_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) static __poll_t serio_raw_poll(struct file *file, poll_table *wait)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) struct serio_raw_client *client = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) struct serio_raw *serio_raw = client->serio_raw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) __poll_t mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) poll_wait(file, &serio_raw->wait, wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) mask = serio_raw->dead ? EPOLLHUP | EPOLLERR : EPOLLOUT | EPOLLWRNORM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) if (serio_raw->head != serio_raw->tail)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) mask |= EPOLLIN | EPOLLRDNORM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) return mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) static const struct file_operations serio_raw_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) .open = serio_raw_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) .release = serio_raw_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) .read = serio_raw_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) .write = serio_raw_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) .poll = serio_raw_poll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) .fasync = serio_raw_fasync,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) .llseek = noop_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) /*********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) * Interface with serio port *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) *********************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) static irqreturn_t serio_raw_interrupt(struct serio *serio, unsigned char data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) unsigned int dfl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) struct serio_raw *serio_raw = serio_get_drvdata(serio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) struct serio_raw_client *client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) unsigned int head = serio_raw->head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) /* we are holding serio->lock here so we are protected */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) serio_raw->queue[head] = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) head = (head + 1) % SERIO_RAW_QUEUE_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) if (likely(head != serio_raw->tail)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) serio_raw->head = head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) list_for_each_entry(client, &serio_raw->client_list, node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) kill_fasync(&client->fasync, SIGIO, POLL_IN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) wake_up_interruptible(&serio_raw->wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) static int serio_raw_connect(struct serio *serio, struct serio_driver *drv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) static atomic_t serio_raw_no = ATOMIC_INIT(-1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) struct serio_raw *serio_raw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) serio_raw = kzalloc(sizeof(struct serio_raw), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) if (!serio_raw) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) dev_dbg(&serio->dev, "can't allocate memory for a device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) snprintf(serio_raw->name, sizeof(serio_raw->name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) "serio_raw%ld", (long)atomic_inc_return(&serio_raw_no));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) kref_init(&serio_raw->kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) INIT_LIST_HEAD(&serio_raw->client_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) init_waitqueue_head(&serio_raw->wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) serio_raw->serio = serio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) get_device(&serio->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) serio_set_drvdata(serio, serio_raw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) err = serio_open(serio, drv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) goto err_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) err = mutex_lock_killable(&serio_raw_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) goto err_close;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) list_add_tail(&serio_raw->node, &serio_raw_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) mutex_unlock(&serio_raw_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) serio_raw->dev.minor = PSMOUSE_MINOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) serio_raw->dev.name = serio_raw->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) serio_raw->dev.parent = &serio->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) serio_raw->dev.fops = &serio_raw_fops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) err = misc_register(&serio_raw->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) serio_raw->dev.minor = MISC_DYNAMIC_MINOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) err = misc_register(&serio_raw->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) dev_err(&serio->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) "failed to register raw access device for %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) serio->phys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) goto err_unlink;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) dev_info(&serio->dev, "raw access enabled on %s (%s, minor %d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) serio->phys, serio_raw->name, serio_raw->dev.minor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) err_unlink:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) list_del_init(&serio_raw->node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) err_close:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) serio_close(serio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) err_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) serio_set_drvdata(serio, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) kref_put(&serio_raw->kref, serio_raw_free);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) static int serio_raw_reconnect(struct serio *serio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) struct serio_raw *serio_raw = serio_get_drvdata(serio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) struct serio_driver *drv = serio->drv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) if (!drv || !serio_raw) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) dev_dbg(&serio->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) "reconnect request, but serio is disconnected, ignoring...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) * Nothing needs to be done here, we just need this method to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) * keep the same device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) * Wake up users waiting for IO so they can disconnect from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) * dead device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) static void serio_raw_hangup(struct serio_raw *serio_raw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) struct serio_raw_client *client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) serio_pause_rx(serio_raw->serio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) list_for_each_entry(client, &serio_raw->client_list, node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) kill_fasync(&client->fasync, SIGIO, POLL_HUP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) serio_continue_rx(serio_raw->serio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) wake_up_interruptible(&serio_raw->wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) static void serio_raw_disconnect(struct serio *serio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) struct serio_raw *serio_raw = serio_get_drvdata(serio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) misc_deregister(&serio_raw->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) mutex_lock(&serio_raw_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) serio_raw->dead = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) list_del_init(&serio_raw->node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) mutex_unlock(&serio_raw_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) serio_raw_hangup(serio_raw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) serio_close(serio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) kref_put(&serio_raw->kref, serio_raw_free);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) serio_set_drvdata(serio, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) static const struct serio_device_id serio_raw_serio_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) .type = SERIO_8042,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) .proto = SERIO_ANY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) .id = SERIO_ANY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) .extra = SERIO_ANY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) .type = SERIO_8042_XL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) .proto = SERIO_ANY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) .id = SERIO_ANY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) .extra = SERIO_ANY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) { 0 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) MODULE_DEVICE_TABLE(serio, serio_raw_serio_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) static struct serio_driver serio_raw_drv = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) .name = "serio_raw",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) .description = DRIVER_DESC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) .id_table = serio_raw_serio_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) .interrupt = serio_raw_interrupt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) .connect = serio_raw_connect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) .reconnect = serio_raw_reconnect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) .disconnect = serio_raw_disconnect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) .manual_bind = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) module_serio_driver(serio_raw_drv);