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