linux/drivers/input/mousedev.c
<<
>>
Prefs
   1/*
   2 * Input driver to ExplorerPS/2 device driver module.
   3 *
   4 * Copyright (c) 1999-2002 Vojtech Pavlik
   5 * Copyright (c) 2004      Dmitry Torokhov
   6 *
   7 * This program is free software; you can redistribute it and/or modify
   8 * it under the terms of the GNU General Public License version 2 as published by
   9 * the Free Software Foundation.
  10 */
  11
  12#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  13
  14#define MOUSEDEV_MINOR_BASE     32
  15#define MOUSEDEV_MINORS         31
  16#define MOUSEDEV_MIX            63
  17
  18#include <linux/sched.h>
  19#include <linux/slab.h>
  20#include <linux/poll.h>
  21#include <linux/module.h>
  22#include <linux/init.h>
  23#include <linux/input.h>
  24#include <linux/random.h>
  25#include <linux/major.h>
  26#include <linux/device.h>
  27#include <linux/cdev.h>
  28#include <linux/kernel.h>
  29
  30MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
  31MODULE_DESCRIPTION("Mouse (ExplorerPS/2) device interfaces");
  32MODULE_LICENSE("GPL");
  33
  34#ifndef CONFIG_INPUT_MOUSEDEV_SCREEN_X
  35#define CONFIG_INPUT_MOUSEDEV_SCREEN_X  1024
  36#endif
  37#ifndef CONFIG_INPUT_MOUSEDEV_SCREEN_Y
  38#define CONFIG_INPUT_MOUSEDEV_SCREEN_Y  768
  39#endif
  40
  41static int xres = CONFIG_INPUT_MOUSEDEV_SCREEN_X;
  42module_param(xres, uint, 0644);
  43MODULE_PARM_DESC(xres, "Horizontal screen resolution");
  44
  45static int yres = CONFIG_INPUT_MOUSEDEV_SCREEN_Y;
  46module_param(yres, uint, 0644);
  47MODULE_PARM_DESC(yres, "Vertical screen resolution");
  48
  49static unsigned tap_time = 200;
  50module_param(tap_time, uint, 0644);
  51MODULE_PARM_DESC(tap_time, "Tap time for touchpads in absolute mode (msecs)");
  52
  53struct mousedev_hw_data {
  54        int dx, dy, dz;
  55        int x, y;
  56        int abs_event;
  57        unsigned long buttons;
  58};
  59
  60struct mousedev {
  61        int open;
  62        struct input_handle handle;
  63        wait_queue_head_t wait;
  64        struct list_head client_list;
  65        spinlock_t client_lock; /* protects client_list */
  66        struct mutex mutex;
  67        struct device dev;
  68        struct cdev cdev;
  69        bool exist;
  70
  71        struct list_head mixdev_node;
  72        bool opened_by_mixdev;
  73
  74        struct mousedev_hw_data packet;
  75        unsigned int pkt_count;
  76        int old_x[4], old_y[4];
  77        int frac_dx, frac_dy;
  78        unsigned long touch;
  79
  80        int (*open_device)(struct mousedev *mousedev);
  81        void (*close_device)(struct mousedev *mousedev);
  82};
  83
  84enum mousedev_emul {
  85        MOUSEDEV_EMUL_PS2,
  86        MOUSEDEV_EMUL_IMPS,
  87        MOUSEDEV_EMUL_EXPS
  88};
  89
  90struct mousedev_motion {
  91        int dx, dy, dz;
  92        unsigned long buttons;
  93};
  94
  95#define PACKET_QUEUE_LEN        16
  96struct mousedev_client {
  97        struct fasync_struct *fasync;
  98        struct mousedev *mousedev;
  99        struct list_head node;
 100
 101        struct mousedev_motion packets[PACKET_QUEUE_LEN];
 102        unsigned int head, tail;
 103        spinlock_t packet_lock;
 104        int pos_x, pos_y;
 105
 106        signed char ps2[6];
 107        unsigned char ready, buffer, bufsiz;
 108        unsigned char imexseq, impsseq;
 109        enum mousedev_emul mode;
 110        unsigned long last_buttons;
 111};
 112
 113#define MOUSEDEV_SEQ_LEN        6
 114
 115static unsigned char mousedev_imps_seq[] = { 0xf3, 200, 0xf3, 100, 0xf3, 80 };
 116static unsigned char mousedev_imex_seq[] = { 0xf3, 200, 0xf3, 200, 0xf3, 80 };
 117
 118static struct mousedev *mousedev_mix;
 119static LIST_HEAD(mousedev_mix_list);
 120
 121#define fx(i)  (mousedev->old_x[(mousedev->pkt_count - (i)) & 03])
 122#define fy(i)  (mousedev->old_y[(mousedev->pkt_count - (i)) & 03])
 123
 124static void mousedev_touchpad_event(struct input_dev *dev,
 125                                    struct mousedev *mousedev,
 126                                    unsigned int code, int value)
 127{
 128        int size, tmp;
 129        enum { FRACTION_DENOM = 128 };
 130
 131        switch (code) {
 132
 133        case ABS_X:
 134
 135                fx(0) = value;
 136                if (mousedev->touch && mousedev->pkt_count >= 2) {
 137                        size = input_abs_get_max(dev, ABS_X) -
 138                                        input_abs_get_min(dev, ABS_X);
 139                        if (size == 0)
 140                                size = 256 * 2;
 141
 142                        tmp = ((value - fx(2)) * 256 * FRACTION_DENOM) / size;
 143                        tmp += mousedev->frac_dx;
 144                        mousedev->packet.dx = tmp / FRACTION_DENOM;
 145                        mousedev->frac_dx =
 146                                tmp - mousedev->packet.dx * FRACTION_DENOM;
 147                }
 148                break;
 149
 150        case ABS_Y:
 151                fy(0) = value;
 152                if (mousedev->touch && mousedev->pkt_count >= 2) {
 153                        /* use X size for ABS_Y to keep the same scale */
 154                        size = input_abs_get_max(dev, ABS_X) -
 155                                        input_abs_get_min(dev, ABS_X);
 156                        if (size == 0)
 157                                size = 256 * 2;
 158
 159                        tmp = -((value - fy(2)) * 256 * FRACTION_DENOM) / size;
 160                        tmp += mousedev->frac_dy;
 161                        mousedev->packet.dy = tmp / FRACTION_DENOM;
 162                        mousedev->frac_dy = tmp -
 163                                mousedev->packet.dy * FRACTION_DENOM;
 164                }
 165                break;
 166        }
 167}
 168
 169static void mousedev_abs_event(struct input_dev *dev, struct mousedev *mousedev,
 170                                unsigned int code, int value)
 171{
 172        int min, max, size;
 173
 174        switch (code) {
 175
 176        case ABS_X:
 177                min = input_abs_get_min(dev, ABS_X);
 178                max = input_abs_get_max(dev, ABS_X);
 179
 180                size = max - min;
 181                if (size == 0)
 182                        size = xres ? : 1;
 183
 184                value = clamp(value, min, max);
 185
 186                mousedev->packet.x = ((value - min) * xres) / size;
 187                mousedev->packet.abs_event = 1;
 188                break;
 189
 190        case ABS_Y:
 191                min = input_abs_get_min(dev, ABS_Y);
 192                max = input_abs_get_max(dev, ABS_Y);
 193
 194                size = max - min;
 195                if (size == 0)
 196                        size = yres ? : 1;
 197
 198                value = clamp(value, min, max);
 199
 200                mousedev->packet.y = yres - ((value - min) * yres) / size;
 201                mousedev->packet.abs_event = 1;
 202                break;
 203        }
 204}
 205
 206static void mousedev_rel_event(struct mousedev *mousedev,
 207                                unsigned int code, int value)
 208{
 209        switch (code) {
 210        case REL_X:
 211                mousedev->packet.dx += value;
 212                break;
 213
 214        case REL_Y:
 215                mousedev->packet.dy -= value;
 216                break;
 217
 218        case REL_WHEEL:
 219                mousedev->packet.dz -= value;
 220                break;
 221        }
 222}
 223
 224static void mousedev_key_event(struct mousedev *mousedev,
 225                                unsigned int code, int value)
 226{
 227        int index;
 228
 229        switch (code) {
 230
 231        case BTN_TOUCH:
 232        case BTN_0:
 233        case BTN_LEFT:          index = 0; break;
 234
 235        case BTN_STYLUS:
 236        case BTN_1:
 237        case BTN_RIGHT:         index = 1; break;
 238
 239        case BTN_2:
 240        case BTN_FORWARD:
 241        case BTN_STYLUS2:
 242        case BTN_MIDDLE:        index = 2; break;
 243
 244        case BTN_3:
 245        case BTN_BACK:
 246        case BTN_SIDE:          index = 3; break;
 247
 248        case BTN_4:
 249        case BTN_EXTRA:         index = 4; break;
 250
 251        default:                return;
 252        }
 253
 254        if (value) {
 255                set_bit(index, &mousedev->packet.buttons);
 256                set_bit(index, &mousedev_mix->packet.buttons);
 257        } else {
 258                clear_bit(index, &mousedev->packet.buttons);
 259                clear_bit(index, &mousedev_mix->packet.buttons);
 260        }
 261}
 262
 263static void mousedev_notify_readers(struct mousedev *mousedev,
 264                                    struct mousedev_hw_data *packet)
 265{
 266        struct mousedev_client *client;
 267        struct mousedev_motion *p;
 268        unsigned int new_head;
 269        int wake_readers = 0;
 270
 271        rcu_read_lock();
 272        list_for_each_entry_rcu(client, &mousedev->client_list, node) {
 273
 274                /* Just acquire the lock, interrupts already disabled */
 275                spin_lock(&client->packet_lock);
 276
 277                p = &client->packets[client->head];
 278                if (client->ready && p->buttons != mousedev->packet.buttons) {
 279                        new_head = (client->head + 1) % PACKET_QUEUE_LEN;
 280                        if (new_head != client->tail) {
 281                                p = &client->packets[client->head = new_head];
 282                                memset(p, 0, sizeof(struct mousedev_motion));
 283                        }
 284                }
 285
 286                if (packet->abs_event) {
 287                        p->dx += packet->x - client->pos_x;
 288                        p->dy += packet->y - client->pos_y;
 289                        client->pos_x = packet->x;
 290                        client->pos_y = packet->y;
 291                }
 292
 293                client->pos_x += packet->dx;
 294                client->pos_x = client->pos_x < 0 ?
 295                        0 : (client->pos_x >= xres ? xres : client->pos_x);
 296                client->pos_y += packet->dy;
 297                client->pos_y = client->pos_y < 0 ?
 298                        0 : (client->pos_y >= yres ? yres : client->pos_y);
 299
 300                p->dx += packet->dx;
 301                p->dy += packet->dy;
 302                p->dz += packet->dz;
 303                p->buttons = mousedev->packet.buttons;
 304
 305                if (p->dx || p->dy || p->dz ||
 306                    p->buttons != client->last_buttons)
 307                        client->ready = 1;
 308
 309                spin_unlock(&client->packet_lock);
 310
 311                if (client->ready) {
 312                        kill_fasync(&client->fasync, SIGIO, POLL_IN);
 313                        wake_readers = 1;
 314                }
 315        }
 316        rcu_read_unlock();
 317
 318        if (wake_readers)
 319                wake_up_interruptible(&mousedev->wait);
 320}
 321
 322static void mousedev_touchpad_touch(struct mousedev *mousedev, int value)
 323{
 324        if (!value) {
 325                if (mousedev->touch &&
 326                    time_before(jiffies,
 327                                mousedev->touch + msecs_to_jiffies(tap_time))) {
 328                        /*
 329                         * Toggle left button to emulate tap.
 330                         * We rely on the fact that mousedev_mix always has 0
 331                         * motion packet so we won't mess current position.
 332                         */
 333                        set_bit(0, &mousedev->packet.buttons);
 334                        set_bit(0, &mousedev_mix->packet.buttons);
 335                        mousedev_notify_readers(mousedev, &mousedev_mix->packet);
 336                        mousedev_notify_readers(mousedev_mix,
 337                                                &mousedev_mix->packet);
 338                        clear_bit(0, &mousedev->packet.buttons);
 339                        clear_bit(0, &mousedev_mix->packet.buttons);
 340                }
 341                mousedev->touch = mousedev->pkt_count = 0;
 342                mousedev->frac_dx = 0;
 343                mousedev->frac_dy = 0;
 344
 345        } else if (!mousedev->touch)
 346                mousedev->touch = jiffies;
 347}
 348
 349static void mousedev_event(struct input_handle *handle,
 350                           unsigned int type, unsigned int code, int value)
 351{
 352        struct mousedev *mousedev = handle->private;
 353
 354        switch (type) {
 355
 356        case EV_ABS:
 357                /* Ignore joysticks */
 358                if (test_bit(BTN_TRIGGER, handle->dev->keybit))
 359                        return;
 360
 361                if (test_bit(BTN_TOOL_FINGER, handle->dev->keybit))
 362                        mousedev_touchpad_event(handle->dev,
 363                                                mousedev, code, value);
 364                else
 365                        mousedev_abs_event(handle->dev, mousedev, code, value);
 366
 367                break;
 368
 369        case EV_REL:
 370                mousedev_rel_event(mousedev, code, value);
 371                break;
 372
 373        case EV_KEY:
 374                if (value != 2) {
 375                        if (code == BTN_TOUCH &&
 376                            test_bit(BTN_TOOL_FINGER, handle->dev->keybit))
 377                                mousedev_touchpad_touch(mousedev, value);
 378                        else
 379                                mousedev_key_event(mousedev, code, value);
 380                }
 381                break;
 382
 383        case EV_SYN:
 384                if (code == SYN_REPORT) {
 385                        if (mousedev->touch) {
 386                                mousedev->pkt_count++;
 387                                /*
 388                                 * Input system eats duplicate events,
 389                                 * but we need all of them to do correct
 390                                 * averaging so apply present one forward
 391                                 */
 392                                fx(0) = fx(1);
 393                                fy(0) = fy(1);
 394                        }
 395
 396                        mousedev_notify_readers(mousedev, &mousedev->packet);
 397                        mousedev_notify_readers(mousedev_mix, &mousedev->packet);
 398
 399                        mousedev->packet.dx = mousedev->packet.dy =
 400                                mousedev->packet.dz = 0;
 401                        mousedev->packet.abs_event = 0;
 402                }
 403                break;
 404        }
 405}
 406
 407static int mousedev_fasync(int fd, struct file *file, int on)
 408{
 409        struct mousedev_client *client = file->private_data;
 410
 411        return fasync_helper(fd, file, on, &client->fasync);
 412}
 413
 414static void mousedev_free(struct device *dev)
 415{
 416        struct mousedev *mousedev = container_of(dev, struct mousedev, dev);
 417
 418        input_put_device(mousedev->handle.dev);
 419        kfree(mousedev);
 420}
 421
 422static int mousedev_open_device(struct mousedev *mousedev)
 423{
 424        int retval;
 425
 426        retval = mutex_lock_interruptible(&mousedev->mutex);
 427        if (retval)
 428                return retval;
 429
 430        if (!mousedev->exist)
 431                retval = -ENODEV;
 432        else if (!mousedev->open++) {
 433                retval = input_open_device(&mousedev->handle);
 434                if (retval)
 435                        mousedev->open--;
 436        }
 437
 438        mutex_unlock(&mousedev->mutex);
 439        return retval;
 440}
 441
 442static void mousedev_close_device(struct mousedev *mousedev)
 443{
 444        mutex_lock(&mousedev->mutex);
 445
 446        if (mousedev->exist && !--mousedev->open)
 447                input_close_device(&mousedev->handle);
 448
 449        mutex_unlock(&mousedev->mutex);
 450}
 451
 452/*
 453 * Open all available devices so they can all be multiplexed in one.
 454 * stream. Note that this function is called with mousedev_mix->mutex
 455 * held.
 456 */
 457static int mixdev_open_devices(struct mousedev *mixdev)
 458{
 459        int error;
 460
 461        error = mutex_lock_interruptible(&mixdev->mutex);
 462        if (error)
 463                return error;
 464
 465        if (!mixdev->open++) {
 466                struct mousedev *mousedev;
 467
 468                list_for_each_entry(mousedev, &mousedev_mix_list, mixdev_node) {
 469                        if (!mousedev->opened_by_mixdev) {
 470                                if (mousedev_open_device(mousedev))
 471                                        continue;
 472
 473                                mousedev->opened_by_mixdev = true;
 474                        }
 475                }
 476        }
 477
 478        mutex_unlock(&mixdev->mutex);
 479        return 0;
 480}
 481
 482/*
 483 * Close all devices that were opened as part of multiplexed
 484 * device. Note that this function is called with mousedev_mix->mutex
 485 * held.
 486 */
 487static void mixdev_close_devices(struct mousedev *mixdev)
 488{
 489        mutex_lock(&mixdev->mutex);
 490
 491        if (!--mixdev->open) {
 492                struct mousedev *mousedev;
 493
 494                list_for_each_entry(mousedev, &mousedev_mix_list, mixdev_node) {
 495                        if (mousedev->opened_by_mixdev) {
 496                                mousedev->opened_by_mixdev = false;
 497                                mousedev_close_device(mousedev);
 498                        }
 499                }
 500        }
 501
 502        mutex_unlock(&mixdev->mutex);
 503}
 504
 505
 506static void mousedev_attach_client(struct mousedev *mousedev,
 507                                   struct mousedev_client *client)
 508{
 509        spin_lock(&mousedev->client_lock);
 510        list_add_tail_rcu(&client->node, &mousedev->client_list);
 511        spin_unlock(&mousedev->client_lock);
 512}
 513
 514static void mousedev_detach_client(struct mousedev *mousedev,
 515                                   struct mousedev_client *client)
 516{
 517        spin_lock(&mousedev->client_lock);
 518        list_del_rcu(&client->node);
 519        spin_unlock(&mousedev->client_lock);
 520        synchronize_rcu();
 521}
 522
 523static int mousedev_release(struct inode *inode, struct file *file)
 524{
 525        struct mousedev_client *client = file->private_data;
 526        struct mousedev *mousedev = client->mousedev;
 527
 528        mousedev_detach_client(mousedev, client);
 529        kfree(client);
 530
 531        mousedev->close_device(mousedev);
 532
 533        return 0;
 534}
 535
 536static int mousedev_open(struct inode *inode, struct file *file)
 537{
 538        struct mousedev_client *client;
 539        struct mousedev *mousedev;
 540        int error;
 541
 542#ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
 543        if (imajor(inode) == MISC_MAJOR)
 544                mousedev = mousedev_mix;
 545        else
 546#endif
 547                mousedev = container_of(inode->i_cdev, struct mousedev, cdev);
 548
 549        client = kzalloc(sizeof(struct mousedev_client), GFP_KERNEL);
 550        if (!client)
 551                return -ENOMEM;
 552
 553        spin_lock_init(&client->packet_lock);
 554        client->pos_x = xres / 2;
 555        client->pos_y = yres / 2;
 556        client->mousedev = mousedev;
 557        mousedev_attach_client(mousedev, client);
 558
 559        error = mousedev->open_device(mousedev);
 560        if (error)
 561                goto err_free_client;
 562
 563        file->private_data = client;
 564        nonseekable_open(inode, file);
 565
 566        return 0;
 567
 568 err_free_client:
 569        mousedev_detach_client(mousedev, client);
 570        kfree(client);
 571        return error;
 572}
 573
 574static inline int mousedev_limit_delta(int delta, int limit)
 575{
 576        return delta > limit ? limit : (delta < -limit ? -limit : delta);
 577}
 578
 579static void mousedev_packet(struct mousedev_client *client,
 580                            signed char *ps2_data)
 581{
 582        struct mousedev_motion *p = &client->packets[client->tail];
 583
 584        ps2_data[0] = 0x08 |
 585                ((p->dx < 0) << 4) | ((p->dy < 0) << 5) | (p->buttons & 0x07);
 586        ps2_data[1] = mousedev_limit_delta(p->dx, 127);
 587        ps2_data[2] = mousedev_limit_delta(p->dy, 127);
 588        p->dx -= ps2_data[1];
 589        p->dy -= ps2_data[2];
 590
 591        switch (client->mode) {
 592        case MOUSEDEV_EMUL_EXPS:
 593                ps2_data[3] = mousedev_limit_delta(p->dz, 7);
 594                p->dz -= ps2_data[3];
 595                ps2_data[3] = (ps2_data[3] & 0x0f) | ((p->buttons & 0x18) << 1);
 596                client->bufsiz = 4;
 597                break;
 598
 599        case MOUSEDEV_EMUL_IMPS:
 600                ps2_data[0] |=
 601                        ((p->buttons & 0x10) >> 3) | ((p->buttons & 0x08) >> 1);
 602                ps2_data[3] = mousedev_limit_delta(p->dz, 127);
 603                p->dz -= ps2_data[3];
 604                client->bufsiz = 4;
 605                break;
 606
 607        case MOUSEDEV_EMUL_PS2:
 608        default:
 609                ps2_data[0] |=
 610                        ((p->buttons & 0x10) >> 3) | ((p->buttons & 0x08) >> 1);
 611                p->dz = 0;
 612                client->bufsiz = 3;
 613                break;
 614        }
 615
 616        if (!p->dx && !p->dy && !p->dz) {
 617                if (client->tail == client->head) {
 618                        client->ready = 0;
 619                        client->last_buttons = p->buttons;
 620                } else
 621                        client->tail = (client->tail + 1) % PACKET_QUEUE_LEN;
 622        }
 623}
 624
 625static void mousedev_generate_response(struct mousedev_client *client,
 626                                        int command)
 627{
 628        client->ps2[0] = 0xfa; /* ACK */
 629
 630        switch (command) {
 631
 632        case 0xeb: /* Poll */
 633                mousedev_packet(client, &client->ps2[1]);
 634                client->bufsiz++; /* account for leading ACK */
 635                break;
 636
 637        case 0xf2: /* Get ID */
 638                switch (client->mode) {
 639                case MOUSEDEV_EMUL_PS2:
 640                        client->ps2[1] = 0;
 641                        break;
 642                case MOUSEDEV_EMUL_IMPS:
 643                        client->ps2[1] = 3;
 644                        break;
 645                case MOUSEDEV_EMUL_EXPS:
 646                        client->ps2[1] = 4;
 647                        break;
 648                }
 649                client->bufsiz = 2;
 650                break;
 651
 652        case 0xe9: /* Get info */
 653                client->ps2[1] = 0x60; client->ps2[2] = 3; client->ps2[3] = 200;
 654                client->bufsiz = 4;
 655                break;
 656
 657        case 0xff: /* Reset */
 658                client->impsseq = client->imexseq = 0;
 659                client->mode = MOUSEDEV_EMUL_PS2;
 660                client->ps2[1] = 0xaa; client->ps2[2] = 0x00;
 661                client->bufsiz = 3;
 662                break;
 663
 664        default:
 665                client->bufsiz = 1;
 666                break;
 667        }
 668        client->buffer = client->bufsiz;
 669}
 670
 671static ssize_t mousedev_write(struct file *file, const char __user *buffer,
 672                                size_t count, loff_t *ppos)
 673{
 674        struct mousedev_client *client = file->private_data;
 675        unsigned char c;
 676        unsigned int i;
 677
 678        for (i = 0; i < count; i++) {
 679
 680                if (get_user(c, buffer + i))
 681                        return -EFAULT;
 682
 683                spin_lock_irq(&client->packet_lock);
 684
 685                if (c == mousedev_imex_seq[client->imexseq]) {
 686                        if (++client->imexseq == MOUSEDEV_SEQ_LEN) {
 687                                client->imexseq = 0;
 688                                client->mode = MOUSEDEV_EMUL_EXPS;
 689                        }
 690                } else
 691                        client->imexseq = 0;
 692
 693                if (c == mousedev_imps_seq[client->impsseq]) {
 694                        if (++client->impsseq == MOUSEDEV_SEQ_LEN) {
 695                                client->impsseq = 0;
 696                                client->mode = MOUSEDEV_EMUL_IMPS;
 697                        }
 698                } else
 699                        client->impsseq = 0;
 700
 701                mousedev_generate_response(client, c);
 702
 703                spin_unlock_irq(&client->packet_lock);
 704        }
 705
 706        kill_fasync(&client->fasync, SIGIO, POLL_IN);
 707        wake_up_interruptible(&client->mousedev->wait);
 708
 709        return count;
 710}
 711
 712static ssize_t mousedev_read(struct file *file, char __user *buffer,
 713                             size_t count, loff_t *ppos)
 714{
 715        struct mousedev_client *client = file->private_data;
 716        struct mousedev *mousedev = client->mousedev;
 717        signed char data[sizeof(client->ps2)];
 718        int retval = 0;
 719
 720        if (!client->ready && !client->buffer && mousedev->exist &&
 721            (file->f_flags & O_NONBLOCK))
 722                return -EAGAIN;
 723
 724        retval = wait_event_interruptible(mousedev->wait,
 725                        !mousedev->exist || client->ready || client->buffer);
 726        if (retval)
 727                return retval;
 728
 729        if (!mousedev->exist)
 730                return -ENODEV;
 731
 732        spin_lock_irq(&client->packet_lock);
 733
 734        if (!client->buffer && client->ready) {
 735                mousedev_packet(client, client->ps2);
 736                client->buffer = client->bufsiz;
 737        }
 738
 739        if (count > client->buffer)
 740                count = client->buffer;
 741
 742        memcpy(data, client->ps2 + client->bufsiz - client->buffer, count);
 743        client->buffer -= count;
 744
 745        spin_unlock_irq(&client->packet_lock);
 746
 747        if (copy_to_user(buffer, data, count))
 748                return -EFAULT;
 749
 750        return count;
 751}
 752
 753/* No kernel lock - fine */
 754static unsigned int mousedev_poll(struct file *file, poll_table *wait)
 755{
 756        struct mousedev_client *client = file->private_data;
 757        struct mousedev *mousedev = client->mousedev;
 758        unsigned int mask;
 759
 760        poll_wait(file, &mousedev->wait, wait);
 761
 762        mask = mousedev->exist ? POLLOUT | POLLWRNORM : POLLHUP | POLLERR;
 763        if (client->ready || client->buffer)
 764                mask |= POLLIN | POLLRDNORM;
 765
 766        return mask;
 767}
 768
 769static const struct file_operations mousedev_fops = {
 770        .owner          = THIS_MODULE,
 771        .read           = mousedev_read,
 772        .write          = mousedev_write,
 773        .poll           = mousedev_poll,
 774        .open           = mousedev_open,
 775        .release        = mousedev_release,
 776        .fasync         = mousedev_fasync,
 777        .llseek         = noop_llseek,
 778};
 779
 780/*
 781 * Mark device non-existent. This disables writes, ioctls and
 782 * prevents new users from opening the device. Already posted
 783 * blocking reads will stay, however new ones will fail.
 784 */
 785static void mousedev_mark_dead(struct mousedev *mousedev)
 786{
 787        mutex_lock(&mousedev->mutex);
 788        mousedev->exist = false;
 789        mutex_unlock(&mousedev->mutex);
 790}
 791
 792/*
 793 * Wake up users waiting for IO so they can disconnect from
 794 * dead device.
 795 */
 796static void mousedev_hangup(struct mousedev *mousedev)
 797{
 798        struct mousedev_client *client;
 799
 800        spin_lock(&mousedev->client_lock);
 801        list_for_each_entry(client, &mousedev->client_list, node)
 802                kill_fasync(&client->fasync, SIGIO, POLL_HUP);
 803        spin_unlock(&mousedev->client_lock);
 804
 805        wake_up_interruptible(&mousedev->wait);
 806}
 807
 808static void mousedev_cleanup(struct mousedev *mousedev)
 809{
 810        struct input_handle *handle = &mousedev->handle;
 811
 812        mousedev_mark_dead(mousedev);
 813        mousedev_hangup(mousedev);
 814
 815        cdev_del(&mousedev->cdev);
 816
 817        /* mousedev is marked dead so no one else accesses mousedev->open */
 818        if (mousedev->open)
 819                input_close_device(handle);
 820}
 821
 822static int mousedev_reserve_minor(bool mixdev)
 823{
 824        int minor;
 825
 826        if (mixdev) {
 827                minor = input_get_new_minor(MOUSEDEV_MIX, 1, false);
 828                if (minor < 0)
 829                        pr_err("failed to reserve mixdev minor: %d\n", minor);
 830        } else {
 831                minor = input_get_new_minor(MOUSEDEV_MINOR_BASE,
 832                                            MOUSEDEV_MINORS, true);
 833                if (minor < 0)
 834                        pr_err("failed to reserve new minor: %d\n", minor);
 835        }
 836
 837        return minor;
 838}
 839
 840static struct mousedev *mousedev_create(struct input_dev *dev,
 841                                        struct input_handler *handler,
 842                                        bool mixdev)
 843{
 844        struct mousedev *mousedev;
 845        int minor;
 846        int error;
 847
 848        minor = mousedev_reserve_minor(mixdev);
 849        if (minor < 0) {
 850                error = minor;
 851                goto err_out;
 852        }
 853
 854        mousedev = kzalloc(sizeof(struct mousedev), GFP_KERNEL);
 855        if (!mousedev) {
 856                error = -ENOMEM;
 857                goto err_free_minor;
 858        }
 859
 860        INIT_LIST_HEAD(&mousedev->client_list);
 861        INIT_LIST_HEAD(&mousedev->mixdev_node);
 862        spin_lock_init(&mousedev->client_lock);
 863        mutex_init(&mousedev->mutex);
 864        lockdep_set_subclass(&mousedev->mutex,
 865                             mixdev ? SINGLE_DEPTH_NESTING : 0);
 866        init_waitqueue_head(&mousedev->wait);
 867
 868        if (mixdev) {
 869                dev_set_name(&mousedev->dev, "mice");
 870
 871                mousedev->open_device = mixdev_open_devices;
 872                mousedev->close_device = mixdev_close_devices;
 873        } else {
 874                int dev_no = minor;
 875                /* Normalize device number if it falls into legacy range */
 876                if (dev_no < MOUSEDEV_MINOR_BASE + MOUSEDEV_MINORS)
 877                        dev_no -= MOUSEDEV_MINOR_BASE;
 878                dev_set_name(&mousedev->dev, "mouse%d", dev_no);
 879
 880                mousedev->open_device = mousedev_open_device;
 881                mousedev->close_device = mousedev_close_device;
 882        }
 883
 884        mousedev->exist = true;
 885        mousedev->handle.dev = input_get_device(dev);
 886        mousedev->handle.name = dev_name(&mousedev->dev);
 887        mousedev->handle.handler = handler;
 888        mousedev->handle.private = mousedev;
 889
 890        mousedev->dev.class = &input_class;
 891        if (dev)
 892                mousedev->dev.parent = &dev->dev;
 893        mousedev->dev.devt = MKDEV(INPUT_MAJOR, minor);
 894        mousedev->dev.release = mousedev_free;
 895        device_initialize(&mousedev->dev);
 896
 897        if (!mixdev) {
 898                error = input_register_handle(&mousedev->handle);
 899                if (error)
 900                        goto err_free_mousedev;
 901        }
 902
 903        cdev_init(&mousedev->cdev, &mousedev_fops);
 904        mousedev->cdev.kobj.parent = &mousedev->dev.kobj;
 905        error = cdev_add(&mousedev->cdev, mousedev->dev.devt, 1);
 906        if (error)
 907                goto err_unregister_handle;
 908
 909        error = device_add(&mousedev->dev);
 910        if (error)
 911                goto err_cleanup_mousedev;
 912
 913        return mousedev;
 914
 915 err_cleanup_mousedev:
 916        mousedev_cleanup(mousedev);
 917 err_unregister_handle:
 918        if (!mixdev)
 919                input_unregister_handle(&mousedev->handle);
 920 err_free_mousedev:
 921        put_device(&mousedev->dev);
 922 err_free_minor:
 923        input_free_minor(minor);
 924 err_out:
 925        return ERR_PTR(error);
 926}
 927
 928static void mousedev_destroy(struct mousedev *mousedev)
 929{
 930        device_del(&mousedev->dev);
 931        mousedev_cleanup(mousedev);
 932        input_free_minor(MINOR(mousedev->dev.devt));
 933        if (mousedev != mousedev_mix)
 934                input_unregister_handle(&mousedev->handle);
 935        put_device(&mousedev->dev);
 936}
 937
 938static int mixdev_add_device(struct mousedev *mousedev)
 939{
 940        int retval;
 941
 942        retval = mutex_lock_interruptible(&mousedev_mix->mutex);
 943        if (retval)
 944                return retval;
 945
 946        if (mousedev_mix->open) {
 947                retval = mousedev_open_device(mousedev);
 948                if (retval)
 949                        goto out;
 950
 951                mousedev->opened_by_mixdev = true;
 952        }
 953
 954        get_device(&mousedev->dev);
 955        list_add_tail(&mousedev->mixdev_node, &mousedev_mix_list);
 956
 957 out:
 958        mutex_unlock(&mousedev_mix->mutex);
 959        return retval;
 960}
 961
 962static void mixdev_remove_device(struct mousedev *mousedev)
 963{
 964        mutex_lock(&mousedev_mix->mutex);
 965
 966        if (mousedev->opened_by_mixdev) {
 967                mousedev->opened_by_mixdev = false;
 968                mousedev_close_device(mousedev);
 969        }
 970
 971        list_del_init(&mousedev->mixdev_node);
 972        mutex_unlock(&mousedev_mix->mutex);
 973
 974        put_device(&mousedev->dev);
 975}
 976
 977static int mousedev_connect(struct input_handler *handler,
 978                            struct input_dev *dev,
 979                            const struct input_device_id *id)
 980{
 981        struct mousedev *mousedev;
 982        int error;
 983
 984        mousedev = mousedev_create(dev, handler, false);
 985        if (IS_ERR(mousedev))
 986                return PTR_ERR(mousedev);
 987
 988        error = mixdev_add_device(mousedev);
 989        if (error) {
 990                mousedev_destroy(mousedev);
 991                return error;
 992        }
 993
 994        return 0;
 995}
 996
 997static void mousedev_disconnect(struct input_handle *handle)
 998{
 999        struct mousedev *mousedev = handle->private;
1000
1001        mixdev_remove_device(mousedev);
1002        mousedev_destroy(mousedev);
1003}
1004
1005static const struct input_device_id mousedev_ids[] = {
1006        {
1007                .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
1008                                INPUT_DEVICE_ID_MATCH_KEYBIT |
1009                                INPUT_DEVICE_ID_MATCH_RELBIT,
1010                .evbit = { BIT_MASK(EV_KEY) | BIT_MASK(EV_REL) },
1011                .keybit = { [BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) },
1012                .relbit = { BIT_MASK(REL_X) | BIT_MASK(REL_Y) },
1013        },      /* A mouse like device, at least one button,
1014                   two relative axes */
1015        {
1016                .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
1017                                INPUT_DEVICE_ID_MATCH_RELBIT,
1018                .evbit = { BIT_MASK(EV_KEY) | BIT_MASK(EV_REL) },
1019                .relbit = { BIT_MASK(REL_WHEEL) },
1020        },      /* A separate scrollwheel */
1021        {
1022                .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
1023                                INPUT_DEVICE_ID_MATCH_KEYBIT |
1024                                INPUT_DEVICE_ID_MATCH_ABSBIT,
1025                .evbit = { BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) },
1026                .keybit = { [BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH) },
1027                .absbit = { BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) },
1028        },      /* A tablet like device, at least touch detection,
1029                   two absolute axes */
1030        {
1031                .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
1032                                INPUT_DEVICE_ID_MATCH_KEYBIT |
1033                                INPUT_DEVICE_ID_MATCH_ABSBIT,
1034                .evbit = { BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) },
1035                .keybit = { [BIT_WORD(BTN_TOOL_FINGER)] =
1036                                BIT_MASK(BTN_TOOL_FINGER) },
1037                .absbit = { BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) |
1038                                BIT_MASK(ABS_PRESSURE) |
1039                                BIT_MASK(ABS_TOOL_WIDTH) },
1040        },      /* A touchpad */
1041        {
1042                .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
1043                        INPUT_DEVICE_ID_MATCH_KEYBIT |
1044                        INPUT_DEVICE_ID_MATCH_ABSBIT,
1045                .evbit = { BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) },
1046                .keybit = { [BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) },
1047                .absbit = { BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) },
1048        },      /* Mouse-like device with absolute X and Y but ordinary
1049                   clicks, like hp ILO2 High Performance mouse */
1050
1051        { },    /* Terminating entry */
1052};
1053
1054MODULE_DEVICE_TABLE(input, mousedev_ids);
1055
1056static struct input_handler mousedev_handler = {
1057        .event          = mousedev_event,
1058        .connect        = mousedev_connect,
1059        .disconnect     = mousedev_disconnect,
1060        .legacy_minors  = true,
1061        .minor          = MOUSEDEV_MINOR_BASE,
1062        .name           = "mousedev",
1063        .id_table       = mousedev_ids,
1064};
1065
1066#ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
1067#include <linux/miscdevice.h>
1068
1069static struct miscdevice psaux_mouse = {
1070        .minor  = PSMOUSE_MINOR,
1071        .name   = "psaux",
1072        .fops   = &mousedev_fops,
1073};
1074
1075static bool psaux_registered;
1076
1077static void __init mousedev_psaux_register(void)
1078{
1079        int error;
1080
1081        error = misc_register(&psaux_mouse);
1082        if (error)
1083                pr_warn("could not register psaux device, error: %d\n",
1084                           error);
1085        else
1086                psaux_registered = true;
1087}
1088
1089static void __exit mousedev_psaux_unregister(void)
1090{
1091        if (psaux_registered)
1092                misc_deregister(&psaux_mouse);
1093}
1094#else
1095static inline void mousedev_psaux_register(void) { }
1096static inline void mousedev_psaux_unregister(void) { }
1097#endif
1098
1099static int __init mousedev_init(void)
1100{
1101        int error;
1102
1103        mousedev_mix = mousedev_create(NULL, &mousedev_handler, true);
1104        if (IS_ERR(mousedev_mix))
1105                return PTR_ERR(mousedev_mix);
1106
1107        error = input_register_handler(&mousedev_handler);
1108        if (error) {
1109                mousedev_destroy(mousedev_mix);
1110                return error;
1111        }
1112
1113        mousedev_psaux_register();
1114
1115        pr_info("PS/2 mouse device common for all mice\n");
1116
1117        return 0;
1118}
1119
1120static void __exit mousedev_exit(void)
1121{
1122        mousedev_psaux_unregister();
1123        input_unregister_handler(&mousedev_handler);
1124        mousedev_destroy(mousedev_mix);
1125}
1126
1127module_init(mousedev_init);
1128module_exit(mousedev_exit);
1129