linux/drivers/usb/class/cdc-wdm.c
<<
>>
Prefs
   1/*
   2 * cdc-wdm.c
   3 *
   4 * This driver supports USB CDC WCM Device Management.
   5 *
   6 * Copyright (c) 2007-2009 Oliver Neukum
   7 *
   8 * Some code taken from cdc-acm.c
   9 *
  10 * Released under the GPLv2.
  11 *
  12 * Many thanks to Carl Nordbeck
  13 */
  14#include <linux/kernel.h>
  15#include <linux/errno.h>
  16#include <linux/slab.h>
  17#include <linux/module.h>
  18#include <linux/mutex.h>
  19#include <linux/uaccess.h>
  20#include <linux/bitops.h>
  21#include <linux/poll.h>
  22#include <linux/usb.h>
  23#include <linux/usb/cdc.h>
  24#include <asm/byteorder.h>
  25#include <asm/unaligned.h>
  26
  27/*
  28 * Version Information
  29 */
  30#define DRIVER_VERSION "v0.03"
  31#define DRIVER_AUTHOR "Oliver Neukum"
  32#define DRIVER_DESC "USB Abstract Control Model driver for USB WCM Device Management"
  33
  34static const struct usb_device_id wdm_ids[] = {
  35        {
  36                .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS |
  37                                 USB_DEVICE_ID_MATCH_INT_SUBCLASS,
  38                .bInterfaceClass = USB_CLASS_COMM,
  39                .bInterfaceSubClass = USB_CDC_SUBCLASS_DMM
  40        },
  41        { }
  42};
  43
  44MODULE_DEVICE_TABLE (usb, wdm_ids);
  45
  46#define WDM_MINOR_BASE  176
  47
  48
  49#define WDM_IN_USE              1
  50#define WDM_DISCONNECTING       2
  51#define WDM_RESULT              3
  52#define WDM_READ                4
  53#define WDM_INT_STALL           5
  54#define WDM_POLL_RUNNING        6
  55#define WDM_RESPONDING          7
  56#define WDM_SUSPENDING          8
  57
  58#define WDM_MAX                 16
  59
  60
  61static DEFINE_MUTEX(wdm_mutex);
  62
  63/* --- method tables --- */
  64
  65struct wdm_device {
  66        u8                      *inbuf; /* buffer for response */
  67        u8                      *outbuf; /* buffer for command */
  68        u8                      *sbuf; /* buffer for status */
  69        u8                      *ubuf; /* buffer for copy to user space */
  70
  71        struct urb              *command;
  72        struct urb              *response;
  73        struct urb              *validity;
  74        struct usb_interface    *intf;
  75        struct usb_ctrlrequest  *orq;
  76        struct usb_ctrlrequest  *irq;
  77        spinlock_t              iuspin;
  78
  79        unsigned long           flags;
  80        u16                     bufsize;
  81        u16                     wMaxCommand;
  82        u16                     wMaxPacketSize;
  83        u16                     bMaxPacketSize0;
  84        __le16                  inum;
  85        int                     reslength;
  86        int                     length;
  87        int                     read;
  88        int                     count;
  89        dma_addr_t              shandle;
  90        dma_addr_t              ihandle;
  91        struct mutex            lock;
  92        wait_queue_head_t       wait;
  93        struct work_struct      rxwork;
  94        int                     werr;
  95        int                     rerr;
  96};
  97
  98static struct usb_driver wdm_driver;
  99
 100/* --- callbacks --- */
 101static void wdm_out_callback(struct urb *urb)
 102{
 103        struct wdm_device *desc;
 104        desc = urb->context;
 105        spin_lock(&desc->iuspin);
 106        desc->werr = urb->status;
 107        spin_unlock(&desc->iuspin);
 108        clear_bit(WDM_IN_USE, &desc->flags);
 109        kfree(desc->outbuf);
 110        wake_up(&desc->wait);
 111}
 112
 113static void wdm_in_callback(struct urb *urb)
 114{
 115        struct wdm_device *desc = urb->context;
 116        int status = urb->status;
 117
 118        spin_lock(&desc->iuspin);
 119        clear_bit(WDM_RESPONDING, &desc->flags);
 120
 121        if (status) {
 122                switch (status) {
 123                case -ENOENT:
 124                        dev_dbg(&desc->intf->dev,
 125                                "nonzero urb status received: -ENOENT");
 126                        goto skip_error;
 127                case -ECONNRESET:
 128                        dev_dbg(&desc->intf->dev,
 129                                "nonzero urb status received: -ECONNRESET");
 130                        goto skip_error;
 131                case -ESHUTDOWN:
 132                        dev_dbg(&desc->intf->dev,
 133                                "nonzero urb status received: -ESHUTDOWN");
 134                        goto skip_error;
 135                case -EPIPE:
 136                        dev_err(&desc->intf->dev,
 137                                "nonzero urb status received: -EPIPE\n");
 138                        break;
 139                default:
 140                        dev_err(&desc->intf->dev,
 141                                "Unexpected error %d\n", status);
 142                        break;
 143                }
 144        }
 145
 146        desc->rerr = status;
 147        desc->reslength = urb->actual_length;
 148        memmove(desc->ubuf + desc->length, desc->inbuf, desc->reslength);
 149        desc->length += desc->reslength;
 150skip_error:
 151        wake_up(&desc->wait);
 152
 153        set_bit(WDM_READ, &desc->flags);
 154        spin_unlock(&desc->iuspin);
 155}
 156
 157static void wdm_int_callback(struct urb *urb)
 158{
 159        int rv = 0;
 160        int status = urb->status;
 161        struct wdm_device *desc;
 162        struct usb_ctrlrequest *req;
 163        struct usb_cdc_notification *dr;
 164
 165        desc = urb->context;
 166        req = desc->irq;
 167        dr = (struct usb_cdc_notification *)desc->sbuf;
 168
 169        if (status) {
 170                switch (status) {
 171                case -ESHUTDOWN:
 172                case -ENOENT:
 173                case -ECONNRESET:
 174                        return; /* unplug */
 175                case -EPIPE:
 176                        set_bit(WDM_INT_STALL, &desc->flags);
 177                        dev_err(&desc->intf->dev, "Stall on int endpoint\n");
 178                        goto sw; /* halt is cleared in work */
 179                default:
 180                        dev_err(&desc->intf->dev,
 181                                "nonzero urb status received: %d\n", status);
 182                        break;
 183                }
 184        }
 185
 186        if (urb->actual_length < sizeof(struct usb_cdc_notification)) {
 187                dev_err(&desc->intf->dev, "wdm_int_callback - %d bytes\n",
 188                        urb->actual_length);
 189                goto exit;
 190        }
 191
 192        switch (dr->bNotificationType) {
 193        case USB_CDC_NOTIFY_RESPONSE_AVAILABLE:
 194                dev_dbg(&desc->intf->dev,
 195                        "NOTIFY_RESPONSE_AVAILABLE received: index %d len %d",
 196                        dr->wIndex, dr->wLength);
 197                break;
 198
 199        case USB_CDC_NOTIFY_NETWORK_CONNECTION:
 200
 201                dev_dbg(&desc->intf->dev,
 202                        "NOTIFY_NETWORK_CONNECTION %s network",
 203                        dr->wValue ? "connected to" : "disconnected from");
 204                goto exit;
 205        default:
 206                clear_bit(WDM_POLL_RUNNING, &desc->flags);
 207                dev_err(&desc->intf->dev,
 208                        "unknown notification %d received: index %d len %d\n",
 209                        dr->bNotificationType, dr->wIndex, dr->wLength);
 210                goto exit;
 211        }
 212
 213        req->bRequestType = (USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE);
 214        req->bRequest = USB_CDC_GET_ENCAPSULATED_RESPONSE;
 215        req->wValue = 0;
 216        req->wIndex = desc->inum;
 217        req->wLength = cpu_to_le16(desc->wMaxCommand);
 218
 219        usb_fill_control_urb(
 220                desc->response,
 221                interface_to_usbdev(desc->intf),
 222                /* using common endpoint 0 */
 223                usb_rcvctrlpipe(interface_to_usbdev(desc->intf), 0),
 224                (unsigned char *)req,
 225                desc->inbuf,
 226                desc->wMaxCommand,
 227                wdm_in_callback,
 228                desc
 229        );
 230        desc->response->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 231        spin_lock(&desc->iuspin);
 232        clear_bit(WDM_READ, &desc->flags);
 233        set_bit(WDM_RESPONDING, &desc->flags);
 234        if (!test_bit(WDM_DISCONNECTING, &desc->flags)
 235                && !test_bit(WDM_SUSPENDING, &desc->flags)) {
 236                rv = usb_submit_urb(desc->response, GFP_ATOMIC);
 237                dev_dbg(&desc->intf->dev, "%s: usb_submit_urb %d",
 238                        __func__, rv);
 239        }
 240        spin_unlock(&desc->iuspin);
 241        if (rv < 0) {
 242                clear_bit(WDM_RESPONDING, &desc->flags);
 243                if (rv == -EPERM)
 244                        return;
 245                if (rv == -ENOMEM) {
 246sw:
 247                        rv = schedule_work(&desc->rxwork);
 248                        if (rv)
 249                                dev_err(&desc->intf->dev,
 250                                        "Cannot schedule work\n");
 251                }
 252        }
 253exit:
 254        rv = usb_submit_urb(urb, GFP_ATOMIC);
 255        if (rv)
 256                dev_err(&desc->intf->dev,
 257                        "%s - usb_submit_urb failed with result %d\n",
 258                        __func__, rv);
 259
 260}
 261
 262static void kill_urbs(struct wdm_device *desc)
 263{
 264        /* the order here is essential */
 265        usb_kill_urb(desc->command);
 266        usb_kill_urb(desc->validity);
 267        usb_kill_urb(desc->response);
 268}
 269
 270static void free_urbs(struct wdm_device *desc)
 271{
 272        usb_free_urb(desc->validity);
 273        usb_free_urb(desc->response);
 274        usb_free_urb(desc->command);
 275}
 276
 277static void cleanup(struct wdm_device *desc)
 278{
 279        usb_buffer_free(interface_to_usbdev(desc->intf),
 280                        desc->wMaxPacketSize,
 281                        desc->sbuf,
 282                        desc->validity->transfer_dma);
 283        usb_buffer_free(interface_to_usbdev(desc->intf),
 284                        desc->wMaxCommand,
 285                        desc->inbuf,
 286                        desc->response->transfer_dma);
 287        kfree(desc->orq);
 288        kfree(desc->irq);
 289        kfree(desc->ubuf);
 290        free_urbs(desc);
 291        kfree(desc);
 292}
 293
 294static ssize_t wdm_write
 295(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
 296{
 297        u8 *buf;
 298        int rv = -EMSGSIZE, r, we;
 299        struct wdm_device *desc = file->private_data;
 300        struct usb_ctrlrequest *req;
 301
 302        if (count > desc->wMaxCommand)
 303                count = desc->wMaxCommand;
 304
 305        spin_lock_irq(&desc->iuspin);
 306        we = desc->werr;
 307        desc->werr = 0;
 308        spin_unlock_irq(&desc->iuspin);
 309        if (we < 0)
 310                return -EIO;
 311
 312        desc->outbuf = buf = kmalloc(count, GFP_KERNEL);
 313        if (!buf) {
 314                rv = -ENOMEM;
 315                goto outnl;
 316        }
 317
 318        r = copy_from_user(buf, buffer, count);
 319        if (r > 0) {
 320                kfree(buf);
 321                rv = -EFAULT;
 322                goto outnl;
 323        }
 324
 325        /* concurrent writes and disconnect */
 326        r = mutex_lock_interruptible(&desc->lock);
 327        rv = -ERESTARTSYS;
 328        if (r) {
 329                kfree(buf);
 330                goto outnl;
 331        }
 332
 333        if (test_bit(WDM_DISCONNECTING, &desc->flags)) {
 334                kfree(buf);
 335                rv = -ENODEV;
 336                goto outnp;
 337        }
 338
 339        r = usb_autopm_get_interface(desc->intf);
 340        if (r < 0) {
 341                kfree(buf);
 342                goto outnp;
 343        }
 344
 345        if (!file->f_flags && O_NONBLOCK)
 346                r = wait_event_interruptible(desc->wait, !test_bit(WDM_IN_USE,
 347                                                                &desc->flags));
 348        else
 349                if (test_bit(WDM_IN_USE, &desc->flags))
 350                        r = -EAGAIN;
 351        if (r < 0) {
 352                kfree(buf);
 353                goto out;
 354        }
 355
 356        req = desc->orq;
 357        usb_fill_control_urb(
 358                desc->command,
 359                interface_to_usbdev(desc->intf),
 360                /* using common endpoint 0 */
 361                usb_sndctrlpipe(interface_to_usbdev(desc->intf), 0),
 362                (unsigned char *)req,
 363                buf,
 364                count,
 365                wdm_out_callback,
 366                desc
 367        );
 368
 369        req->bRequestType = (USB_DIR_OUT | USB_TYPE_CLASS |
 370                             USB_RECIP_INTERFACE);
 371        req->bRequest = USB_CDC_SEND_ENCAPSULATED_COMMAND;
 372        req->wValue = 0;
 373        req->wIndex = desc->inum;
 374        req->wLength = cpu_to_le16(count);
 375        set_bit(WDM_IN_USE, &desc->flags);
 376
 377        rv = usb_submit_urb(desc->command, GFP_KERNEL);
 378        if (rv < 0) {
 379                kfree(buf);
 380                clear_bit(WDM_IN_USE, &desc->flags);
 381                dev_err(&desc->intf->dev, "Tx URB error: %d\n", rv);
 382        } else {
 383                dev_dbg(&desc->intf->dev, "Tx URB has been submitted index=%d",
 384                        req->wIndex);
 385        }
 386out:
 387        usb_autopm_put_interface(desc->intf);
 388outnp:
 389        mutex_unlock(&desc->lock);
 390outnl:
 391        return rv < 0 ? rv : count;
 392}
 393
 394static ssize_t wdm_read
 395(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
 396{
 397        int rv, cntr = 0;
 398        int i = 0;
 399        struct wdm_device *desc = file->private_data;
 400
 401
 402        rv = mutex_lock_interruptible(&desc->lock); /*concurrent reads */
 403        if (rv < 0)
 404                return -ERESTARTSYS;
 405
 406        if (desc->length == 0) {
 407                desc->read = 0;
 408retry:
 409                if (test_bit(WDM_DISCONNECTING, &desc->flags)) {
 410                        rv = -ENODEV;
 411                        goto err;
 412                }
 413                i++;
 414                if (file->f_flags & O_NONBLOCK) {
 415                        if (!test_bit(WDM_READ, &desc->flags)) {
 416                                rv = cntr ? cntr : -EAGAIN;
 417                                goto err;
 418                        }
 419                        rv = 0;
 420                } else {
 421                        rv = wait_event_interruptible(desc->wait,
 422                                test_bit(WDM_READ, &desc->flags));
 423                }
 424
 425                /* may have happened while we slept */
 426                if (test_bit(WDM_DISCONNECTING, &desc->flags)) {
 427                        rv = -ENODEV;
 428                        goto err;
 429                }
 430                usb_mark_last_busy(interface_to_usbdev(desc->intf));
 431                if (rv < 0) {
 432                        rv = -ERESTARTSYS;
 433                        goto err;
 434                }
 435
 436                spin_lock_irq(&desc->iuspin);
 437
 438                if (desc->rerr) { /* read completed, error happened */
 439                        desc->rerr = 0;
 440                        spin_unlock_irq(&desc->iuspin);
 441                        rv = -EIO;
 442                        goto err;
 443                }
 444                /*
 445                 * recheck whether we've lost the race
 446                 * against the completion handler
 447                 */
 448                if (!test_bit(WDM_READ, &desc->flags)) { /* lost race */
 449                        spin_unlock_irq(&desc->iuspin);
 450                        goto retry;
 451                }
 452                if (!desc->reslength) { /* zero length read */
 453                        spin_unlock_irq(&desc->iuspin);
 454                        goto retry;
 455                }
 456                clear_bit(WDM_READ, &desc->flags);
 457                spin_unlock_irq(&desc->iuspin);
 458        }
 459
 460        cntr = count > desc->length ? desc->length : count;
 461        rv = copy_to_user(buffer, desc->ubuf, cntr);
 462        if (rv > 0) {
 463                rv = -EFAULT;
 464                goto err;
 465        }
 466
 467        for (i = 0; i < desc->length - cntr; i++)
 468                desc->ubuf[i] = desc->ubuf[i + cntr];
 469
 470        desc->length -= cntr;
 471        /* in case we had outstanding data */
 472        if (!desc->length)
 473                clear_bit(WDM_READ, &desc->flags);
 474        rv = cntr;
 475
 476err:
 477        mutex_unlock(&desc->lock);
 478        return rv;
 479}
 480
 481static int wdm_flush(struct file *file, fl_owner_t id)
 482{
 483        struct wdm_device *desc = file->private_data;
 484
 485        wait_event(desc->wait, !test_bit(WDM_IN_USE, &desc->flags));
 486        if (desc->werr < 0)
 487                dev_err(&desc->intf->dev, "Error in flush path: %d\n",
 488                        desc->werr);
 489
 490        return desc->werr;
 491}
 492
 493static unsigned int wdm_poll(struct file *file, struct poll_table_struct *wait)
 494{
 495        struct wdm_device *desc = file->private_data;
 496        unsigned long flags;
 497        unsigned int mask = 0;
 498
 499        spin_lock_irqsave(&desc->iuspin, flags);
 500        if (test_bit(WDM_DISCONNECTING, &desc->flags)) {
 501                mask = POLLERR;
 502                spin_unlock_irqrestore(&desc->iuspin, flags);
 503                goto desc_out;
 504        }
 505        if (test_bit(WDM_READ, &desc->flags))
 506                mask = POLLIN | POLLRDNORM;
 507        if (desc->rerr || desc->werr)
 508                mask |= POLLERR;
 509        if (!test_bit(WDM_IN_USE, &desc->flags))
 510                mask |= POLLOUT | POLLWRNORM;
 511        spin_unlock_irqrestore(&desc->iuspin, flags);
 512
 513        poll_wait(file, &desc->wait, wait);
 514
 515desc_out:
 516        return mask;
 517}
 518
 519static int wdm_open(struct inode *inode, struct file *file)
 520{
 521        int minor = iminor(inode);
 522        int rv = -ENODEV;
 523        struct usb_interface *intf;
 524        struct wdm_device *desc;
 525
 526        mutex_lock(&wdm_mutex);
 527        intf = usb_find_interface(&wdm_driver, minor);
 528        if (!intf)
 529                goto out;
 530
 531        desc = usb_get_intfdata(intf);
 532        if (test_bit(WDM_DISCONNECTING, &desc->flags))
 533                goto out;
 534        file->private_data = desc;
 535
 536        rv = usb_autopm_get_interface(desc->intf);
 537        if (rv < 0) {
 538                dev_err(&desc->intf->dev, "Error autopm - %d\n", rv);
 539                goto out;
 540        }
 541        intf->needs_remote_wakeup = 1;
 542
 543        mutex_lock(&desc->lock);
 544        if (!desc->count++) {
 545                rv = usb_submit_urb(desc->validity, GFP_KERNEL);
 546                if (rv < 0) {
 547                        desc->count--;
 548                        dev_err(&desc->intf->dev,
 549                                "Error submitting int urb - %d\n", rv);
 550                }
 551        } else {
 552                rv = 0;
 553        }
 554        mutex_unlock(&desc->lock);
 555        usb_autopm_put_interface(desc->intf);
 556out:
 557        mutex_unlock(&wdm_mutex);
 558        return rv;
 559}
 560
 561static int wdm_release(struct inode *inode, struct file *file)
 562{
 563        struct wdm_device *desc = file->private_data;
 564
 565        mutex_lock(&wdm_mutex);
 566        mutex_lock(&desc->lock);
 567        desc->count--;
 568        mutex_unlock(&desc->lock);
 569
 570        if (!desc->count) {
 571                dev_dbg(&desc->intf->dev, "wdm_release: cleanup");
 572                kill_urbs(desc);
 573                if (!test_bit(WDM_DISCONNECTING, &desc->flags))
 574                        desc->intf->needs_remote_wakeup = 0;
 575        }
 576        mutex_unlock(&wdm_mutex);
 577        return 0;
 578}
 579
 580static const struct file_operations wdm_fops = {
 581        .owner =        THIS_MODULE,
 582        .read =         wdm_read,
 583        .write =        wdm_write,
 584        .open =         wdm_open,
 585        .flush =        wdm_flush,
 586        .release =      wdm_release,
 587        .poll =         wdm_poll
 588};
 589
 590static struct usb_class_driver wdm_class = {
 591        .name =         "cdc-wdm%d",
 592        .fops =         &wdm_fops,
 593        .minor_base =   WDM_MINOR_BASE,
 594};
 595
 596/* --- error handling --- */
 597static void wdm_rxwork(struct work_struct *work)
 598{
 599        struct wdm_device *desc = container_of(work, struct wdm_device, rxwork);
 600        unsigned long flags;
 601        int rv;
 602
 603        spin_lock_irqsave(&desc->iuspin, flags);
 604        if (test_bit(WDM_DISCONNECTING, &desc->flags)) {
 605                spin_unlock_irqrestore(&desc->iuspin, flags);
 606        } else {
 607                spin_unlock_irqrestore(&desc->iuspin, flags);
 608                rv = usb_submit_urb(desc->response, GFP_KERNEL);
 609                if (rv < 0 && rv != -EPERM) {
 610                        spin_lock_irqsave(&desc->iuspin, flags);
 611                        if (!test_bit(WDM_DISCONNECTING, &desc->flags))
 612                                schedule_work(&desc->rxwork);
 613                        spin_unlock_irqrestore(&desc->iuspin, flags);
 614                }
 615        }
 616}
 617
 618/* --- hotplug --- */
 619
 620static int wdm_probe(struct usb_interface *intf, const struct usb_device_id *id)
 621{
 622        int rv = -EINVAL;
 623        struct usb_device *udev = interface_to_usbdev(intf);
 624        struct wdm_device *desc;
 625        struct usb_host_interface *iface;
 626        struct usb_endpoint_descriptor *ep;
 627        struct usb_cdc_dmm_desc *dmhd;
 628        u8 *buffer = intf->altsetting->extra;
 629        int buflen = intf->altsetting->extralen;
 630        u16 maxcom = 0;
 631
 632        if (!buffer)
 633                goto out;
 634
 635        while (buflen > 2) {
 636                if (buffer [1] != USB_DT_CS_INTERFACE) {
 637                        dev_err(&intf->dev, "skipping garbage\n");
 638                        goto next_desc;
 639                }
 640
 641                switch (buffer [2]) {
 642                case USB_CDC_HEADER_TYPE:
 643                        break;
 644                case USB_CDC_DMM_TYPE:
 645                        dmhd = (struct usb_cdc_dmm_desc *)buffer;
 646                        maxcom = le16_to_cpu(dmhd->wMaxCommand);
 647                        dev_dbg(&intf->dev,
 648                                "Finding maximum buffer length: %d", maxcom);
 649                        break;
 650                default:
 651                        dev_err(&intf->dev,
 652                                "Ignoring extra header, type %d, length %d\n",
 653                                buffer[2], buffer[0]);
 654                        break;
 655                }
 656next_desc:
 657                buflen -= buffer[0];
 658                buffer += buffer[0];
 659        }
 660
 661        rv = -ENOMEM;
 662        desc = kzalloc(sizeof(struct wdm_device), GFP_KERNEL);
 663        if (!desc)
 664                goto out;
 665        mutex_init(&desc->lock);
 666        spin_lock_init(&desc->iuspin);
 667        init_waitqueue_head(&desc->wait);
 668        desc->wMaxCommand = maxcom;
 669        /* this will be expanded and needed in hardware endianness */
 670        desc->inum = cpu_to_le16((u16)intf->cur_altsetting->desc.bInterfaceNumber);
 671        desc->intf = intf;
 672        INIT_WORK(&desc->rxwork, wdm_rxwork);
 673
 674        rv = -EINVAL;
 675        iface = intf->cur_altsetting;
 676        if (iface->desc.bNumEndpoints != 1)
 677                goto err;
 678        ep = &iface->endpoint[0].desc;
 679        if (!ep || !usb_endpoint_is_int_in(ep))
 680                goto err;
 681
 682        desc->wMaxPacketSize = le16_to_cpu(ep->wMaxPacketSize);
 683        desc->bMaxPacketSize0 = udev->descriptor.bMaxPacketSize0;
 684
 685        desc->orq = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL);
 686        if (!desc->orq)
 687                goto err;
 688        desc->irq = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL);
 689        if (!desc->irq)
 690                goto err;
 691
 692        desc->validity = usb_alloc_urb(0, GFP_KERNEL);
 693        if (!desc->validity)
 694                goto err;
 695
 696        desc->response = usb_alloc_urb(0, GFP_KERNEL);
 697        if (!desc->response)
 698                goto err;
 699
 700        desc->command = usb_alloc_urb(0, GFP_KERNEL);
 701        if (!desc->command)
 702                goto err;
 703
 704        desc->ubuf = kmalloc(desc->wMaxCommand, GFP_KERNEL);
 705        if (!desc->ubuf)
 706                goto err;
 707
 708        desc->sbuf = usb_buffer_alloc(interface_to_usbdev(intf),
 709                                        desc->wMaxPacketSize,
 710                                        GFP_KERNEL,
 711                                        &desc->validity->transfer_dma);
 712        if (!desc->sbuf)
 713                goto err;
 714
 715        desc->inbuf = usb_buffer_alloc(interface_to_usbdev(intf),
 716                                        desc->bMaxPacketSize0,
 717                                        GFP_KERNEL,
 718                                        &desc->response->transfer_dma);
 719        if (!desc->inbuf)
 720                goto err2;
 721
 722        usb_fill_int_urb(
 723                desc->validity,
 724                interface_to_usbdev(intf),
 725                usb_rcvintpipe(interface_to_usbdev(intf), ep->bEndpointAddress),
 726                desc->sbuf,
 727                desc->wMaxPacketSize,
 728                wdm_int_callback,
 729                desc,
 730                ep->bInterval
 731        );
 732        desc->validity->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 733
 734        usb_set_intfdata(intf, desc);
 735        rv = usb_register_dev(intf, &wdm_class);
 736        if (rv < 0)
 737                goto err3;
 738        else
 739                dev_info(&intf->dev, "cdc-wdm%d: USB WDM device\n",
 740                        intf->minor - WDM_MINOR_BASE);
 741out:
 742        return rv;
 743err3:
 744        usb_set_intfdata(intf, NULL);
 745        usb_buffer_free(interface_to_usbdev(desc->intf),
 746                        desc->bMaxPacketSize0,
 747                        desc->inbuf,
 748                        desc->response->transfer_dma);
 749err2:
 750        usb_buffer_free(interface_to_usbdev(desc->intf),
 751                        desc->wMaxPacketSize,
 752                        desc->sbuf,
 753                        desc->validity->transfer_dma);
 754err:
 755        free_urbs(desc);
 756        kfree(desc->ubuf);
 757        kfree(desc->orq);
 758        kfree(desc->irq);
 759        kfree(desc);
 760        return rv;
 761}
 762
 763static void wdm_disconnect(struct usb_interface *intf)
 764{
 765        struct wdm_device *desc;
 766        unsigned long flags;
 767
 768        usb_deregister_dev(intf, &wdm_class);
 769        mutex_lock(&wdm_mutex);
 770        desc = usb_get_intfdata(intf);
 771
 772        /* the spinlock makes sure no new urbs are generated in the callbacks */
 773        spin_lock_irqsave(&desc->iuspin, flags);
 774        set_bit(WDM_DISCONNECTING, &desc->flags);
 775        set_bit(WDM_READ, &desc->flags);
 776        /* to terminate pending flushes */
 777        clear_bit(WDM_IN_USE, &desc->flags);
 778        spin_unlock_irqrestore(&desc->iuspin, flags);
 779        mutex_lock(&desc->lock);
 780        kill_urbs(desc);
 781        cancel_work_sync(&desc->rxwork);
 782        mutex_unlock(&desc->lock);
 783        wake_up_all(&desc->wait);
 784        if (!desc->count)
 785                cleanup(desc);
 786        mutex_unlock(&wdm_mutex);
 787}
 788
 789#ifdef CONFIG_PM
 790static int wdm_suspend(struct usb_interface *intf, pm_message_t message)
 791{
 792        struct wdm_device *desc = usb_get_intfdata(intf);
 793        int rv = 0;
 794
 795        dev_dbg(&desc->intf->dev, "wdm%d_suspend\n", intf->minor);
 796
 797        /* if this is an autosuspend the caller does the locking */
 798        if (!(message.event & PM_EVENT_AUTO))
 799                mutex_lock(&desc->lock);
 800        spin_lock_irq(&desc->iuspin);
 801
 802        if ((message.event & PM_EVENT_AUTO) &&
 803                        (test_bit(WDM_IN_USE, &desc->flags)
 804                        || test_bit(WDM_RESPONDING, &desc->flags))) {
 805                spin_unlock_irq(&desc->iuspin);
 806                rv = -EBUSY;
 807        } else {
 808
 809                set_bit(WDM_SUSPENDING, &desc->flags);
 810                spin_unlock_irq(&desc->iuspin);
 811                /* callback submits work - order is essential */
 812                kill_urbs(desc);
 813                cancel_work_sync(&desc->rxwork);
 814        }
 815        if (!(message.event & PM_EVENT_AUTO))
 816                mutex_unlock(&desc->lock);
 817
 818        return rv;
 819}
 820#endif
 821
 822static int recover_from_urb_loss(struct wdm_device *desc)
 823{
 824        int rv = 0;
 825
 826        if (desc->count) {
 827                rv = usb_submit_urb(desc->validity, GFP_NOIO);
 828                if (rv < 0)
 829                        dev_err(&desc->intf->dev,
 830                                "Error resume submitting int urb - %d\n", rv);
 831        }
 832        return rv;
 833}
 834
 835#ifdef CONFIG_PM
 836static int wdm_resume(struct usb_interface *intf)
 837{
 838        struct wdm_device *desc = usb_get_intfdata(intf);
 839        int rv;
 840
 841        dev_dbg(&desc->intf->dev, "wdm%d_resume\n", intf->minor);
 842
 843        clear_bit(WDM_SUSPENDING, &desc->flags);
 844        rv = recover_from_urb_loss(desc);
 845
 846        return rv;
 847}
 848#endif
 849
 850static int wdm_pre_reset(struct usb_interface *intf)
 851{
 852        struct wdm_device *desc = usb_get_intfdata(intf);
 853
 854        mutex_lock(&desc->lock);
 855        return 0;
 856}
 857
 858static int wdm_post_reset(struct usb_interface *intf)
 859{
 860        struct wdm_device *desc = usb_get_intfdata(intf);
 861        int rv;
 862
 863        rv = recover_from_urb_loss(desc);
 864        mutex_unlock(&desc->lock);
 865        return 0;
 866}
 867
 868static struct usb_driver wdm_driver = {
 869        .name =         "cdc_wdm",
 870        .probe =        wdm_probe,
 871        .disconnect =   wdm_disconnect,
 872#ifdef CONFIG_PM
 873        .suspend =      wdm_suspend,
 874        .resume =       wdm_resume,
 875        .reset_resume = wdm_resume,
 876#endif
 877        .pre_reset =    wdm_pre_reset,
 878        .post_reset =   wdm_post_reset,
 879        .id_table =     wdm_ids,
 880        .supports_autosuspend = 1,
 881};
 882
 883/* --- low level module stuff --- */
 884
 885static int __init wdm_init(void)
 886{
 887        int rv;
 888
 889        rv = usb_register(&wdm_driver);
 890
 891        return rv;
 892}
 893
 894static void __exit wdm_exit(void)
 895{
 896        usb_deregister(&wdm_driver);
 897}
 898
 899module_init(wdm_init);
 900module_exit(wdm_exit);
 901
 902MODULE_AUTHOR(DRIVER_AUTHOR);
 903MODULE_DESCRIPTION(DRIVER_DESC);
 904MODULE_LICENSE("GPL");
 905
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.