aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/class/cdc-wdm.c
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
commit8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch)
treea8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /drivers/usb/class/cdc-wdm.c
parent406089d01562f1e2bf9f089fd7637009ebaad589 (diff)
Patched in Tegra support.
Diffstat (limited to 'drivers/usb/class/cdc-wdm.c')
-rw-r--r--drivers/usb/class/cdc-wdm.c408
1 files changed, 155 insertions, 253 deletions
diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c
index 5f0cb417b73..90581a85134 100644
--- a/drivers/usb/class/cdc-wdm.c
+++ b/drivers/usb/class/cdc-wdm.c
@@ -23,7 +23,6 @@
23#include <linux/usb/cdc.h> 23#include <linux/usb/cdc.h>
24#include <asm/byteorder.h> 24#include <asm/byteorder.h>
25#include <asm/unaligned.h> 25#include <asm/unaligned.h>
26#include <linux/usb/cdc-wdm.h>
27 26
28/* 27/*
29 * Version Information 28 * Version Information
@@ -55,7 +54,6 @@ MODULE_DEVICE_TABLE (usb, wdm_ids);
55#define WDM_POLL_RUNNING 6 54#define WDM_POLL_RUNNING 6
56#define WDM_RESPONDING 7 55#define WDM_RESPONDING 7
57#define WDM_SUSPENDING 8 56#define WDM_SUSPENDING 8
58#define WDM_RESETTING 9
59 57
60#define WDM_MAX 16 58#define WDM_MAX 16
61 59
@@ -63,8 +61,6 @@ MODULE_DEVICE_TABLE (usb, wdm_ids);
63#define WDM_DEFAULT_BUFSIZE 256 61#define WDM_DEFAULT_BUFSIZE 256
64 62
65static DEFINE_MUTEX(wdm_mutex); 63static DEFINE_MUTEX(wdm_mutex);
66static DEFINE_SPINLOCK(wdm_device_list_lock);
67static LIST_HEAD(wdm_device_list);
68 64
69/* --- method tables --- */ 65/* --- method tables --- */
70 66
@@ -86,6 +82,7 @@ struct wdm_device {
86 u16 bufsize; 82 u16 bufsize;
87 u16 wMaxCommand; 83 u16 wMaxCommand;
88 u16 wMaxPacketSize; 84 u16 wMaxPacketSize;
85 u16 bMaxPacketSize0;
89 __le16 inum; 86 __le16 inum;
90 int reslength; 87 int reslength;
91 int length; 88 int length;
@@ -99,44 +96,10 @@ struct wdm_device {
99 struct work_struct rxwork; 96 struct work_struct rxwork;
100 int werr; 97 int werr;
101 int rerr; 98 int rerr;
102
103 struct list_head device_list;
104 int (*manage_power)(struct usb_interface *, int);
105}; 99};
106 100
107static struct usb_driver wdm_driver; 101static struct usb_driver wdm_driver;
108 102
109/* return intfdata if we own the interface, else look up intf in the list */
110static struct wdm_device *wdm_find_device(struct usb_interface *intf)
111{
112 struct wdm_device *desc;
113
114 spin_lock(&wdm_device_list_lock);
115 list_for_each_entry(desc, &wdm_device_list, device_list)
116 if (desc->intf == intf)
117 goto found;
118 desc = NULL;
119found:
120 spin_unlock(&wdm_device_list_lock);
121
122 return desc;
123}
124
125static struct wdm_device *wdm_find_device_by_minor(int minor)
126{
127 struct wdm_device *desc;
128
129 spin_lock(&wdm_device_list_lock);
130 list_for_each_entry(desc, &wdm_device_list, device_list)
131 if (desc->intf->minor == minor)
132 goto found;
133 desc = NULL;
134found:
135 spin_unlock(&wdm_device_list_lock);
136
137 return desc;
138}
139
140/* --- callbacks --- */ 103/* --- callbacks --- */
141static void wdm_out_callback(struct urb *urb) 104static void wdm_out_callback(struct urb *urb)
142{ 105{
@@ -145,9 +108,8 @@ static void wdm_out_callback(struct urb *urb)
145 spin_lock(&desc->iuspin); 108 spin_lock(&desc->iuspin);
146 desc->werr = urb->status; 109 desc->werr = urb->status;
147 spin_unlock(&desc->iuspin); 110 spin_unlock(&desc->iuspin);
148 kfree(desc->outbuf);
149 desc->outbuf = NULL;
150 clear_bit(WDM_IN_USE, &desc->flags); 111 clear_bit(WDM_IN_USE, &desc->flags);
112 kfree(desc->outbuf);
151 wake_up(&desc->wait); 113 wake_up(&desc->wait);
152} 114}
153 115
@@ -200,9 +162,11 @@ static void wdm_int_callback(struct urb *urb)
200 int rv = 0; 162 int rv = 0;
201 int status = urb->status; 163 int status = urb->status;
202 struct wdm_device *desc; 164 struct wdm_device *desc;
165 struct usb_ctrlrequest *req;
203 struct usb_cdc_notification *dr; 166 struct usb_cdc_notification *dr;
204 167
205 desc = urb->context; 168 desc = urb->context;
169 req = desc->irq;
206 dr = (struct usb_cdc_notification *)desc->sbuf; 170 dr = (struct usb_cdc_notification *)desc->sbuf;
207 171
208 if (status) { 172 if (status) {
@@ -249,6 +213,24 @@ static void wdm_int_callback(struct urb *urb)
249 goto exit; 213 goto exit;
250 } 214 }
251 215
216 req->bRequestType = (USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE);
217 req->bRequest = USB_CDC_GET_ENCAPSULATED_RESPONSE;
218 req->wValue = 0;
219 req->wIndex = desc->inum;
220 req->wLength = cpu_to_le16(desc->wMaxCommand);
221
222 usb_fill_control_urb(
223 desc->response,
224 interface_to_usbdev(desc->intf),
225 /* using common endpoint 0 */
226 usb_rcvctrlpipe(interface_to_usbdev(desc->intf), 0),
227 (unsigned char *)req,
228 desc->inbuf,
229 desc->wMaxCommand,
230 wdm_in_callback,
231 desc
232 );
233 desc->response->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
252 spin_lock(&desc->iuspin); 234 spin_lock(&desc->iuspin);
253 clear_bit(WDM_READ, &desc->flags); 235 clear_bit(WDM_READ, &desc->flags);
254 set_bit(WDM_RESPONDING, &desc->flags); 236 set_bit(WDM_RESPONDING, &desc->flags);
@@ -297,8 +279,14 @@ static void free_urbs(struct wdm_device *desc)
297 279
298static void cleanup(struct wdm_device *desc) 280static void cleanup(struct wdm_device *desc)
299{ 281{
300 kfree(desc->sbuf); 282 usb_free_coherent(interface_to_usbdev(desc->intf),
301 kfree(desc->inbuf); 283 desc->wMaxPacketSize,
284 desc->sbuf,
285 desc->validity->transfer_dma);
286 usb_free_coherent(interface_to_usbdev(desc->intf),
287 desc->bMaxPacketSize0,
288 desc->inbuf,
289 desc->response->transfer_dma);
302 kfree(desc->orq); 290 kfree(desc->orq);
303 kfree(desc->irq); 291 kfree(desc->irq);
304 kfree(desc->ubuf); 292 kfree(desc->ubuf);
@@ -324,7 +312,7 @@ static ssize_t wdm_write
324 if (we < 0) 312 if (we < 0)
325 return -EIO; 313 return -EIO;
326 314
327 buf = kmalloc(count, GFP_KERNEL); 315 desc->outbuf = buf = kmalloc(count, GFP_KERNEL);
328 if (!buf) { 316 if (!buf) {
329 rv = -ENOMEM; 317 rv = -ENOMEM;
330 goto outnl; 318 goto outnl;
@@ -354,7 +342,6 @@ static ssize_t wdm_write
354 r = usb_autopm_get_interface(desc->intf); 342 r = usb_autopm_get_interface(desc->intf);
355 if (r < 0) { 343 if (r < 0) {
356 kfree(buf); 344 kfree(buf);
357 rv = usb_translate_errors(r);
358 goto outnp; 345 goto outnp;
359 } 346 }
360 347
@@ -364,13 +351,8 @@ static ssize_t wdm_write
364 else 351 else
365 if (test_bit(WDM_IN_USE, &desc->flags)) 352 if (test_bit(WDM_IN_USE, &desc->flags))
366 r = -EAGAIN; 353 r = -EAGAIN;
367
368 if (test_bit(WDM_RESETTING, &desc->flags))
369 r = -EIO;
370
371 if (r < 0) { 354 if (r < 0) {
372 kfree(buf); 355 kfree(buf);
373 rv = r;
374 goto out; 356 goto out;
375 } 357 }
376 358
@@ -394,15 +376,12 @@ static ssize_t wdm_write
394 req->wIndex = desc->inum; 376 req->wIndex = desc->inum;
395 req->wLength = cpu_to_le16(count); 377 req->wLength = cpu_to_le16(count);
396 set_bit(WDM_IN_USE, &desc->flags); 378 set_bit(WDM_IN_USE, &desc->flags);
397 desc->outbuf = buf;
398 379
399 rv = usb_submit_urb(desc->command, GFP_KERNEL); 380 rv = usb_submit_urb(desc->command, GFP_KERNEL);
400 if (rv < 0) { 381 if (rv < 0) {
401 kfree(buf); 382 kfree(buf);
402 desc->outbuf = NULL;
403 clear_bit(WDM_IN_USE, &desc->flags); 383 clear_bit(WDM_IN_USE, &desc->flags);
404 dev_err(&desc->intf->dev, "Tx URB error: %d\n", rv); 384 dev_err(&desc->intf->dev, "Tx URB error: %d\n", rv);
405 rv = usb_translate_errors(rv);
406 } else { 385 } else {
407 dev_dbg(&desc->intf->dev, "Tx URB has been submitted index=%d", 386 dev_dbg(&desc->intf->dev, "Tx URB has been submitted index=%d",
408 req->wIndex); 387 req->wIndex);
@@ -418,7 +397,7 @@ outnl:
418static ssize_t wdm_read 397static ssize_t wdm_read
419(struct file *file, char __user *buffer, size_t count, loff_t *ppos) 398(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
420{ 399{
421 int rv, cntr; 400 int rv, cntr = 0;
422 int i = 0; 401 int i = 0;
423 struct wdm_device *desc = file->private_data; 402 struct wdm_device *desc = file->private_data;
424 403
@@ -427,8 +406,7 @@ static ssize_t wdm_read
427 if (rv < 0) 406 if (rv < 0)
428 return -ERESTARTSYS; 407 return -ERESTARTSYS;
429 408
430 cntr = ACCESS_ONCE(desc->length); 409 if (desc->length == 0) {
431 if (cntr == 0) {
432 desc->read = 0; 410 desc->read = 0;
433retry: 411retry:
434 if (test_bit(WDM_DISCONNECTING, &desc->flags)) { 412 if (test_bit(WDM_DISCONNECTING, &desc->flags)) {
@@ -452,10 +430,6 @@ retry:
452 rv = -ENODEV; 430 rv = -ENODEV;
453 goto err; 431 goto err;
454 } 432 }
455 if (test_bit(WDM_RESETTING, &desc->flags)) {
456 rv = -EIO;
457 goto err;
458 }
459 usb_mark_last_busy(interface_to_usbdev(desc->intf)); 433 usb_mark_last_busy(interface_to_usbdev(desc->intf));
460 if (rv < 0) { 434 if (rv < 0) {
461 rv = -ERESTARTSYS; 435 rv = -ERESTARTSYS;
@@ -479,35 +453,29 @@ retry:
479 goto retry; 453 goto retry;
480 } 454 }
481 if (!desc->reslength) { /* zero length read */ 455 if (!desc->reslength) { /* zero length read */
482 dev_dbg(&desc->intf->dev, "%s: zero length - clearing WDM_READ\n", __func__);
483 clear_bit(WDM_READ, &desc->flags);
484 spin_unlock_irq(&desc->iuspin); 456 spin_unlock_irq(&desc->iuspin);
485 goto retry; 457 goto retry;
486 } 458 }
487 cntr = desc->length; 459 clear_bit(WDM_READ, &desc->flags);
488 spin_unlock_irq(&desc->iuspin); 460 spin_unlock_irq(&desc->iuspin);
489 } 461 }
490 462
491 if (cntr > count) 463 cntr = count > desc->length ? desc->length : count;
492 cntr = count;
493 rv = copy_to_user(buffer, desc->ubuf, cntr); 464 rv = copy_to_user(buffer, desc->ubuf, cntr);
494 if (rv > 0) { 465 if (rv > 0) {
495 rv = -EFAULT; 466 rv = -EFAULT;
496 goto err; 467 goto err;
497 } 468 }
498 469
499 spin_lock_irq(&desc->iuspin);
500
501 for (i = 0; i < desc->length - cntr; i++) 470 for (i = 0; i < desc->length - cntr; i++)
502 desc->ubuf[i] = desc->ubuf[i + cntr]; 471 desc->ubuf[i] = desc->ubuf[i + cntr];
503 472
473 spin_lock_irq(&desc->iuspin);
504 desc->length -= cntr; 474 desc->length -= cntr;
475 spin_unlock_irq(&desc->iuspin);
505 /* in case we had outstanding data */ 476 /* in case we had outstanding data */
506 if (!desc->length) 477 if (!desc->length)
507 clear_bit(WDM_READ, &desc->flags); 478 clear_bit(WDM_READ, &desc->flags);
508
509 spin_unlock_irq(&desc->iuspin);
510
511 rv = cntr; 479 rv = cntr;
512 480
513err: 481err:
@@ -520,13 +488,11 @@ static int wdm_flush(struct file *file, fl_owner_t id)
520 struct wdm_device *desc = file->private_data; 488 struct wdm_device *desc = file->private_data;
521 489
522 wait_event(desc->wait, !test_bit(WDM_IN_USE, &desc->flags)); 490 wait_event(desc->wait, !test_bit(WDM_IN_USE, &desc->flags));
523 491 if (desc->werr < 0)
524 /* cannot dereference desc->intf if WDM_DISCONNECTING */
525 if (desc->werr < 0 && !test_bit(WDM_DISCONNECTING, &desc->flags))
526 dev_err(&desc->intf->dev, "Error in flush path: %d\n", 492 dev_err(&desc->intf->dev, "Error in flush path: %d\n",
527 desc->werr); 493 desc->werr);
528 494
529 return usb_translate_errors(desc->werr); 495 return desc->werr;
530} 496}
531 497
532static unsigned int wdm_poll(struct file *file, struct poll_table_struct *wait) 498static unsigned int wdm_poll(struct file *file, struct poll_table_struct *wait)
@@ -537,7 +503,7 @@ static unsigned int wdm_poll(struct file *file, struct poll_table_struct *wait)
537 503
538 spin_lock_irqsave(&desc->iuspin, flags); 504 spin_lock_irqsave(&desc->iuspin, flags);
539 if (test_bit(WDM_DISCONNECTING, &desc->flags)) { 505 if (test_bit(WDM_DISCONNECTING, &desc->flags)) {
540 mask = POLLHUP | POLLERR; 506 mask = POLLERR;
541 spin_unlock_irqrestore(&desc->iuspin, flags); 507 spin_unlock_irqrestore(&desc->iuspin, flags);
542 goto desc_out; 508 goto desc_out;
543 } 509 }
@@ -563,11 +529,11 @@ static int wdm_open(struct inode *inode, struct file *file)
563 struct wdm_device *desc; 529 struct wdm_device *desc;
564 530
565 mutex_lock(&wdm_mutex); 531 mutex_lock(&wdm_mutex);
566 desc = wdm_find_device_by_minor(minor); 532 intf = usb_find_interface(&wdm_driver, minor);
567 if (!desc) 533 if (!intf)
568 goto out; 534 goto out;
569 535
570 intf = desc->intf; 536 desc = usb_get_intfdata(intf);
571 if (test_bit(WDM_DISCONNECTING, &desc->flags)) 537 if (test_bit(WDM_DISCONNECTING, &desc->flags))
572 goto out; 538 goto out;
573 file->private_data = desc; 539 file->private_data = desc;
@@ -577,6 +543,7 @@ static int wdm_open(struct inode *inode, struct file *file)
577 dev_err(&desc->intf->dev, "Error autopm - %d\n", rv); 543 dev_err(&desc->intf->dev, "Error autopm - %d\n", rv);
578 goto out; 544 goto out;
579 } 545 }
546 intf->needs_remote_wakeup = 1;
580 547
581 /* using write lock to protect desc->count */ 548 /* using write lock to protect desc->count */
582 mutex_lock(&desc->wlock); 549 mutex_lock(&desc->wlock);
@@ -588,14 +555,11 @@ static int wdm_open(struct inode *inode, struct file *file)
588 desc->count--; 555 desc->count--;
589 dev_err(&desc->intf->dev, 556 dev_err(&desc->intf->dev,
590 "Error submitting int urb - %d\n", rv); 557 "Error submitting int urb - %d\n", rv);
591 rv = usb_translate_errors(rv);
592 } 558 }
593 } else { 559 } else {
594 rv = 0; 560 rv = 0;
595 } 561 }
596 mutex_unlock(&desc->wlock); 562 mutex_unlock(&desc->wlock);
597 if (desc->count == 1)
598 desc->manage_power(intf, 1);
599 usb_autopm_put_interface(desc->intf); 563 usb_autopm_put_interface(desc->intf);
600out: 564out:
601 mutex_unlock(&wdm_mutex); 565 mutex_unlock(&wdm_mutex);
@@ -614,15 +578,10 @@ static int wdm_release(struct inode *inode, struct file *file)
614 mutex_unlock(&desc->wlock); 578 mutex_unlock(&desc->wlock);
615 579
616 if (!desc->count) { 580 if (!desc->count) {
617 if (!test_bit(WDM_DISCONNECTING, &desc->flags)) { 581 dev_dbg(&desc->intf->dev, "wdm_release: cleanup");
618 dev_dbg(&desc->intf->dev, "wdm_release: cleanup"); 582 kill_urbs(desc);
619 kill_urbs(desc); 583 if (!test_bit(WDM_DISCONNECTING, &desc->flags))
620 desc->manage_power(desc->intf, 0); 584 desc->intf->needs_remote_wakeup = 0;
621 } else {
622 /* must avoid dev_printk here as desc->intf is invalid */
623 pr_debug(KBUILD_MODNAME " %s: device gone - cleaning up\n", __func__);
624 cleanup(desc);
625 }
626 } 585 }
627 mutex_unlock(&wdm_mutex); 586 mutex_unlock(&wdm_mutex);
628 return 0; 587 return 0;
@@ -669,31 +628,71 @@ static void wdm_rxwork(struct work_struct *work)
669 628
670/* --- hotplug --- */ 629/* --- hotplug --- */
671 630
672static int wdm_create(struct usb_interface *intf, struct usb_endpoint_descriptor *ep, 631static int wdm_probe(struct usb_interface *intf, const struct usb_device_id *id)
673 u16 bufsize, int (*manage_power)(struct usb_interface *, int))
674{ 632{
675 int rv = -ENOMEM; 633 int rv = -EINVAL;
634 struct usb_device *udev = interface_to_usbdev(intf);
676 struct wdm_device *desc; 635 struct wdm_device *desc;
636 struct usb_host_interface *iface;
637 struct usb_endpoint_descriptor *ep;
638 struct usb_cdc_dmm_desc *dmhd;
639 u8 *buffer = intf->altsetting->extra;
640 int buflen = intf->altsetting->extralen;
641 u16 maxcom = WDM_DEFAULT_BUFSIZE;
677 642
643 if (!buffer)
644 goto out;
645
646 while (buflen > 2) {
647 if (buffer [1] != USB_DT_CS_INTERFACE) {
648 dev_err(&intf->dev, "skipping garbage\n");
649 goto next_desc;
650 }
651
652 switch (buffer [2]) {
653 case USB_CDC_HEADER_TYPE:
654 break;
655 case USB_CDC_DMM_TYPE:
656 dmhd = (struct usb_cdc_dmm_desc *)buffer;
657 maxcom = le16_to_cpu(dmhd->wMaxCommand);
658 dev_dbg(&intf->dev,
659 "Finding maximum buffer length: %d", maxcom);
660 break;
661 default:
662 dev_err(&intf->dev,
663 "Ignoring extra header, type %d, length %d\n",
664 buffer[2], buffer[0]);
665 break;
666 }
667next_desc:
668 buflen -= buffer[0];
669 buffer += buffer[0];
670 }
671
672 rv = -ENOMEM;
678 desc = kzalloc(sizeof(struct wdm_device), GFP_KERNEL); 673 desc = kzalloc(sizeof(struct wdm_device), GFP_KERNEL);
679 if (!desc) 674 if (!desc)
680 goto out; 675 goto out;
681 INIT_LIST_HEAD(&desc->device_list);
682 mutex_init(&desc->rlock); 676 mutex_init(&desc->rlock);
683 mutex_init(&desc->wlock); 677 mutex_init(&desc->wlock);
684 spin_lock_init(&desc->iuspin); 678 spin_lock_init(&desc->iuspin);
685 init_waitqueue_head(&desc->wait); 679 init_waitqueue_head(&desc->wait);
686 desc->wMaxCommand = bufsize; 680 desc->wMaxCommand = maxcom;
687 /* this will be expanded and needed in hardware endianness */ 681 /* this will be expanded and needed in hardware endianness */
688 desc->inum = cpu_to_le16((u16)intf->cur_altsetting->desc.bInterfaceNumber); 682 desc->inum = cpu_to_le16((u16)intf->cur_altsetting->desc.bInterfaceNumber);
689 desc->intf = intf; 683 desc->intf = intf;
690 INIT_WORK(&desc->rxwork, wdm_rxwork); 684 INIT_WORK(&desc->rxwork, wdm_rxwork);
691 685
692 rv = -EINVAL; 686 rv = -EINVAL;
693 if (!usb_endpoint_is_int_in(ep)) 687 iface = intf->cur_altsetting;
688 if (iface->desc.bNumEndpoints != 1)
689 goto err;
690 ep = &iface->endpoint[0].desc;
691 if (!ep || !usb_endpoint_is_int_in(ep))
694 goto err; 692 goto err;
695 693
696 desc->wMaxPacketSize = usb_endpoint_maxp(ep); 694 desc->wMaxPacketSize = le16_to_cpu(ep->wMaxPacketSize);
695 desc->bMaxPacketSize0 = udev->descriptor.bMaxPacketSize0;
697 696
698 desc->orq = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL); 697 desc->orq = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL);
699 if (!desc->orq) 698 if (!desc->orq)
@@ -718,13 +717,19 @@ static int wdm_create(struct usb_interface *intf, struct usb_endpoint_descriptor
718 if (!desc->ubuf) 717 if (!desc->ubuf)
719 goto err; 718 goto err;
720 719
721 desc->sbuf = kmalloc(desc->wMaxPacketSize, GFP_KERNEL); 720 desc->sbuf = usb_alloc_coherent(interface_to_usbdev(intf),
721 desc->wMaxPacketSize,
722 GFP_KERNEL,
723 &desc->validity->transfer_dma);
722 if (!desc->sbuf) 724 if (!desc->sbuf)
723 goto err; 725 goto err;
724 726
725 desc->inbuf = kmalloc(desc->wMaxCommand, GFP_KERNEL); 727 desc->inbuf = usb_alloc_coherent(interface_to_usbdev(intf),
728 desc->wMaxCommand,
729 GFP_KERNEL,
730 &desc->response->transfer_dma);
726 if (!desc->inbuf) 731 if (!desc->inbuf)
727 goto err; 732 goto err2;
728 733
729 usb_fill_int_urb( 734 usb_fill_int_urb(
730 desc->validity, 735 desc->validity,
@@ -736,152 +741,45 @@ static int wdm_create(struct usb_interface *intf, struct usb_endpoint_descriptor
736 desc, 741 desc,
737 ep->bInterval 742 ep->bInterval
738 ); 743 );
744 desc->validity->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
739 745
740 desc->irq->bRequestType = (USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE); 746 usb_set_intfdata(intf, desc);
741 desc->irq->bRequest = USB_CDC_GET_ENCAPSULATED_RESPONSE;
742 desc->irq->wValue = 0;
743 desc->irq->wIndex = desc->inum;
744 desc->irq->wLength = cpu_to_le16(desc->wMaxCommand);
745
746 usb_fill_control_urb(
747 desc->response,
748 interface_to_usbdev(intf),
749 /* using common endpoint 0 */
750 usb_rcvctrlpipe(interface_to_usbdev(desc->intf), 0),
751 (unsigned char *)desc->irq,
752 desc->inbuf,
753 desc->wMaxCommand,
754 wdm_in_callback,
755 desc
756 );
757
758 desc->manage_power = manage_power;
759
760 spin_lock(&wdm_device_list_lock);
761 list_add(&desc->device_list, &wdm_device_list);
762 spin_unlock(&wdm_device_list_lock);
763
764 rv = usb_register_dev(intf, &wdm_class); 747 rv = usb_register_dev(intf, &wdm_class);
765 if (rv < 0) 748 if (rv < 0)
766 goto err; 749 goto err3;
767 else 750 else
768 dev_info(&intf->dev, "%s: USB WDM device\n", dev_name(intf->usb_dev)); 751 dev_info(&intf->dev, "cdc-wdm%d: USB WDM device\n",
752 intf->minor - WDM_MINOR_BASE);
769out: 753out:
770 return rv; 754 return rv;
755err3:
756 usb_set_intfdata(intf, NULL);
757 usb_free_coherent(interface_to_usbdev(desc->intf),
758 desc->bMaxPacketSize0,
759 desc->inbuf,
760 desc->response->transfer_dma);
761err2:
762 usb_free_coherent(interface_to_usbdev(desc->intf),
763 desc->wMaxPacketSize,
764 desc->sbuf,
765 desc->validity->transfer_dma);
771err: 766err:
772 spin_lock(&wdm_device_list_lock); 767 free_urbs(desc);
773 list_del(&desc->device_list); 768 kfree(desc->ubuf);
774 spin_unlock(&wdm_device_list_lock); 769 kfree(desc->orq);
775 cleanup(desc); 770 kfree(desc->irq);
776 return rv; 771 kfree(desc);
777}
778
779static int wdm_manage_power(struct usb_interface *intf, int on)
780{
781 /* need autopm_get/put here to ensure the usbcore sees the new value */
782 int rv = usb_autopm_get_interface(intf);
783 if (rv < 0)
784 goto err;
785
786 intf->needs_remote_wakeup = on;
787 usb_autopm_put_interface(intf);
788err:
789 return rv;
790}
791
792static int wdm_probe(struct usb_interface *intf, const struct usb_device_id *id)
793{
794 int rv = -EINVAL;
795 struct usb_host_interface *iface;
796 struct usb_endpoint_descriptor *ep;
797 struct usb_cdc_dmm_desc *dmhd;
798 u8 *buffer = intf->altsetting->extra;
799 int buflen = intf->altsetting->extralen;
800 u16 maxcom = WDM_DEFAULT_BUFSIZE;
801
802 if (!buffer)
803 goto err;
804 while (buflen > 2) {
805 if (buffer[1] != USB_DT_CS_INTERFACE) {
806 dev_err(&intf->dev, "skipping garbage\n");
807 goto next_desc;
808 }
809
810 switch (buffer[2]) {
811 case USB_CDC_HEADER_TYPE:
812 break;
813 case USB_CDC_DMM_TYPE:
814 dmhd = (struct usb_cdc_dmm_desc *)buffer;
815 maxcom = le16_to_cpu(dmhd->wMaxCommand);
816 dev_dbg(&intf->dev,
817 "Finding maximum buffer length: %d", maxcom);
818 break;
819 default:
820 dev_err(&intf->dev,
821 "Ignoring extra header, type %d, length %d\n",
822 buffer[2], buffer[0]);
823 break;
824 }
825next_desc:
826 buflen -= buffer[0];
827 buffer += buffer[0];
828 }
829
830 iface = intf->cur_altsetting;
831 if (iface->desc.bNumEndpoints != 1)
832 goto err;
833 ep = &iface->endpoint[0].desc;
834
835 rv = wdm_create(intf, ep, maxcom, &wdm_manage_power);
836
837err:
838 return rv; 772 return rv;
839} 773}
840 774
841/**
842 * usb_cdc_wdm_register - register a WDM subdriver
843 * @intf: usb interface the subdriver will associate with
844 * @ep: interrupt endpoint to monitor for notifications
845 * @bufsize: maximum message size to support for read/write
846 *
847 * Create WDM usb class character device and associate it with intf
848 * without binding, allowing another driver to manage the interface.
849 *
850 * The subdriver will manage the given interrupt endpoint exclusively
851 * and will issue control requests referring to the given intf. It
852 * will otherwise avoid interferring, and in particular not do
853 * usb_set_intfdata/usb_get_intfdata on intf.
854 *
855 * The return value is a pointer to the subdriver's struct usb_driver.
856 * The registering driver is responsible for calling this subdriver's
857 * disconnect, suspend, resume, pre_reset and post_reset methods from
858 * its own.
859 */
860struct usb_driver *usb_cdc_wdm_register(struct usb_interface *intf,
861 struct usb_endpoint_descriptor *ep,
862 int bufsize,
863 int (*manage_power)(struct usb_interface *, int))
864{
865 int rv = -EINVAL;
866
867 rv = wdm_create(intf, ep, bufsize, manage_power);
868 if (rv < 0)
869 goto err;
870
871 return &wdm_driver;
872err:
873 return ERR_PTR(rv);
874}
875EXPORT_SYMBOL(usb_cdc_wdm_register);
876
877static void wdm_disconnect(struct usb_interface *intf) 775static void wdm_disconnect(struct usb_interface *intf)
878{ 776{
879 struct wdm_device *desc; 777 struct wdm_device *desc;
880 unsigned long flags; 778 unsigned long flags;
881 779
882 usb_deregister_dev(intf, &wdm_class); 780 usb_deregister_dev(intf, &wdm_class);
883 desc = wdm_find_device(intf);
884 mutex_lock(&wdm_mutex); 781 mutex_lock(&wdm_mutex);
782 desc = usb_get_intfdata(intf);
885 783
886 /* the spinlock makes sure no new urbs are generated in the callbacks */ 784 /* the spinlock makes sure no new urbs are generated in the callbacks */
887 spin_lock_irqsave(&desc->iuspin, flags); 785 spin_lock_irqsave(&desc->iuspin, flags);
@@ -897,35 +795,27 @@ static void wdm_disconnect(struct usb_interface *intf)
897 cancel_work_sync(&desc->rxwork); 795 cancel_work_sync(&desc->rxwork);
898 mutex_unlock(&desc->wlock); 796 mutex_unlock(&desc->wlock);
899 mutex_unlock(&desc->rlock); 797 mutex_unlock(&desc->rlock);
900
901 /* the desc->intf pointer used as list key is now invalid */
902 spin_lock(&wdm_device_list_lock);
903 list_del(&desc->device_list);
904 spin_unlock(&wdm_device_list_lock);
905
906 if (!desc->count) 798 if (!desc->count)
907 cleanup(desc); 799 cleanup(desc);
908 else
909 dev_dbg(&intf->dev, "%s: %d open files - postponing cleanup\n", __func__, desc->count);
910 mutex_unlock(&wdm_mutex); 800 mutex_unlock(&wdm_mutex);
911} 801}
912 802
913#ifdef CONFIG_PM 803#ifdef CONFIG_PM
914static int wdm_suspend(struct usb_interface *intf, pm_message_t message) 804static int wdm_suspend(struct usb_interface *intf, pm_message_t message)
915{ 805{
916 struct wdm_device *desc = wdm_find_device(intf); 806 struct wdm_device *desc = usb_get_intfdata(intf);
917 int rv = 0; 807 int rv = 0;
918 808
919 dev_dbg(&desc->intf->dev, "wdm%d_suspend\n", intf->minor); 809 dev_dbg(&desc->intf->dev, "wdm%d_suspend\n", intf->minor);
920 810
921 /* if this is an autosuspend the caller does the locking */ 811 /* if this is an autosuspend the caller does the locking */
922 if (!PMSG_IS_AUTO(message)) { 812 if (!(message.event & PM_EVENT_AUTO)) {
923 mutex_lock(&desc->rlock); 813 mutex_lock(&desc->rlock);
924 mutex_lock(&desc->wlock); 814 mutex_lock(&desc->wlock);
925 } 815 }
926 spin_lock_irq(&desc->iuspin); 816 spin_lock_irq(&desc->iuspin);
927 817
928 if (PMSG_IS_AUTO(message) && 818 if ((message.event & PM_EVENT_AUTO) &&
929 (test_bit(WDM_IN_USE, &desc->flags) 819 (test_bit(WDM_IN_USE, &desc->flags)
930 || test_bit(WDM_RESPONDING, &desc->flags))) { 820 || test_bit(WDM_RESPONDING, &desc->flags))) {
931 spin_unlock_irq(&desc->iuspin); 821 spin_unlock_irq(&desc->iuspin);
@@ -938,7 +828,7 @@ static int wdm_suspend(struct usb_interface *intf, pm_message_t message)
938 kill_urbs(desc); 828 kill_urbs(desc);
939 cancel_work_sync(&desc->rxwork); 829 cancel_work_sync(&desc->rxwork);
940 } 830 }
941 if (!PMSG_IS_AUTO(message)) { 831 if (!(message.event & PM_EVENT_AUTO)) {
942 mutex_unlock(&desc->wlock); 832 mutex_unlock(&desc->wlock);
943 mutex_unlock(&desc->rlock); 833 mutex_unlock(&desc->rlock);
944 } 834 }
@@ -963,7 +853,7 @@ static int recover_from_urb_loss(struct wdm_device *desc)
963#ifdef CONFIG_PM 853#ifdef CONFIG_PM
964static int wdm_resume(struct usb_interface *intf) 854static int wdm_resume(struct usb_interface *intf)
965{ 855{
966 struct wdm_device *desc = wdm_find_device(intf); 856 struct wdm_device *desc = usb_get_intfdata(intf);
967 int rv; 857 int rv;
968 858
969 dev_dbg(&desc->intf->dev, "wdm%d_resume\n", intf->minor); 859 dev_dbg(&desc->intf->dev, "wdm%d_resume\n", intf->minor);
@@ -977,7 +867,11 @@ static int wdm_resume(struct usb_interface *intf)
977 867
978static int wdm_pre_reset(struct usb_interface *intf) 868static int wdm_pre_reset(struct usb_interface *intf)
979{ 869{
980 struct wdm_device *desc = wdm_find_device(intf); 870 struct wdm_device *desc = usb_get_intfdata(intf);
871
872 mutex_lock(&desc->rlock);
873 mutex_lock(&desc->wlock);
874 kill_urbs(desc);
981 875
982 /* 876 /*
983 * we notify everybody using poll of 877 * we notify everybody using poll of
@@ -986,25 +880,17 @@ static int wdm_pre_reset(struct usb_interface *intf)
986 * message from the device is lost 880 * message from the device is lost
987 */ 881 */
988 spin_lock_irq(&desc->iuspin); 882 spin_lock_irq(&desc->iuspin);
989 set_bit(WDM_RESETTING, &desc->flags); /* inform read/write */
990 set_bit(WDM_READ, &desc->flags); /* unblock read */
991 clear_bit(WDM_IN_USE, &desc->flags); /* unblock write */
992 desc->rerr = -EINTR; 883 desc->rerr = -EINTR;
993 spin_unlock_irq(&desc->iuspin); 884 spin_unlock_irq(&desc->iuspin);
994 wake_up_all(&desc->wait); 885 wake_up_all(&desc->wait);
995 mutex_lock(&desc->rlock);
996 mutex_lock(&desc->wlock);
997 kill_urbs(desc);
998 cancel_work_sync(&desc->rxwork);
999 return 0; 886 return 0;
1000} 887}
1001 888
1002static int wdm_post_reset(struct usb_interface *intf) 889static int wdm_post_reset(struct usb_interface *intf)
1003{ 890{
1004 struct wdm_device *desc = wdm_find_device(intf); 891 struct wdm_device *desc = usb_get_intfdata(intf);
1005 int rv; 892 int rv;
1006 893
1007 clear_bit(WDM_RESETTING, &desc->flags);
1008 rv = recover_from_urb_loss(desc); 894 rv = recover_from_urb_loss(desc);
1009 mutex_unlock(&desc->wlock); 895 mutex_unlock(&desc->wlock);
1010 mutex_unlock(&desc->rlock); 896 mutex_unlock(&desc->rlock);
@@ -1024,10 +910,26 @@ static struct usb_driver wdm_driver = {
1024 .post_reset = wdm_post_reset, 910 .post_reset = wdm_post_reset,
1025 .id_table = wdm_ids, 911 .id_table = wdm_ids,
1026 .supports_autosuspend = 1, 912 .supports_autosuspend = 1,
1027 .disable_hub_initiated_lpm = 1,
1028}; 913};
1029 914
1030module_usb_driver(wdm_driver); 915/* --- low level module stuff --- */
916
917static int __init wdm_init(void)
918{
919 int rv;
920
921 rv = usb_register(&wdm_driver);
922
923 return rv;
924}
925
926static void __exit wdm_exit(void)
927{
928 usb_deregister(&wdm_driver);
929}
930
931module_init(wdm_init);
932module_exit(wdm_exit);
1031 933
1032MODULE_AUTHOR(DRIVER_AUTHOR); 934MODULE_AUTHOR(DRIVER_AUTHOR);
1033MODULE_DESCRIPTION(DRIVER_DESC); 935MODULE_DESCRIPTION(DRIVER_DESC);