linux/drivers/staging/frontier/alphatrack.c
<<
>>
Prefs
   1/*
   2 * Frontier Designs Alphatrack driver
   3 *
   4 * Copyright (C) 2007 Michael Taht (m@taht.net)
   5 *
   6 * Based on the usbled driver and ldusb drivers by
   7 *
   8 * Copyright (C) 2004 Greg Kroah-Hartman (greg@kroah.com)
   9 * Copyright (C) 2005 Michael Hund <mhund@ld-didactic.de>
  10 *
  11 * The ldusb driver was, in turn, derived from Lego USB Tower driver
  12 * Copyright (C) 2003 David Glance <advidgsf@sourceforge.net>
  13 *               2001-2004 Juergen Stuber <starblue@users.sourceforge.net>
  14 *
  15 *      This program is free software; you can redistribute it and/or
  16 *      modify it under the terms of the GNU General Public License as
  17 *      published by the Free Software Foundation, version 2.
  18 *
  19 */
  20
  21/**
  22 * This driver uses a ring buffer for time critical reading of
  23 * interrupt in reports and provides read and write methods for
  24 * raw interrupt reports.
  25 */
  26
  27/* Note: this currently uses a dumb ringbuffer for reads and writes.
  28 * A more optimal driver would cache and kill off outstanding urbs that are
  29 * now invalid, and ignore ones that already were in the queue but valid
  30 * as we only have 30 commands for the alphatrack. In particular this is
  31 * key for getting lights to flash in time as otherwise many commands
  32 * can be buffered up before the light change makes it to the interface.
  33*/
  34
  35#include <linux/kernel.h>
  36#include <linux/errno.h>
  37#include <linux/init.h>
  38#include <linux/slab.h>
  39#include <linux/module.h>
  40#include <linux/kobject.h>
  41#include <linux/mutex.h>
  42
  43#include <linux/uaccess.h>
  44#include <linux/input.h>
  45#include <linux/usb.h>
  46#include <linux/poll.h>
  47
  48#include "alphatrack.h"
  49
  50#define VENDOR_ID       0x165b
  51#define PRODUCT_ID      0xfad1
  52
  53#ifdef CONFIG_USB_DYNAMIC_MINORS
  54#define USB_ALPHATRACK_MINOR_BASE       0
  55#else
  56/* FIXME 176 - is another driver's minor - apply for that */
  57#define USB_ALPHATRACK_MINOR_BASE       176
  58#endif
  59
  60/* table of devices that work with this driver */
  61static const struct usb_device_id usb_alphatrack_table[] = {
  62        {USB_DEVICE(VENDOR_ID, PRODUCT_ID)},
  63        {}                      /* Terminating entry */
  64};
  65
  66MODULE_DEVICE_TABLE(usb, usb_alphatrack_table);
  67MODULE_VERSION("0.41");
  68MODULE_AUTHOR("Mike Taht <m@taht.net>");
  69MODULE_DESCRIPTION("Alphatrack USB Driver");
  70MODULE_LICENSE("GPL");
  71MODULE_SUPPORTED_DEVICE("Frontier Designs Alphatrack Control Surface");
  72
  73/* These aren't done yet */
  74
  75#define SUPPRESS_EXTRA_ONLINE_EVENTS 0
  76#define BUFFERED_WRITES 0
  77#define SUPPRESS_EXTRA_OFFLINE_EVENTS 0
  78#define COMPRESS_FADER_EVENTS 0
  79
  80#define BUFFERED_READS 1
  81#define RING_BUFFER_SIZE 512
  82#define WRITE_BUFFER_SIZE 34
  83#define ALPHATRACK_USB_TIMEOUT 10
  84#define OUTPUT_CMD_SIZE 8
  85#define INPUT_CMD_SIZE 12
  86#define ALPHATRACK_DEBUG 0
  87
  88static int debug = ALPHATRACK_DEBUG;
  89
  90/* Use our own dbg macro */
  91#define dbg_info(dev, format, arg...) do \
  92        { if (debug) dev_info(dev , format , ## arg); } while (0)
  93
  94#define alphatrack_ocmd_info(dev, cmd, format, arg...)
  95
  96#define alphatrack_icmd_info(dev, cmd, format, arg...)
  97
  98/* Module parameters */
  99
 100module_param(debug, int, S_IRUGO | S_IWUSR);
 101MODULE_PARM_DESC(debug, "Debug enabled or not");
 102
 103/* All interrupt in transfers are collected in a ring buffer to
 104 * avoid racing conditions and get better performance of the driver.
 105 */
 106
 107static int ring_buffer_size = RING_BUFFER_SIZE;
 108
 109module_param(ring_buffer_size, int, S_IRUGO);
 110MODULE_PARM_DESC(ring_buffer_size, "Read ring buffer size");
 111
 112/* The write_buffer can one day contain more than one interrupt out transfer.
 113 */
 114
 115static int write_buffer_size = WRITE_BUFFER_SIZE;
 116module_param(write_buffer_size, int, S_IRUGO);
 117MODULE_PARM_DESC(write_buffer_size, "Write buffer size");
 118
 119/*
 120 * Increase the interval for debugging purposes.
 121 * or set to 1 to use the standard interval from the endpoint descriptors.
 122 */
 123
 124static int min_interrupt_in_interval = ALPHATRACK_USB_TIMEOUT;
 125module_param(min_interrupt_in_interval, int, 0);
 126MODULE_PARM_DESC(min_interrupt_in_interval,
 127                 "Minimum interrupt in interval in ms");
 128
 129static int min_interrupt_out_interval = ALPHATRACK_USB_TIMEOUT;
 130module_param(min_interrupt_out_interval, int, 0);
 131MODULE_PARM_DESC(min_interrupt_out_interval,
 132                 "Minimum interrupt out interval in ms");
 133
 134/* Structure to hold all of our device specific stuff */
 135
 136struct usb_alphatrack {
 137        struct mutex mtx;       /* locks this structure */
 138        struct usb_interface *intf;     /* save off the usb interface pointer */
 139        int open_count;         /* number of times this port has been opened */
 140
 141        /* make gcc happy */
 142        struct alphatrack_icmd (*ring_buffer)[RING_BUFFER_SIZE];
 143        struct alphatrack_ocmd (*write_buffer)[WRITE_BUFFER_SIZE];
 144        unsigned int ring_head;
 145        unsigned int ring_tail;
 146
 147        wait_queue_head_t read_wait;
 148        wait_queue_head_t write_wait;
 149
 150        unsigned char *interrupt_in_buffer;
 151        unsigned char *oldi_buffer;
 152        struct usb_endpoint_descriptor *interrupt_in_endpoint;
 153        struct urb *interrupt_in_urb;
 154        int interrupt_in_interval;
 155        size_t interrupt_in_endpoint_size;
 156        int interrupt_in_running;
 157        int interrupt_in_done;
 158
 159        char *interrupt_out_buffer;
 160        struct usb_endpoint_descriptor *interrupt_out_endpoint;
 161        struct urb *interrupt_out_urb;
 162        int interrupt_out_interval;
 163        size_t interrupt_out_endpoint_size;
 164        int interrupt_out_busy;
 165
 166        atomic_t writes_pending;
 167        int event;              /* alternate interface to events */
 168        int fader;              /* 10 bits */
 169        int lights;             /* 23 bits */
 170        unsigned char dump_state;       /* 0 if disabled 1 if enabled */
 171        unsigned char enable;   /* 0 if disabled 1 if enabled */
 172        unsigned char offline;  /* if the device is out of range or asleep */
 173        unsigned char verbose;  /* be verbose in error reporting */
 174        unsigned char last_cmd[OUTPUT_CMD_SIZE];
 175        unsigned char screen[32];
 176};
 177
 178/* prevent races between open() and disconnect() */
 179static DEFINE_MUTEX(disconnect_mutex);
 180
 181/* forward declaration */
 182
 183static struct usb_driver usb_alphatrack_driver;
 184
 185/**
 186 *      usb_alphatrack_abort_transfers
 187 *      aborts transfers and frees associated data structures
 188 */
 189static void usb_alphatrack_abort_transfers(struct usb_alphatrack *dev)
 190{
 191        /* shutdown transfer */
 192        if (dev->interrupt_in_running) {
 193                dev->interrupt_in_running = 0;
 194                if (dev->intf)
 195                        usb_kill_urb(dev->interrupt_in_urb);
 196        }
 197        if (dev->interrupt_out_busy)
 198                if (dev->intf)
 199                        usb_kill_urb(dev->interrupt_out_urb);
 200}
 201
 202/**
 203 *      usb_alphatrack_delete
 204 */
 205static void usb_alphatrack_delete(struct usb_alphatrack *dev)
 206{
 207        usb_alphatrack_abort_transfers(dev);
 208        usb_free_urb(dev->interrupt_in_urb);
 209        usb_free_urb(dev->interrupt_out_urb);
 210        kfree(dev->ring_buffer);
 211        kfree(dev->interrupt_in_buffer);
 212        kfree(dev->interrupt_out_buffer);
 213        kfree(dev);             /* fixme oldi_buffer */
 214}
 215
 216/**
 217 *      usb_alphatrack_interrupt_in_callback
 218 */
 219
 220static void usb_alphatrack_interrupt_in_callback(struct urb *urb)
 221{
 222        struct usb_alphatrack *dev = urb->context;
 223        unsigned int next_ring_head;
 224        int retval = -1;
 225
 226        if (urb->status) {
 227                if (urb->status == -ENOENT ||
 228                    urb->status == -ECONNRESET || urb->status == -ESHUTDOWN) {
 229                        goto exit;
 230                } else {
 231                        dbg_info(&dev->intf->dev,
 232                                 "%s: nonzero status received: %d\n", __func__,
 233                                 urb->status);
 234                        goto resubmit;  /* maybe we can recover */
 235                }
 236        }
 237
 238        if (urb->actual_length != INPUT_CMD_SIZE) {
 239                dev_warn(&dev->intf->dev,
 240                         "Urb length was %d bytes!!"
 241                         "Do something intelligent\n", urb->actual_length);
 242        } else {
 243                alphatrack_ocmd_info(&dev->intf->dev,
 244                                     &(*dev->ring_buffer)[dev->ring_tail].cmd,
 245                                     "%s", "bla");
 246                if (memcmp
 247                    (dev->interrupt_in_buffer, dev->oldi_buffer,
 248                     INPUT_CMD_SIZE) == 0) {
 249                        goto resubmit;
 250                }
 251                memcpy(dev->oldi_buffer, dev->interrupt_in_buffer,
 252                       INPUT_CMD_SIZE);
 253
 254#if SUPPRESS_EXTRA_OFFLINE_EVENTS
 255                if (dev->offline == 2 && dev->interrupt_in_buffer[1] == 0xff)
 256                        goto resubmit;
 257                if (dev->offline == 1 && dev->interrupt_in_buffer[1] == 0xff) {
 258                        dev->offline = 2;
 259                        goto resubmit;
 260                }
 261/* Always pass one offline event up the stack */
 262                if (dev->offline > 0 && dev->interrupt_in_buffer[1] != 0xff)
 263                        dev->offline = 0;
 264                if (dev->offline == 0 && dev->interrupt_in_buffer[1] == 0xff)
 265                        dev->offline = 1;
 266#endif
 267                dbg_info(&dev->intf->dev, "%s: head, tail are %x, %x\n",
 268                         __func__, dev->ring_head, dev->ring_tail);
 269                next_ring_head = (dev->ring_head + 1) % ring_buffer_size;
 270
 271                if (next_ring_head != dev->ring_tail) {
 272                        memcpy(&((*dev->ring_buffer)[dev->ring_head]),
 273                               dev->interrupt_in_buffer, urb->actual_length);
 274                        dev->ring_head = next_ring_head;
 275                        retval = 0;
 276                        memset(dev->interrupt_in_buffer, 0, urb->actual_length);
 277                } else {
 278                        dev_warn(&dev->intf->dev,
 279                                 "Ring buffer overflow, %d bytes dropped\n",
 280                                 urb->actual_length);
 281                        memset(dev->interrupt_in_buffer, 0, urb->actual_length);
 282                }
 283        }
 284
 285resubmit:
 286        /* resubmit if we're still running */
 287        if (dev->interrupt_in_running && dev->intf) {
 288                retval = usb_submit_urb(dev->interrupt_in_urb, GFP_ATOMIC);
 289                if (retval)
 290                        dev_err(&dev->intf->dev,
 291                                "usb_submit_urb failed (%d)\n", retval);
 292        }
 293
 294exit:
 295        dev->interrupt_in_done = 1;
 296        wake_up_interruptible(&dev->read_wait);
 297}
 298
 299/**
 300 *      usb_alphatrack_interrupt_out_callback
 301 */
 302static void usb_alphatrack_interrupt_out_callback(struct urb *urb)
 303{
 304        struct usb_alphatrack *dev = urb->context;
 305
 306        /* sync/async unlink faults aren't errors */
 307        if (urb->status && !(urb->status == -ENOENT ||
 308                             urb->status == -ECONNRESET ||
 309                             urb->status == -ESHUTDOWN))
 310                dbg_info(&dev->intf->dev,
 311                         "%s - nonzero write interrupt status received: %d\n",
 312                         __func__, urb->status);
 313        atomic_dec(&dev->writes_pending);
 314        dev->interrupt_out_busy = 0;
 315        wake_up_interruptible(&dev->write_wait);
 316}
 317
 318/**
 319 *      usb_alphatrack_open
 320 */
 321static int usb_alphatrack_open(struct inode *inode, struct file *file)
 322{
 323        struct usb_alphatrack *dev;
 324        int subminor;
 325        int retval = 0;
 326        struct usb_interface *interface;
 327
 328        nonseekable_open(inode, file);
 329        subminor = iminor(inode);
 330
 331        mutex_lock(&disconnect_mutex);
 332
 333        interface = usb_find_interface(&usb_alphatrack_driver, subminor);
 334
 335        if (!interface) {
 336                err("%s - error, can't find device for minor %d\n",
 337                    __func__, subminor);
 338                retval = -ENODEV;
 339                goto unlock_disconnect_exit;
 340        }
 341
 342        dev = usb_get_intfdata(interface);
 343
 344        if (!dev) {
 345                retval = -ENODEV;
 346                goto unlock_disconnect_exit;
 347        }
 348
 349        /* lock this device */
 350        if (mutex_lock_interruptible(&dev->mtx)) {
 351                retval = -ERESTARTSYS;
 352                goto unlock_disconnect_exit;
 353        }
 354
 355        /* allow opening only once */
 356        if (dev->open_count) {
 357                retval = -EBUSY;
 358                goto unlock_exit;
 359        }
 360        dev->open_count = 1;
 361
 362        /* initialize in direction */
 363        dev->ring_head = 0;
 364        dev->ring_tail = 0;
 365        usb_fill_int_urb(dev->interrupt_in_urb,
 366                         interface_to_usbdev(interface),
 367                         usb_rcvintpipe(interface_to_usbdev(interface),
 368                                        dev->interrupt_in_endpoint->
 369                                        bEndpointAddress),
 370                         dev->interrupt_in_buffer,
 371                         dev->interrupt_in_endpoint_size,
 372                         usb_alphatrack_interrupt_in_callback, dev,
 373                         dev->interrupt_in_interval);
 374
 375        dev->interrupt_in_running = 1;
 376        dev->interrupt_in_done = 0;
 377        dev->enable = 1;
 378        dev->offline = 0;
 379
 380        retval = usb_submit_urb(dev->interrupt_in_urb, GFP_KERNEL);
 381        if (retval) {
 382                dev_err(&interface->dev,
 383                        "Couldn't submit interrupt_in_urb %d\n", retval);
 384                dev->interrupt_in_running = 0;
 385                dev->open_count = 0;
 386                goto unlock_exit;
 387        }
 388
 389        /* save device in the file's private structure */
 390        file->private_data = dev;
 391
 392unlock_exit:
 393        mutex_unlock(&dev->mtx);
 394
 395unlock_disconnect_exit:
 396        mutex_unlock(&disconnect_mutex);
 397
 398        return retval;
 399}
 400
 401/**
 402 *      usb_alphatrack_release
 403 */
 404static int usb_alphatrack_release(struct inode *inode, struct file *file)
 405{
 406        struct usb_alphatrack *dev;
 407        int retval = 0;
 408
 409        dev = file->private_data;
 410
 411        if (dev == NULL) {
 412                retval = -ENODEV;
 413                goto exit;
 414        }
 415
 416        if (mutex_lock_interruptible(&dev->mtx)) {
 417                retval = -ERESTARTSYS;
 418                goto exit;
 419        }
 420
 421        if (dev->open_count != 1) {
 422                retval = -ENODEV;
 423                goto unlock_exit;
 424        }
 425
 426        if (dev->intf == NULL) {
 427                /* the device was unplugged before the file was released */
 428                mutex_unlock(&dev->mtx);
 429                /* unlock here as usb_alphatrack_delete frees dev */
 430                usb_alphatrack_delete(dev);
 431                retval = -ENODEV;
 432                goto exit;
 433        }
 434
 435        /* wait until write transfer is finished */
 436        if (dev->interrupt_out_busy)
 437                wait_event_interruptible_timeout(dev->write_wait,
 438                                                 !dev->interrupt_out_busy,
 439                                                 2 * HZ);
 440        usb_alphatrack_abort_transfers(dev);
 441        dev->open_count = 0;
 442
 443unlock_exit:
 444        mutex_unlock(&dev->mtx);
 445
 446exit:
 447        return retval;
 448}
 449
 450/**
 451 *      usb_alphatrack_poll
 452 */
 453static unsigned int usb_alphatrack_poll(struct file *file, poll_table * wait)
 454{
 455        struct usb_alphatrack *dev;
 456        unsigned int mask = 0;
 457
 458        dev = file->private_data;
 459
 460        poll_wait(file, &dev->read_wait, wait);
 461        poll_wait(file, &dev->write_wait, wait);
 462
 463        if (dev->ring_head != dev->ring_tail)
 464                mask |= POLLIN | POLLRDNORM;
 465        if (!dev->interrupt_out_busy)
 466                mask |= POLLOUT | POLLWRNORM;
 467
 468        return mask;
 469}
 470
 471/**
 472 *      usb_alphatrack_read
 473 */
 474static ssize_t usb_alphatrack_read(struct file *file, char __user *buffer,
 475                                   size_t count, loff_t *ppos)
 476{
 477        struct usb_alphatrack *dev;
 478        int retval = 0;
 479
 480        int c = 0;
 481
 482        dev = file->private_data;
 483
 484        /* verify that we actually have some data to read */
 485        if (count == 0)
 486                goto exit;
 487
 488        /* lock this object */
 489        if (mutex_lock_interruptible(&dev->mtx)) {
 490                retval = -ERESTARTSYS;
 491                goto exit;
 492        }
 493
 494        /* verify that the device wasn't unplugged */
 495        if (dev->intf == NULL) {
 496                retval = -ENODEV;
 497                err("No device or device unplugged %d\n", retval);
 498                goto unlock_exit;
 499        }
 500
 501        while (dev->ring_head == dev->ring_tail) {
 502                if (file->f_flags & O_NONBLOCK) {
 503                        retval = -EAGAIN;
 504                        goto unlock_exit;
 505                }
 506                dev->interrupt_in_done = 0;
 507                retval =
 508                    wait_event_interruptible(dev->read_wait,
 509                                             dev->interrupt_in_done);
 510                if (retval < 0)
 511                        goto unlock_exit;
 512        }
 513
 514        alphatrack_ocmd_info(&dev->intf->dev,
 515                             &(*dev->ring_buffer)[dev->ring_tail].cmd, "%s",
 516                             ": copying to userspace");
 517
 518        c = 0;
 519        while ((c < count) && (dev->ring_tail != dev->ring_head)) {
 520                if (copy_to_user
 521                    (&buffer[c], &(*dev->ring_buffer)[dev->ring_tail],
 522                     INPUT_CMD_SIZE)) {
 523                        retval = -EFAULT;
 524                        goto unlock_exit;
 525                }
 526                dev->ring_tail = (dev->ring_tail + 1) % ring_buffer_size;
 527                c += INPUT_CMD_SIZE;
 528                dbg_info(&dev->intf->dev, "%s: head, tail are %x, %x\n",
 529                         __func__, dev->ring_head, dev->ring_tail);
 530        }
 531        retval = c;
 532
 533unlock_exit:
 534        /* unlock the device */
 535        mutex_unlock(&dev->mtx);
 536
 537exit:
 538        return retval;
 539}
 540
 541/**
 542 *      usb_alphatrack_write
 543 */
 544static ssize_t usb_alphatrack_write(struct file *file,
 545                                    const char __user *buffer, size_t count,
 546                                    loff_t *ppos)
 547{
 548        struct usb_alphatrack *dev;
 549        size_t bytes_to_write;
 550        int retval = 0;
 551
 552        dev = file->private_data;
 553
 554        /* verify that we actually have some data to write */
 555        if (count == 0)
 556                goto exit;
 557
 558        /* lock this object */
 559        if (mutex_lock_interruptible(&dev->mtx)) {
 560                retval = -ERESTARTSYS;
 561                goto exit;
 562        }
 563
 564        /* verify that the device wasn't unplugged */
 565        if (dev->intf == NULL) {
 566                retval = -ENODEV;
 567                err("No device or device unplugged %d\n", retval);
 568                goto unlock_exit;
 569        }
 570
 571        /* wait until previous transfer is finished */
 572        if (dev->interrupt_out_busy) {
 573                if (file->f_flags & O_NONBLOCK) {
 574                        retval = -EAGAIN;
 575                        goto unlock_exit;
 576                }
 577                retval =
 578                    wait_event_interruptible(dev->write_wait,
 579                                             !dev->interrupt_out_busy);
 580                if (retval < 0)
 581                        goto unlock_exit;
 582        }
 583
 584        /* write the data into interrupt_out_buffer from userspace */
 585        /* FIXME - if you write more than 12 bytes this breaks */
 586        bytes_to_write =
 587            min(count, write_buffer_size * dev->interrupt_out_endpoint_size);
 588        if (bytes_to_write < count)
 589                dev_warn(&dev->intf->dev,
 590                         "Write buffer overflow, %zd bytes dropped\n",
 591                         count - bytes_to_write);
 592
 593        dbg_info(&dev->intf->dev, "%s: count = %zd, bytes_to_write = %zd\n",
 594                 __func__, count, bytes_to_write);
 595
 596        if (copy_from_user(dev->interrupt_out_buffer, buffer, bytes_to_write)) {
 597                retval = -EFAULT;
 598                goto unlock_exit;
 599        }
 600
 601        if (dev->interrupt_out_endpoint == NULL) {
 602                err("Endpoint should not be be null!\n");
 603                goto unlock_exit;
 604        }
 605
 606        /* send off the urb */
 607        usb_fill_int_urb(dev->interrupt_out_urb,
 608                         interface_to_usbdev(dev->intf),
 609                         usb_sndintpipe(interface_to_usbdev(dev->intf),
 610                                        dev->interrupt_out_endpoint->
 611                                        bEndpointAddress),
 612                         dev->interrupt_out_buffer, bytes_to_write,
 613                         usb_alphatrack_interrupt_out_callback, dev,
 614                         dev->interrupt_out_interval);
 615        dev->interrupt_out_busy = 1;
 616        atomic_inc(&dev->writes_pending);
 617        wmb();
 618
 619        retval = usb_submit_urb(dev->interrupt_out_urb, GFP_KERNEL);
 620        if (retval) {
 621                dev->interrupt_out_busy = 0;
 622                err("Couldn't submit interrupt_out_urb %d\n", retval);
 623                atomic_dec(&dev->writes_pending);
 624                goto unlock_exit;
 625        }
 626        retval = bytes_to_write;
 627
 628unlock_exit:
 629        /* unlock the device */
 630        mutex_unlock(&dev->mtx);
 631
 632exit:
 633        return retval;
 634}
 635
 636/* file operations needed when we register this driver */
 637static const struct file_operations usb_alphatrack_fops = {
 638        .owner = THIS_MODULE,
 639        .read = usb_alphatrack_read,
 640        .write = usb_alphatrack_write,
 641        .open = usb_alphatrack_open,
 642        .release = usb_alphatrack_release,
 643        .poll = usb_alphatrack_poll,
 644        .llseek = no_llseek,
 645};
 646
 647/*
 648 * usb class driver info in order to get a minor number from the usb core,
 649 * and to have the device registered with the driver core
 650 */
 651
 652static struct usb_class_driver usb_alphatrack_class = {
 653        .name = "alphatrack%d",
 654        .fops = &usb_alphatrack_fops,
 655        .minor_base = USB_ALPHATRACK_MINOR_BASE,
 656};
 657
 658/**
 659 *      usb_alphatrack_probe
 660 *
 661 *      Called by the usb core when a new device is connected that it thinks
 662 *      this driver might be interested in.
 663 */
 664static int usb_alphatrack_probe(struct usb_interface *intf,
 665                                const struct usb_device_id *id)
 666{
 667        struct usb_device *udev = interface_to_usbdev(intf);
 668        struct usb_alphatrack *dev = NULL;
 669        struct usb_host_interface *iface_desc;
 670        struct usb_endpoint_descriptor *endpoint;
 671        int i;
 672        int true_size;
 673        int retval = -ENOMEM;
 674
 675        /* allocate memory for our device state and initialize it */
 676
 677        dev = kzalloc(sizeof(*dev), GFP_KERNEL);
 678        if (dev == NULL) {
 679                dev_err(&intf->dev, "Out of memory\n");
 680                goto exit;
 681        }
 682        mutex_init(&dev->mtx);
 683        dev->intf = intf;
 684        init_waitqueue_head(&dev->read_wait);
 685        init_waitqueue_head(&dev->write_wait);
 686
 687        iface_desc = intf->cur_altsetting;
 688
 689        /* set up the endpoint information */
 690        for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
 691                endpoint = &iface_desc->endpoint[i].desc;
 692
 693                if (usb_endpoint_is_int_in(endpoint))
 694                        dev->interrupt_in_endpoint = endpoint;
 695
 696                if (usb_endpoint_is_int_out(endpoint))
 697                        dev->interrupt_out_endpoint = endpoint;
 698        }
 699        if (dev->interrupt_in_endpoint == NULL) {
 700                dev_err(&intf->dev, "Interrupt in endpoint not found\n");
 701                goto error;
 702        }
 703        if (dev->interrupt_out_endpoint == NULL)
 704                dev_warn(&intf->dev,
 705                         "Interrupt out endpoint not found"
 706                         "(using control endpoint instead)\n");
 707
 708        dev->interrupt_in_endpoint_size =
 709            le16_to_cpu(dev->interrupt_in_endpoint->wMaxPacketSize);
 710
 711        if (dev->interrupt_in_endpoint_size != 64)
 712                dev_warn(&intf->dev, "Interrupt in endpoint size is not 64!\n");
 713
 714        if (ring_buffer_size == 0)
 715                ring_buffer_size = RING_BUFFER_SIZE;
 716
 717        true_size = min(ring_buffer_size, RING_BUFFER_SIZE);
 718
 719        /* FIXME - there are more usb_alloc routines for dma correctness.
 720           Needed? */
 721        dev->ring_buffer =
 722            kmalloc((true_size * sizeof(struct alphatrack_icmd)), GFP_KERNEL);
 723
 724        if (!dev->ring_buffer) {
 725                dev_err(&intf->dev,
 726                        "Couldn't allocate input ring_buffer of size %d\n",
 727                        true_size);
 728                goto error;
 729        }
 730
 731        dev->interrupt_in_buffer =
 732            kmalloc(dev->interrupt_in_endpoint_size, GFP_KERNEL);
 733
 734        if (!dev->interrupt_in_buffer) {
 735                dev_err(&intf->dev, "Couldn't allocate interrupt_in_buffer\n");
 736                goto error;
 737        }
 738        dev->oldi_buffer = kmalloc(dev->interrupt_in_endpoint_size, GFP_KERNEL);
 739        if (!dev->oldi_buffer) {
 740                dev_err(&intf->dev, "Couldn't allocate old buffer\n");
 741                goto error;
 742        }
 743        dev->interrupt_in_urb = usb_alloc_urb(0, GFP_KERNEL);
 744        if (!dev->interrupt_in_urb) {
 745                dev_err(&intf->dev, "Couldn't allocate interrupt_in_urb\n");
 746                goto error;
 747        }
 748
 749        dev->interrupt_out_endpoint_size =
 750            dev->interrupt_out_endpoint ? le16_to_cpu(dev->
 751                                                      interrupt_out_endpoint->
 752                                                      wMaxPacketSize) : udev->
 753            descriptor.bMaxPacketSize0;
 754
 755        if (dev->interrupt_out_endpoint_size != 64)
 756                dev_warn(&intf->dev,
 757                         "Interrupt out endpoint size is not 64!)\n");
 758
 759        if (write_buffer_size == 0)
 760                write_buffer_size = WRITE_BUFFER_SIZE;
 761        true_size = min(write_buffer_size, WRITE_BUFFER_SIZE);
 762
 763        dev->interrupt_out_buffer =
 764            kmalloc(true_size * dev->interrupt_out_endpoint_size, GFP_KERNEL);
 765
 766        if (!dev->interrupt_out_buffer) {
 767                dev_err(&intf->dev, "Couldn't allocate interrupt_out_buffer\n");
 768                goto error;
 769        }
 770
 771        dev->write_buffer =
 772            kmalloc(true_size * sizeof(struct alphatrack_ocmd), GFP_KERNEL);
 773
 774        if (!dev->write_buffer) {
 775                dev_err(&intf->dev, "Couldn't allocate write_buffer\n");
 776                goto error;
 777        }
 778
 779        dev->interrupt_out_urb = usb_alloc_urb(0, GFP_KERNEL);
 780        if (!dev->interrupt_out_urb) {
 781                dev_err(&intf->dev, "Couldn't allocate interrupt_out_urb\n");
 782                goto error;
 783        }
 784        dev->interrupt_in_interval =
 785            min_interrupt_in_interval >
 786            dev->interrupt_in_endpoint->
 787            bInterval ? min_interrupt_in_interval : dev->interrupt_in_endpoint->
 788            bInterval;
 789        if (dev->interrupt_out_endpoint)
 790                dev->interrupt_out_interval =
 791                    min_interrupt_out_interval >
 792                    dev->interrupt_out_endpoint->
 793                    bInterval ? min_interrupt_out_interval : dev->
 794                    interrupt_out_endpoint->bInterval;
 795
 796        /* we can register the device now, as it is ready */
 797        usb_set_intfdata(intf, dev);
 798
 799        atomic_set(&dev->writes_pending, 0);
 800        retval = usb_register_dev(intf, &usb_alphatrack_class);
 801        if (retval) {
 802                /* something prevented us from registering this driver */
 803                dev_err(&intf->dev,
 804                        "Not able to get a minor for this device.\n");
 805                usb_set_intfdata(intf, NULL);
 806                goto error;
 807        }
 808
 809        /* let the user know what node this device is now attached to */
 810        dev_info(&intf->dev,
 811                 "Alphatrack Device #%d now attached to major %d minor %d\n",
 812                 (intf->minor - USB_ALPHATRACK_MINOR_BASE), USB_MAJOR,
 813                 intf->minor);
 814
 815exit:
 816        return retval;
 817
 818error:
 819        usb_alphatrack_delete(dev);
 820
 821        return retval;
 822}
 823
 824/**
 825 *      usb_alphatrack_disconnect
 826 *
 827 *      Called by the usb core when the device is removed from the system.
 828 */
 829static void usb_alphatrack_disconnect(struct usb_interface *intf)
 830{
 831        struct usb_alphatrack *dev;
 832        int minor;
 833
 834        mutex_lock(&disconnect_mutex);
 835
 836        dev = usb_get_intfdata(intf);
 837        usb_set_intfdata(intf, NULL);
 838
 839        mutex_lock(&dev->mtx);
 840
 841        minor = intf->minor;
 842
 843        /* give back our minor */
 844        usb_deregister_dev(intf, &usb_alphatrack_class);
 845
 846        /* if the device is not opened, then we clean up right now */
 847        if (!dev->open_count) {
 848                mutex_unlock(&dev->mtx);
 849                usb_alphatrack_delete(dev);
 850        } else {
 851                dev->intf = NULL;
 852                mutex_unlock(&dev->mtx);
 853        }
 854
 855        atomic_set(&dev->writes_pending, 0);
 856        mutex_unlock(&disconnect_mutex);
 857
 858        dev_info(&intf->dev, "Alphatrack Surface #%d now disconnected\n",
 859                 (minor - USB_ALPHATRACK_MINOR_BASE));
 860}
 861
 862/* usb specific object needed to register this driver with the usb subsystem */
 863static struct usb_driver usb_alphatrack_driver = {
 864        .name = "alphatrack",
 865        .probe = usb_alphatrack_probe,
 866        .disconnect = usb_alphatrack_disconnect,
 867        .id_table = usb_alphatrack_table,
 868};
 869
 870/**
 871 *      usb_alphatrack_init
 872 */
 873static int __init usb_alphatrack_init(void)
 874{
 875        int retval;
 876
 877        /* register this driver with the USB subsystem */
 878        retval = usb_register(&usb_alphatrack_driver);
 879        if (retval)
 880                err("usb_register failed for the " __FILE__
 881                    " driver. Error number %d\n", retval);
 882
 883        return retval;
 884}
 885
 886/**
 887 *      usb_alphatrack_exit
 888 */
 889static void __exit usb_alphatrack_exit(void)
 890{
 891        /* deregister this driver with the USB subsystem */
 892        usb_deregister(&usb_alphatrack_driver);
 893}
 894
 895module_init(usb_alphatrack_init);
 896module_exit(usb_alphatrack_exit);
 897