linux/drivers/staging/frontier/tranzport.c
<<
>>
Prefs
   1/*
   2 * Frontier Designs Tranzport 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 17 commands for the tranzport. 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/mutex.h>
  41
  42#include <linux/uaccess.h>
  43#include <linux/input.h>
  44#include <linux/usb.h>
  45#include <linux/poll.h>
  46
  47/* Define these values to match your devices */
  48#define VENDOR_ID   0x165b
  49#define PRODUCT_ID  0x8101
  50
  51#ifdef CONFIG_USB_DYNAMIC_MINORS
  52#define USB_TRANZPORT_MINOR_BASE        0
  53#else  /* FIXME 177- is the another driver's minor - apply for a minor soon */
  54#define USB_TRANZPORT_MINOR_BASE        177
  55#endif
  56
  57/* table of devices that work with this driver */
  58static const struct usb_device_id usb_tranzport_table[] = {
  59        {USB_DEVICE(VENDOR_ID, PRODUCT_ID)},
  60        {}                      /* Terminating entry */
  61};
  62
  63MODULE_DEVICE_TABLE(usb, usb_tranzport_table);
  64MODULE_VERSION("0.35");
  65MODULE_AUTHOR("Mike Taht <m@taht.net>");
  66MODULE_DESCRIPTION("Tranzport USB Driver");
  67MODULE_LICENSE("GPL");
  68MODULE_SUPPORTED_DEVICE("Frontier Designs Tranzport Control Surface");
  69
  70#define SUPPRESS_EXTRA_OFFLINE_EVENTS 1
  71#define COMPRESS_WHEEL_EVENTS 1
  72#define BUFFERED_READS 1
  73#define RING_BUFFER_SIZE 1000
  74#define WRITE_BUFFER_SIZE 34
  75#define TRANZPORT_USB_TIMEOUT 10
  76#define TRANZPORT_DEBUG 0
  77
  78static int debug = TRANZPORT_DEBUG;
  79
  80/* Use our own dbg macro */
  81#define dbg_info(dev, format, arg...) do                        \
  82        { if (debug) dev_info(dev , format , ## arg); } while (0)
  83
  84/* Module parameters */
  85
  86module_param(debug, int, S_IRUGO | S_IWUSR);
  87MODULE_PARM_DESC(debug, "Debug enabled or not");
  88
  89/*
  90 * All interrupt in transfers are collected in a ring buffer to
  91 * avoid racing conditions and get better performance of the driver.
  92 */
  93
  94static int ring_buffer_size = RING_BUFFER_SIZE;
  95
  96module_param(ring_buffer_size, int, S_IRUGO);
  97MODULE_PARM_DESC(ring_buffer_size, "Read ring buffer size in reports");
  98
  99/*
 100 * The write_buffer can one day contain more than one interrupt out transfer.
 101 */
 102static int write_buffer_size = WRITE_BUFFER_SIZE;
 103module_param(write_buffer_size, int, S_IRUGO);
 104MODULE_PARM_DESC(write_buffer_size, "Write buffer size");
 105
 106/*
 107 * Increase the interval for debugging purposes.
 108 * or set to 1 to use the standard interval from the endpoint descriptors.
 109 */
 110
 111static int min_interrupt_in_interval = TRANZPORT_USB_TIMEOUT;
 112module_param(min_interrupt_in_interval, int, 0);
 113MODULE_PARM_DESC(min_interrupt_in_interval,
 114                "Minimum interrupt in interval in ms");
 115
 116static int min_interrupt_out_interval = TRANZPORT_USB_TIMEOUT;
 117module_param(min_interrupt_out_interval, int, 0);
 118MODULE_PARM_DESC(min_interrupt_out_interval,
 119                "Minimum interrupt out interval in ms");
 120
 121struct tranzport_cmd {
 122        unsigned char cmd[8];
 123};
 124
 125/* Structure to hold all of our device specific stuff */
 126
 127struct usb_tranzport {
 128        struct mutex mtx;       /* locks this structure */
 129        struct usb_interface *intf;     /* save off the usb interface pointer */
 130        int open_count;         /* number of times this port opened */
 131        struct tranzport_cmd (*ring_buffer)[RING_BUFFER_SIZE];
 132        unsigned int ring_head;
 133        unsigned int ring_tail;
 134        wait_queue_head_t read_wait;
 135        wait_queue_head_t write_wait;
 136        unsigned char *interrupt_in_buffer;
 137        struct usb_endpoint_descriptor *interrupt_in_endpoint;
 138        struct urb *interrupt_in_urb;
 139        int interrupt_in_interval;
 140        size_t interrupt_in_endpoint_size;
 141        int interrupt_in_running;
 142        int interrupt_in_done;
 143        char *interrupt_out_buffer;
 144        struct usb_endpoint_descriptor *interrupt_out_endpoint;
 145        struct urb *interrupt_out_urb;
 146        int interrupt_out_interval;
 147        size_t interrupt_out_endpoint_size;
 148        int interrupt_out_busy;
 149
 150        /* Sysfs support */
 151
 152        unsigned char enable;   /* 0 if disabled 1 if enabled */
 153        unsigned char offline;  /* if the device is out of range or asleep */
 154        unsigned char compress_wheel;   /* flag to compress wheel events */
 155};
 156
 157/* prevent races between open() and disconnect() */
 158static DEFINE_MUTEX(disconnect_mutex);
 159
 160static struct usb_driver usb_tranzport_driver;
 161
 162/**
 163 *      usb_tranzport_abort_transfers
 164 *      aborts transfers and frees associated data structures
 165 */
 166static void usb_tranzport_abort_transfers(struct usb_tranzport *dev)
 167{
 168        /* shutdown transfer */
 169        if (dev->interrupt_in_running) {
 170                dev->interrupt_in_running = 0;
 171                if (dev->intf)
 172                        usb_kill_urb(dev->interrupt_in_urb);
 173        }
 174        if (dev->interrupt_out_busy)
 175                if (dev->intf)
 176                        usb_kill_urb(dev->interrupt_out_urb);
 177}
 178
 179#define show_int(value) \
 180        static ssize_t show_##value(struct device *dev, \
 181                              struct device_attribute *attr, char *buf) \
 182        {       \
 183                struct usb_interface *intf = to_usb_interface(dev);     \
 184                struct usb_tranzport *t = usb_get_intfdata(intf);       \
 185                return sprintf(buf, "%d\n", t->value);  \
 186        }       \
 187        static DEVICE_ATTR(value, S_IRUGO, show_##value, NULL);
 188
 189#define show_set_int(value)     \
 190        static ssize_t show_##value(struct device *dev, \
 191                              struct device_attribute *attr, char *buf) \
 192        {       \
 193                struct usb_interface *intf = to_usb_interface(dev);     \
 194                struct usb_tranzport *t = usb_get_intfdata(intf);       \
 195                return sprintf(buf, "%d\n", t->value);  \
 196        }       \
 197        static ssize_t set_##value(struct device *dev,  \
 198                             struct device_attribute *attr,             \
 199                             const char *buf, size_t count)             \
 200        {       \
 201                struct usb_interface *intf = to_usb_interface(dev);     \
 202                struct usb_tranzport *t = usb_get_intfdata(intf);       \
 203                unsigned long temp;     \
 204                if (kstrtoul(buf, 10, &temp))   \
 205                        return -EINVAL; \
 206                t->value = temp;        \
 207                return count;   \
 208        }       \
 209        static DEVICE_ATTR(value, S_IWUSR | S_IRUGO, show_##value, set_##value);
 210
 211show_int(enable);
 212show_int(offline);
 213show_set_int(compress_wheel);
 214
 215/**
 216 *      usb_tranzport_delete
 217 */
 218static void usb_tranzport_delete(struct usb_tranzport *dev)
 219{
 220        usb_tranzport_abort_transfers(dev);
 221        if (dev->intf != NULL) {
 222                device_remove_file(&dev->intf->dev, &dev_attr_enable);
 223                device_remove_file(&dev->intf->dev, &dev_attr_offline);
 224                device_remove_file(&dev->intf->dev, &dev_attr_compress_wheel);
 225        }
 226
 227        /* free data structures */
 228        usb_free_urb(dev->interrupt_in_urb);
 229        usb_free_urb(dev->interrupt_out_urb);
 230        kfree(dev->ring_buffer);
 231        kfree(dev->interrupt_in_buffer);
 232        kfree(dev->interrupt_out_buffer);
 233        kfree(dev);
 234}
 235
 236/**
 237 *      usb_tranzport_interrupt_in_callback
 238 */
 239
 240static void usb_tranzport_interrupt_in_callback(struct urb *urb)
 241{
 242        struct usb_tranzport *dev = urb->context;
 243        unsigned int next_ring_head;
 244        int retval = -1;
 245
 246        if (urb->status) {
 247                if (urb->status == -ENOENT ||
 248                        urb->status == -ECONNRESET ||
 249                        urb->status == -ESHUTDOWN) {
 250                        goto exit;
 251                } else {
 252                        dbg_info(&dev->intf->dev,
 253                                 "%s: nonzero status received: %d\n",
 254                                 __func__, urb->status);
 255                        goto resubmit;  /* maybe we can recover */
 256                }
 257        }
 258
 259        if (urb->actual_length != 8) {
 260                dev_warn(&dev->intf->dev,
 261                        "Urb length was %d bytes!!"
 262                        "Do something intelligent\n",
 263                         urb->actual_length);
 264        } else {
 265                dbg_info(&dev->intf->dev,
 266                         "%s: received: %02x%02x%02x%02x%02x%02x%02x%02x\n",
 267                         __func__, dev->interrupt_in_buffer[0],
 268                         dev->interrupt_in_buffer[1],
 269                         dev->interrupt_in_buffer[2],
 270                         dev->interrupt_in_buffer[3],
 271                         dev->interrupt_in_buffer[4],
 272                         dev->interrupt_in_buffer[5],
 273                         dev->interrupt_in_buffer[6],
 274                         dev->interrupt_in_buffer[7]);
 275#if SUPPRESS_EXTRA_OFFLINE_EVENTS
 276        if (dev->offline == 2 && dev->interrupt_in_buffer[1] == 0xff)
 277                goto resubmit;
 278                if (dev->offline == 1 && dev->interrupt_in_buffer[1] == 0xff) {
 279                        dev->offline = 2;
 280                        goto resubmit;
 281                }
 282
 283                /* Always pass one offline event up the stack */
 284                if (dev->offline > 0 && dev->interrupt_in_buffer[1] != 0xff)
 285                        dev->offline = 0;
 286                if (dev->offline == 0 && dev->interrupt_in_buffer[1] == 0xff)
 287                        dev->offline = 1;
 288
 289#endif  /* SUPPRESS_EXTRA_OFFLINE_EVENTS */
 290           dbg_info(&dev->intf->dev, "%s: head, tail are %x, %x\n",
 291                __func__, dev->ring_head, dev->ring_tail);
 292
 293                next_ring_head = (dev->ring_head + 1) % ring_buffer_size;
 294
 295                if (next_ring_head != dev->ring_tail) {
 296                        memcpy(&((*dev->ring_buffer)[dev->ring_head]),
 297                               dev->interrupt_in_buffer, urb->actual_length);
 298                        dev->ring_head = next_ring_head;
 299                        retval = 0;
 300                        memset(dev->interrupt_in_buffer, 0, urb->actual_length);
 301                } else {
 302                        dev_warn(&dev->intf->dev,
 303                                 "Ring buffer overflow, %d bytes dropped\n",
 304                                 urb->actual_length);
 305                        memset(dev->interrupt_in_buffer, 0, urb->actual_length);
 306                }
 307        }
 308
 309resubmit:
 310/* resubmit if we're still running */
 311        if (dev->interrupt_in_running && dev->intf) {
 312                retval = usb_submit_urb(dev->interrupt_in_urb, GFP_ATOMIC);
 313                if (retval)
 314                        dev_err(&dev->intf->dev,
 315                                "usb_submit_urb failed (%d)\n", retval);
 316        }
 317
 318exit:
 319        dev->interrupt_in_done = 1;
 320        wake_up_interruptible(&dev->read_wait);
 321}
 322
 323/**
 324 *      usb_tranzport_interrupt_out_callback
 325 */
 326static void usb_tranzport_interrupt_out_callback(struct urb *urb)
 327{
 328        struct usb_tranzport *dev = urb->context;
 329        /* sync/async unlink faults aren't errors */
 330        if (urb->status && !(urb->status == -ENOENT ||
 331                                urb->status == -ECONNRESET ||
 332                                urb->status == -ESHUTDOWN))
 333                dbg_info(&dev->intf->dev,
 334                        "%s - nonzero write interrupt status received: %d\n",
 335                        __func__, urb->status);
 336
 337        dev->interrupt_out_busy = 0;
 338        wake_up_interruptible(&dev->write_wait);
 339}
 340/**
 341 *      usb_tranzport_open
 342 */
 343static int usb_tranzport_open(struct inode *inode, struct file *file)
 344{
 345        struct usb_tranzport *dev;
 346        int subminor;
 347        int retval = 0;
 348        struct usb_interface *interface;
 349
 350        nonseekable_open(inode, file);
 351        subminor = iminor(inode);
 352
 353        mutex_lock(&disconnect_mutex);
 354
 355        interface = usb_find_interface(&usb_tranzport_driver, subminor);
 356
 357        if (!interface) {
 358                pr_err("%s - error, can't find device for minor %d\n",
 359                       __func__, subminor);
 360                retval = -ENODEV;
 361                goto unlock_disconnect_exit;
 362        }
 363
 364        dev = usb_get_intfdata(interface);
 365
 366        if (!dev) {
 367                retval = -ENODEV;
 368                goto unlock_disconnect_exit;
 369        }
 370
 371        /* lock this device */
 372        if (mutex_lock_interruptible(&dev->mtx)) {
 373                retval = -ERESTARTSYS;
 374                goto unlock_disconnect_exit;
 375        }
 376
 377        /* allow opening only once */
 378        if (dev->open_count) {
 379                retval = -EBUSY;
 380                goto unlock_exit;
 381        }
 382        dev->open_count = 1;
 383
 384        /* initialize in direction */
 385        dev->ring_head = 0;
 386        dev->ring_tail = 0;
 387        usb_fill_int_urb(dev->interrupt_in_urb,
 388                        interface_to_usbdev(interface),
 389                        usb_rcvintpipe(interface_to_usbdev(interface),
 390                                dev->interrupt_in_endpoint->
 391                                bEndpointAddress),
 392                        dev->interrupt_in_buffer,
 393                        dev->interrupt_in_endpoint_size,
 394                        usb_tranzport_interrupt_in_callback, dev,
 395                        dev->interrupt_in_interval);
 396
 397        dev->interrupt_in_running = 1;
 398        dev->interrupt_in_done = 0;
 399        dev->enable = 1;
 400        dev->offline = 0;
 401        dev->compress_wheel = 1;
 402
 403        retval = usb_submit_urb(dev->interrupt_in_urb, GFP_KERNEL);
 404        if (retval) {
 405                dev_err(&interface->dev,
 406                        "Couldn't submit interrupt_in_urb %d\n", retval);
 407                dev->interrupt_in_running = 0;
 408                dev->open_count = 0;
 409                goto unlock_exit;
 410        }
 411
 412        /* save device in the file's private structure */
 413        file->private_data = dev;
 414
 415unlock_exit:
 416        mutex_unlock(&dev->mtx);
 417
 418unlock_disconnect_exit:
 419        mutex_unlock(&disconnect_mutex);
 420
 421        return retval;
 422}
 423
 424/**
 425 *      usb_tranzport_release
 426 */
 427static int usb_tranzport_release(struct inode *inode, struct file *file)
 428{
 429        struct usb_tranzport *dev;
 430        int retval = 0;
 431
 432        dev = file->private_data;
 433
 434        if (dev == NULL) {
 435                retval = -ENODEV;
 436                goto exit;
 437        }
 438
 439        if (mutex_lock_interruptible(&dev->mtx)) {
 440                retval = -ERESTARTSYS;
 441                goto exit;
 442        }
 443
 444        if (dev->open_count != 1) {
 445                retval = -ENODEV;
 446                goto unlock_exit;
 447        }
 448
 449        if (dev->intf == NULL) {
 450                /* the device was unplugged before the file was released */
 451                mutex_unlock(&dev->mtx);
 452                /* unlock here as usb_tranzport_delete frees dev */
 453                usb_tranzport_delete(dev);
 454                retval = -ENODEV;
 455                goto exit;
 456        }
 457
 458        /* wait until write transfer is finished */
 459        if (dev->interrupt_out_busy)
 460                wait_event_interruptible_timeout(dev->write_wait,
 461                                                !dev->interrupt_out_busy,
 462                                                2 * HZ);
 463        usb_tranzport_abort_transfers(dev);
 464        dev->open_count = 0;
 465
 466unlock_exit:
 467        mutex_unlock(&dev->mtx);
 468
 469exit:
 470        return retval;
 471}
 472
 473/**
 474 *      usb_tranzport_poll
 475 */
 476static unsigned int usb_tranzport_poll(struct file *file, poll_table *wait)
 477{
 478        struct usb_tranzport *dev;
 479        unsigned int mask = 0;
 480        dev = file->private_data;
 481        poll_wait(file, &dev->read_wait, wait);
 482        poll_wait(file, &dev->write_wait, wait);
 483        if (dev->ring_head != dev->ring_tail)
 484                mask |= POLLIN | POLLRDNORM;
 485        if (!dev->interrupt_out_busy)
 486                mask |= POLLOUT | POLLWRNORM;
 487        return mask;
 488}
 489/**
 490 *      usb_tranzport_read
 491 */
 492
 493static ssize_t usb_tranzport_read(struct file *file, char __user *buffer,
 494                                size_t count, loff_t *ppos)
 495{
 496        struct usb_tranzport *dev;
 497        int retval = 0;
 498#if BUFFERED_READS
 499        int c = 0;
 500#endif
 501#if COMPRESS_WHEEL_EVENTS
 502        signed char oldwheel;
 503        signed char newwheel;
 504        int cancompress = 1;
 505        int next_tail;
 506#endif
 507
 508        /* do I have such a thing as a null event? */
 509
 510        dev = file->private_data;
 511
 512        /* verify that we actually have some data to read */
 513        if (count == 0)
 514                goto exit;
 515
 516        /* lock this object */
 517        if (mutex_lock_interruptible(&dev->mtx)) {
 518                retval = -ERESTARTSYS;
 519                goto exit;
 520        }
 521
 522        /* verify that the device wasn't unplugged */
 523        if (dev->intf == NULL) {
 524                retval = -ENODEV;
 525                pr_err("%s: No device or device unplugged %d\n",
 526                       __func__, retval);
 527                goto unlock_exit;
 528        }
 529
 530        while (dev->ring_head == dev->ring_tail) {
 531
 532                if (file->f_flags & O_NONBLOCK) {
 533                        retval = -EAGAIN;
 534                        goto unlock_exit;
 535                }
 536                /* tiny race - FIXME: make atomic? */
 537                /* atomic_cmp_exchange(&dev->interrupt_in_done,0,0); */
 538                dev->interrupt_in_done = 0;
 539                retval = wait_event_interruptible(dev->read_wait,
 540                                                  dev->interrupt_in_done);
 541                if (retval < 0)
 542                        goto unlock_exit;
 543        }
 544
 545        dbg_info(&dev->intf->dev,
 546                "%s: copying to userspace: "
 547                "%02x%02x%02x%02x%02x%02x%02x%02x\n",
 548                 __func__,
 549                 (*dev->ring_buffer)[dev->ring_tail].cmd[0],
 550                 (*dev->ring_buffer)[dev->ring_tail].cmd[1],
 551                 (*dev->ring_buffer)[dev->ring_tail].cmd[2],
 552                 (*dev->ring_buffer)[dev->ring_tail].cmd[3],
 553                 (*dev->ring_buffer)[dev->ring_tail].cmd[4],
 554                 (*dev->ring_buffer)[dev->ring_tail].cmd[5],
 555                 (*dev->ring_buffer)[dev->ring_tail].cmd[6],
 556                 (*dev->ring_buffer)[dev->ring_tail].cmd[7]);
 557
 558#if BUFFERED_READS
 559        c = 0;
 560        while ((c < count) && (dev->ring_tail != dev->ring_head)) {
 561
 562#if COMPRESS_WHEEL_EVENTS
 563                next_tail = (dev->ring_tail+1) % ring_buffer_size;
 564                if (dev->compress_wheel)
 565                        cancompress = 1;
 566                while (dev->ring_head != next_tail && cancompress == 1) {
 567                        newwheel = (*dev->ring_buffer)[next_tail].cmd[6];
 568                        oldwheel = (*dev->ring_buffer)[dev->ring_tail].cmd[6];
 569                        /* if both are wheel events, and
 570                         * no buttons have changes (FIXME, do I have to check?),
 571                         * and we are the same sign, we can compress +- 7F
 572                         */
 573                        dbg_info(&dev->intf->dev,
 574                                "%s: trying to compress: "
 575                                "%02x%02x%02x%02x%02x%02x%02x%02x\n",
 576                                __func__,
 577                                (*dev->ring_buffer)[dev->ring_tail].cmd[0],
 578                                (*dev->ring_buffer)[dev->ring_tail].cmd[1],
 579                                (*dev->ring_buffer)[dev->ring_tail].cmd[2],
 580                                (*dev->ring_buffer)[dev->ring_tail].cmd[3],
 581                                (*dev->ring_buffer)[dev->ring_tail].cmd[4],
 582                                (*dev->ring_buffer)[dev->ring_tail].cmd[5],
 583                                (*dev->ring_buffer)[dev->ring_tail].cmd[6],
 584                                (*dev->ring_buffer)[dev->ring_tail].cmd[7]);
 585
 586                        if (((*dev->ring_buffer)[dev->ring_tail].cmd[6] != 0 &&
 587                                (*dev->ring_buffer)[next_tail].cmd[6] != 0) &&
 588                                ((newwheel > 0 && oldwheel > 0) ||
 589                                        (newwheel < 0 && oldwheel < 0)) &&
 590                                ((*dev->ring_buffer)[dev->ring_tail].cmd[2] ==
 591                                (*dev->ring_buffer)[next_tail].cmd[2]) &&
 592                                ((*dev->ring_buffer)[dev->ring_tail].cmd[3] ==
 593                                (*dev->ring_buffer)[next_tail].cmd[3]) &&
 594                                ((*dev->ring_buffer)[dev->ring_tail].cmd[4] ==
 595                                (*dev->ring_buffer)[next_tail].cmd[4]) &&
 596                                ((*dev->ring_buffer)[dev->ring_tail].cmd[5] ==
 597                                (*dev->ring_buffer)[next_tail].cmd[5])) {
 598                                dbg_info(&dev->intf->dev,
 599                                        "%s: should compress: "
 600                                        "%02x%02x%02x%02x%02x%02x%02x%02x\n",
 601                                        __func__,
 602                                        (*dev->ring_buffer)[dev->ring_tail].
 603                                        cmd[0],
 604                                        (*dev->ring_buffer)[dev->ring_tail].
 605                                        cmd[1],
 606                                        (*dev->ring_buffer)[dev->ring_tail].
 607                                        cmd[2],
 608                                        (*dev->ring_buffer)[dev->ring_tail].
 609                                        cmd[3],
 610                                        (*dev->ring_buffer)[dev->ring_tail].
 611                                        cmd[4],
 612                                        (*dev->ring_buffer)[dev->ring_tail].
 613                                        cmd[5],
 614                                        (*dev->ring_buffer)[dev->ring_tail].
 615                                        cmd[6],
 616                                        (*dev->ring_buffer)[dev->ring_tail].
 617                                        cmd[7]);
 618                                newwheel += oldwheel;
 619                                if (oldwheel > 0 && !(newwheel > 0)) {
 620                                        newwheel = 0x7f;
 621                                        cancompress = 0;
 622                                }
 623                                if (oldwheel < 0 && !(newwheel < 0)) {
 624                                        newwheel = 0x80;
 625                                        cancompress = 0;
 626                                }
 627
 628                                (*dev->ring_buffer)[next_tail].cmd[6] =
 629                                        newwheel;
 630                                dev->ring_tail = next_tail;
 631                                next_tail =
 632                                        (dev->ring_tail + 1) % ring_buffer_size;
 633                        } else {
 634                                cancompress = 0;
 635                        }
 636                }
 637#endif /* COMPRESS_WHEEL_EVENTS */
 638                if (copy_to_user(
 639                                &buffer[c],
 640                                &(*dev->ring_buffer)[dev->ring_tail], 8)) {
 641                        retval = -EFAULT;
 642                        goto unlock_exit;
 643                }
 644                dev->ring_tail = (dev->ring_tail + 1) % ring_buffer_size;
 645                c += 8;
 646                dbg_info(&dev->intf->dev,
 647                         "%s: head, tail are %x, %x\n",
 648                         __func__, dev->ring_head, dev->ring_tail);
 649        }
 650        retval = c;
 651
 652#else
 653/*  if (copy_to_user(buffer, &(*dev->ring_buffer)[dev->ring_tail], 8)) { */
 654        retval = -EFAULT;
 655        goto unlock_exit;
 656}
 657
 658dev->ring_tail = (dev->ring_tail + 1) % ring_buffer_size;
 659dbg_info(&dev->intf->dev, "%s: head, tail are %x, %x\n",
 660         __func__, dev->ring_head, dev->ring_tail);
 661
 662retval = 8;
 663#endif /* BUFFERED_READS */
 664
 665unlock_exit:
 666/* unlock the device */
 667mutex_unlock(&dev->mtx);
 668
 669exit:
 670return retval;
 671}
 672
 673/**
 674 *      usb_tranzport_write
 675 */
 676static ssize_t usb_tranzport_write(struct file *file,
 677                                const char __user *buffer, size_t count,
 678                                loff_t *ppos)
 679{
 680        struct usb_tranzport *dev;
 681        size_t bytes_to_write;
 682        int retval = 0;
 683
 684        dev = file->private_data;
 685
 686        /* verify that we actually have some data to write */
 687        if (count == 0)
 688                goto exit;
 689
 690        /* lock this object */
 691        if (mutex_lock_interruptible(&dev->mtx)) {
 692                retval = -ERESTARTSYS;
 693                goto exit;
 694        }
 695        /* verify that the device wasn't unplugged */
 696        if (dev->intf == NULL) {
 697                retval = -ENODEV;
 698                pr_err("%s: No device or device unplugged %d\n",
 699                       __func__, retval);
 700                goto unlock_exit;
 701        }
 702
 703        /* wait until previous transfer is finished */
 704        if (dev->interrupt_out_busy) {
 705                if (file->f_flags & O_NONBLOCK) {
 706                        retval = -EAGAIN;
 707                        goto unlock_exit;
 708                }
 709                retval = wait_event_interruptible(dev->write_wait,
 710                                                !dev->interrupt_out_busy);
 711                if (retval < 0)
 712                        goto unlock_exit;
 713        }
 714
 715        /* write the data into interrupt_out_buffer from userspace */
 716        bytes_to_write = min(count,
 717                        write_buffer_size *
 718                        dev->interrupt_out_endpoint_size);
 719        if (bytes_to_write < count)
 720                dev_warn(&dev->intf->dev,
 721                        "Write buffer overflow, %zd bytes dropped\n",
 722                        count - bytes_to_write);
 723
 724        dbg_info(&dev->intf->dev,
 725                "%s: count = %zd, bytes_to_write = %zd\n", __func__,
 726                count, bytes_to_write);
 727
 728        if (copy_from_user(dev->interrupt_out_buffer, buffer, bytes_to_write)) {
 729                retval = -EFAULT;
 730                goto unlock_exit;
 731        }
 732
 733        if (dev->interrupt_out_endpoint == NULL) {
 734                dev_err(&dev->intf->dev, "Endpoint should not be null!\n");
 735                goto unlock_exit;
 736        }
 737
 738        /* send off the urb */
 739        usb_fill_int_urb(dev->interrupt_out_urb,
 740                        interface_to_usbdev(dev->intf),
 741                        usb_sndintpipe(interface_to_usbdev(dev->intf),
 742                                dev->interrupt_out_endpoint->
 743                                bEndpointAddress),
 744                        dev->interrupt_out_buffer, bytes_to_write,
 745                        usb_tranzport_interrupt_out_callback, dev,
 746                        dev->interrupt_out_interval);
 747
 748        dev->interrupt_out_busy = 1;
 749        wmb();
 750
 751        retval = usb_submit_urb(dev->interrupt_out_urb, GFP_KERNEL);
 752        if (retval) {
 753                dev->interrupt_out_busy = 0;
 754                dev_err(&dev->intf->dev,
 755                        "Couldn't submit interrupt_out_urb %d\n", retval);
 756                goto unlock_exit;
 757        }
 758        retval = bytes_to_write;
 759
 760unlock_exit:
 761        /* unlock the device */
 762        mutex_unlock(&dev->mtx);
 763
 764exit:
 765        return retval;
 766}
 767
 768/* file operations needed when we register this driver */
 769static const struct file_operations usb_tranzport_fops = {
 770        .owner = THIS_MODULE,
 771        .read = usb_tranzport_read,
 772        .write = usb_tranzport_write,
 773        .open = usb_tranzport_open,
 774        .release = usb_tranzport_release,
 775        .poll = usb_tranzport_poll,
 776        .llseek = no_llseek,
 777};
 778
 779/*
 780 * usb class driver info in order to get a minor number from the usb core,
 781 * and to have the device registered with the driver core
 782 */
 783static struct usb_class_driver usb_tranzport_class = {
 784        .name = "tranzport%d",
 785        .fops = &usb_tranzport_fops,
 786        .minor_base = USB_TRANZPORT_MINOR_BASE,
 787};
 788
 789/**
 790 *      usb_tranzport_probe
 791 *
 792 *      Called by the usb core when a new device is connected that it thinks
 793 *      this driver might be interested in.
 794 */
 795static int usb_tranzport_probe(struct usb_interface *intf,
 796                               const struct usb_device_id *id) {
 797        struct usb_device *udev = interface_to_usbdev(intf);
 798        struct usb_tranzport *dev = NULL;
 799        struct usb_host_interface *iface_desc;
 800        struct usb_endpoint_descriptor *endpoint;
 801        int i;
 802        int true_size;
 803        int retval = -ENOMEM;
 804
 805        /* allocate memory for our device state and initialize it */
 806
 807         dev = kzalloc(sizeof(*dev), GFP_KERNEL);
 808        if (dev == NULL)
 809                goto exit;
 810
 811        mutex_init(&dev->mtx);
 812        dev->intf = intf;
 813        init_waitqueue_head(&dev->read_wait);
 814        init_waitqueue_head(&dev->write_wait);
 815
 816        iface_desc = intf->cur_altsetting;
 817
 818        /* set up the endpoint information */
 819        for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
 820                endpoint = &iface_desc->endpoint[i].desc;
 821
 822                if (usb_endpoint_is_int_in(endpoint))
 823                        dev->interrupt_in_endpoint = endpoint;
 824
 825                if (usb_endpoint_is_int_out(endpoint))
 826                        dev->interrupt_out_endpoint = endpoint;
 827        }
 828        if (dev->interrupt_in_endpoint == NULL) {
 829                dev_err(&intf->dev, "Interrupt in endpoint not found\n");
 830                goto error;
 831        }
 832        if (dev->interrupt_out_endpoint == NULL)
 833                dev_warn(&intf->dev,
 834                        "Interrupt out endpoint not found"
 835                        "(using control endpoint instead)\n");
 836
 837        dev->interrupt_in_endpoint_size =
 838            le16_to_cpu(dev->interrupt_in_endpoint->wMaxPacketSize);
 839
 840        if (dev->interrupt_in_endpoint_size != 8)
 841                dev_warn(&intf->dev, "Interrupt in endpoint size is not 8!\n");
 842
 843        if (ring_buffer_size == 0)
 844                ring_buffer_size = RING_BUFFER_SIZE;
 845        true_size = min(ring_buffer_size, RING_BUFFER_SIZE);
 846
 847        /*
 848         * FIXME - there are more usb_alloc routines for dma correctness.
 849         * Needed?
 850         */
 851
 852        dev->ring_buffer =
 853            kmalloc((true_size * sizeof(struct tranzport_cmd)) + 8, GFP_KERNEL);
 854        if (!dev->ring_buffer)
 855                goto error;
 856
 857        dev->interrupt_in_buffer =
 858            kmalloc(dev->interrupt_in_endpoint_size, GFP_KERNEL);
 859        if (!dev->interrupt_in_buffer)
 860                goto error;
 861
 862        dev->interrupt_in_urb = usb_alloc_urb(0, GFP_KERNEL);
 863        if (!dev->interrupt_in_urb) {
 864                dev_err(&intf->dev, "Couldn't allocate interrupt_in_urb\n");
 865                goto error;
 866        }
 867        dev->interrupt_out_endpoint_size =
 868            dev->interrupt_out_endpoint ?
 869            le16_to_cpu(dev->interrupt_out_endpoint->wMaxPacketSize) :
 870            udev->descriptor.bMaxPacketSize0;
 871
 872        if (dev->interrupt_out_endpoint_size != 8)
 873                dev_warn(&intf->dev,
 874                         "Interrupt out endpoint size is not 8!)\n");
 875
 876        dev->interrupt_out_buffer =
 877                kmalloc_array(write_buffer_size,
 878                              dev->interrupt_out_endpoint_size, GFP_KERNEL);
 879        if (!dev->interrupt_out_buffer)
 880                goto error;
 881
 882        dev->interrupt_out_urb = usb_alloc_urb(0, GFP_KERNEL);
 883        if (!dev->interrupt_out_urb) {
 884                dev_err(&intf->dev, "Couldn't allocate interrupt_out_urb\n");
 885                goto error;
 886        }
 887        dev->interrupt_in_interval =
 888            min_interrupt_in_interval >
 889            dev->interrupt_in_endpoint->bInterval ? min_interrupt_in_interval
 890            : dev->interrupt_in_endpoint->bInterval;
 891
 892        if (dev->interrupt_out_endpoint) {
 893                dev->interrupt_out_interval =
 894                    min_interrupt_out_interval >
 895                    dev->interrupt_out_endpoint->bInterval ?
 896                    min_interrupt_out_interval :
 897                    dev->interrupt_out_endpoint->bInterval;
 898        }
 899
 900        /* we can register the device now, as it is ready */
 901        usb_set_intfdata(intf, dev);
 902
 903        retval = usb_register_dev(intf, &usb_tranzport_class);
 904        if (retval) {
 905                /* something prevented us from registering this driver */
 906                dev_err(&intf->dev,
 907                        "Not able to get a minor for this device.\n");
 908                usb_set_intfdata(intf, NULL);
 909                goto error;
 910        }
 911
 912        retval = device_create_file(&intf->dev, &dev_attr_compress_wheel);
 913        if (retval)
 914                goto error;
 915        retval = device_create_file(&intf->dev, &dev_attr_enable);
 916        if (retval)
 917                goto error;
 918        retval = device_create_file(&intf->dev, &dev_attr_offline);
 919        if (retval)
 920                goto error;
 921
 922        /* let the user know what node this device is now attached to */
 923        dev_info(&intf->dev,
 924                "Tranzport Device #%d now attached to major %d minor %d\n",
 925                (intf->minor - USB_TRANZPORT_MINOR_BASE), USB_MAJOR,
 926                intf->minor);
 927
 928exit:
 929        return retval;
 930
 931error:
 932        usb_tranzport_delete(dev);
 933        return retval;
 934}
 935
 936/**
 937 *      usb_tranzport_disconnect
 938 *
 939 *      Called by the usb core when the device is removed from the system.
 940 */
 941static void usb_tranzport_disconnect(struct usb_interface *intf)
 942{
 943        struct usb_tranzport *dev;
 944        int minor;
 945        mutex_lock(&disconnect_mutex);
 946        dev = usb_get_intfdata(intf);
 947        usb_set_intfdata(intf, NULL);
 948        mutex_lock(&dev->mtx);
 949        minor = intf->minor;
 950        /* give back our minor */
 951        usb_deregister_dev(intf, &usb_tranzport_class);
 952
 953        /* if the device is not opened, then we clean up right now */
 954        if (!dev->open_count) {
 955                mutex_unlock(&dev->mtx);
 956                usb_tranzport_delete(dev);
 957        } else {
 958                dev->intf = NULL;
 959                mutex_unlock(&dev->mtx);
 960        }
 961
 962        mutex_unlock(&disconnect_mutex);
 963
 964        dev_info(&intf->dev, "Tranzport Surface #%d now disconnected\n",
 965                (minor - USB_TRANZPORT_MINOR_BASE));
 966}
 967
 968/* usb specific object needed to register this driver with the usb subsystem */
 969static struct usb_driver usb_tranzport_driver = {
 970        .name = "tranzport",
 971        .probe = usb_tranzport_probe,
 972        .disconnect = usb_tranzport_disconnect,
 973        .id_table = usb_tranzport_table,
 974};
 975
 976module_usb_driver(usb_tranzport_driver);
 977