Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Input driver to ExplorerPS/2 device driver module.
0004  *
0005  * Copyright (c) 1999-2002 Vojtech Pavlik
0006  * Copyright (c) 2004      Dmitry Torokhov
0007  */
0008 
0009 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0010 
0011 #define MOUSEDEV_MINOR_BASE 32
0012 #define MOUSEDEV_MINORS     31
0013 #define MOUSEDEV_MIX        63
0014 
0015 #include <linux/bitops.h>
0016 #include <linux/sched.h>
0017 #include <linux/slab.h>
0018 #include <linux/poll.h>
0019 #include <linux/module.h>
0020 #include <linux/init.h>
0021 #include <linux/input.h>
0022 #include <linux/random.h>
0023 #include <linux/major.h>
0024 #include <linux/device.h>
0025 #include <linux/cdev.h>
0026 #include <linux/kernel.h>
0027 
0028 MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
0029 MODULE_DESCRIPTION("Mouse (ExplorerPS/2) device interfaces");
0030 MODULE_LICENSE("GPL");
0031 
0032 #ifndef CONFIG_INPUT_MOUSEDEV_SCREEN_X
0033 #define CONFIG_INPUT_MOUSEDEV_SCREEN_X  1024
0034 #endif
0035 #ifndef CONFIG_INPUT_MOUSEDEV_SCREEN_Y
0036 #define CONFIG_INPUT_MOUSEDEV_SCREEN_Y  768
0037 #endif
0038 
0039 static int xres = CONFIG_INPUT_MOUSEDEV_SCREEN_X;
0040 module_param(xres, uint, 0644);
0041 MODULE_PARM_DESC(xres, "Horizontal screen resolution");
0042 
0043 static int yres = CONFIG_INPUT_MOUSEDEV_SCREEN_Y;
0044 module_param(yres, uint, 0644);
0045 MODULE_PARM_DESC(yres, "Vertical screen resolution");
0046 
0047 static unsigned tap_time = 200;
0048 module_param(tap_time, uint, 0644);
0049 MODULE_PARM_DESC(tap_time, "Tap time for touchpads in absolute mode (msecs)");
0050 
0051 struct mousedev_hw_data {
0052     int dx, dy, dz;
0053     int x, y;
0054     int abs_event;
0055     unsigned long buttons;
0056 };
0057 
0058 struct mousedev {
0059     int open;
0060     struct input_handle handle;
0061     wait_queue_head_t wait;
0062     struct list_head client_list;
0063     spinlock_t client_lock; /* protects client_list */
0064     struct mutex mutex;
0065     struct device dev;
0066     struct cdev cdev;
0067     bool exist;
0068 
0069     struct list_head mixdev_node;
0070     bool opened_by_mixdev;
0071 
0072     struct mousedev_hw_data packet;
0073     unsigned int pkt_count;
0074     int old_x[4], old_y[4];
0075     int frac_dx, frac_dy;
0076     unsigned long touch;
0077 
0078     int (*open_device)(struct mousedev *mousedev);
0079     void (*close_device)(struct mousedev *mousedev);
0080 };
0081 
0082 enum mousedev_emul {
0083     MOUSEDEV_EMUL_PS2,
0084     MOUSEDEV_EMUL_IMPS,
0085     MOUSEDEV_EMUL_EXPS
0086 };
0087 
0088 struct mousedev_motion {
0089     int dx, dy, dz;
0090     unsigned long buttons;
0091 };
0092 
0093 #define PACKET_QUEUE_LEN    16
0094 struct mousedev_client {
0095     struct fasync_struct *fasync;
0096     struct mousedev *mousedev;
0097     struct list_head node;
0098 
0099     struct mousedev_motion packets[PACKET_QUEUE_LEN];
0100     unsigned int head, tail;
0101     spinlock_t packet_lock;
0102     int pos_x, pos_y;
0103 
0104     u8 ps2[6];
0105     unsigned char ready, buffer, bufsiz;
0106     unsigned char imexseq, impsseq;
0107     enum mousedev_emul mode;
0108     unsigned long last_buttons;
0109 };
0110 
0111 #define MOUSEDEV_SEQ_LEN    6
0112 
0113 static unsigned char mousedev_imps_seq[] = { 0xf3, 200, 0xf3, 100, 0xf3, 80 };
0114 static unsigned char mousedev_imex_seq[] = { 0xf3, 200, 0xf3, 200, 0xf3, 80 };
0115 
0116 static struct mousedev *mousedev_mix;
0117 static LIST_HEAD(mousedev_mix_list);
0118 
0119 #define fx(i)  (mousedev->old_x[(mousedev->pkt_count - (i)) & 03])
0120 #define fy(i)  (mousedev->old_y[(mousedev->pkt_count - (i)) & 03])
0121 
0122 static void mousedev_touchpad_event(struct input_dev *dev,
0123                     struct mousedev *mousedev,
0124                     unsigned int code, int value)
0125 {
0126     int size, tmp;
0127     enum { FRACTION_DENOM = 128 };
0128 
0129     switch (code) {
0130 
0131     case ABS_X:
0132 
0133         fx(0) = value;
0134         if (mousedev->touch && mousedev->pkt_count >= 2) {
0135             size = input_abs_get_max(dev, ABS_X) -
0136                     input_abs_get_min(dev, ABS_X);
0137             if (size == 0)
0138                 size = 256 * 2;
0139 
0140             tmp = ((value - fx(2)) * 256 * FRACTION_DENOM) / size;
0141             tmp += mousedev->frac_dx;
0142             mousedev->packet.dx = tmp / FRACTION_DENOM;
0143             mousedev->frac_dx =
0144                 tmp - mousedev->packet.dx * FRACTION_DENOM;
0145         }
0146         break;
0147 
0148     case ABS_Y:
0149         fy(0) = value;
0150         if (mousedev->touch && mousedev->pkt_count >= 2) {
0151             /* use X size for ABS_Y to keep the same scale */
0152             size = input_abs_get_max(dev, ABS_X) -
0153                     input_abs_get_min(dev, ABS_X);
0154             if (size == 0)
0155                 size = 256 * 2;
0156 
0157             tmp = -((value - fy(2)) * 256 * FRACTION_DENOM) / size;
0158             tmp += mousedev->frac_dy;
0159             mousedev->packet.dy = tmp / FRACTION_DENOM;
0160             mousedev->frac_dy = tmp -
0161                 mousedev->packet.dy * FRACTION_DENOM;
0162         }
0163         break;
0164     }
0165 }
0166 
0167 static void mousedev_abs_event(struct input_dev *dev, struct mousedev *mousedev,
0168                 unsigned int code, int value)
0169 {
0170     int min, max, size;
0171 
0172     switch (code) {
0173 
0174     case ABS_X:
0175         min = input_abs_get_min(dev, ABS_X);
0176         max = input_abs_get_max(dev, ABS_X);
0177 
0178         size = max - min;
0179         if (size == 0)
0180             size = xres ? : 1;
0181 
0182         value = clamp(value, min, max);
0183 
0184         mousedev->packet.x = ((value - min) * xres) / size;
0185         mousedev->packet.abs_event = 1;
0186         break;
0187 
0188     case ABS_Y:
0189         min = input_abs_get_min(dev, ABS_Y);
0190         max = input_abs_get_max(dev, ABS_Y);
0191 
0192         size = max - min;
0193         if (size == 0)
0194             size = yres ? : 1;
0195 
0196         value = clamp(value, min, max);
0197 
0198         mousedev->packet.y = yres - ((value - min) * yres) / size;
0199         mousedev->packet.abs_event = 1;
0200         break;
0201     }
0202 }
0203 
0204 static void mousedev_rel_event(struct mousedev *mousedev,
0205                 unsigned int code, int value)
0206 {
0207     switch (code) {
0208     case REL_X:
0209         mousedev->packet.dx += value;
0210         break;
0211 
0212     case REL_Y:
0213         mousedev->packet.dy -= value;
0214         break;
0215 
0216     case REL_WHEEL:
0217         mousedev->packet.dz -= value;
0218         break;
0219     }
0220 }
0221 
0222 static void mousedev_key_event(struct mousedev *mousedev,
0223                 unsigned int code, int value)
0224 {
0225     int index;
0226 
0227     switch (code) {
0228 
0229     case BTN_TOUCH:
0230     case BTN_0:
0231     case BTN_LEFT:      index = 0; break;
0232 
0233     case BTN_STYLUS:
0234     case BTN_1:
0235     case BTN_RIGHT:     index = 1; break;
0236 
0237     case BTN_2:
0238     case BTN_FORWARD:
0239     case BTN_STYLUS2:
0240     case BTN_MIDDLE:    index = 2; break;
0241 
0242     case BTN_3:
0243     case BTN_BACK:
0244     case BTN_SIDE:      index = 3; break;
0245 
0246     case BTN_4:
0247     case BTN_EXTRA:     index = 4; break;
0248 
0249     default:        return;
0250     }
0251 
0252     if (value) {
0253         set_bit(index, &mousedev->packet.buttons);
0254         set_bit(index, &mousedev_mix->packet.buttons);
0255     } else {
0256         clear_bit(index, &mousedev->packet.buttons);
0257         clear_bit(index, &mousedev_mix->packet.buttons);
0258     }
0259 }
0260 
0261 static void mousedev_notify_readers(struct mousedev *mousedev,
0262                     struct mousedev_hw_data *packet)
0263 {
0264     struct mousedev_client *client;
0265     struct mousedev_motion *p;
0266     unsigned int new_head;
0267     int wake_readers = 0;
0268 
0269     rcu_read_lock();
0270     list_for_each_entry_rcu(client, &mousedev->client_list, node) {
0271 
0272         /* Just acquire the lock, interrupts already disabled */
0273         spin_lock(&client->packet_lock);
0274 
0275         p = &client->packets[client->head];
0276         if (client->ready && p->buttons != mousedev->packet.buttons) {
0277             new_head = (client->head + 1) % PACKET_QUEUE_LEN;
0278             if (new_head != client->tail) {
0279                 p = &client->packets[client->head = new_head];
0280                 memset(p, 0, sizeof(struct mousedev_motion));
0281             }
0282         }
0283 
0284         if (packet->abs_event) {
0285             p->dx += packet->x - client->pos_x;
0286             p->dy += packet->y - client->pos_y;
0287             client->pos_x = packet->x;
0288             client->pos_y = packet->y;
0289         }
0290 
0291         client->pos_x += packet->dx;
0292         client->pos_x = clamp_val(client->pos_x, 0, xres);
0293 
0294         client->pos_y += packet->dy;
0295         client->pos_y = clamp_val(client->pos_y, 0, yres);
0296 
0297         p->dx += packet->dx;
0298         p->dy += packet->dy;
0299         p->dz += packet->dz;
0300         p->buttons = mousedev->packet.buttons;
0301 
0302         if (p->dx || p->dy || p->dz ||
0303             p->buttons != client->last_buttons)
0304             client->ready = 1;
0305 
0306         spin_unlock(&client->packet_lock);
0307 
0308         if (client->ready) {
0309             kill_fasync(&client->fasync, SIGIO, POLL_IN);
0310             wake_readers = 1;
0311         }
0312     }
0313     rcu_read_unlock();
0314 
0315     if (wake_readers)
0316         wake_up_interruptible(&mousedev->wait);
0317 }
0318 
0319 static void mousedev_touchpad_touch(struct mousedev *mousedev, int value)
0320 {
0321     if (!value) {
0322         if (mousedev->touch &&
0323             time_before(jiffies,
0324                 mousedev->touch + msecs_to_jiffies(tap_time))) {
0325             /*
0326              * Toggle left button to emulate tap.
0327              * We rely on the fact that mousedev_mix always has 0
0328              * motion packet so we won't mess current position.
0329              */
0330             set_bit(0, &mousedev->packet.buttons);
0331             set_bit(0, &mousedev_mix->packet.buttons);
0332             mousedev_notify_readers(mousedev, &mousedev_mix->packet);
0333             mousedev_notify_readers(mousedev_mix,
0334                         &mousedev_mix->packet);
0335             clear_bit(0, &mousedev->packet.buttons);
0336             clear_bit(0, &mousedev_mix->packet.buttons);
0337         }
0338         mousedev->touch = mousedev->pkt_count = 0;
0339         mousedev->frac_dx = 0;
0340         mousedev->frac_dy = 0;
0341 
0342     } else if (!mousedev->touch)
0343         mousedev->touch = jiffies;
0344 }
0345 
0346 static void mousedev_event(struct input_handle *handle,
0347                unsigned int type, unsigned int code, int value)
0348 {
0349     struct mousedev *mousedev = handle->private;
0350 
0351     switch (type) {
0352 
0353     case EV_ABS:
0354         /* Ignore joysticks */
0355         if (test_bit(BTN_TRIGGER, handle->dev->keybit))
0356             return;
0357 
0358         if (test_bit(BTN_TOOL_FINGER, handle->dev->keybit))
0359             mousedev_touchpad_event(handle->dev,
0360                         mousedev, code, value);
0361         else
0362             mousedev_abs_event(handle->dev, mousedev, code, value);
0363 
0364         break;
0365 
0366     case EV_REL:
0367         mousedev_rel_event(mousedev, code, value);
0368         break;
0369 
0370     case EV_KEY:
0371         if (value != 2) {
0372             if (code == BTN_TOUCH &&
0373                 test_bit(BTN_TOOL_FINGER, handle->dev->keybit))
0374                 mousedev_touchpad_touch(mousedev, value);
0375             else
0376                 mousedev_key_event(mousedev, code, value);
0377         }
0378         break;
0379 
0380     case EV_SYN:
0381         if (code == SYN_REPORT) {
0382             if (mousedev->touch) {
0383                 mousedev->pkt_count++;
0384                 /*
0385                  * Input system eats duplicate events,
0386                  * but we need all of them to do correct
0387                  * averaging so apply present one forward
0388                  */
0389                 fx(0) = fx(1);
0390                 fy(0) = fy(1);
0391             }
0392 
0393             mousedev_notify_readers(mousedev, &mousedev->packet);
0394             mousedev_notify_readers(mousedev_mix, &mousedev->packet);
0395 
0396             mousedev->packet.dx = mousedev->packet.dy =
0397                 mousedev->packet.dz = 0;
0398             mousedev->packet.abs_event = 0;
0399         }
0400         break;
0401     }
0402 }
0403 
0404 static int mousedev_fasync(int fd, struct file *file, int on)
0405 {
0406     struct mousedev_client *client = file->private_data;
0407 
0408     return fasync_helper(fd, file, on, &client->fasync);
0409 }
0410 
0411 static void mousedev_free(struct device *dev)
0412 {
0413     struct mousedev *mousedev = container_of(dev, struct mousedev, dev);
0414 
0415     input_put_device(mousedev->handle.dev);
0416     kfree(mousedev);
0417 }
0418 
0419 static int mousedev_open_device(struct mousedev *mousedev)
0420 {
0421     int retval;
0422 
0423     retval = mutex_lock_interruptible(&mousedev->mutex);
0424     if (retval)
0425         return retval;
0426 
0427     if (!mousedev->exist)
0428         retval = -ENODEV;
0429     else if (!mousedev->open++) {
0430         retval = input_open_device(&mousedev->handle);
0431         if (retval)
0432             mousedev->open--;
0433     }
0434 
0435     mutex_unlock(&mousedev->mutex);
0436     return retval;
0437 }
0438 
0439 static void mousedev_close_device(struct mousedev *mousedev)
0440 {
0441     mutex_lock(&mousedev->mutex);
0442 
0443     if (mousedev->exist && !--mousedev->open)
0444         input_close_device(&mousedev->handle);
0445 
0446     mutex_unlock(&mousedev->mutex);
0447 }
0448 
0449 /*
0450  * Open all available devices so they can all be multiplexed in one.
0451  * stream. Note that this function is called with mousedev_mix->mutex
0452  * held.
0453  */
0454 static int mixdev_open_devices(struct mousedev *mixdev)
0455 {
0456     int error;
0457 
0458     error = mutex_lock_interruptible(&mixdev->mutex);
0459     if (error)
0460         return error;
0461 
0462     if (!mixdev->open++) {
0463         struct mousedev *mousedev;
0464 
0465         list_for_each_entry(mousedev, &mousedev_mix_list, mixdev_node) {
0466             if (!mousedev->opened_by_mixdev) {
0467                 if (mousedev_open_device(mousedev))
0468                     continue;
0469 
0470                 mousedev->opened_by_mixdev = true;
0471             }
0472         }
0473     }
0474 
0475     mutex_unlock(&mixdev->mutex);
0476     return 0;
0477 }
0478 
0479 /*
0480  * Close all devices that were opened as part of multiplexed
0481  * device. Note that this function is called with mousedev_mix->mutex
0482  * held.
0483  */
0484 static void mixdev_close_devices(struct mousedev *mixdev)
0485 {
0486     mutex_lock(&mixdev->mutex);
0487 
0488     if (!--mixdev->open) {
0489         struct mousedev *mousedev;
0490 
0491         list_for_each_entry(mousedev, &mousedev_mix_list, mixdev_node) {
0492             if (mousedev->opened_by_mixdev) {
0493                 mousedev->opened_by_mixdev = false;
0494                 mousedev_close_device(mousedev);
0495             }
0496         }
0497     }
0498 
0499     mutex_unlock(&mixdev->mutex);
0500 }
0501 
0502 
0503 static void mousedev_attach_client(struct mousedev *mousedev,
0504                    struct mousedev_client *client)
0505 {
0506     spin_lock(&mousedev->client_lock);
0507     list_add_tail_rcu(&client->node, &mousedev->client_list);
0508     spin_unlock(&mousedev->client_lock);
0509 }
0510 
0511 static void mousedev_detach_client(struct mousedev *mousedev,
0512                    struct mousedev_client *client)
0513 {
0514     spin_lock(&mousedev->client_lock);
0515     list_del_rcu(&client->node);
0516     spin_unlock(&mousedev->client_lock);
0517     synchronize_rcu();
0518 }
0519 
0520 static int mousedev_release(struct inode *inode, struct file *file)
0521 {
0522     struct mousedev_client *client = file->private_data;
0523     struct mousedev *mousedev = client->mousedev;
0524 
0525     mousedev_detach_client(mousedev, client);
0526     kfree(client);
0527 
0528     mousedev->close_device(mousedev);
0529 
0530     return 0;
0531 }
0532 
0533 static int mousedev_open(struct inode *inode, struct file *file)
0534 {
0535     struct mousedev_client *client;
0536     struct mousedev *mousedev;
0537     int error;
0538 
0539 #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
0540     if (imajor(inode) == MISC_MAJOR)
0541         mousedev = mousedev_mix;
0542     else
0543 #endif
0544         mousedev = container_of(inode->i_cdev, struct mousedev, cdev);
0545 
0546     client = kzalloc(sizeof(struct mousedev_client), GFP_KERNEL);
0547     if (!client)
0548         return -ENOMEM;
0549 
0550     spin_lock_init(&client->packet_lock);
0551     client->pos_x = xres / 2;
0552     client->pos_y = yres / 2;
0553     client->mousedev = mousedev;
0554     mousedev_attach_client(mousedev, client);
0555 
0556     error = mousedev->open_device(mousedev);
0557     if (error)
0558         goto err_free_client;
0559 
0560     file->private_data = client;
0561     stream_open(inode, file);
0562 
0563     return 0;
0564 
0565  err_free_client:
0566     mousedev_detach_client(mousedev, client);
0567     kfree(client);
0568     return error;
0569 }
0570 
0571 static void mousedev_packet(struct mousedev_client *client, u8 *ps2_data)
0572 {
0573     struct mousedev_motion *p = &client->packets[client->tail];
0574     s8 dx, dy, dz;
0575 
0576     dx = clamp_val(p->dx, -127, 127);
0577     p->dx -= dx;
0578 
0579     dy = clamp_val(p->dy, -127, 127);
0580     p->dy -= dy;
0581 
0582     ps2_data[0] = BIT(3);
0583     ps2_data[0] |= ((dx & BIT(7)) >> 3) | ((dy & BIT(7)) >> 2);
0584     ps2_data[0] |= p->buttons & 0x07;
0585     ps2_data[1] = dx;
0586     ps2_data[2] = dy;
0587 
0588     switch (client->mode) {
0589     case MOUSEDEV_EMUL_EXPS:
0590         dz = clamp_val(p->dz, -7, 7);
0591         p->dz -= dz;
0592 
0593         ps2_data[3] = (dz & 0x0f) | ((p->buttons & 0x18) << 1);
0594         client->bufsiz = 4;
0595         break;
0596 
0597     case MOUSEDEV_EMUL_IMPS:
0598         dz = clamp_val(p->dz, -127, 127);
0599         p->dz -= dz;
0600 
0601         ps2_data[0] |= ((p->buttons & 0x10) >> 3) |
0602                    ((p->buttons & 0x08) >> 1);
0603         ps2_data[3] = dz;
0604 
0605         client->bufsiz = 4;
0606         break;
0607 
0608     case MOUSEDEV_EMUL_PS2:
0609     default:
0610         p->dz = 0;
0611 
0612         ps2_data[0] |= ((p->buttons & 0x10) >> 3) |
0613                    ((p->buttons & 0x08) >> 1);
0614 
0615         client->bufsiz = 3;
0616         break;
0617     }
0618 
0619     if (!p->dx && !p->dy && !p->dz) {
0620         if (client->tail == client->head) {
0621             client->ready = 0;
0622             client->last_buttons = p->buttons;
0623         } else
0624             client->tail = (client->tail + 1) % PACKET_QUEUE_LEN;
0625     }
0626 }
0627 
0628 static void mousedev_generate_response(struct mousedev_client *client,
0629                     int command)
0630 {
0631     client->ps2[0] = 0xfa; /* ACK */
0632 
0633     switch (command) {
0634 
0635     case 0xeb: /* Poll */
0636         mousedev_packet(client, &client->ps2[1]);
0637         client->bufsiz++; /* account for leading ACK */
0638         break;
0639 
0640     case 0xf2: /* Get ID */
0641         switch (client->mode) {
0642         case MOUSEDEV_EMUL_PS2:
0643             client->ps2[1] = 0;
0644             break;
0645         case MOUSEDEV_EMUL_IMPS:
0646             client->ps2[1] = 3;
0647             break;
0648         case MOUSEDEV_EMUL_EXPS:
0649             client->ps2[1] = 4;
0650             break;
0651         }
0652         client->bufsiz = 2;
0653         break;
0654 
0655     case 0xe9: /* Get info */
0656         client->ps2[1] = 0x60; client->ps2[2] = 3; client->ps2[3] = 200;
0657         client->bufsiz = 4;
0658         break;
0659 
0660     case 0xff: /* Reset */
0661         client->impsseq = client->imexseq = 0;
0662         client->mode = MOUSEDEV_EMUL_PS2;
0663         client->ps2[1] = 0xaa; client->ps2[2] = 0x00;
0664         client->bufsiz = 3;
0665         break;
0666 
0667     default:
0668         client->bufsiz = 1;
0669         break;
0670     }
0671     client->buffer = client->bufsiz;
0672 }
0673 
0674 static ssize_t mousedev_write(struct file *file, const char __user *buffer,
0675                 size_t count, loff_t *ppos)
0676 {
0677     struct mousedev_client *client = file->private_data;
0678     unsigned char c;
0679     unsigned int i;
0680 
0681     for (i = 0; i < count; i++) {
0682 
0683         if (get_user(c, buffer + i))
0684             return -EFAULT;
0685 
0686         spin_lock_irq(&client->packet_lock);
0687 
0688         if (c == mousedev_imex_seq[client->imexseq]) {
0689             if (++client->imexseq == MOUSEDEV_SEQ_LEN) {
0690                 client->imexseq = 0;
0691                 client->mode = MOUSEDEV_EMUL_EXPS;
0692             }
0693         } else
0694             client->imexseq = 0;
0695 
0696         if (c == mousedev_imps_seq[client->impsseq]) {
0697             if (++client->impsseq == MOUSEDEV_SEQ_LEN) {
0698                 client->impsseq = 0;
0699                 client->mode = MOUSEDEV_EMUL_IMPS;
0700             }
0701         } else
0702             client->impsseq = 0;
0703 
0704         mousedev_generate_response(client, c);
0705 
0706         spin_unlock_irq(&client->packet_lock);
0707         cond_resched();
0708     }
0709 
0710     kill_fasync(&client->fasync, SIGIO, POLL_IN);
0711     wake_up_interruptible(&client->mousedev->wait);
0712 
0713     return count;
0714 }
0715 
0716 static ssize_t mousedev_read(struct file *file, char __user *buffer,
0717                  size_t count, loff_t *ppos)
0718 {
0719     struct mousedev_client *client = file->private_data;
0720     struct mousedev *mousedev = client->mousedev;
0721     u8 data[sizeof(client->ps2)];
0722     int retval = 0;
0723 
0724     if (!client->ready && !client->buffer && mousedev->exist &&
0725         (file->f_flags & O_NONBLOCK))
0726         return -EAGAIN;
0727 
0728     retval = wait_event_interruptible(mousedev->wait,
0729             !mousedev->exist || client->ready || client->buffer);
0730     if (retval)
0731         return retval;
0732 
0733     if (!mousedev->exist)
0734         return -ENODEV;
0735 
0736     spin_lock_irq(&client->packet_lock);
0737 
0738     if (!client->buffer && client->ready) {
0739         mousedev_packet(client, client->ps2);
0740         client->buffer = client->bufsiz;
0741     }
0742 
0743     if (count > client->buffer)
0744         count = client->buffer;
0745 
0746     memcpy(data, client->ps2 + client->bufsiz - client->buffer, count);
0747     client->buffer -= count;
0748 
0749     spin_unlock_irq(&client->packet_lock);
0750 
0751     if (copy_to_user(buffer, data, count))
0752         return -EFAULT;
0753 
0754     return count;
0755 }
0756 
0757 /* No kernel lock - fine */
0758 static __poll_t mousedev_poll(struct file *file, poll_table *wait)
0759 {
0760     struct mousedev_client *client = file->private_data;
0761     struct mousedev *mousedev = client->mousedev;
0762     __poll_t mask;
0763 
0764     poll_wait(file, &mousedev->wait, wait);
0765 
0766     mask = mousedev->exist ? EPOLLOUT | EPOLLWRNORM : EPOLLHUP | EPOLLERR;
0767     if (client->ready || client->buffer)
0768         mask |= EPOLLIN | EPOLLRDNORM;
0769 
0770     return mask;
0771 }
0772 
0773 static const struct file_operations mousedev_fops = {
0774     .owner      = THIS_MODULE,
0775     .read       = mousedev_read,
0776     .write      = mousedev_write,
0777     .poll       = mousedev_poll,
0778     .open       = mousedev_open,
0779     .release    = mousedev_release,
0780     .fasync     = mousedev_fasync,
0781     .llseek     = noop_llseek,
0782 };
0783 
0784 /*
0785  * Mark device non-existent. This disables writes, ioctls and
0786  * prevents new users from opening the device. Already posted
0787  * blocking reads will stay, however new ones will fail.
0788  */
0789 static void mousedev_mark_dead(struct mousedev *mousedev)
0790 {
0791     mutex_lock(&mousedev->mutex);
0792     mousedev->exist = false;
0793     mutex_unlock(&mousedev->mutex);
0794 }
0795 
0796 /*
0797  * Wake up users waiting for IO so they can disconnect from
0798  * dead device.
0799  */
0800 static void mousedev_hangup(struct mousedev *mousedev)
0801 {
0802     struct mousedev_client *client;
0803 
0804     spin_lock(&mousedev->client_lock);
0805     list_for_each_entry(client, &mousedev->client_list, node)
0806         kill_fasync(&client->fasync, SIGIO, POLL_HUP);
0807     spin_unlock(&mousedev->client_lock);
0808 
0809     wake_up_interruptible(&mousedev->wait);
0810 }
0811 
0812 static void mousedev_cleanup(struct mousedev *mousedev)
0813 {
0814     struct input_handle *handle = &mousedev->handle;
0815 
0816     mousedev_mark_dead(mousedev);
0817     mousedev_hangup(mousedev);
0818 
0819     /* mousedev is marked dead so no one else accesses mousedev->open */
0820     if (mousedev->open)
0821         input_close_device(handle);
0822 }
0823 
0824 static int mousedev_reserve_minor(bool mixdev)
0825 {
0826     int minor;
0827 
0828     if (mixdev) {
0829         minor = input_get_new_minor(MOUSEDEV_MIX, 1, false);
0830         if (minor < 0)
0831             pr_err("failed to reserve mixdev minor: %d\n", minor);
0832     } else {
0833         minor = input_get_new_minor(MOUSEDEV_MINOR_BASE,
0834                         MOUSEDEV_MINORS, true);
0835         if (minor < 0)
0836             pr_err("failed to reserve new minor: %d\n", minor);
0837     }
0838 
0839     return minor;
0840 }
0841 
0842 static struct mousedev *mousedev_create(struct input_dev *dev,
0843                     struct input_handler *handler,
0844                     bool mixdev)
0845 {
0846     struct mousedev *mousedev;
0847     int minor;
0848     int error;
0849 
0850     minor = mousedev_reserve_minor(mixdev);
0851     if (minor < 0) {
0852         error = minor;
0853         goto err_out;
0854     }
0855 
0856     mousedev = kzalloc(sizeof(struct mousedev), GFP_KERNEL);
0857     if (!mousedev) {
0858         error = -ENOMEM;
0859         goto err_free_minor;
0860     }
0861 
0862     INIT_LIST_HEAD(&mousedev->client_list);
0863     INIT_LIST_HEAD(&mousedev->mixdev_node);
0864     spin_lock_init(&mousedev->client_lock);
0865     mutex_init(&mousedev->mutex);
0866     lockdep_set_subclass(&mousedev->mutex,
0867                  mixdev ? SINGLE_DEPTH_NESTING : 0);
0868     init_waitqueue_head(&mousedev->wait);
0869 
0870     if (mixdev) {
0871         dev_set_name(&mousedev->dev, "mice");
0872 
0873         mousedev->open_device = mixdev_open_devices;
0874         mousedev->close_device = mixdev_close_devices;
0875     } else {
0876         int dev_no = minor;
0877         /* Normalize device number if it falls into legacy range */
0878         if (dev_no < MOUSEDEV_MINOR_BASE + MOUSEDEV_MINORS)
0879             dev_no -= MOUSEDEV_MINOR_BASE;
0880         dev_set_name(&mousedev->dev, "mouse%d", dev_no);
0881 
0882         mousedev->open_device = mousedev_open_device;
0883         mousedev->close_device = mousedev_close_device;
0884     }
0885 
0886     mousedev->exist = true;
0887     mousedev->handle.dev = input_get_device(dev);
0888     mousedev->handle.name = dev_name(&mousedev->dev);
0889     mousedev->handle.handler = handler;
0890     mousedev->handle.private = mousedev;
0891 
0892     mousedev->dev.class = &input_class;
0893     if (dev)
0894         mousedev->dev.parent = &dev->dev;
0895     mousedev->dev.devt = MKDEV(INPUT_MAJOR, minor);
0896     mousedev->dev.release = mousedev_free;
0897     device_initialize(&mousedev->dev);
0898 
0899     if (!mixdev) {
0900         error = input_register_handle(&mousedev->handle);
0901         if (error)
0902             goto err_free_mousedev;
0903     }
0904 
0905     cdev_init(&mousedev->cdev, &mousedev_fops);
0906 
0907     error = cdev_device_add(&mousedev->cdev, &mousedev->dev);
0908     if (error)
0909         goto err_cleanup_mousedev;
0910 
0911     return mousedev;
0912 
0913  err_cleanup_mousedev:
0914     mousedev_cleanup(mousedev);
0915     if (!mixdev)
0916         input_unregister_handle(&mousedev->handle);
0917  err_free_mousedev:
0918     put_device(&mousedev->dev);
0919  err_free_minor:
0920     input_free_minor(minor);
0921  err_out:
0922     return ERR_PTR(error);
0923 }
0924 
0925 static void mousedev_destroy(struct mousedev *mousedev)
0926 {
0927     cdev_device_del(&mousedev->cdev, &mousedev->dev);
0928     mousedev_cleanup(mousedev);
0929     input_free_minor(MINOR(mousedev->dev.devt));
0930     if (mousedev != mousedev_mix)
0931         input_unregister_handle(&mousedev->handle);
0932     put_device(&mousedev->dev);
0933 }
0934 
0935 static int mixdev_add_device(struct mousedev *mousedev)
0936 {
0937     int retval;
0938 
0939     retval = mutex_lock_interruptible(&mousedev_mix->mutex);
0940     if (retval)
0941         return retval;
0942 
0943     if (mousedev_mix->open) {
0944         retval = mousedev_open_device(mousedev);
0945         if (retval)
0946             goto out;
0947 
0948         mousedev->opened_by_mixdev = true;
0949     }
0950 
0951     get_device(&mousedev->dev);
0952     list_add_tail(&mousedev->mixdev_node, &mousedev_mix_list);
0953 
0954  out:
0955     mutex_unlock(&mousedev_mix->mutex);
0956     return retval;
0957 }
0958 
0959 static void mixdev_remove_device(struct mousedev *mousedev)
0960 {
0961     mutex_lock(&mousedev_mix->mutex);
0962 
0963     if (mousedev->opened_by_mixdev) {
0964         mousedev->opened_by_mixdev = false;
0965         mousedev_close_device(mousedev);
0966     }
0967 
0968     list_del_init(&mousedev->mixdev_node);
0969     mutex_unlock(&mousedev_mix->mutex);
0970 
0971     put_device(&mousedev->dev);
0972 }
0973 
0974 static int mousedev_connect(struct input_handler *handler,
0975                 struct input_dev *dev,
0976                 const struct input_device_id *id)
0977 {
0978     struct mousedev *mousedev;
0979     int error;
0980 
0981     mousedev = mousedev_create(dev, handler, false);
0982     if (IS_ERR(mousedev))
0983         return PTR_ERR(mousedev);
0984 
0985     error = mixdev_add_device(mousedev);
0986     if (error) {
0987         mousedev_destroy(mousedev);
0988         return error;
0989     }
0990 
0991     return 0;
0992 }
0993 
0994 static void mousedev_disconnect(struct input_handle *handle)
0995 {
0996     struct mousedev *mousedev = handle->private;
0997 
0998     mixdev_remove_device(mousedev);
0999     mousedev_destroy(mousedev);
1000 }
1001 
1002 static const struct input_device_id mousedev_ids[] = {
1003     {
1004         .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
1005                 INPUT_DEVICE_ID_MATCH_KEYBIT |
1006                 INPUT_DEVICE_ID_MATCH_RELBIT,
1007         .evbit = { BIT_MASK(EV_KEY) | BIT_MASK(EV_REL) },
1008         .keybit = { [BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) },
1009         .relbit = { BIT_MASK(REL_X) | BIT_MASK(REL_Y) },
1010     },  /* A mouse like device, at least one button,
1011            two relative axes */
1012     {
1013         .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
1014                 INPUT_DEVICE_ID_MATCH_RELBIT,
1015         .evbit = { BIT_MASK(EV_KEY) | BIT_MASK(EV_REL) },
1016         .relbit = { BIT_MASK(REL_WHEEL) },
1017     },  /* A separate scrollwheel */
1018     {
1019         .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
1020                 INPUT_DEVICE_ID_MATCH_KEYBIT |
1021                 INPUT_DEVICE_ID_MATCH_ABSBIT,
1022         .evbit = { BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) },
1023         .keybit = { [BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH) },
1024         .absbit = { BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) },
1025     },  /* A tablet like device, at least touch detection,
1026            two absolute axes */
1027     {
1028         .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
1029                 INPUT_DEVICE_ID_MATCH_KEYBIT |
1030                 INPUT_DEVICE_ID_MATCH_ABSBIT,
1031         .evbit = { BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) },
1032         .keybit = { [BIT_WORD(BTN_TOOL_FINGER)] =
1033                 BIT_MASK(BTN_TOOL_FINGER) },
1034         .absbit = { BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) |
1035                 BIT_MASK(ABS_PRESSURE) |
1036                 BIT_MASK(ABS_TOOL_WIDTH) },
1037     },  /* A touchpad */
1038     {
1039         .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
1040             INPUT_DEVICE_ID_MATCH_KEYBIT |
1041             INPUT_DEVICE_ID_MATCH_ABSBIT,
1042         .evbit = { BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) },
1043         .keybit = { [BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) },
1044         .absbit = { BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) },
1045     },  /* Mouse-like device with absolute X and Y but ordinary
1046            clicks, like hp ILO2 High Performance mouse */
1047 
1048     { },    /* Terminating entry */
1049 };
1050 
1051 MODULE_DEVICE_TABLE(input, mousedev_ids);
1052 
1053 static struct input_handler mousedev_handler = {
1054     .event      = mousedev_event,
1055     .connect    = mousedev_connect,
1056     .disconnect = mousedev_disconnect,
1057     .legacy_minors  = true,
1058     .minor      = MOUSEDEV_MINOR_BASE,
1059     .name       = "mousedev",
1060     .id_table   = mousedev_ids,
1061 };
1062 
1063 #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
1064 #include <linux/miscdevice.h>
1065 
1066 static struct miscdevice psaux_mouse = {
1067     .minor  = PSMOUSE_MINOR,
1068     .name   = "psaux",
1069     .fops   = &mousedev_fops,
1070 };
1071 
1072 static bool psaux_registered;
1073 
1074 static void __init mousedev_psaux_register(void)
1075 {
1076     int error;
1077 
1078     error = misc_register(&psaux_mouse);
1079     if (error)
1080         pr_warn("could not register psaux device, error: %d\n",
1081                error);
1082     else
1083         psaux_registered = true;
1084 }
1085 
1086 static void __exit mousedev_psaux_unregister(void)
1087 {
1088     if (psaux_registered)
1089         misc_deregister(&psaux_mouse);
1090 }
1091 #else
1092 static inline void mousedev_psaux_register(void) { }
1093 static inline void mousedev_psaux_unregister(void) { }
1094 #endif
1095 
1096 static int __init mousedev_init(void)
1097 {
1098     int error;
1099 
1100     mousedev_mix = mousedev_create(NULL, &mousedev_handler, true);
1101     if (IS_ERR(mousedev_mix))
1102         return PTR_ERR(mousedev_mix);
1103 
1104     error = input_register_handler(&mousedev_handler);
1105     if (error) {
1106         mousedev_destroy(mousedev_mix);
1107         return error;
1108     }
1109 
1110     mousedev_psaux_register();
1111 
1112     pr_info("PS/2 mouse device common for all mice\n");
1113 
1114     return 0;
1115 }
1116 
1117 static void __exit mousedev_exit(void)
1118 {
1119     mousedev_psaux_unregister();
1120     input_unregister_handler(&mousedev_handler);
1121     mousedev_destroy(mousedev_mix);
1122 }
1123 
1124 module_init(mousedev_init);
1125 module_exit(mousedev_exit);