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