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