linux/drivers/input/joydev.c
<<
>>
Prefs
   1/*
   2 * Joystick device driver for the input driver suite.
   3 *
   4 * Copyright (c) 1999-2002 Vojtech Pavlik
   5 * Copyright (c) 1999 Colin Van Dyke
   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 as published by
   9 * the Free Software Foundation; either version 2 of the License, or
  10 * (at your option) any later version.
  11 */
  12
  13#include <asm/io.h>
  14#include <asm/system.h>
  15#include <linux/delay.h>
  16#include <linux/errno.h>
  17#include <linux/joystick.h>
  18#include <linux/input.h>
  19#include <linux/kernel.h>
  20#include <linux/major.h>
  21#include <linux/sched.h>
  22#include <linux/slab.h>
  23#include <linux/mm.h>
  24#include <linux/miscdevice.h>
  25#include <linux/module.h>
  26#include <linux/poll.h>
  27#include <linux/init.h>
  28#include <linux/device.h>
  29
  30MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
  31MODULE_DESCRIPTION("Joystick device interfaces");
  32MODULE_SUPPORTED_DEVICE("input/js");
  33MODULE_LICENSE("GPL");
  34
  35#define JOYDEV_MINOR_BASE       0
  36#define JOYDEV_MINORS           16
  37#define JOYDEV_BUFFER_SIZE      64
  38
  39struct joydev {
  40        int exist;
  41        int open;
  42        int minor;
  43        struct input_handle handle;
  44        wait_queue_head_t wait;
  45        struct list_head client_list;
  46        spinlock_t client_lock; /* protects client_list */
  47        struct mutex mutex;
  48        struct device dev;
  49
  50        struct js_corr corr[ABS_MAX + 1];
  51        struct JS_DATA_SAVE_TYPE glue;
  52        int nabs;
  53        int nkey;
  54        __u16 keymap[KEY_MAX - BTN_MISC + 1];
  55        __u16 keypam[KEY_MAX - BTN_MISC + 1];
  56        __u8 absmap[ABS_MAX + 1];
  57        __u8 abspam[ABS_MAX + 1];
  58        __s16 abs[ABS_MAX + 1];
  59};
  60
  61struct joydev_client {
  62        struct js_event buffer[JOYDEV_BUFFER_SIZE];
  63        int head;
  64        int tail;
  65        int startup;
  66        spinlock_t buffer_lock; /* protects access to buffer, head and tail */
  67        struct fasync_struct *fasync;
  68        struct joydev *joydev;
  69        struct list_head node;
  70};
  71
  72static struct joydev *joydev_table[JOYDEV_MINORS];
  73static DEFINE_MUTEX(joydev_table_mutex);
  74
  75static int joydev_correct(int value, struct js_corr *corr)
  76{
  77        switch (corr->type) {
  78
  79        case JS_CORR_NONE:
  80                break;
  81
  82        case JS_CORR_BROKEN:
  83                value = value > corr->coef[0] ? (value < corr->coef[1] ? 0 :
  84                        ((corr->coef[3] * (value - corr->coef[1])) >> 14)) :
  85                        ((corr->coef[2] * (value - corr->coef[0])) >> 14);
  86                break;
  87
  88        default:
  89                return 0;
  90        }
  91
  92        return value < -32767 ? -32767 : (value > 32767 ? 32767 : value);
  93}
  94
  95static void joydev_pass_event(struct joydev_client *client,
  96                              struct js_event *event)
  97{
  98        struct joydev *joydev = client->joydev;
  99
 100        /*
 101         * IRQs already disabled, just acquire the lock
 102         */
 103        spin_lock(&client->buffer_lock);
 104
 105        client->buffer[client->head] = *event;
 106
 107        if (client->startup == joydev->nabs + joydev->nkey) {
 108                client->head++;
 109                client->head &= JOYDEV_BUFFER_SIZE - 1;
 110                if (client->tail == client->head)
 111                        client->startup = 0;
 112        }
 113
 114        spin_unlock(&client->buffer_lock);
 115
 116        kill_fasync(&client->fasync, SIGIO, POLL_IN);
 117}
 118
 119static void joydev_event(struct input_handle *handle,
 120                         unsigned int type, unsigned int code, int value)
 121{
 122        struct joydev *joydev = handle->private;
 123        struct joydev_client *client;
 124        struct js_event event;
 125
 126        switch (type) {
 127
 128        case EV_KEY:
 129                if (code < BTN_MISC || value == 2)
 130                        return;
 131                event.type = JS_EVENT_BUTTON;
 132                event.number = joydev->keymap[code - BTN_MISC];
 133                event.value = value;
 134                break;
 135
 136        case EV_ABS:
 137                event.type = JS_EVENT_AXIS;
 138                event.number = joydev->absmap[code];
 139                event.value = joydev_correct(value,
 140                                        &joydev->corr[event.number]);
 141                if (event.value == joydev->abs[event.number])
 142                        return;
 143                joydev->abs[event.number] = event.value;
 144                break;
 145
 146        default:
 147                return;
 148        }
 149
 150        event.time = jiffies_to_msecs(jiffies);
 151
 152        rcu_read_lock();
 153        list_for_each_entry_rcu(client, &joydev->client_list, node)
 154                joydev_pass_event(client, &event);
 155        rcu_read_unlock();
 156
 157        wake_up_interruptible(&joydev->wait);
 158}
 159
 160static int joydev_fasync(int fd, struct file *file, int on)
 161{
 162        struct joydev_client *client = file->private_data;
 163
 164        return fasync_helper(fd, file, on, &client->fasync);
 165}
 166
 167static void joydev_free(struct device *dev)
 168{
 169        struct joydev *joydev = container_of(dev, struct joydev, dev);
 170
 171        input_put_device(joydev->handle.dev);
 172        kfree(joydev);
 173}
 174
 175static void joydev_attach_client(struct joydev *joydev,
 176                                 struct joydev_client *client)
 177{
 178        spin_lock(&joydev->client_lock);
 179        list_add_tail_rcu(&client->node, &joydev->client_list);
 180        spin_unlock(&joydev->client_lock);
 181        synchronize_rcu();
 182}
 183
 184static void joydev_detach_client(struct joydev *joydev,
 185                                 struct joydev_client *client)
 186{
 187        spin_lock(&joydev->client_lock);
 188        list_del_rcu(&client->node);
 189        spin_unlock(&joydev->client_lock);
 190        synchronize_rcu();
 191}
 192
 193static int joydev_open_device(struct joydev *joydev)
 194{
 195        int retval;
 196
 197        retval = mutex_lock_interruptible(&joydev->mutex);
 198        if (retval)
 199                return retval;
 200
 201        if (!joydev->exist)
 202                retval = -ENODEV;
 203        else if (!joydev->open++) {
 204                retval = input_open_device(&joydev->handle);
 205                if (retval)
 206                        joydev->open--;
 207        }
 208
 209        mutex_unlock(&joydev->mutex);
 210        return retval;
 211}
 212
 213static void joydev_close_device(struct joydev *joydev)
 214{
 215        mutex_lock(&joydev->mutex);
 216
 217        if (joydev->exist && !--joydev->open)
 218                input_close_device(&joydev->handle);
 219
 220        mutex_unlock(&joydev->mutex);
 221}
 222
 223/*
 224 * Wake up users waiting for IO so they can disconnect from
 225 * dead device.
 226 */
 227static void joydev_hangup(struct joydev *joydev)
 228{
 229        struct joydev_client *client;
 230
 231        spin_lock(&joydev->client_lock);
 232        list_for_each_entry(client, &joydev->client_list, node)
 233                kill_fasync(&client->fasync, SIGIO, POLL_HUP);
 234        spin_unlock(&joydev->client_lock);
 235
 236        wake_up_interruptible(&joydev->wait);
 237}
 238
 239static int joydev_release(struct inode *inode, struct file *file)
 240{
 241        struct joydev_client *client = file->private_data;
 242        struct joydev *joydev = client->joydev;
 243
 244        joydev_detach_client(joydev, client);
 245        kfree(client);
 246
 247        joydev_close_device(joydev);
 248        put_device(&joydev->dev);
 249
 250        return 0;
 251}
 252
 253static int joydev_open(struct inode *inode, struct file *file)
 254{
 255        struct joydev_client *client;
 256        struct joydev *joydev;
 257        int i = iminor(inode) - JOYDEV_MINOR_BASE;
 258        int error;
 259
 260        if (i >= JOYDEV_MINORS)
 261                return -ENODEV;
 262
 263        error = mutex_lock_interruptible(&joydev_table_mutex);
 264        if (error)
 265                return error;
 266        joydev = joydev_table[i];
 267        if (joydev)
 268                get_device(&joydev->dev);
 269        mutex_unlock(&joydev_table_mutex);
 270
 271        if (!joydev)
 272                return -ENODEV;
 273
 274        client = kzalloc(sizeof(struct joydev_client), GFP_KERNEL);
 275        if (!client) {
 276                error = -ENOMEM;
 277                goto err_put_joydev;
 278        }
 279
 280        spin_lock_init(&client->buffer_lock);
 281        client->joydev = joydev;
 282        joydev_attach_client(joydev, client);
 283
 284        error = joydev_open_device(joydev);
 285        if (error)
 286                goto err_free_client;
 287
 288        file->private_data = client;
 289        return 0;
 290
 291 err_free_client:
 292        joydev_detach_client(joydev, client);
 293        kfree(client);
 294 err_put_joydev:
 295        put_device(&joydev->dev);
 296        return error;
 297}
 298
 299static int joydev_generate_startup_event(struct joydev_client *client,
 300                                         struct input_dev *input,
 301                                         struct js_event *event)
 302{
 303        struct joydev *joydev = client->joydev;
 304        int have_event;
 305
 306        spin_lock_irq(&client->buffer_lock);
 307
 308        have_event = client->startup < joydev->nabs + joydev->nkey;
 309
 310        if (have_event) {
 311
 312                event->time = jiffies_to_msecs(jiffies);
 313                if (client->startup < joydev->nkey) {
 314                        event->type = JS_EVENT_BUTTON | JS_EVENT_INIT;
 315                        event->number = client->startup;
 316                        event->value = !!test_bit(joydev->keypam[event->number],
 317                                                  input->key);
 318                } else {
 319                        event->type = JS_EVENT_AXIS | JS_EVENT_INIT;
 320                        event->number = client->startup - joydev->nkey;
 321                        event->value = joydev->abs[event->number];
 322                }
 323                client->startup++;
 324        }
 325
 326        spin_unlock_irq(&client->buffer_lock);
 327
 328        return have_event;
 329}
 330
 331static int joydev_fetch_next_event(struct joydev_client *client,
 332                                   struct js_event *event)
 333{
 334        int have_event;
 335
 336        spin_lock_irq(&client->buffer_lock);
 337
 338        have_event = client->head != client->tail;
 339        if (have_event) {
 340                *event = client->buffer[client->tail++];
 341                client->tail &= JOYDEV_BUFFER_SIZE - 1;
 342        }
 343
 344        spin_unlock_irq(&client->buffer_lock);
 345
 346        return have_event;
 347}
 348
 349/*
 350 * Old joystick interface
 351 */
 352static ssize_t joydev_0x_read(struct joydev_client *client,
 353                              struct input_dev *input,
 354                              char __user *buf)
 355{
 356        struct joydev *joydev = client->joydev;
 357        struct JS_DATA_TYPE data;
 358        int i;
 359
 360        spin_lock_irq(&input->event_lock);
 361
 362        /*
 363         * Get device state
 364         */
 365        for (data.buttons = i = 0; i < 32 && i < joydev->nkey; i++)
 366                data.buttons |=
 367                        test_bit(joydev->keypam[i], input->key) ? (1 << i) : 0;
 368        data.x = (joydev->abs[0] / 256 + 128) >> joydev->glue.JS_CORR.x;
 369        data.y = (joydev->abs[1] / 256 + 128) >> joydev->glue.JS_CORR.y;
 370
 371        /*
 372         * Reset reader's event queue
 373         */
 374        spin_lock(&client->buffer_lock);
 375        client->startup = 0;
 376        client->tail = client->head;
 377        spin_unlock(&client->buffer_lock);
 378
 379        spin_unlock_irq(&input->event_lock);
 380
 381        if (copy_to_user(buf, &data, sizeof(struct JS_DATA_TYPE)))
 382                return -EFAULT;
 383
 384        return sizeof(struct JS_DATA_TYPE);
 385}
 386
 387static inline int joydev_data_pending(struct joydev_client *client)
 388{
 389        struct joydev *joydev = client->joydev;
 390
 391        return client->startup < joydev->nabs + joydev->nkey ||
 392                client->head != client->tail;
 393}
 394
 395static ssize_t joydev_read(struct file *file, char __user *buf,
 396                           size_t count, loff_t *ppos)
 397{
 398        struct joydev_client *client = file->private_data;
 399        struct joydev *joydev = client->joydev;
 400        struct input_dev *input = joydev->handle.dev;
 401        struct js_event event;
 402        int retval;
 403
 404        if (!joydev->exist)
 405                return -ENODEV;
 406
 407        if (count < sizeof(struct js_event))
 408                return -EINVAL;
 409
 410        if (count == sizeof(struct JS_DATA_TYPE))
 411                return joydev_0x_read(client, input, buf);
 412
 413        if (!joydev_data_pending(client) && (file->f_flags & O_NONBLOCK))
 414                return -EAGAIN;
 415
 416        retval = wait_event_interruptible(joydev->wait,
 417                        !joydev->exist || joydev_data_pending(client));
 418        if (retval)
 419                return retval;
 420
 421        if (!joydev->exist)
 422                return -ENODEV;
 423
 424        while (retval + sizeof(struct js_event) <= count &&
 425               joydev_generate_startup_event(client, input, &event)) {
 426
 427                if (copy_to_user(buf + retval, &event, sizeof(struct js_event)))
 428                        return -EFAULT;
 429
 430                retval += sizeof(struct js_event);
 431        }
 432
 433        while (retval + sizeof(struct js_event) <= count &&
 434               joydev_fetch_next_event(client, &event)) {
 435
 436                if (copy_to_user(buf + retval, &event, sizeof(struct js_event)))
 437                        return -EFAULT;
 438
 439                retval += sizeof(struct js_event);
 440        }
 441
 442        return retval;
 443}
 444
 445/* No kernel lock - fine */
 446static unsigned int joydev_poll(struct file *file, poll_table *wait)
 447{
 448        struct joydev_client *client = file->private_data;
 449        struct joydev *joydev = client->joydev;
 450
 451        poll_wait(file, &joydev->wait, wait);
 452        return (joydev_data_pending(client) ? (POLLIN | POLLRDNORM) : 0) |
 453                (joydev->exist ?  0 : (POLLHUP | POLLERR));
 454}
 455
 456static int joydev_handle_JSIOCSAXMAP(struct joydev *joydev,
 457                                     void __user *argp, size_t len)
 458{
 459        __u8 *abspam;
 460        int i;
 461        int retval = 0;
 462
 463        len = min(len, sizeof(joydev->abspam));
 464
 465        /* Validate the map. */
 466        abspam = kmalloc(len, GFP_KERNEL);
 467        if (!abspam)
 468                return -ENOMEM;
 469
 470        if (copy_from_user(abspam, argp, len)) {
 471                retval = -EFAULT;
 472                goto out;
 473        }
 474
 475        for (i = 0; i < joydev->nabs; i++) {
 476                if (abspam[i] > ABS_MAX) {
 477                        retval = -EINVAL;
 478                        goto out;
 479                }
 480        }
 481
 482        memcpy(joydev->abspam, abspam, len);
 483
 484 out:
 485        kfree(abspam);
 486        return retval;
 487}
 488
 489static int joydev_handle_JSIOCSBTNMAP(struct joydev *joydev,
 490                                      void __user *argp, size_t len)
 491{
 492        __u16 *keypam;
 493        int i;
 494        int retval = 0;
 495
 496        len = min(len, sizeof(joydev->keypam));
 497
 498        /* Validate the map. */
 499        keypam = kmalloc(len, GFP_KERNEL);
 500        if (!keypam)
 501                return -ENOMEM;
 502
 503        if (copy_from_user(keypam, argp, len)) {
 504                retval = -EFAULT;
 505                goto out;
 506        }
 507
 508        for (i = 0; i < joydev->nkey; i++) {
 509                if (keypam[i] > KEY_MAX || keypam[i] < BTN_MISC) {
 510                        retval = -EINVAL;
 511                        goto out;
 512                }
 513        }
 514
 515        memcpy(joydev->keypam, keypam, len);
 516
 517        for (i = 0; i < joydev->nkey; i++)
 518                joydev->keymap[keypam[i] - BTN_MISC] = i;
 519
 520 out:
 521        kfree(keypam);
 522        return retval;
 523}
 524
 525
 526static int joydev_ioctl_common(struct joydev *joydev,
 527                                unsigned int cmd, void __user *argp)
 528{
 529        struct input_dev *dev = joydev->handle.dev;
 530        size_t len;
 531        int i, j;
 532        const char *name;
 533
 534        /* Process fixed-sized commands. */
 535        switch (cmd) {
 536
 537        case JS_SET_CAL:
 538                return copy_from_user(&joydev->glue.JS_CORR, argp,
 539                                sizeof(joydev->glue.JS_CORR)) ? -EFAULT : 0;
 540
 541        case JS_GET_CAL:
 542                return copy_to_user(argp, &joydev->glue.JS_CORR,
 543                                sizeof(joydev->glue.JS_CORR)) ? -EFAULT : 0;
 544
 545        case JS_SET_TIMEOUT:
 546                return get_user(joydev->glue.JS_TIMEOUT, (s32 __user *) argp);
 547
 548        case JS_GET_TIMEOUT:
 549                return put_user(joydev->glue.JS_TIMEOUT, (s32 __user *) argp);
 550
 551        case JSIOCGVERSION:
 552                return put_user(JS_VERSION, (__u32 __user *) argp);
 553
 554        case JSIOCGAXES:
 555                return put_user(joydev->nabs, (__u8 __user *) argp);
 556
 557        case JSIOCGBUTTONS:
 558                return put_user(joydev->nkey, (__u8 __user *) argp);
 559
 560        case JSIOCSCORR:
 561                if (copy_from_user(joydev->corr, argp,
 562                              sizeof(joydev->corr[0]) * joydev->nabs))
 563                    return -EFAULT;
 564
 565                for (i = 0; i < joydev->nabs; i++) {
 566                        j = joydev->abspam[i];
 567                        joydev->abs[i] = joydev_correct(dev->abs[j],
 568                                                        &joydev->corr[i]);
 569                }
 570                return 0;
 571
 572        case JSIOCGCORR:
 573                return copy_to_user(argp, joydev->corr,
 574                        sizeof(joydev->corr[0]) * joydev->nabs) ? -EFAULT : 0;
 575
 576        }
 577
 578        /*
 579         * Process variable-sized commands (the axis and button map commands
 580         * are considered variable-sized to decouple them from the values of
 581         * ABS_MAX and KEY_MAX).
 582         */
 583        switch (cmd & ~IOCSIZE_MASK) {
 584
 585        case (JSIOCSAXMAP & ~IOCSIZE_MASK):
 586                return joydev_handle_JSIOCSAXMAP(joydev, argp, _IOC_SIZE(cmd));
 587
 588        case (JSIOCGAXMAP & ~IOCSIZE_MASK):
 589                len = min_t(size_t, _IOC_SIZE(cmd), sizeof(joydev->abspam));
 590                return copy_to_user(argp, joydev->abspam, len) ? -EFAULT : len;
 591
 592        case (JSIOCSBTNMAP & ~IOCSIZE_MASK):
 593                return joydev_handle_JSIOCSBTNMAP(joydev, argp, _IOC_SIZE(cmd));
 594
 595        case (JSIOCGBTNMAP & ~IOCSIZE_MASK):
 596                len = min_t(size_t, _IOC_SIZE(cmd), sizeof(joydev->keypam));
 597                return copy_to_user(argp, joydev->keypam, len) ? -EFAULT : len;
 598
 599        case JSIOCGNAME(0):
 600                name = dev->name;
 601                if (!name)
 602                        return 0;
 603
 604                len = min_t(size_t, _IOC_SIZE(cmd), strlen(name) + 1);
 605                return copy_to_user(argp, name, len) ? -EFAULT : len;
 606        }
 607
 608        return -EINVAL;
 609}
 610
 611#ifdef CONFIG_COMPAT
 612static long joydev_compat_ioctl(struct file *file,
 613                                unsigned int cmd, unsigned long arg)
 614{
 615        struct joydev_client *client = file->private_data;
 616        struct joydev *joydev = client->joydev;
 617        void __user *argp = (void __user *)arg;
 618        s32 tmp32;
 619        struct JS_DATA_SAVE_TYPE_32 ds32;
 620        int retval;
 621
 622        retval = mutex_lock_interruptible(&joydev->mutex);
 623        if (retval)
 624                return retval;
 625
 626        if (!joydev->exist) {
 627                retval = -ENODEV;
 628                goto out;
 629        }
 630
 631        switch (cmd) {
 632
 633        case JS_SET_TIMELIMIT:
 634                retval = get_user(tmp32, (s32 __user *) arg);
 635                if (retval == 0)
 636                        joydev->glue.JS_TIMELIMIT = tmp32;
 637                break;
 638
 639        case JS_GET_TIMELIMIT:
 640                tmp32 = joydev->glue.JS_TIMELIMIT;
 641                retval = put_user(tmp32, (s32 __user *) arg);
 642                break;
 643
 644        case JS_SET_ALL:
 645                retval = copy_from_user(&ds32, argp,
 646                                        sizeof(ds32)) ? -EFAULT : 0;
 647                if (retval == 0) {
 648                        joydev->glue.JS_TIMEOUT    = ds32.JS_TIMEOUT;
 649                        joydev->glue.BUSY          = ds32.BUSY;
 650                        joydev->glue.JS_EXPIRETIME = ds32.JS_EXPIRETIME;
 651                        joydev->glue.JS_TIMELIMIT  = ds32.JS_TIMELIMIT;
 652                        joydev->glue.JS_SAVE       = ds32.JS_SAVE;
 653                        joydev->glue.JS_CORR       = ds32.JS_CORR;
 654                }
 655                break;
 656
 657        case JS_GET_ALL:
 658                ds32.JS_TIMEOUT    = joydev->glue.JS_TIMEOUT;
 659                ds32.BUSY          = joydev->glue.BUSY;
 660                ds32.JS_EXPIRETIME = joydev->glue.JS_EXPIRETIME;
 661                ds32.JS_TIMELIMIT  = joydev->glue.JS_TIMELIMIT;
 662                ds32.JS_SAVE       = joydev->glue.JS_SAVE;
 663                ds32.JS_CORR       = joydev->glue.JS_CORR;
 664
 665                retval = copy_to_user(argp, &ds32, sizeof(ds32)) ? -EFAULT : 0;
 666                break;
 667
 668        default:
 669                retval = joydev_ioctl_common(joydev, cmd, argp);
 670                break;
 671        }
 672
 673 out:
 674        mutex_unlock(&joydev->mutex);
 675        return retval;
 676}
 677#endif /* CONFIG_COMPAT */
 678
 679static long joydev_ioctl(struct file *file,
 680                         unsigned int cmd, unsigned long arg)
 681{
 682        struct joydev_client *client = file->private_data;
 683        struct joydev *joydev = client->joydev;
 684        void __user *argp = (void __user *)arg;
 685        int retval;
 686
 687        retval = mutex_lock_interruptible(&joydev->mutex);
 688        if (retval)
 689                return retval;
 690
 691        if (!joydev->exist) {
 692                retval = -ENODEV;
 693                goto out;
 694        }
 695
 696        switch (cmd) {
 697
 698        case JS_SET_TIMELIMIT:
 699                retval = get_user(joydev->glue.JS_TIMELIMIT,
 700                                  (long __user *) arg);
 701                break;
 702
 703        case JS_GET_TIMELIMIT:
 704                retval = put_user(joydev->glue.JS_TIMELIMIT,
 705                                  (long __user *) arg);
 706                break;
 707
 708        case JS_SET_ALL:
 709                retval = copy_from_user(&joydev->glue, argp,
 710                                        sizeof(joydev->glue)) ? -EFAULT: 0;
 711                break;
 712
 713        case JS_GET_ALL:
 714                retval = copy_to_user(argp, &joydev->glue,
 715                                      sizeof(joydev->glue)) ? -EFAULT : 0;
 716                break;
 717
 718        default:
 719                retval = joydev_ioctl_common(joydev, cmd, argp);
 720                break;
 721        }
 722 out:
 723        mutex_unlock(&joydev->mutex);
 724        return retval;
 725}
 726
 727static const struct file_operations joydev_fops = {
 728        .owner          = THIS_MODULE,
 729        .read           = joydev_read,
 730        .poll           = joydev_poll,
 731        .open           = joydev_open,
 732        .release        = joydev_release,
 733        .unlocked_ioctl = joydev_ioctl,
 734#ifdef CONFIG_COMPAT
 735        .compat_ioctl   = joydev_compat_ioctl,
 736#endif
 737        .fasync         = joydev_fasync,
 738};
 739
 740static int joydev_install_chrdev(struct joydev *joydev)
 741{
 742        joydev_table[joydev->minor] = joydev;
 743        return 0;
 744}
 745
 746static void joydev_remove_chrdev(struct joydev *joydev)
 747{
 748        mutex_lock(&joydev_table_mutex);
 749        joydev_table[joydev->minor] = NULL;
 750        mutex_unlock(&joydev_table_mutex);
 751}
 752
 753/*
 754 * Mark device non-existant. This disables writes, ioctls and
 755 * prevents new users from opening the device. Already posted
 756 * blocking reads will stay, however new ones will fail.
 757 */
 758static void joydev_mark_dead(struct joydev *joydev)
 759{
 760        mutex_lock(&joydev->mutex);
 761        joydev->exist = 0;
 762        mutex_unlock(&joydev->mutex);
 763}
 764
 765static void joydev_cleanup(struct joydev *joydev)
 766{
 767        struct input_handle *handle = &joydev->handle;
 768
 769        joydev_mark_dead(joydev);
 770        joydev_hangup(joydev);
 771        joydev_remove_chrdev(joydev);
 772
 773        /* joydev is marked dead so noone else accesses joydev->open */
 774        if (joydev->open)
 775                input_close_device(handle);
 776}
 777
 778static int joydev_connect(struct input_handler *handler, struct input_dev *dev,
 779                          const struct input_device_id *id)
 780{
 781        struct joydev *joydev;
 782        int i, j, t, minor;
 783        int error;
 784
 785        for (minor = 0; minor < JOYDEV_MINORS; minor++)
 786                if (!joydev_table[minor])
 787                        break;
 788
 789        if (minor == JOYDEV_MINORS) {
 790                printk(KERN_ERR "joydev: no more free joydev devices\n");
 791                return -ENFILE;
 792        }
 793
 794        joydev = kzalloc(sizeof(struct joydev), GFP_KERNEL);
 795        if (!joydev)
 796                return -ENOMEM;
 797
 798        INIT_LIST_HEAD(&joydev->client_list);
 799        spin_lock_init(&joydev->client_lock);
 800        mutex_init(&joydev->mutex);
 801        init_waitqueue_head(&joydev->wait);
 802
 803        dev_set_name(&joydev->dev, "js%d", minor);
 804        joydev->exist = 1;
 805        joydev->minor = minor;
 806
 807        joydev->exist = 1;
 808        joydev->handle.dev = input_get_device(dev);
 809        joydev->handle.name = dev_name(&joydev->dev);
 810        joydev->handle.handler = handler;
 811        joydev->handle.private = joydev;
 812
 813        for (i = 0; i < ABS_MAX + 1; i++)
 814                if (test_bit(i, dev->absbit)) {
 815                        joydev->absmap[i] = joydev->nabs;
 816                        joydev->abspam[joydev->nabs] = i;
 817                        joydev->nabs++;
 818                }
 819
 820        for (i = BTN_JOYSTICK - BTN_MISC; i < KEY_MAX - BTN_MISC + 1; i++)
 821                if (test_bit(i + BTN_MISC, dev->keybit)) {
 822                        joydev->keymap[i] = joydev->nkey;
 823                        joydev->keypam[joydev->nkey] = i + BTN_MISC;
 824                        joydev->nkey++;
 825                }
 826
 827        for (i = 0; i < BTN_JOYSTICK - BTN_MISC; i++)
 828                if (test_bit(i + BTN_MISC, dev->keybit)) {
 829                        joydev->keymap[i] = joydev->nkey;
 830                        joydev->keypam[joydev->nkey] = i + BTN_MISC;
 831                        joydev->nkey++;
 832                }
 833
 834        for (i = 0; i < joydev->nabs; i++) {
 835                j = joydev->abspam[i];
 836                if (dev->absmax[j] == dev->absmin[j]) {
 837                        joydev->corr[i].type = JS_CORR_NONE;
 838                        joydev->abs[i] = dev->abs[j];
 839                        continue;
 840                }
 841                joydev->corr[i].type = JS_CORR_BROKEN;
 842                joydev->corr[i].prec = dev->absfuzz[j];
 843                joydev->corr[i].coef[0] =
 844                        (dev->absmax[j] + dev->absmin[j]) / 2 - dev->absflat[j];
 845                joydev->corr[i].coef[1] =
 846                        (dev->absmax[j] + dev->absmin[j]) / 2 + dev->absflat[j];
 847
 848                t = (dev->absmax[j] - dev->absmin[j]) / 2 - 2 * dev->absflat[j];
 849                if (t) {
 850                        joydev->corr[i].coef[2] = (1 << 29) / t;
 851                        joydev->corr[i].coef[3] = (1 << 29) / t;
 852
 853                        joydev->abs[i] = joydev_correct(dev->abs[j],
 854                                                        joydev->corr + i);
 855                }
 856        }
 857
 858        joydev->dev.devt = MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor);
 859        joydev->dev.class = &input_class;
 860        joydev->dev.parent = &dev->dev;
 861        joydev->dev.release = joydev_free;
 862        device_initialize(&joydev->dev);
 863
 864        error = input_register_handle(&joydev->handle);
 865        if (error)
 866                goto err_free_joydev;
 867
 868        error = joydev_install_chrdev(joydev);
 869        if (error)
 870                goto err_unregister_handle;
 871
 872        error = device_add(&joydev->dev);
 873        if (error)
 874                goto err_cleanup_joydev;
 875
 876        return 0;
 877
 878 err_cleanup_joydev:
 879        joydev_cleanup(joydev);
 880 err_unregister_handle:
 881        input_unregister_handle(&joydev->handle);
 882 err_free_joydev:
 883        put_device(&joydev->dev);
 884        return error;
 885}
 886
 887static void joydev_disconnect(struct input_handle *handle)
 888{
 889        struct joydev *joydev = handle->private;
 890
 891        device_del(&joydev->dev);
 892        joydev_cleanup(joydev);
 893        input_unregister_handle(handle);
 894        put_device(&joydev->dev);
 895}
 896
 897static const struct input_device_id joydev_blacklist[] = {
 898        {
 899                .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
 900                                INPUT_DEVICE_ID_MATCH_KEYBIT,
 901                .evbit = { BIT_MASK(EV_KEY) },
 902                .keybit = { [BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH) },
 903        },      /* Avoid itouchpads and touchscreens */
 904        {
 905                .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
 906                                INPUT_DEVICE_ID_MATCH_KEYBIT,
 907                .evbit = { BIT_MASK(EV_KEY) },
 908                .keybit = { [BIT_WORD(BTN_DIGI)] = BIT_MASK(BTN_DIGI) },
 909        },      /* Avoid tablets, digitisers and similar devices */
 910        { }     /* Terminating entry */
 911};
 912
 913static const struct input_device_id joydev_ids[] = {
 914        {
 915                .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
 916                                INPUT_DEVICE_ID_MATCH_ABSBIT,
 917                .evbit = { BIT_MASK(EV_ABS) },
 918                .absbit = { BIT_MASK(ABS_X) },
 919        },
 920        {
 921                .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
 922                                INPUT_DEVICE_ID_MATCH_ABSBIT,
 923                .evbit = { BIT_MASK(EV_ABS) },
 924                .absbit = { BIT_MASK(ABS_WHEEL) },
 925        },
 926        {
 927                .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
 928                                INPUT_DEVICE_ID_MATCH_ABSBIT,
 929                .evbit = { BIT_MASK(EV_ABS) },
 930                .absbit = { BIT_MASK(ABS_THROTTLE) },
 931        },
 932        { }     /* Terminating entry */
 933};
 934
 935MODULE_DEVICE_TABLE(input, joydev_ids);
 936
 937static struct input_handler joydev_handler = {
 938        .event          = joydev_event,
 939        .connect        = joydev_connect,
 940        .disconnect     = joydev_disconnect,
 941        .fops           = &joydev_fops,
 942        .minor          = JOYDEV_MINOR_BASE,
 943        .name           = "joydev",
 944        .id_table       = joydev_ids,
 945        .blacklist      = joydev_blacklist,
 946};
 947
 948static int __init joydev_init(void)
 949{
 950        return input_register_handler(&joydev_handler);
 951}
 952
 953static void __exit joydev_exit(void)
 954{
 955        input_unregister_handler(&joydev_handler);
 956}
 957
 958module_init(joydev_init);
 959module_exit(joydev_exit);
 960