root/drivers/input/serio/serio_raw.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. serio_raw_fasync
  2. serio_raw_locate
  3. serio_raw_open
  4. serio_raw_free
  5. serio_raw_release
  6. serio_raw_fetch_byte
  7. serio_raw_read
  8. serio_raw_write
  9. serio_raw_poll
  10. serio_raw_interrupt
  11. serio_raw_connect
  12. serio_raw_reconnect
  13. serio_raw_hangup
  14. serio_raw_disconnect

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

/* [<][>][^][v][top][bottom][index][help] */