1 // SPDX-License-Identifier: GPL-2.0-only
3 * Raw serio device providing access to a raw byte stream from underlying
4 * serio port. Closely emulates behavior of pre-2.6 /dev/psaux device
6 * Copyright (c) 2004 Dmitry Torokhov
9 #include <linux/kref.h>
10 #include <linux/sched.h>
11 #include <linux/slab.h>
12 #include <linux/poll.h>
13 #include <linux/module.h>
14 #include <linux/serio.h>
15 #include <linux/major.h>
16 #include <linux/device.h>
17 #include <linux/miscdevice.h>
18 #include <linux/wait.h>
19 #include <linux/mutex.h>
21 #define DRIVER_DESC "Raw serio driver"
23 MODULE_AUTHOR("Dmitry Torokhov <dtor@mail.ru>");
24 MODULE_DESCRIPTION(DRIVER_DESC
);
25 MODULE_LICENSE("GPL");
27 #define SERIO_RAW_QUEUE_LEN 64
29 unsigned char queue
[SERIO_RAW_QUEUE_LEN
];
30 unsigned int tail
, head
;
35 struct miscdevice dev
;
36 wait_queue_head_t wait
;
37 struct list_head client_list
;
38 struct list_head node
;
42 struct serio_raw_client
{
43 struct fasync_struct
*fasync
;
44 struct serio_raw
*serio_raw
;
45 struct list_head node
;
48 static DEFINE_MUTEX(serio_raw_mutex
);
49 static LIST_HEAD(serio_raw_list
);
51 /*********************************************************************
52 * Interface with userspace (file operations) *
53 *********************************************************************/
55 static int serio_raw_fasync(int fd
, struct file
*file
, int on
)
57 struct serio_raw_client
*client
= file
->private_data
;
59 return fasync_helper(fd
, file
, on
, &client
->fasync
);
62 static struct serio_raw
*serio_raw_locate(int minor
)
64 struct serio_raw
*serio_raw
;
66 list_for_each_entry(serio_raw
, &serio_raw_list
, node
) {
67 if (serio_raw
->dev
.minor
== minor
)
74 static int serio_raw_open(struct inode
*inode
, struct file
*file
)
76 struct serio_raw
*serio_raw
;
77 struct serio_raw_client
*client
;
79 scoped_guard(mutex_intr
, &serio_raw_mutex
) {
80 serio_raw
= serio_raw_locate(iminor(inode
));
87 client
= kzalloc(sizeof(*client
), GFP_KERNEL
);
91 client
->serio_raw
= serio_raw
;
92 file
->private_data
= client
;
94 kref_get(&serio_raw
->kref
);
96 scoped_guard(serio_pause_rx
, serio_raw
->serio
)
97 list_add_tail(&client
->node
, &serio_raw
->client_list
);
105 static void serio_raw_free(struct kref
*kref
)
107 struct serio_raw
*serio_raw
=
108 container_of(kref
, struct serio_raw
, kref
);
110 put_device(&serio_raw
->serio
->dev
);
114 static int serio_raw_release(struct inode
*inode
, struct file
*file
)
116 struct serio_raw_client
*client
= file
->private_data
;
117 struct serio_raw
*serio_raw
= client
->serio_raw
;
119 scoped_guard(serio_pause_rx
, serio_raw
->serio
)
120 list_del(&client
->node
);
124 kref_put(&serio_raw
->kref
, serio_raw_free
);
129 static bool serio_raw_fetch_byte(struct serio_raw
*serio_raw
, char *c
)
131 guard(serio_pause_rx
)(serio_raw
->serio
);
133 if (serio_raw
->head
== serio_raw
->tail
)
134 return false; /* queue is empty */
136 *c
= serio_raw
->queue
[serio_raw
->tail
];
137 serio_raw
->tail
= (serio_raw
->tail
+ 1) % SERIO_RAW_QUEUE_LEN
;
142 static ssize_t
serio_raw_read(struct file
*file
, char __user
*buffer
,
143 size_t count
, loff_t
*ppos
)
145 struct serio_raw_client
*client
= file
->private_data
;
146 struct serio_raw
*serio_raw
= client
->serio_raw
;
155 if (serio_raw
->head
== serio_raw
->tail
&&
156 (file
->f_flags
& O_NONBLOCK
))
162 while (read
< count
&& serio_raw_fetch_byte(serio_raw
, &c
)) {
163 if (put_user(c
, buffer
++))
171 if (!(file
->f_flags
& O_NONBLOCK
)) {
172 error
= wait_event_interruptible(serio_raw
->wait
,
173 serio_raw
->head
!= serio_raw
->tail
||
183 static ssize_t
serio_raw_write(struct file
*file
, const char __user
*buffer
,
184 size_t count
, loff_t
*ppos
)
186 struct serio_raw_client
*client
= file
->private_data
;
187 struct serio_raw
*serio_raw
= client
->serio_raw
;
191 scoped_guard(mutex_intr
, &serio_raw_mutex
) {
199 if (get_user(c
, buffer
++))
202 if (serio_write(serio_raw
->serio
, c
)) {
203 /* Either signal error or partial write */
204 return written
?: -EIO
;
216 static __poll_t
serio_raw_poll(struct file
*file
, poll_table
*wait
)
218 struct serio_raw_client
*client
= file
->private_data
;
219 struct serio_raw
*serio_raw
= client
->serio_raw
;
222 poll_wait(file
, &serio_raw
->wait
, wait
);
224 mask
= serio_raw
->dead
? EPOLLHUP
| EPOLLERR
: EPOLLOUT
| EPOLLWRNORM
;
225 if (serio_raw
->head
!= serio_raw
->tail
)
226 mask
|= EPOLLIN
| EPOLLRDNORM
;
231 static const struct file_operations serio_raw_fops
= {
232 .owner
= THIS_MODULE
,
233 .open
= serio_raw_open
,
234 .release
= serio_raw_release
,
235 .read
= serio_raw_read
,
236 .write
= serio_raw_write
,
237 .poll
= serio_raw_poll
,
238 .fasync
= serio_raw_fasync
,
239 .llseek
= noop_llseek
,
243 /*********************************************************************
244 * Interface with serio port *
245 *********************************************************************/
247 static irqreturn_t
serio_raw_interrupt(struct serio
*serio
, unsigned char data
,
250 struct serio_raw
*serio_raw
= serio_get_drvdata(serio
);
251 struct serio_raw_client
*client
;
252 unsigned int head
= serio_raw
->head
;
254 /* we are holding serio->lock here so we are protected */
255 serio_raw
->queue
[head
] = data
;
256 head
= (head
+ 1) % SERIO_RAW_QUEUE_LEN
;
257 if (likely(head
!= serio_raw
->tail
)) {
258 serio_raw
->head
= head
;
259 list_for_each_entry(client
, &serio_raw
->client_list
, node
)
260 kill_fasync(&client
->fasync
, SIGIO
, POLL_IN
);
261 wake_up_interruptible(&serio_raw
->wait
);
267 static int serio_raw_connect(struct serio
*serio
, struct serio_driver
*drv
)
269 static atomic_t serio_raw_no
= ATOMIC_INIT(-1);
270 struct serio_raw
*serio_raw
;
273 serio_raw
= kzalloc(sizeof(*serio_raw
), GFP_KERNEL
);
275 dev_dbg(&serio
->dev
, "can't allocate memory for a device\n");
279 snprintf(serio_raw
->name
, sizeof(serio_raw
->name
),
280 "serio_raw%u", atomic_inc_return(&serio_raw_no
));
281 kref_init(&serio_raw
->kref
);
282 INIT_LIST_HEAD(&serio_raw
->client_list
);
283 init_waitqueue_head(&serio_raw
->wait
);
285 serio_raw
->serio
= serio
;
286 get_device(&serio
->dev
);
288 serio_set_drvdata(serio
, serio_raw
);
290 err
= serio_open(serio
, drv
);
294 err
= mutex_lock_killable(&serio_raw_mutex
);
298 list_add_tail(&serio_raw
->node
, &serio_raw_list
);
299 mutex_unlock(&serio_raw_mutex
);
301 serio_raw
->dev
.minor
= PSMOUSE_MINOR
;
302 serio_raw
->dev
.name
= serio_raw
->name
;
303 serio_raw
->dev
.parent
= &serio
->dev
;
304 serio_raw
->dev
.fops
= &serio_raw_fops
;
306 err
= misc_register(&serio_raw
->dev
);
308 serio_raw
->dev
.minor
= MISC_DYNAMIC_MINOR
;
309 err
= misc_register(&serio_raw
->dev
);
314 "failed to register raw access device for %s\n",
319 dev_info(&serio
->dev
, "raw access enabled on %s (%s, minor %d)\n",
320 serio
->phys
, serio_raw
->name
, serio_raw
->dev
.minor
);
324 list_del_init(&serio_raw
->node
);
328 serio_set_drvdata(serio
, NULL
);
329 kref_put(&serio_raw
->kref
, serio_raw_free
);
333 static int serio_raw_reconnect(struct serio
*serio
)
335 struct serio_raw
*serio_raw
= serio_get_drvdata(serio
);
336 struct serio_driver
*drv
= serio
->drv
;
338 if (!drv
|| !serio_raw
) {
340 "reconnect request, but serio is disconnected, ignoring...\n");
345 * Nothing needs to be done here, we just need this method to
346 * keep the same device.
352 * Wake up users waiting for IO so they can disconnect from
355 static void serio_raw_hangup(struct serio_raw
*serio_raw
)
357 struct serio_raw_client
*client
;
359 scoped_guard(serio_pause_rx
, serio_raw
->serio
) {
360 list_for_each_entry(client
, &serio_raw
->client_list
, node
)
361 kill_fasync(&client
->fasync
, SIGIO
, POLL_HUP
);
364 wake_up_interruptible(&serio_raw
->wait
);
368 static void serio_raw_disconnect(struct serio
*serio
)
370 struct serio_raw
*serio_raw
= serio_get_drvdata(serio
);
372 misc_deregister(&serio_raw
->dev
);
374 scoped_guard(mutex
, &serio_raw_mutex
) {
375 serio_raw
->dead
= true;
376 list_del_init(&serio_raw
->node
);
379 serio_raw_hangup(serio_raw
);
382 kref_put(&serio_raw
->kref
, serio_raw_free
);
384 serio_set_drvdata(serio
, NULL
);
387 static const struct serio_device_id serio_raw_serio_ids
[] = {
395 .type
= SERIO_8042_XL
,
403 MODULE_DEVICE_TABLE(serio
, serio_raw_serio_ids
);
405 static struct serio_driver serio_raw_drv
= {
409 .description
= DRIVER_DESC
,
410 .id_table
= serio_raw_serio_ids
,
411 .interrupt
= serio_raw_interrupt
,
412 .connect
= serio_raw_connect
,
413 .reconnect
= serio_raw_reconnect
,
414 .disconnect
= serio_raw_disconnect
,
418 module_serio_driver(serio_raw_drv
);