Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Raw serio device providing access to a raw byte stream from underlying
0004  * serio port. Closely emulates behavior of pre-2.6 /dev/psaux device
0005  *
0006  * Copyright (c) 2004 Dmitry Torokhov
0007  */
0008 
0009 #include <linux/kref.h>
0010 #include <linux/sched.h>
0011 #include <linux/slab.h>
0012 #include <linux/poll.h>
0013 #include <linux/module.h>
0014 #include <linux/serio.h>
0015 #include <linux/major.h>
0016 #include <linux/device.h>
0017 #include <linux/miscdevice.h>
0018 #include <linux/wait.h>
0019 #include <linux/mutex.h>
0020 
0021 #define DRIVER_DESC "Raw serio driver"
0022 
0023 MODULE_AUTHOR("Dmitry Torokhov <dtor@mail.ru>");
0024 MODULE_DESCRIPTION(DRIVER_DESC);
0025 MODULE_LICENSE("GPL");
0026 
0027 #define SERIO_RAW_QUEUE_LEN 64
0028 struct serio_raw {
0029     unsigned char queue[SERIO_RAW_QUEUE_LEN];
0030     unsigned int tail, head;
0031 
0032     char name[16];
0033     struct kref kref;
0034     struct serio *serio;
0035     struct miscdevice dev;
0036     wait_queue_head_t wait;
0037     struct list_head client_list;
0038     struct list_head node;
0039     bool dead;
0040 };
0041 
0042 struct serio_raw_client {
0043     struct fasync_struct *fasync;
0044     struct serio_raw *serio_raw;
0045     struct list_head node;
0046 };
0047 
0048 static DEFINE_MUTEX(serio_raw_mutex);
0049 static LIST_HEAD(serio_raw_list);
0050 
0051 /*********************************************************************
0052  *             Interface with userspace (file operations)            *
0053  *********************************************************************/
0054 
0055 static int serio_raw_fasync(int fd, struct file *file, int on)
0056 {
0057     struct serio_raw_client *client = file->private_data;
0058 
0059     return fasync_helper(fd, file, on, &client->fasync);
0060 }
0061 
0062 static struct serio_raw *serio_raw_locate(int minor)
0063 {
0064     struct serio_raw *serio_raw;
0065 
0066     list_for_each_entry(serio_raw, &serio_raw_list, node) {
0067         if (serio_raw->dev.minor == minor)
0068             return serio_raw;
0069     }
0070 
0071     return NULL;
0072 }
0073 
0074 static int serio_raw_open(struct inode *inode, struct file *file)
0075 {
0076     struct serio_raw *serio_raw;
0077     struct serio_raw_client *client;
0078     int retval;
0079 
0080     retval = mutex_lock_interruptible(&serio_raw_mutex);
0081     if (retval)
0082         return retval;
0083 
0084     serio_raw = serio_raw_locate(iminor(inode));
0085     if (!serio_raw) {
0086         retval = -ENODEV;
0087         goto out;
0088     }
0089 
0090     if (serio_raw->dead) {
0091         retval = -ENODEV;
0092         goto out;
0093     }
0094 
0095     client = kzalloc(sizeof(struct serio_raw_client), GFP_KERNEL);
0096     if (!client) {
0097         retval = -ENOMEM;
0098         goto out;
0099     }
0100 
0101     client->serio_raw = serio_raw;
0102     file->private_data = client;
0103 
0104     kref_get(&serio_raw->kref);
0105 
0106     serio_pause_rx(serio_raw->serio);
0107     list_add_tail(&client->node, &serio_raw->client_list);
0108     serio_continue_rx(serio_raw->serio);
0109 
0110 out:
0111     mutex_unlock(&serio_raw_mutex);
0112     return retval;
0113 }
0114 
0115 static void serio_raw_free(struct kref *kref)
0116 {
0117     struct serio_raw *serio_raw =
0118             container_of(kref, struct serio_raw, kref);
0119 
0120     put_device(&serio_raw->serio->dev);
0121     kfree(serio_raw);
0122 }
0123 
0124 static int serio_raw_release(struct inode *inode, struct file *file)
0125 {
0126     struct serio_raw_client *client = file->private_data;
0127     struct serio_raw *serio_raw = client->serio_raw;
0128 
0129     serio_pause_rx(serio_raw->serio);
0130     list_del(&client->node);
0131     serio_continue_rx(serio_raw->serio);
0132 
0133     kfree(client);
0134 
0135     kref_put(&serio_raw->kref, serio_raw_free);
0136 
0137     return 0;
0138 }
0139 
0140 static bool serio_raw_fetch_byte(struct serio_raw *serio_raw, char *c)
0141 {
0142     bool empty;
0143 
0144     serio_pause_rx(serio_raw->serio);
0145 
0146     empty = serio_raw->head == serio_raw->tail;
0147     if (!empty) {
0148         *c = serio_raw->queue[serio_raw->tail];
0149         serio_raw->tail = (serio_raw->tail + 1) % SERIO_RAW_QUEUE_LEN;
0150     }
0151 
0152     serio_continue_rx(serio_raw->serio);
0153 
0154     return !empty;
0155 }
0156 
0157 static ssize_t serio_raw_read(struct file *file, char __user *buffer,
0158                   size_t count, loff_t *ppos)
0159 {
0160     struct serio_raw_client *client = file->private_data;
0161     struct serio_raw *serio_raw = client->serio_raw;
0162     char c;
0163     ssize_t read = 0;
0164     int error;
0165 
0166     for (;;) {
0167         if (serio_raw->dead)
0168             return -ENODEV;
0169 
0170         if (serio_raw->head == serio_raw->tail &&
0171             (file->f_flags & O_NONBLOCK))
0172             return -EAGAIN;
0173 
0174         if (count == 0)
0175             break;
0176 
0177         while (read < count && serio_raw_fetch_byte(serio_raw, &c)) {
0178             if (put_user(c, buffer++))
0179                 return -EFAULT;
0180             read++;
0181         }
0182 
0183         if (read)
0184             break;
0185 
0186         if (!(file->f_flags & O_NONBLOCK)) {
0187             error = wait_event_interruptible(serio_raw->wait,
0188                     serio_raw->head != serio_raw->tail ||
0189                     serio_raw->dead);
0190             if (error)
0191                 return error;
0192         }
0193     }
0194 
0195     return read;
0196 }
0197 
0198 static ssize_t serio_raw_write(struct file *file, const char __user *buffer,
0199                    size_t count, loff_t *ppos)
0200 {
0201     struct serio_raw_client *client = file->private_data;
0202     struct serio_raw *serio_raw = client->serio_raw;
0203     int retval = 0;
0204     unsigned char c;
0205 
0206     retval = mutex_lock_interruptible(&serio_raw_mutex);
0207     if (retval)
0208         return retval;
0209 
0210     if (serio_raw->dead) {
0211         retval = -ENODEV;
0212         goto out;
0213     }
0214 
0215     if (count > 32)
0216         count = 32;
0217 
0218     while (count--) {
0219         if (get_user(c, buffer++)) {
0220             retval = -EFAULT;
0221             goto out;
0222         }
0223 
0224         if (serio_write(serio_raw->serio, c)) {
0225             /* Either signal error or partial write */
0226             if (retval == 0)
0227                 retval = -EIO;
0228             goto out;
0229         }
0230 
0231         retval++;
0232     }
0233 
0234 out:
0235     mutex_unlock(&serio_raw_mutex);
0236     return retval;
0237 }
0238 
0239 static __poll_t serio_raw_poll(struct file *file, poll_table *wait)
0240 {
0241     struct serio_raw_client *client = file->private_data;
0242     struct serio_raw *serio_raw = client->serio_raw;
0243     __poll_t mask;
0244 
0245     poll_wait(file, &serio_raw->wait, wait);
0246 
0247     mask = serio_raw->dead ? EPOLLHUP | EPOLLERR : EPOLLOUT | EPOLLWRNORM;
0248     if (serio_raw->head != serio_raw->tail)
0249         mask |= EPOLLIN | EPOLLRDNORM;
0250 
0251     return mask;
0252 }
0253 
0254 static const struct file_operations serio_raw_fops = {
0255     .owner      = THIS_MODULE,
0256     .open       = serio_raw_open,
0257     .release    = serio_raw_release,
0258     .read       = serio_raw_read,
0259     .write      = serio_raw_write,
0260     .poll       = serio_raw_poll,
0261     .fasync     = serio_raw_fasync,
0262     .llseek     = noop_llseek,
0263 };
0264 
0265 
0266 /*********************************************************************
0267  *                   Interface with serio port                       *
0268  *********************************************************************/
0269 
0270 static irqreturn_t serio_raw_interrupt(struct serio *serio, unsigned char data,
0271                     unsigned int dfl)
0272 {
0273     struct serio_raw *serio_raw = serio_get_drvdata(serio);
0274     struct serio_raw_client *client;
0275     unsigned int head = serio_raw->head;
0276 
0277     /* we are holding serio->lock here so we are protected */
0278     serio_raw->queue[head] = data;
0279     head = (head + 1) % SERIO_RAW_QUEUE_LEN;
0280     if (likely(head != serio_raw->tail)) {
0281         serio_raw->head = head;
0282         list_for_each_entry(client, &serio_raw->client_list, node)
0283             kill_fasync(&client->fasync, SIGIO, POLL_IN);
0284         wake_up_interruptible(&serio_raw->wait);
0285     }
0286 
0287     return IRQ_HANDLED;
0288 }
0289 
0290 static int serio_raw_connect(struct serio *serio, struct serio_driver *drv)
0291 {
0292     static atomic_t serio_raw_no = ATOMIC_INIT(-1);
0293     struct serio_raw *serio_raw;
0294     int err;
0295 
0296     serio_raw = kzalloc(sizeof(struct serio_raw), GFP_KERNEL);
0297     if (!serio_raw) {
0298         dev_dbg(&serio->dev, "can't allocate memory for a device\n");
0299         return -ENOMEM;
0300     }
0301 
0302     snprintf(serio_raw->name, sizeof(serio_raw->name),
0303          "serio_raw%ld", (long)atomic_inc_return(&serio_raw_no));
0304     kref_init(&serio_raw->kref);
0305     INIT_LIST_HEAD(&serio_raw->client_list);
0306     init_waitqueue_head(&serio_raw->wait);
0307 
0308     serio_raw->serio = serio;
0309     get_device(&serio->dev);
0310 
0311     serio_set_drvdata(serio, serio_raw);
0312 
0313     err = serio_open(serio, drv);
0314     if (err)
0315         goto err_free;
0316 
0317     err = mutex_lock_killable(&serio_raw_mutex);
0318     if (err)
0319         goto err_close;
0320 
0321     list_add_tail(&serio_raw->node, &serio_raw_list);
0322     mutex_unlock(&serio_raw_mutex);
0323 
0324     serio_raw->dev.minor = PSMOUSE_MINOR;
0325     serio_raw->dev.name = serio_raw->name;
0326     serio_raw->dev.parent = &serio->dev;
0327     serio_raw->dev.fops = &serio_raw_fops;
0328 
0329     err = misc_register(&serio_raw->dev);
0330     if (err) {
0331         serio_raw->dev.minor = MISC_DYNAMIC_MINOR;
0332         err = misc_register(&serio_raw->dev);
0333     }
0334 
0335     if (err) {
0336         dev_err(&serio->dev,
0337             "failed to register raw access device for %s\n",
0338             serio->phys);
0339         goto err_unlink;
0340     }
0341 
0342     dev_info(&serio->dev, "raw access enabled on %s (%s, minor %d)\n",
0343          serio->phys, serio_raw->name, serio_raw->dev.minor);
0344     return 0;
0345 
0346 err_unlink:
0347     list_del_init(&serio_raw->node);
0348 err_close:
0349     serio_close(serio);
0350 err_free:
0351     serio_set_drvdata(serio, NULL);
0352     kref_put(&serio_raw->kref, serio_raw_free);
0353     return err;
0354 }
0355 
0356 static int serio_raw_reconnect(struct serio *serio)
0357 {
0358     struct serio_raw *serio_raw = serio_get_drvdata(serio);
0359     struct serio_driver *drv = serio->drv;
0360 
0361     if (!drv || !serio_raw) {
0362         dev_dbg(&serio->dev,
0363             "reconnect request, but serio is disconnected, ignoring...\n");
0364         return -1;
0365     }
0366 
0367     /*
0368      * Nothing needs to be done here, we just need this method to
0369      * keep the same device.
0370      */
0371     return 0;
0372 }
0373 
0374 /*
0375  * Wake up users waiting for IO so they can disconnect from
0376  * dead device.
0377  */
0378 static void serio_raw_hangup(struct serio_raw *serio_raw)
0379 {
0380     struct serio_raw_client *client;
0381 
0382     serio_pause_rx(serio_raw->serio);
0383     list_for_each_entry(client, &serio_raw->client_list, node)
0384         kill_fasync(&client->fasync, SIGIO, POLL_HUP);
0385     serio_continue_rx(serio_raw->serio);
0386 
0387     wake_up_interruptible(&serio_raw->wait);
0388 }
0389 
0390 
0391 static void serio_raw_disconnect(struct serio *serio)
0392 {
0393     struct serio_raw *serio_raw = serio_get_drvdata(serio);
0394 
0395     misc_deregister(&serio_raw->dev);
0396 
0397     mutex_lock(&serio_raw_mutex);
0398     serio_raw->dead = true;
0399     list_del_init(&serio_raw->node);
0400     mutex_unlock(&serio_raw_mutex);
0401 
0402     serio_raw_hangup(serio_raw);
0403 
0404     serio_close(serio);
0405     kref_put(&serio_raw->kref, serio_raw_free);
0406 
0407     serio_set_drvdata(serio, NULL);
0408 }
0409 
0410 static const struct serio_device_id serio_raw_serio_ids[] = {
0411     {
0412         .type   = SERIO_8042,
0413         .proto  = SERIO_ANY,
0414         .id = SERIO_ANY,
0415         .extra  = SERIO_ANY,
0416     },
0417     {
0418         .type   = SERIO_8042_XL,
0419         .proto  = SERIO_ANY,
0420         .id = SERIO_ANY,
0421         .extra  = SERIO_ANY,
0422     },
0423     { 0 }
0424 };
0425 
0426 MODULE_DEVICE_TABLE(serio, serio_raw_serio_ids);
0427 
0428 static struct serio_driver serio_raw_drv = {
0429     .driver     = {
0430         .name   = "serio_raw",
0431     },
0432     .description    = DRIVER_DESC,
0433     .id_table   = serio_raw_serio_ids,
0434     .interrupt  = serio_raw_interrupt,
0435     .connect    = serio_raw_connect,
0436     .reconnect  = serio_raw_reconnect,
0437     .disconnect = serio_raw_disconnect,
0438     .manual_bind    = true,
0439 };
0440 
0441 module_serio_driver(serio_raw_drv);