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