aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/class
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-03-20 14:26:30 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-03-20 14:26:30 -0400
commited378a52dabf77b406b447fd3238f83ea24b71fa (patch)
tree07e1a7ec2d1c08767ee81b9910f5912b80502632 /drivers/usb/class
parent843ec558f91b8e8fdb6efc908f2c0506407cc750 (diff)
parent11207b6fe05438b2e87a26435cd98db3d55e6fa7 (diff)
Merge tag 'usb-3.3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
Pull USB merge for 3.4-rc1 from Greg KH: "Here's the big USB merge for the 3.4-rc1 merge window. Lots of gadget driver reworks here, driver updates, xhci changes, some new drivers added, usb-serial core reworking to fix some bugs, and other various minor things. There are some patches touching arch code, but they have all been acked by the various arch maintainers." * tag 'usb-3.3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (302 commits) net: qmi_wwan: add support for ZTE MF820D USB: option: add ZTE MF820D usb: gadget: f_fs: Remove lock is held before freeing checks USB: option: make interface blacklist work again usb/ub: deprecate & schedule for removal the "Low Performance USB Block" driver USB: ohci-pxa27x: add clk_prepare/clk_unprepare calls USB: use generic platform driver on ath79 USB: EHCI: Add a generic platform device driver USB: OHCI: Add a generic platform device driver USB: ftdi_sio: new PID: LUMEL PD12 USB: ftdi_sio: add support for FT-X series devices USB: serial: mos7840: Fixed MCS7820 device attach problem usb: Don't make USB_ARCH_HAS_{XHCI,OHCI,EHCI} depend on USB_SUPPORT. usb gadget: fix a section mismatch when compiling g_ffs with CONFIG_USB_FUNCTIONFS_ETH USB: ohci-nxp: Remove i2c_write(), use smbus USB: ohci-nxp: Support for LPC32xx USB: ohci-nxp: Rename symbols from pnx4008 to nxp USB: OHCI-HCD: Rename ohci-pnx4008 to ohci-nxp usb: gadget: Kconfig: fix typo for 'different' usb: dwc3: pci: fix another failure path in dwc3_pci_probe() ...
Diffstat (limited to 'drivers/usb/class')
-rw-r--r--drivers/usb/class/cdc-acm.c30
-rw-r--r--drivers/usb/class/cdc-wdm.c352
2 files changed, 256 insertions, 126 deletions
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index 6bb8472155c6..b32ccb461019 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -39,6 +39,7 @@
39#include <linux/serial.h> 39#include <linux/serial.h>
40#include <linux/tty_driver.h> 40#include <linux/tty_driver.h>
41#include <linux/tty_flip.h> 41#include <linux/tty_flip.h>
42#include <linux/serial.h>
42#include <linux/module.h> 43#include <linux/module.h>
43#include <linux/mutex.h> 44#include <linux/mutex.h>
44#include <linux/uaccess.h> 45#include <linux/uaccess.h>
@@ -768,10 +769,37 @@ static int acm_tty_tiocmset(struct tty_struct *tty,
768 return acm_set_control(acm, acm->ctrlout = newctrl); 769 return acm_set_control(acm, acm->ctrlout = newctrl);
769} 770}
770 771
772static int get_serial_info(struct acm *acm, struct serial_struct __user *info)
773{
774 struct serial_struct tmp;
775
776 if (!info)
777 return -EINVAL;
778
779 memset(&tmp, 0, sizeof(tmp));
780 tmp.flags = ASYNC_LOW_LATENCY;
781 tmp.xmit_fifo_size = acm->writesize;
782 tmp.baud_base = le32_to_cpu(acm->line.dwDTERate);
783
784 if (copy_to_user(info, &tmp, sizeof(tmp)))
785 return -EFAULT;
786 else
787 return 0;
788}
789
771static int acm_tty_ioctl(struct tty_struct *tty, 790static int acm_tty_ioctl(struct tty_struct *tty,
772 unsigned int cmd, unsigned long arg) 791 unsigned int cmd, unsigned long arg)
773{ 792{
774 return -ENOIOCTLCMD; 793 struct acm *acm = tty->driver_data;
794 int rv = -ENOIOCTLCMD;
795
796 switch (cmd) {
797 case TIOCGSERIAL: /* gets serial port data */
798 rv = get_serial_info(acm, (struct serial_struct __user *) arg);
799 break;
800 }
801
802 return rv;
775} 803}
776 804
777static const __u32 acm_tty_speed[] = { 805static const __u32 acm_tty_speed[] = {
diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c
index d2b3cffca3f7..c6f6560d436c 100644
--- a/drivers/usb/class/cdc-wdm.c
+++ b/drivers/usb/class/cdc-wdm.c
@@ -23,6 +23,7 @@
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>
26 27
27/* 28/*
28 * Version Information 29 * Version Information
@@ -31,6 +32,8 @@
31#define DRIVER_AUTHOR "Oliver Neukum" 32#define DRIVER_AUTHOR "Oliver Neukum"
32#define DRIVER_DESC "USB Abstract Control Model driver for USB WCM Device Management" 33#define DRIVER_DESC "USB Abstract Control Model driver for USB WCM Device Management"
33 34
35#define HUAWEI_VENDOR_ID 0x12D1
36
34static const struct usb_device_id wdm_ids[] = { 37static const struct usb_device_id wdm_ids[] = {
35 { 38 {
36 .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS | 39 .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS |
@@ -38,6 +41,20 @@ static const struct usb_device_id wdm_ids[] = {
38 .bInterfaceClass = USB_CLASS_COMM, 41 .bInterfaceClass = USB_CLASS_COMM,
39 .bInterfaceSubClass = USB_CDC_SUBCLASS_DMM 42 .bInterfaceSubClass = USB_CDC_SUBCLASS_DMM
40 }, 43 },
44 {
45 /*
46 * Huawei E392, E398 and possibly other Qualcomm based modems
47 * embed the Qualcomm QMI protocol inside CDC on CDC ECM like
48 * control interfaces. Userspace access to this is required
49 * to configure the accompanying data interface
50 */
51 .match_flags = USB_DEVICE_ID_MATCH_VENDOR |
52 USB_DEVICE_ID_MATCH_INT_INFO,
53 .idVendor = HUAWEI_VENDOR_ID,
54 .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
55 .bInterfaceSubClass = 1,
56 .bInterfaceProtocol = 9, /* NOTE: CDC ECM control interface! */
57 },
41 { } 58 { }
42}; 59};
43 60
@@ -54,6 +71,7 @@ MODULE_DEVICE_TABLE (usb, wdm_ids);
54#define WDM_POLL_RUNNING 6 71#define WDM_POLL_RUNNING 6
55#define WDM_RESPONDING 7 72#define WDM_RESPONDING 7
56#define WDM_SUSPENDING 8 73#define WDM_SUSPENDING 8
74#define WDM_RESETTING 9
57 75
58#define WDM_MAX 16 76#define WDM_MAX 16
59 77
@@ -61,6 +79,8 @@ MODULE_DEVICE_TABLE (usb, wdm_ids);
61#define WDM_DEFAULT_BUFSIZE 256 79#define WDM_DEFAULT_BUFSIZE 256
62 80
63static DEFINE_MUTEX(wdm_mutex); 81static DEFINE_MUTEX(wdm_mutex);
82static DEFINE_SPINLOCK(wdm_device_list_lock);
83static LIST_HEAD(wdm_device_list);
64 84
65/* --- method tables --- */ 85/* --- method tables --- */
66 86
@@ -82,7 +102,6 @@ struct wdm_device {
82 u16 bufsize; 102 u16 bufsize;
83 u16 wMaxCommand; 103 u16 wMaxCommand;
84 u16 wMaxPacketSize; 104 u16 wMaxPacketSize;
85 u16 bMaxPacketSize0;
86 __le16 inum; 105 __le16 inum;
87 int reslength; 106 int reslength;
88 int length; 107 int length;
@@ -96,10 +115,40 @@ struct wdm_device {
96 struct work_struct rxwork; 115 struct work_struct rxwork;
97 int werr; 116 int werr;
98 int rerr; 117 int rerr;
118
119 struct list_head device_list;
120 int (*manage_power)(struct usb_interface *, int);
99}; 121};
100 122
101static struct usb_driver wdm_driver; 123static struct usb_driver wdm_driver;
102 124
125/* return intfdata if we own the interface, else look up intf in the list */
126static struct wdm_device *wdm_find_device(struct usb_interface *intf)
127{
128 struct wdm_device *desc = NULL;
129
130 spin_lock(&wdm_device_list_lock);
131 list_for_each_entry(desc, &wdm_device_list, device_list)
132 if (desc->intf == intf)
133 break;
134 spin_unlock(&wdm_device_list_lock);
135
136 return desc;
137}
138
139static struct wdm_device *wdm_find_device_by_minor(int minor)
140{
141 struct wdm_device *desc = NULL;
142
143 spin_lock(&wdm_device_list_lock);
144 list_for_each_entry(desc, &wdm_device_list, device_list)
145 if (desc->intf->minor == minor)
146 break;
147 spin_unlock(&wdm_device_list_lock);
148
149 return desc;
150}
151
103/* --- callbacks --- */ 152/* --- callbacks --- */
104static void wdm_out_callback(struct urb *urb) 153static void wdm_out_callback(struct urb *urb)
105{ 154{
@@ -162,11 +211,9 @@ static void wdm_int_callback(struct urb *urb)
162 int rv = 0; 211 int rv = 0;
163 int status = urb->status; 212 int status = urb->status;
164 struct wdm_device *desc; 213 struct wdm_device *desc;
165 struct usb_ctrlrequest *req;
166 struct usb_cdc_notification *dr; 214 struct usb_cdc_notification *dr;
167 215
168 desc = urb->context; 216 desc = urb->context;
169 req = desc->irq;
170 dr = (struct usb_cdc_notification *)desc->sbuf; 217 dr = (struct usb_cdc_notification *)desc->sbuf;
171 218
172 if (status) { 219 if (status) {
@@ -213,24 +260,6 @@ static void wdm_int_callback(struct urb *urb)
213 goto exit; 260 goto exit;
214 } 261 }
215 262
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;
234 spin_lock(&desc->iuspin); 263 spin_lock(&desc->iuspin);
235 clear_bit(WDM_READ, &desc->flags); 264 clear_bit(WDM_READ, &desc->flags);
236 set_bit(WDM_RESPONDING, &desc->flags); 265 set_bit(WDM_RESPONDING, &desc->flags);
@@ -279,14 +308,11 @@ static void free_urbs(struct wdm_device *desc)
279 308
280static void cleanup(struct wdm_device *desc) 309static void cleanup(struct wdm_device *desc)
281{ 310{
282 usb_free_coherent(interface_to_usbdev(desc->intf), 311 spin_lock(&wdm_device_list_lock);
283 desc->wMaxPacketSize, 312 list_del(&desc->device_list);
284 desc->sbuf, 313 spin_unlock(&wdm_device_list_lock);
285 desc->validity->transfer_dma); 314 kfree(desc->sbuf);
286 usb_free_coherent(interface_to_usbdev(desc->intf), 315 kfree(desc->inbuf);
287 desc->bMaxPacketSize0,
288 desc->inbuf,
289 desc->response->transfer_dma);
290 kfree(desc->orq); 316 kfree(desc->orq);
291 kfree(desc->irq); 317 kfree(desc->irq);
292 kfree(desc->ubuf); 318 kfree(desc->ubuf);
@@ -351,6 +377,10 @@ static ssize_t wdm_write
351 else 377 else
352 if (test_bit(WDM_IN_USE, &desc->flags)) 378 if (test_bit(WDM_IN_USE, &desc->flags))
353 r = -EAGAIN; 379 r = -EAGAIN;
380
381 if (test_bit(WDM_RESETTING, &desc->flags))
382 r = -EIO;
383
354 if (r < 0) { 384 if (r < 0) {
355 kfree(buf); 385 kfree(buf);
356 goto out; 386 goto out;
@@ -397,7 +427,7 @@ outnl:
397static ssize_t wdm_read 427static ssize_t wdm_read
398(struct file *file, char __user *buffer, size_t count, loff_t *ppos) 428(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
399{ 429{
400 int rv, cntr = 0; 430 int rv, cntr;
401 int i = 0; 431 int i = 0;
402 struct wdm_device *desc = file->private_data; 432 struct wdm_device *desc = file->private_data;
403 433
@@ -406,7 +436,8 @@ static ssize_t wdm_read
406 if (rv < 0) 436 if (rv < 0)
407 return -ERESTARTSYS; 437 return -ERESTARTSYS;
408 438
409 if (desc->length == 0) { 439 cntr = ACCESS_ONCE(desc->length);
440 if (cntr == 0) {
410 desc->read = 0; 441 desc->read = 0;
411retry: 442retry:
412 if (test_bit(WDM_DISCONNECTING, &desc->flags)) { 443 if (test_bit(WDM_DISCONNECTING, &desc->flags)) {
@@ -430,6 +461,10 @@ retry:
430 rv = -ENODEV; 461 rv = -ENODEV;
431 goto err; 462 goto err;
432 } 463 }
464 if (test_bit(WDM_RESETTING, &desc->flags)) {
465 rv = -EIO;
466 goto err;
467 }
433 usb_mark_last_busy(interface_to_usbdev(desc->intf)); 468 usb_mark_last_busy(interface_to_usbdev(desc->intf));
434 if (rv < 0) { 469 if (rv < 0) {
435 rv = -ERESTARTSYS; 470 rv = -ERESTARTSYS;
@@ -456,26 +491,30 @@ retry:
456 spin_unlock_irq(&desc->iuspin); 491 spin_unlock_irq(&desc->iuspin);
457 goto retry; 492 goto retry;
458 } 493 }
459 clear_bit(WDM_READ, &desc->flags); 494 cntr = desc->length;
460 spin_unlock_irq(&desc->iuspin); 495 spin_unlock_irq(&desc->iuspin);
461 } 496 }
462 497
463 cntr = count > desc->length ? desc->length : count; 498 if (cntr > count)
499 cntr = count;
464 rv = copy_to_user(buffer, desc->ubuf, cntr); 500 rv = copy_to_user(buffer, desc->ubuf, cntr);
465 if (rv > 0) { 501 if (rv > 0) {
466 rv = -EFAULT; 502 rv = -EFAULT;
467 goto err; 503 goto err;
468 } 504 }
469 505
506 spin_lock_irq(&desc->iuspin);
507
470 for (i = 0; i < desc->length - cntr; i++) 508 for (i = 0; i < desc->length - cntr; i++)
471 desc->ubuf[i] = desc->ubuf[i + cntr]; 509 desc->ubuf[i] = desc->ubuf[i + cntr];
472 510
473 spin_lock_irq(&desc->iuspin);
474 desc->length -= cntr; 511 desc->length -= cntr;
475 spin_unlock_irq(&desc->iuspin);
476 /* in case we had outstanding data */ 512 /* in case we had outstanding data */
477 if (!desc->length) 513 if (!desc->length)
478 clear_bit(WDM_READ, &desc->flags); 514 clear_bit(WDM_READ, &desc->flags);
515
516 spin_unlock_irq(&desc->iuspin);
517
479 rv = cntr; 518 rv = cntr;
480 519
481err: 520err:
@@ -529,11 +568,11 @@ static int wdm_open(struct inode *inode, struct file *file)
529 struct wdm_device *desc; 568 struct wdm_device *desc;
530 569
531 mutex_lock(&wdm_mutex); 570 mutex_lock(&wdm_mutex);
532 intf = usb_find_interface(&wdm_driver, minor); 571 desc = wdm_find_device_by_minor(minor);
533 if (!intf) 572 if (!desc)
534 goto out; 573 goto out;
535 574
536 desc = usb_get_intfdata(intf); 575 intf = desc->intf;
537 if (test_bit(WDM_DISCONNECTING, &desc->flags)) 576 if (test_bit(WDM_DISCONNECTING, &desc->flags))
538 goto out; 577 goto out;
539 file->private_data = desc; 578 file->private_data = desc;
@@ -543,7 +582,6 @@ static int wdm_open(struct inode *inode, struct file *file)
543 dev_err(&desc->intf->dev, "Error autopm - %d\n", rv); 582 dev_err(&desc->intf->dev, "Error autopm - %d\n", rv);
544 goto out; 583 goto out;
545 } 584 }
546 intf->needs_remote_wakeup = 1;
547 585
548 /* using write lock to protect desc->count */ 586 /* using write lock to protect desc->count */
549 mutex_lock(&desc->wlock); 587 mutex_lock(&desc->wlock);
@@ -560,6 +598,8 @@ static int wdm_open(struct inode *inode, struct file *file)
560 rv = 0; 598 rv = 0;
561 } 599 }
562 mutex_unlock(&desc->wlock); 600 mutex_unlock(&desc->wlock);
601 if (desc->count == 1)
602 desc->manage_power(intf, 1);
563 usb_autopm_put_interface(desc->intf); 603 usb_autopm_put_interface(desc->intf);
564out: 604out:
565 mutex_unlock(&wdm_mutex); 605 mutex_unlock(&wdm_mutex);
@@ -581,7 +621,7 @@ static int wdm_release(struct inode *inode, struct file *file)
581 dev_dbg(&desc->intf->dev, "wdm_release: cleanup"); 621 dev_dbg(&desc->intf->dev, "wdm_release: cleanup");
582 kill_urbs(desc); 622 kill_urbs(desc);
583 if (!test_bit(WDM_DISCONNECTING, &desc->flags)) 623 if (!test_bit(WDM_DISCONNECTING, &desc->flags))
584 desc->intf->needs_remote_wakeup = 0; 624 desc->manage_power(desc->intf, 0);
585 } 625 }
586 mutex_unlock(&wdm_mutex); 626 mutex_unlock(&wdm_mutex);
587 return 0; 627 return 0;
@@ -628,71 +668,31 @@ static void wdm_rxwork(struct work_struct *work)
628 668
629/* --- hotplug --- */ 669/* --- hotplug --- */
630 670
631static int wdm_probe(struct usb_interface *intf, const struct usb_device_id *id) 671static int wdm_create(struct usb_interface *intf, struct usb_endpoint_descriptor *ep,
672 u16 bufsize, int (*manage_power)(struct usb_interface *, int))
632{ 673{
633 int rv = -EINVAL; 674 int rv = -ENOMEM;
634 struct usb_device *udev = interface_to_usbdev(intf);
635 struct wdm_device *desc; 675 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;
642
643 if (!buffer)
644 goto out;
645 676
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;
673 desc = kzalloc(sizeof(struct wdm_device), GFP_KERNEL); 677 desc = kzalloc(sizeof(struct wdm_device), GFP_KERNEL);
674 if (!desc) 678 if (!desc)
675 goto out; 679 goto out;
680 INIT_LIST_HEAD(&desc->device_list);
676 mutex_init(&desc->rlock); 681 mutex_init(&desc->rlock);
677 mutex_init(&desc->wlock); 682 mutex_init(&desc->wlock);
678 spin_lock_init(&desc->iuspin); 683 spin_lock_init(&desc->iuspin);
679 init_waitqueue_head(&desc->wait); 684 init_waitqueue_head(&desc->wait);
680 desc->wMaxCommand = maxcom; 685 desc->wMaxCommand = bufsize;
681 /* this will be expanded and needed in hardware endianness */ 686 /* this will be expanded and needed in hardware endianness */
682 desc->inum = cpu_to_le16((u16)intf->cur_altsetting->desc.bInterfaceNumber); 687 desc->inum = cpu_to_le16((u16)intf->cur_altsetting->desc.bInterfaceNumber);
683 desc->intf = intf; 688 desc->intf = intf;
684 INIT_WORK(&desc->rxwork, wdm_rxwork); 689 INIT_WORK(&desc->rxwork, wdm_rxwork);
685 690
686 rv = -EINVAL; 691 rv = -EINVAL;
687 iface = intf->cur_altsetting; 692 if (!usb_endpoint_is_int_in(ep))
688 if (iface->desc.bNumEndpoints != 1)
689 goto err;
690 ep = &iface->endpoint[0].desc;
691 if (!ep || !usb_endpoint_is_int_in(ep))
692 goto err; 693 goto err;
693 694
694 desc->wMaxPacketSize = usb_endpoint_maxp(ep); 695 desc->wMaxPacketSize = usb_endpoint_maxp(ep);
695 desc->bMaxPacketSize0 = udev->descriptor.bMaxPacketSize0;
696 696
697 desc->orq = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL); 697 desc->orq = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL);
698 if (!desc->orq) 698 if (!desc->orq)
@@ -717,19 +717,13 @@ next_desc:
717 if (!desc->ubuf) 717 if (!desc->ubuf)
718 goto err; 718 goto err;
719 719
720 desc->sbuf = usb_alloc_coherent(interface_to_usbdev(intf), 720 desc->sbuf = kmalloc(desc->wMaxPacketSize, GFP_KERNEL);
721 desc->wMaxPacketSize,
722 GFP_KERNEL,
723 &desc->validity->transfer_dma);
724 if (!desc->sbuf) 721 if (!desc->sbuf)
725 goto err; 722 goto err;
726 723
727 desc->inbuf = usb_alloc_coherent(interface_to_usbdev(intf), 724 desc->inbuf = kmalloc(desc->wMaxCommand, GFP_KERNEL);
728 desc->wMaxCommand,
729 GFP_KERNEL,
730 &desc->response->transfer_dma);
731 if (!desc->inbuf) 725 if (!desc->inbuf)
732 goto err2; 726 goto err;
733 727
734 usb_fill_int_urb( 728 usb_fill_int_urb(
735 desc->validity, 729 desc->validity,
@@ -741,45 +735,149 @@ next_desc:
741 desc, 735 desc,
742 ep->bInterval 736 ep->bInterval
743 ); 737 );
744 desc->validity->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
745 738
746 usb_set_intfdata(intf, desc); 739 desc->irq->bRequestType = (USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE);
740 desc->irq->bRequest = USB_CDC_GET_ENCAPSULATED_RESPONSE;
741 desc->irq->wValue = 0;
742 desc->irq->wIndex = desc->inum;
743 desc->irq->wLength = cpu_to_le16(desc->wMaxCommand);
744
745 usb_fill_control_urb(
746 desc->response,
747 interface_to_usbdev(intf),
748 /* using common endpoint 0 */
749 usb_rcvctrlpipe(interface_to_usbdev(desc->intf), 0),
750 (unsigned char *)desc->irq,
751 desc->inbuf,
752 desc->wMaxCommand,
753 wdm_in_callback,
754 desc
755 );
756
757 desc->manage_power = manage_power;
758
759 spin_lock(&wdm_device_list_lock);
760 list_add(&desc->device_list, &wdm_device_list);
761 spin_unlock(&wdm_device_list_lock);
762
747 rv = usb_register_dev(intf, &wdm_class); 763 rv = usb_register_dev(intf, &wdm_class);
748 if (rv < 0) 764 if (rv < 0)
749 goto err3; 765 goto err;
750 else 766 else
751 dev_info(&intf->dev, "cdc-wdm%d: USB WDM device\n", 767 dev_info(&intf->dev, "%s: USB WDM device\n", dev_name(intf->usb_dev));
752 intf->minor - WDM_MINOR_BASE);
753out: 768out:
754 return rv; 769 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);
766err: 770err:
767 free_urbs(desc); 771 cleanup(desc);
768 kfree(desc->ubuf); 772 return rv;
769 kfree(desc->orq); 773}
770 kfree(desc->irq); 774
771 kfree(desc); 775static int wdm_manage_power(struct usb_interface *intf, int on)
776{
777 /* need autopm_get/put here to ensure the usbcore sees the new value */
778 int rv = usb_autopm_get_interface(intf);
779 if (rv < 0)
780 goto err;
781
782 intf->needs_remote_wakeup = on;
783 usb_autopm_put_interface(intf);
784err:
785 return rv;
786}
787
788static int wdm_probe(struct usb_interface *intf, const struct usb_device_id *id)
789{
790 int rv = -EINVAL;
791 struct usb_host_interface *iface;
792 struct usb_endpoint_descriptor *ep;
793 struct usb_cdc_dmm_desc *dmhd;
794 u8 *buffer = intf->altsetting->extra;
795 int buflen = intf->altsetting->extralen;
796 u16 maxcom = WDM_DEFAULT_BUFSIZE;
797
798 if (!buffer)
799 goto err;
800 while (buflen > 2) {
801 if (buffer[1] != USB_DT_CS_INTERFACE) {
802 dev_err(&intf->dev, "skipping garbage\n");
803 goto next_desc;
804 }
805
806 switch (buffer[2]) {
807 case USB_CDC_HEADER_TYPE:
808 break;
809 case USB_CDC_DMM_TYPE:
810 dmhd = (struct usb_cdc_dmm_desc *)buffer;
811 maxcom = le16_to_cpu(dmhd->wMaxCommand);
812 dev_dbg(&intf->dev,
813 "Finding maximum buffer length: %d", maxcom);
814 break;
815 default:
816 dev_err(&intf->dev,
817 "Ignoring extra header, type %d, length %d\n",
818 buffer[2], buffer[0]);
819 break;
820 }
821next_desc:
822 buflen -= buffer[0];
823 buffer += buffer[0];
824 }
825
826 iface = intf->cur_altsetting;
827 if (iface->desc.bNumEndpoints != 1)
828 goto err;
829 ep = &iface->endpoint[0].desc;
830
831 rv = wdm_create(intf, ep, maxcom, &wdm_manage_power);
832
833err:
772 return rv; 834 return rv;
773} 835}
774 836
837/**
838 * usb_cdc_wdm_register - register a WDM subdriver
839 * @intf: usb interface the subdriver will associate with
840 * @ep: interrupt endpoint to monitor for notifications
841 * @bufsize: maximum message size to support for read/write
842 *
843 * Create WDM usb class character device and associate it with intf
844 * without binding, allowing another driver to manage the interface.
845 *
846 * The subdriver will manage the given interrupt endpoint exclusively
847 * and will issue control requests referring to the given intf. It
848 * will otherwise avoid interferring, and in particular not do
849 * usb_set_intfdata/usb_get_intfdata on intf.
850 *
851 * The return value is a pointer to the subdriver's struct usb_driver.
852 * The registering driver is responsible for calling this subdriver's
853 * disconnect, suspend, resume, pre_reset and post_reset methods from
854 * its own.
855 */
856struct usb_driver *usb_cdc_wdm_register(struct usb_interface *intf,
857 struct usb_endpoint_descriptor *ep,
858 int bufsize,
859 int (*manage_power)(struct usb_interface *, int))
860{
861 int rv = -EINVAL;
862
863 rv = wdm_create(intf, ep, bufsize, manage_power);
864 if (rv < 0)
865 goto err;
866
867 return &wdm_driver;
868err:
869 return ERR_PTR(rv);
870}
871EXPORT_SYMBOL(usb_cdc_wdm_register);
872
775static void wdm_disconnect(struct usb_interface *intf) 873static void wdm_disconnect(struct usb_interface *intf)
776{ 874{
777 struct wdm_device *desc; 875 struct wdm_device *desc;
778 unsigned long flags; 876 unsigned long flags;
779 877
780 usb_deregister_dev(intf, &wdm_class); 878 usb_deregister_dev(intf, &wdm_class);
879 desc = wdm_find_device(intf);
781 mutex_lock(&wdm_mutex); 880 mutex_lock(&wdm_mutex);
782 desc = usb_get_intfdata(intf);
783 881
784 /* the spinlock makes sure no new urbs are generated in the callbacks */ 882 /* the spinlock makes sure no new urbs are generated in the callbacks */
785 spin_lock_irqsave(&desc->iuspin, flags); 883 spin_lock_irqsave(&desc->iuspin, flags);
@@ -803,7 +901,7 @@ static void wdm_disconnect(struct usb_interface *intf)
803#ifdef CONFIG_PM 901#ifdef CONFIG_PM
804static int wdm_suspend(struct usb_interface *intf, pm_message_t message) 902static int wdm_suspend(struct usb_interface *intf, pm_message_t message)
805{ 903{
806 struct wdm_device *desc = usb_get_intfdata(intf); 904 struct wdm_device *desc = wdm_find_device(intf);
807 int rv = 0; 905 int rv = 0;
808 906
809 dev_dbg(&desc->intf->dev, "wdm%d_suspend\n", intf->minor); 907 dev_dbg(&desc->intf->dev, "wdm%d_suspend\n", intf->minor);
@@ -853,7 +951,7 @@ static int recover_from_urb_loss(struct wdm_device *desc)
853#ifdef CONFIG_PM 951#ifdef CONFIG_PM
854static int wdm_resume(struct usb_interface *intf) 952static int wdm_resume(struct usb_interface *intf)
855{ 953{
856 struct wdm_device *desc = usb_get_intfdata(intf); 954 struct wdm_device *desc = wdm_find_device(intf);
857 int rv; 955 int rv;
858 956
859 dev_dbg(&desc->intf->dev, "wdm%d_resume\n", intf->minor); 957 dev_dbg(&desc->intf->dev, "wdm%d_resume\n", intf->minor);
@@ -867,11 +965,7 @@ static int wdm_resume(struct usb_interface *intf)
867 965
868static int wdm_pre_reset(struct usb_interface *intf) 966static int wdm_pre_reset(struct usb_interface *intf)
869{ 967{
870 struct wdm_device *desc = usb_get_intfdata(intf); 968 struct wdm_device *desc = wdm_find_device(intf);
871
872 mutex_lock(&desc->rlock);
873 mutex_lock(&desc->wlock);
874 kill_urbs(desc);
875 969
876 /* 970 /*
877 * we notify everybody using poll of 971 * we notify everybody using poll of
@@ -880,17 +974,25 @@ static int wdm_pre_reset(struct usb_interface *intf)
880 * message from the device is lost 974 * message from the device is lost
881 */ 975 */
882 spin_lock_irq(&desc->iuspin); 976 spin_lock_irq(&desc->iuspin);
977 set_bit(WDM_RESETTING, &desc->flags); /* inform read/write */
978 set_bit(WDM_READ, &desc->flags); /* unblock read */
979 clear_bit(WDM_IN_USE, &desc->flags); /* unblock write */
883 desc->rerr = -EINTR; 980 desc->rerr = -EINTR;
884 spin_unlock_irq(&desc->iuspin); 981 spin_unlock_irq(&desc->iuspin);
885 wake_up_all(&desc->wait); 982 wake_up_all(&desc->wait);
983 mutex_lock(&desc->rlock);
984 mutex_lock(&desc->wlock);
985 kill_urbs(desc);
986 cancel_work_sync(&desc->rxwork);
886 return 0; 987 return 0;
887} 988}
888 989
889static int wdm_post_reset(struct usb_interface *intf) 990static int wdm_post_reset(struct usb_interface *intf)
890{ 991{
891 struct wdm_device *desc = usb_get_intfdata(intf); 992 struct wdm_device *desc = wdm_find_device(intf);
892 int rv; 993 int rv;
893 994
995 clear_bit(WDM_RESETTING, &desc->flags);
894 rv = recover_from_urb_loss(desc); 996 rv = recover_from_urb_loss(desc);
895 mutex_unlock(&desc->wlock); 997 mutex_unlock(&desc->wlock);
896 mutex_unlock(&desc->rlock); 998 mutex_unlock(&desc->rlock);