linux/drivers/usb/misc/yurex.c
<<
>>
Prefs
   1/*
   2 * Driver for Meywa-Denki & KAYAC YUREX
   3 *
   4 * Copyright (C) 2010 Tomoki Sekiyama (tomoki.sekiyama@gmail.com)
   5 *
   6 *      This program is free software; you can redistribute it and/or
   7 *      modify it under the terms of the GNU General Public License as
   8 *      published by the Free Software Foundation, version 2.
   9 *
  10 */
  11
  12#include <linux/kernel.h>
  13#include <linux/errno.h>
  14#include <linux/init.h>
  15#include <linux/slab.h>
  16#include <linux/module.h>
  17#include <linux/kref.h>
  18#include <linux/mutex.h>
  19#include <linux/uaccess.h>
  20#include <linux/usb.h>
  21#include <linux/hid.h>
  22
  23#define DRIVER_AUTHOR "Tomoki Sekiyama"
  24#define DRIVER_DESC "Driver for Meywa-Denki & KAYAC YUREX"
  25
  26#define YUREX_VENDOR_ID         0x0c45
  27#define YUREX_PRODUCT_ID        0x1010
  28
  29#define CMD_ACK         '!'
  30#define CMD_ANIMATE     'A'
  31#define CMD_COUNT       'C'
  32#define CMD_LED         'L'
  33#define CMD_READ        'R'
  34#define CMD_SET         'S'
  35#define CMD_VERSION     'V'
  36#define CMD_EOF         0x0d
  37#define CMD_PADDING     0xff
  38
  39#define YUREX_BUF_SIZE          8
  40#define YUREX_WRITE_TIMEOUT     (HZ*2)
  41
  42/* table of devices that work with this driver */
  43static struct usb_device_id yurex_table[] = {
  44        { USB_DEVICE(YUREX_VENDOR_ID, YUREX_PRODUCT_ID) },
  45        { }                                     /* Terminating entry */
  46};
  47MODULE_DEVICE_TABLE(usb, yurex_table);
  48
  49#ifdef CONFIG_USB_DYNAMIC_MINORS
  50#define YUREX_MINOR_BASE        0
  51#else
  52#define YUREX_MINOR_BASE        192
  53#endif
  54
  55/* Structure to hold all of our device specific stuff */
  56struct usb_yurex {
  57        struct usb_device       *udev;
  58        struct usb_interface    *interface;
  59        __u8                    int_in_endpointAddr;
  60        struct urb              *urb;           /* URB for interrupt in */
  61        unsigned char           *int_buffer;    /* buffer for intterupt in */
  62        struct urb              *cntl_urb;      /* URB for control msg */
  63        struct usb_ctrlrequest  *cntl_req;      /* req for control msg */
  64        unsigned char           *cntl_buffer;   /* buffer for control msg */
  65
  66        struct kref             kref;
  67        struct mutex            io_mutex;
  68        struct fasync_struct    *async_queue;
  69        wait_queue_head_t       waitq;
  70
  71        spinlock_t              lock;
  72        __s64                   bbu;            /* BBU from device */
  73};
  74#define to_yurex_dev(d) container_of(d, struct usb_yurex, kref)
  75
  76static struct usb_driver yurex_driver;
  77static const struct file_operations yurex_fops;
  78
  79
  80static void yurex_control_callback(struct urb *urb)
  81{
  82        struct usb_yurex *dev = urb->context;
  83        int status = urb->status;
  84
  85        if (status) {
  86                err("%s - control failed: %d\n", __func__, status);
  87                wake_up_interruptible(&dev->waitq);
  88                return;
  89        }
  90        /* on success, sender woken up by CMD_ACK int in, or timeout */
  91}
  92
  93static void yurex_delete(struct kref *kref)
  94{
  95        struct usb_yurex *dev = to_yurex_dev(kref);
  96
  97        dbg("yurex_delete");
  98
  99        usb_put_dev(dev->udev);
 100        if (dev->cntl_urb) {
 101                usb_kill_urb(dev->cntl_urb);
 102                if (dev->cntl_req)
 103                        usb_free_coherent(dev->udev, YUREX_BUF_SIZE,
 104                                dev->cntl_req, dev->cntl_urb->setup_dma);
 105                if (dev->cntl_buffer)
 106                        usb_free_coherent(dev->udev, YUREX_BUF_SIZE,
 107                                dev->cntl_buffer, dev->cntl_urb->transfer_dma);
 108                usb_free_urb(dev->cntl_urb);
 109        }
 110        if (dev->urb) {
 111                usb_kill_urb(dev->urb);
 112                if (dev->int_buffer)
 113                        usb_free_coherent(dev->udev, YUREX_BUF_SIZE,
 114                                dev->int_buffer, dev->urb->transfer_dma);
 115                usb_free_urb(dev->urb);
 116        }
 117        kfree(dev);
 118}
 119
 120/*
 121 * usb class driver info in order to get a minor number from the usb core,
 122 * and to have the device registered with the driver core
 123 */
 124static struct usb_class_driver yurex_class = {
 125        .name =         "yurex%d",
 126        .fops =         &yurex_fops,
 127        .minor_base =   YUREX_MINOR_BASE,
 128};
 129
 130static void yurex_interrupt(struct urb *urb)
 131{
 132        struct usb_yurex *dev = urb->context;
 133        unsigned char *buf = dev->int_buffer;
 134        int status = urb->status;
 135        unsigned long flags;
 136        int retval, i;
 137
 138        switch (status) {
 139        case 0: /*success*/
 140                break;
 141        case -EOVERFLOW:
 142                err("%s - overflow with length %d, actual length is %d",
 143                    __func__, YUREX_BUF_SIZE, dev->urb->actual_length);
 144        case -ECONNRESET:
 145        case -ENOENT:
 146        case -ESHUTDOWN:
 147        case -EILSEQ:
 148                /* The device is terminated, clean up */
 149                return;
 150        default:
 151                err("%s - unknown status received: %d", __func__, status);
 152                goto exit;
 153        }
 154
 155        /* handle received message */
 156        switch (buf[0]) {
 157        case CMD_COUNT:
 158        case CMD_READ:
 159                if (buf[6] == CMD_EOF) {
 160                        spin_lock_irqsave(&dev->lock, flags);
 161                        dev->bbu = 0;
 162                        for (i = 1; i < 6; i++) {
 163                                dev->bbu += buf[i];
 164                                if (i != 5)
 165                                        dev->bbu <<= 8;
 166                        }
 167                        dbg("%s count: %lld", __func__, dev->bbu);
 168                        spin_unlock_irqrestore(&dev->lock, flags);
 169
 170                        kill_fasync(&dev->async_queue, SIGIO, POLL_IN);
 171                }
 172                else
 173                        dbg("data format error - no EOF");
 174                break;
 175        case CMD_ACK:
 176                dbg("%s ack: %c", __func__, buf[1]);
 177                wake_up_interruptible(&dev->waitq);
 178                break;
 179        }
 180
 181exit:
 182        retval = usb_submit_urb(dev->urb, GFP_ATOMIC);
 183        if (retval) {
 184                err("%s - usb_submit_urb failed: %d",
 185                        __func__, retval);
 186        }
 187}
 188
 189static int yurex_probe(struct usb_interface *interface, const struct usb_device_id *id)
 190{
 191        struct usb_yurex *dev;
 192        struct usb_host_interface *iface_desc;
 193        struct usb_endpoint_descriptor *endpoint;
 194        int retval = -ENOMEM;
 195        int i;
 196        DEFINE_WAIT(wait);
 197
 198        /* allocate memory for our device state and initialize it */
 199        dev = kzalloc(sizeof(*dev), GFP_KERNEL);
 200        if (!dev) {
 201                err("Out of memory");
 202                goto error;
 203        }
 204        kref_init(&dev->kref);
 205        mutex_init(&dev->io_mutex);
 206        spin_lock_init(&dev->lock);
 207        init_waitqueue_head(&dev->waitq);
 208
 209        dev->udev = usb_get_dev(interface_to_usbdev(interface));
 210        dev->interface = interface;
 211
 212        /* set up the endpoint information */
 213        iface_desc = interface->cur_altsetting;
 214        for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) {
 215                endpoint = &iface_desc->endpoint[i].desc;
 216
 217                if (usb_endpoint_is_int_in(endpoint)) {
 218                        dev->int_in_endpointAddr = endpoint->bEndpointAddress;
 219                        break;
 220                }
 221        }
 222        if (!dev->int_in_endpointAddr) {
 223                retval = -ENODEV;
 224                err("Could not find endpoints");
 225                goto error;
 226        }
 227
 228
 229        /* allocate control URB */
 230        dev->cntl_urb = usb_alloc_urb(0, GFP_KERNEL);
 231        if (!dev->cntl_urb) {
 232                err("Could not allocate control URB");
 233                goto error;
 234        }
 235
 236        /* allocate buffer for control req */
 237        dev->cntl_req = usb_alloc_coherent(dev->udev, YUREX_BUF_SIZE,
 238                                           GFP_KERNEL,
 239                                           &dev->cntl_urb->setup_dma);
 240        if (!dev->cntl_req) {
 241                err("Could not allocate cntl_req");
 242                goto error;
 243        }
 244
 245        /* allocate buffer for control msg */
 246        dev->cntl_buffer = usb_alloc_coherent(dev->udev, YUREX_BUF_SIZE,
 247                                              GFP_KERNEL,
 248                                              &dev->cntl_urb->transfer_dma);
 249        if (!dev->cntl_buffer) {
 250                err("Could not allocate cntl_buffer");
 251                goto error;
 252        }
 253
 254        /* configure control URB */
 255        dev->cntl_req->bRequestType = USB_DIR_OUT | USB_TYPE_CLASS |
 256                                      USB_RECIP_INTERFACE;
 257        dev->cntl_req->bRequest = HID_REQ_SET_REPORT;
 258        dev->cntl_req->wValue   = cpu_to_le16((HID_OUTPUT_REPORT + 1) << 8);
 259        dev->cntl_req->wIndex   = cpu_to_le16(iface_desc->desc.bInterfaceNumber);
 260        dev->cntl_req->wLength  = cpu_to_le16(YUREX_BUF_SIZE);
 261
 262        usb_fill_control_urb(dev->cntl_urb, dev->udev,
 263                             usb_sndctrlpipe(dev->udev, 0),
 264                             (void *)dev->cntl_req, dev->cntl_buffer,
 265                             YUREX_BUF_SIZE, yurex_control_callback, dev);
 266        dev->cntl_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 267
 268
 269        /* allocate interrupt URB */
 270        dev->urb = usb_alloc_urb(0, GFP_KERNEL);
 271        if (!dev->urb) {
 272                err("Could not allocate URB");
 273                goto error;
 274        }
 275
 276        /* allocate buffer for interrupt in */
 277        dev->int_buffer = usb_alloc_coherent(dev->udev, YUREX_BUF_SIZE,
 278                                        GFP_KERNEL, &dev->urb->transfer_dma);
 279        if (!dev->int_buffer) {
 280                err("Could not allocate int_buffer");
 281                goto error;
 282        }
 283
 284        /* configure interrupt URB */
 285        usb_fill_int_urb(dev->urb, dev->udev,
 286                         usb_rcvintpipe(dev->udev, dev->int_in_endpointAddr),
 287                         dev->int_buffer, YUREX_BUF_SIZE, yurex_interrupt,
 288                         dev, 1);
 289        dev->cntl_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 290        if (usb_submit_urb(dev->urb, GFP_KERNEL)) {
 291                retval = -EIO;
 292                err("Could not submitting URB");
 293                goto error;
 294        }
 295
 296        /* save our data pointer in this interface device */
 297        usb_set_intfdata(interface, dev);
 298
 299        /* we can register the device now, as it is ready */
 300        retval = usb_register_dev(interface, &yurex_class);
 301        if (retval) {
 302                err("Not able to get a minor for this device.");
 303                usb_set_intfdata(interface, NULL);
 304                goto error;
 305        }
 306
 307        dev->bbu = -1;
 308
 309        dev_info(&interface->dev,
 310                 "USB YUREX device now attached to Yurex #%d\n",
 311                 interface->minor);
 312
 313        return 0;
 314
 315error:
 316        if (dev)
 317                /* this frees allocated memory */
 318                kref_put(&dev->kref, yurex_delete);
 319        return retval;
 320}
 321
 322static void yurex_disconnect(struct usb_interface *interface)
 323{
 324        struct usb_yurex *dev;
 325        int minor = interface->minor;
 326
 327        dev = usb_get_intfdata(interface);
 328        usb_set_intfdata(interface, NULL);
 329
 330        /* give back our minor */
 331        usb_deregister_dev(interface, &yurex_class);
 332
 333        /* prevent more I/O from starting */
 334        mutex_lock(&dev->io_mutex);
 335        dev->interface = NULL;
 336        mutex_unlock(&dev->io_mutex);
 337
 338        /* wakeup waiters */
 339        kill_fasync(&dev->async_queue, SIGIO, POLL_IN);
 340        wake_up_interruptible(&dev->waitq);
 341
 342        /* decrement our usage count */
 343        kref_put(&dev->kref, yurex_delete);
 344
 345        dev_info(&interface->dev, "USB YUREX #%d now disconnected\n", minor);
 346}
 347
 348static struct usb_driver yurex_driver = {
 349        .name =         "yurex",
 350        .probe =        yurex_probe,
 351        .disconnect =   yurex_disconnect,
 352        .id_table =     yurex_table,
 353};
 354
 355
 356static int yurex_fasync(int fd, struct file *file, int on)
 357{
 358        struct usb_yurex *dev;
 359
 360        dev = (struct usb_yurex *)file->private_data;
 361        return fasync_helper(fd, file, on, &dev->async_queue);
 362}
 363
 364static int yurex_open(struct inode *inode, struct file *file)
 365{
 366        struct usb_yurex *dev;
 367        struct usb_interface *interface;
 368        int subminor;
 369        int retval = 0;
 370
 371        subminor = iminor(inode);
 372
 373        interface = usb_find_interface(&yurex_driver, subminor);
 374        if (!interface) {
 375                err("%s - error, can't find device for minor %d",
 376                    __func__, subminor);
 377                retval = -ENODEV;
 378                goto exit;
 379        }
 380
 381        dev = usb_get_intfdata(interface);
 382        if (!dev) {
 383                retval = -ENODEV;
 384                goto exit;
 385        }
 386
 387        /* increment our usage count for the device */
 388        kref_get(&dev->kref);
 389
 390        /* save our object in the file's private structure */
 391        mutex_lock(&dev->io_mutex);
 392        file->private_data = dev;
 393        mutex_unlock(&dev->io_mutex);
 394
 395exit:
 396        return retval;
 397}
 398
 399static int yurex_release(struct inode *inode, struct file *file)
 400{
 401        struct usb_yurex *dev;
 402
 403        dev = (struct usb_yurex *)file->private_data;
 404        if (dev == NULL)
 405                return -ENODEV;
 406
 407        yurex_fasync(-1, file, 0);
 408
 409        /* decrement the count on our device */
 410        kref_put(&dev->kref, yurex_delete);
 411        return 0;
 412}
 413
 414static ssize_t yurex_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
 415{
 416        struct usb_yurex *dev;
 417        int retval = 0;
 418        int bytes_read = 0;
 419        char in_buffer[20];
 420        unsigned long flags;
 421
 422        dev = (struct usb_yurex *)file->private_data;
 423
 424        mutex_lock(&dev->io_mutex);
 425        if (!dev->interface) {          /* already disconnected */
 426                retval = -ENODEV;
 427                goto exit;
 428        }
 429
 430        spin_lock_irqsave(&dev->lock, flags);
 431        bytes_read = snprintf(in_buffer, 20, "%lld\n", dev->bbu);
 432        spin_unlock_irqrestore(&dev->lock, flags);
 433
 434        if (*ppos < bytes_read) {
 435                if (copy_to_user(buffer, in_buffer + *ppos, bytes_read - *ppos))
 436                        retval = -EFAULT;
 437                else {
 438                        retval = bytes_read - *ppos;
 439                        *ppos += bytes_read;
 440                }
 441        }
 442
 443exit:
 444        mutex_unlock(&dev->io_mutex);
 445        return retval;
 446}
 447
 448static ssize_t yurex_write(struct file *file, const char *user_buffer, size_t count, loff_t *ppos)
 449{
 450        struct usb_yurex *dev;
 451        int i, set = 0, retval = 0;
 452        char buffer[16];
 453        char *data = buffer;
 454        unsigned long long c, c2 = 0;
 455        signed long timeout = 0;
 456        DEFINE_WAIT(wait);
 457
 458        count = min(sizeof(buffer), count);
 459        dev = (struct usb_yurex *)file->private_data;
 460
 461        /* verify that we actually have some data to write */
 462        if (count == 0)
 463                goto error;
 464
 465        mutex_lock(&dev->io_mutex);
 466        if (!dev->interface) {          /* alreaday disconnected */
 467                mutex_unlock(&dev->io_mutex);
 468                retval = -ENODEV;
 469                goto error;
 470        }
 471
 472        if (copy_from_user(buffer, user_buffer, count)) {
 473                mutex_unlock(&dev->io_mutex);
 474                retval = -EFAULT;
 475                goto error;
 476        }
 477        memset(dev->cntl_buffer, CMD_PADDING, YUREX_BUF_SIZE);
 478
 479        switch (buffer[0]) {
 480        case CMD_ANIMATE:
 481        case CMD_LED:
 482                dev->cntl_buffer[0] = buffer[0];
 483                dev->cntl_buffer[1] = buffer[1];
 484                dev->cntl_buffer[2] = CMD_EOF;
 485                break;
 486        case CMD_READ:
 487        case CMD_VERSION:
 488                dev->cntl_buffer[0] = buffer[0];
 489                dev->cntl_buffer[1] = 0x00;
 490                dev->cntl_buffer[2] = CMD_EOF;
 491                break;
 492        case CMD_SET:
 493                data++;
 494                /* FALL THROUGH */
 495        case '0' ... '9':
 496                set = 1;
 497                c = c2 = simple_strtoull(data, NULL, 0);
 498                dev->cntl_buffer[0] = CMD_SET;
 499                for (i = 1; i < 6; i++) {
 500                        dev->cntl_buffer[i] = (c>>32) & 0xff;
 501                        c <<= 8;
 502                }
 503                buffer[6] = CMD_EOF;
 504                break;
 505        default:
 506                mutex_unlock(&dev->io_mutex);
 507                return -EINVAL;
 508        }
 509
 510        /* send the data as the control msg */
 511        prepare_to_wait(&dev->waitq, &wait, TASK_INTERRUPTIBLE);
 512        dbg("%s - submit %c", __func__, dev->cntl_buffer[0]);
 513        retval = usb_submit_urb(dev->cntl_urb, GFP_KERNEL);
 514        if (retval >= 0)
 515                timeout = schedule_timeout(YUREX_WRITE_TIMEOUT);
 516        finish_wait(&dev->waitq, &wait);
 517
 518        mutex_unlock(&dev->io_mutex);
 519
 520        if (retval < 0) {
 521                err("%s - failed to send bulk msg, error %d", __func__, retval);
 522                goto error;
 523        }
 524        if (set && timeout)
 525                dev->bbu = c2;
 526        return timeout ? count : -EIO;
 527
 528error:
 529        return retval;
 530}
 531
 532static const struct file_operations yurex_fops = {
 533        .owner =        THIS_MODULE,
 534        .read =         yurex_read,
 535        .write =        yurex_write,
 536        .open =         yurex_open,
 537        .release =      yurex_release,
 538        .fasync =       yurex_fasync,
 539        .llseek =       default_llseek,
 540};
 541
 542
 543static int __init usb_yurex_init(void)
 544{
 545        int result;
 546
 547        /* register this driver with the USB subsystem */
 548        result = usb_register(&yurex_driver);
 549        if (result)
 550                err("usb_register failed. Error number %d", result);
 551
 552        return result;
 553}
 554
 555static void __exit usb_yurex_exit(void)
 556{
 557        /* deregister this driver with the USB subsystem */
 558        usb_deregister(&yurex_driver);
 559}
 560
 561module_init(usb_yurex_init);
 562module_exit(usb_yurex_exit);
 563
 564MODULE_LICENSE("GPL");
 565