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