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