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