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