aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid/usbhid/hiddev.c
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/hid/usbhid/hiddev.c
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'drivers/hid/usbhid/hiddev.c')
-rw-r--r--drivers/hid/usbhid/hiddev.c297
1 files changed, 134 insertions, 163 deletions
diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c
index 681e620eb95b..7c1188b53c3e 100644
--- a/drivers/hid/usbhid/hiddev.c
+++ b/drivers/hid/usbhid/hiddev.c
@@ -29,7 +29,6 @@
29#include <linux/slab.h> 29#include <linux/slab.h>
30#include <linux/module.h> 30#include <linux/module.h>
31#include <linux/init.h> 31#include <linux/init.h>
32#include <linux/smp_lock.h>
33#include <linux/input.h> 32#include <linux/input.h>
34#include <linux/usb.h> 33#include <linux/usb.h>
35#include <linux/hid.h> 34#include <linux/hid.h>
@@ -67,8 +66,6 @@ struct hiddev_list {
67 struct mutex thread_lock; 66 struct mutex thread_lock;
68}; 67};
69 68
70static struct usb_driver hiddev_driver;
71
72/* 69/*
73 * Find a report, given the report's type and ID. The ID can be specified 70 * Find a report, given the report's type and ID. The ID can be specified
74 * indirectly by REPORT_ID_FIRST (which returns the first report of the given 71 * indirectly by REPORT_ID_FIRST (which returns the first report of the given
@@ -245,15 +242,20 @@ static int hiddev_release(struct inode * inode, struct file * file)
245 list_del(&list->node); 242 list_del(&list->node);
246 spin_unlock_irqrestore(&list->hiddev->list_lock, flags); 243 spin_unlock_irqrestore(&list->hiddev->list_lock, flags);
247 244
245 mutex_lock(&list->hiddev->existancelock);
248 if (!--list->hiddev->open) { 246 if (!--list->hiddev->open) {
249 if (list->hiddev->exist) { 247 if (list->hiddev->exist) {
250 usbhid_close(list->hiddev->hid); 248 usbhid_close(list->hiddev->hid);
251 usbhid_put_power(list->hiddev->hid); 249 usbhid_put_power(list->hiddev->hid);
252 } else { 250 } else {
251 mutex_unlock(&list->hiddev->existancelock);
253 kfree(list->hiddev); 252 kfree(list->hiddev);
253 kfree(list);
254 return 0;
254 } 255 }
255 } 256 }
256 257
258 mutex_unlock(&list->hiddev->existancelock);
257 kfree(list); 259 kfree(list);
258 260
259 return 0; 261 return 0;
@@ -303,17 +305,21 @@ static int hiddev_open(struct inode *inode, struct file *file)
303 list_add_tail(&list->node, &hiddev->list); 305 list_add_tail(&list->node, &hiddev->list);
304 spin_unlock_irq(&list->hiddev->list_lock); 306 spin_unlock_irq(&list->hiddev->list_lock);
305 307
308 mutex_lock(&hiddev->existancelock);
306 if (!list->hiddev->open++) 309 if (!list->hiddev->open++)
307 if (list->hiddev->exist) { 310 if (list->hiddev->exist) {
308 struct hid_device *hid = hiddev->hid; 311 struct hid_device *hid = hiddev->hid;
309 res = usbhid_get_power(hid); 312 res = usbhid_get_power(hid);
310 if (res < 0) { 313 if (res < 0) {
311 res = -EIO; 314 res = -EIO;
312 goto bail; 315 goto bail_unlock;
313 } 316 }
314 usbhid_open(hid); 317 usbhid_open(hid);
315 } 318 }
319 mutex_unlock(&hiddev->existancelock);
316 return 0; 320 return 0;
321bail_unlock:
322 mutex_unlock(&hiddev->existancelock);
317bail: 323bail:
318 file->private_data = NULL; 324 file->private_data = NULL;
319 kfree(list); 325 kfree(list);
@@ -370,8 +376,10 @@ static ssize_t hiddev_read(struct file * file, char __user * buffer, size_t coun
370 /* let O_NONBLOCK tasks run */ 376 /* let O_NONBLOCK tasks run */
371 mutex_unlock(&list->thread_lock); 377 mutex_unlock(&list->thread_lock);
372 schedule(); 378 schedule();
373 if (mutex_lock_interruptible(&list->thread_lock)) 379 if (mutex_lock_interruptible(&list->thread_lock)) {
380 finish_wait(&list->hiddev->wait, &wait);
374 return -EINTR; 381 return -EINTR;
382 }
375 set_current_state(TASK_INTERRUPTIBLE); 383 set_current_state(TASK_INTERRUPTIBLE);
376 } 384 }
377 finish_wait(&list->hiddev->wait, &wait); 385 finish_wait(&list->hiddev->wait, &wait);
@@ -512,7 +520,7 @@ static noinline int hiddev_ioctl_usage(struct hiddev *hiddev, unsigned int cmd,
512 (uref_multi->num_values > HID_MAX_MULTI_USAGES || 520 (uref_multi->num_values > HID_MAX_MULTI_USAGES ||
513 uref->usage_index + uref_multi->num_values > field->report_count)) 521 uref->usage_index + uref_multi->num_values > field->report_count))
514 goto inval; 522 goto inval;
515 } 523 }
516 524
517 switch (cmd) { 525 switch (cmd) {
518 case HIDIOCGUSAGE: 526 case HIDIOCGUSAGE:
@@ -588,163 +596,168 @@ static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
588{ 596{
589 struct hiddev_list *list = file->private_data; 597 struct hiddev_list *list = file->private_data;
590 struct hiddev *hiddev = list->hiddev; 598 struct hiddev *hiddev = list->hiddev;
591 struct hid_device *hid = hiddev->hid; 599 struct hid_device *hid;
592 struct usb_device *dev;
593 struct hiddev_collection_info cinfo; 600 struct hiddev_collection_info cinfo;
594 struct hiddev_report_info rinfo; 601 struct hiddev_report_info rinfo;
595 struct hiddev_field_info finfo; 602 struct hiddev_field_info finfo;
596 struct hiddev_devinfo dinfo; 603 struct hiddev_devinfo dinfo;
597 struct hid_report *report; 604 struct hid_report *report;
598 struct hid_field *field; 605 struct hid_field *field;
599 struct usbhid_device *usbhid = hid->driver_data;
600 void __user *user_arg = (void __user *)arg; 606 void __user *user_arg = (void __user *)arg;
601 int i, r; 607 int i, r = -EINVAL;
602 608
603 /* Called without BKL by compat methods so no BKL taken */ 609 /* Called without BKL by compat methods so no BKL taken */
604 610
605 /* FIXME: Who or what stop this racing with a disconnect ?? */ 611 mutex_lock(&hiddev->existancelock);
606 if (!hiddev->exist || !hid) 612 if (!hiddev->exist) {
607 return -EIO; 613 r = -ENODEV;
614 goto ret_unlock;
615 }
608 616
609 dev = hid_to_usb_dev(hid); 617 hid = hiddev->hid;
610 618
611 switch (cmd) { 619 switch (cmd) {
612 620
613 case HIDIOCGVERSION: 621 case HIDIOCGVERSION:
614 return put_user(HID_VERSION, (int __user *)arg); 622 r = put_user(HID_VERSION, (int __user *)arg) ?
623 -EFAULT : 0;
624 break;
615 625
616 case HIDIOCAPPLICATION: 626 case HIDIOCAPPLICATION:
617 if (arg < 0 || arg >= hid->maxapplication) 627 if (arg < 0 || arg >= hid->maxapplication)
618 return -EINVAL; 628 break;
619 629
620 for (i = 0; i < hid->maxcollection; i++) 630 for (i = 0; i < hid->maxcollection; i++)
621 if (hid->collection[i].type == 631 if (hid->collection[i].type ==
622 HID_COLLECTION_APPLICATION && arg-- == 0) 632 HID_COLLECTION_APPLICATION && arg-- == 0)
623 break; 633 break;
624 634
625 if (i == hid->maxcollection) 635 if (i < hid->maxcollection)
626 return -EINVAL; 636 r = hid->collection[i].usage;
627 637 break;
628 return hid->collection[i].usage;
629 638
630 case HIDIOCGDEVINFO: 639 case HIDIOCGDEVINFO:
631 dinfo.bustype = BUS_USB; 640 {
632 dinfo.busnum = dev->bus->busnum; 641 struct usb_device *dev = hid_to_usb_dev(hid);
633 dinfo.devnum = dev->devnum; 642 struct usbhid_device *usbhid = hid->driver_data;
634 dinfo.ifnum = usbhid->ifnum; 643
635 dinfo.vendor = le16_to_cpu(dev->descriptor.idVendor); 644 dinfo.bustype = BUS_USB;
636 dinfo.product = le16_to_cpu(dev->descriptor.idProduct); 645 dinfo.busnum = dev->bus->busnum;
637 dinfo.version = le16_to_cpu(dev->descriptor.bcdDevice); 646 dinfo.devnum = dev->devnum;
638 dinfo.num_applications = hid->maxapplication; 647 dinfo.ifnum = usbhid->ifnum;
639 if (copy_to_user(user_arg, &dinfo, sizeof(dinfo))) 648 dinfo.vendor = le16_to_cpu(dev->descriptor.idVendor);
640 return -EFAULT; 649 dinfo.product = le16_to_cpu(dev->descriptor.idProduct);
641 650 dinfo.version = le16_to_cpu(dev->descriptor.bcdDevice);
642 return 0; 651 dinfo.num_applications = hid->maxapplication;
652
653 r = copy_to_user(user_arg, &dinfo, sizeof(dinfo)) ?
654 -EFAULT : 0;
655 break;
656 }
643 657
644 case HIDIOCGFLAG: 658 case HIDIOCGFLAG:
645 if (put_user(list->flags, (int __user *)arg)) 659 r = put_user(list->flags, (int __user *)arg) ?
646 return -EFAULT; 660 -EFAULT : 0;
647 661 break;
648 return 0;
649 662
650 case HIDIOCSFLAG: 663 case HIDIOCSFLAG:
651 { 664 {
652 int newflags; 665 int newflags;
653 if (get_user(newflags, (int __user *)arg)) 666
654 return -EFAULT; 667 if (get_user(newflags, (int __user *)arg)) {
668 r = -EFAULT;
669 break;
670 }
655 671
656 if ((newflags & ~HIDDEV_FLAGS) != 0 || 672 if ((newflags & ~HIDDEV_FLAGS) != 0 ||
657 ((newflags & HIDDEV_FLAG_REPORT) != 0 && 673 ((newflags & HIDDEV_FLAG_REPORT) != 0 &&
658 (newflags & HIDDEV_FLAG_UREF) == 0)) 674 (newflags & HIDDEV_FLAG_UREF) == 0))
659 return -EINVAL; 675 break;
660 676
661 list->flags = newflags; 677 list->flags = newflags;
662 678
663 return 0; 679 r = 0;
680 break;
664 } 681 }
665 682
666 case HIDIOCGSTRING: 683 case HIDIOCGSTRING:
667 mutex_lock(&hiddev->existancelock); 684 r = hiddev_ioctl_string(hiddev, cmd, user_arg);
668 if (hiddev->exist) 685 break;
669 r = hiddev_ioctl_string(hiddev, cmd, user_arg);
670 else
671 r = -ENODEV;
672 mutex_unlock(&hiddev->existancelock);
673 return r;
674 686
675 case HIDIOCINITREPORT: 687 case HIDIOCINITREPORT:
676 mutex_lock(&hiddev->existancelock);
677 if (!hiddev->exist) {
678 mutex_unlock(&hiddev->existancelock);
679 return -ENODEV;
680 }
681 usbhid_init_reports(hid); 688 usbhid_init_reports(hid);
682 mutex_unlock(&hiddev->existancelock); 689 r = 0;
683 690 break;
684 return 0;
685 691
686 case HIDIOCGREPORT: 692 case HIDIOCGREPORT:
687 if (copy_from_user(&rinfo, user_arg, sizeof(rinfo))) 693 if (copy_from_user(&rinfo, user_arg, sizeof(rinfo))) {
688 return -EFAULT; 694 r = -EFAULT;
695 break;
696 }
689 697
690 if (rinfo.report_type == HID_REPORT_TYPE_OUTPUT) 698 if (rinfo.report_type == HID_REPORT_TYPE_OUTPUT)
691 return -EINVAL; 699 break;
692 700
693 if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL) 701 report = hiddev_lookup_report(hid, &rinfo);
694 return -EINVAL; 702 if (report == NULL)
703 break;
695 704
696 mutex_lock(&hiddev->existancelock); 705 usbhid_submit_report(hid, report, USB_DIR_IN);
697 if (hiddev->exist) { 706 usbhid_wait_io(hid);
698 usbhid_submit_report(hid, report, USB_DIR_IN);
699 usbhid_wait_io(hid);
700 }
701 mutex_unlock(&hiddev->existancelock);
702 707
703 return 0; 708 r = 0;
709 break;
704 710
705 case HIDIOCSREPORT: 711 case HIDIOCSREPORT:
706 if (copy_from_user(&rinfo, user_arg, sizeof(rinfo))) 712 if (copy_from_user(&rinfo, user_arg, sizeof(rinfo))) {
707 return -EFAULT; 713 r = -EFAULT;
714 break;
715 }
708 716
709 if (rinfo.report_type == HID_REPORT_TYPE_INPUT) 717 if (rinfo.report_type == HID_REPORT_TYPE_INPUT)
710 return -EINVAL; 718 break;
711 719
712 if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL) 720 report = hiddev_lookup_report(hid, &rinfo);
713 return -EINVAL; 721 if (report == NULL)
722 break;
714 723
715 mutex_lock(&hiddev->existancelock); 724 usbhid_submit_report(hid, report, USB_DIR_OUT);
716 if (hiddev->exist) { 725 usbhid_wait_io(hid);
717 usbhid_submit_report(hid, report, USB_DIR_OUT);
718 usbhid_wait_io(hid);
719 }
720 mutex_unlock(&hiddev->existancelock);
721 726
722 return 0; 727 r = 0;
728 break;
723 729
724 case HIDIOCGREPORTINFO: 730 case HIDIOCGREPORTINFO:
725 if (copy_from_user(&rinfo, user_arg, sizeof(rinfo))) 731 if (copy_from_user(&rinfo, user_arg, sizeof(rinfo))) {
726 return -EFAULT; 732 r = -EFAULT;
733 break;
734 }
727 735
728 if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL) 736 report = hiddev_lookup_report(hid, &rinfo);
729 return -EINVAL; 737 if (report == NULL)
738 break;
730 739
731 rinfo.num_fields = report->maxfield; 740 rinfo.num_fields = report->maxfield;
732 741
733 if (copy_to_user(user_arg, &rinfo, sizeof(rinfo))) 742 r = copy_to_user(user_arg, &rinfo, sizeof(rinfo)) ?
734 return -EFAULT; 743 -EFAULT : 0;
735 744 break;
736 return 0;
737 745
738 case HIDIOCGFIELDINFO: 746 case HIDIOCGFIELDINFO:
739 if (copy_from_user(&finfo, user_arg, sizeof(finfo))) 747 if (copy_from_user(&finfo, user_arg, sizeof(finfo))) {
740 return -EFAULT; 748 r = -EFAULT;
749 break;
750 }
751
741 rinfo.report_type = finfo.report_type; 752 rinfo.report_type = finfo.report_type;
742 rinfo.report_id = finfo.report_id; 753 rinfo.report_id = finfo.report_id;
743 if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL) 754
744 return -EINVAL; 755 report = hiddev_lookup_report(hid, &rinfo);
756 if (report == NULL)
757 break;
745 758
746 if (finfo.field_index >= report->maxfield) 759 if (finfo.field_index >= report->maxfield)
747 return -EINVAL; 760 break;
748 761
749 field = report->field[finfo.field_index]; 762 field = report->field[finfo.field_index];
750 memset(&finfo, 0, sizeof(finfo)); 763 memset(&finfo, 0, sizeof(finfo));
@@ -763,10 +776,9 @@ static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
763 finfo.unit_exponent = field->unit_exponent; 776 finfo.unit_exponent = field->unit_exponent;
764 finfo.unit = field->unit; 777 finfo.unit = field->unit;
765 778
766 if (copy_to_user(user_arg, &finfo, sizeof(finfo))) 779 r = copy_to_user(user_arg, &finfo, sizeof(finfo)) ?
767 return -EFAULT; 780 -EFAULT : 0;
768 781 break;
769 return 0;
770 782
771 case HIDIOCGUCODE: 783 case HIDIOCGUCODE:
772 /* fall through */ 784 /* fall through */
@@ -775,57 +787,52 @@ static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
775 case HIDIOCGUSAGES: 787 case HIDIOCGUSAGES:
776 case HIDIOCSUSAGES: 788 case HIDIOCSUSAGES:
777 case HIDIOCGCOLLECTIONINDEX: 789 case HIDIOCGCOLLECTIONINDEX:
778 mutex_lock(&hiddev->existancelock); 790 r = hiddev_ioctl_usage(hiddev, cmd, user_arg);
779 if (hiddev->exist) 791 break;
780 r = hiddev_ioctl_usage(hiddev, cmd, user_arg);
781 else
782 r = -ENODEV;
783 mutex_unlock(&hiddev->existancelock);
784 return r;
785 792
786 case HIDIOCGCOLLECTIONINFO: 793 case HIDIOCGCOLLECTIONINFO:
787 if (copy_from_user(&cinfo, user_arg, sizeof(cinfo))) 794 if (copy_from_user(&cinfo, user_arg, sizeof(cinfo))) {
788 return -EFAULT; 795 r = -EFAULT;
796 break;
797 }
789 798
790 if (cinfo.index >= hid->maxcollection) 799 if (cinfo.index >= hid->maxcollection)
791 return -EINVAL; 800 break;
792 801
793 cinfo.type = hid->collection[cinfo.index].type; 802 cinfo.type = hid->collection[cinfo.index].type;
794 cinfo.usage = hid->collection[cinfo.index].usage; 803 cinfo.usage = hid->collection[cinfo.index].usage;
795 cinfo.level = hid->collection[cinfo.index].level; 804 cinfo.level = hid->collection[cinfo.index].level;
796 805
797 if (copy_to_user(user_arg, &cinfo, sizeof(cinfo))) 806 r = copy_to_user(user_arg, &cinfo, sizeof(cinfo)) ?
798 return -EFAULT; 807 -EFAULT : 0;
799 return 0; 808 break;
800 809
801 default: 810 default:
802
803 if (_IOC_TYPE(cmd) != 'H' || _IOC_DIR(cmd) != _IOC_READ) 811 if (_IOC_TYPE(cmd) != 'H' || _IOC_DIR(cmd) != _IOC_READ)
804 return -EINVAL; 812 break;
805 813
806 if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGNAME(0))) { 814 if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGNAME(0))) {
807 int len; 815 int len = strlen(hid->name) + 1;
808 if (!hid->name)
809 return 0;
810 len = strlen(hid->name) + 1;
811 if (len > _IOC_SIZE(cmd)) 816 if (len > _IOC_SIZE(cmd))
812 len = _IOC_SIZE(cmd); 817 len = _IOC_SIZE(cmd);
813 return copy_to_user(user_arg, hid->name, len) ? 818 r = copy_to_user(user_arg, hid->name, len) ?
814 -EFAULT : len; 819 -EFAULT : len;
820 break;
815 } 821 }
816 822
817 if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGPHYS(0))) { 823 if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGPHYS(0))) {
818 int len; 824 int len = strlen(hid->phys) + 1;
819 if (!hid->phys)
820 return 0;
821 len = strlen(hid->phys) + 1;
822 if (len > _IOC_SIZE(cmd)) 825 if (len > _IOC_SIZE(cmd))
823 len = _IOC_SIZE(cmd); 826 len = _IOC_SIZE(cmd);
824 return copy_to_user(user_arg, hid->phys, len) ? 827 r = copy_to_user(user_arg, hid->phys, len) ?
825 -EFAULT : len; 828 -EFAULT : len;
829 break;
826 } 830 }
827 } 831 }
828 return -EINVAL; 832
833ret_unlock:
834 mutex_unlock(&hiddev->existancelock);
835 return r;
829} 836}
830 837
831#ifdef CONFIG_COMPAT 838#ifdef CONFIG_COMPAT
@@ -847,6 +854,7 @@ static const struct file_operations hiddev_fops = {
847#ifdef CONFIG_COMPAT 854#ifdef CONFIG_COMPAT
848 .compat_ioctl = hiddev_compat_ioctl, 855 .compat_ioctl = hiddev_compat_ioctl,
849#endif 856#endif
857 .llseek = noop_llseek,
850}; 858};
851 859
852static char *hiddev_devnode(struct device *dev, mode_t *mode) 860static char *hiddev_devnode(struct device *dev, mode_t *mode)
@@ -894,7 +902,7 @@ int hiddev_connect(struct hid_device *hid, unsigned int force)
894 hiddev->exist = 1; 902 hiddev->exist = 1;
895 retval = usb_register_dev(usbhid->intf, &hiddev_class); 903 retval = usb_register_dev(usbhid->intf, &hiddev_class);
896 if (retval) { 904 if (retval) {
897 err_hid("Not able to get a minor for this device."); 905 hid_err(hid, "Not able to get a minor for this device\n");
898 hid->hiddev = NULL; 906 hid->hiddev = NULL;
899 kfree(hiddev); 907 kfree(hiddev);
900 return -1; 908 return -1;
@@ -914,52 +922,15 @@ void hiddev_disconnect(struct hid_device *hid)
914 922
915 mutex_lock(&hiddev->existancelock); 923 mutex_lock(&hiddev->existancelock);
916 hiddev->exist = 0; 924 hiddev->exist = 0;
917 mutex_unlock(&hiddev->existancelock);
918 925
919 usb_deregister_dev(usbhid->intf, &hiddev_class); 926 usb_deregister_dev(usbhid->intf, &hiddev_class);
920 927
921 if (hiddev->open) { 928 if (hiddev->open) {
929 mutex_unlock(&hiddev->existancelock);
922 usbhid_close(hiddev->hid); 930 usbhid_close(hiddev->hid);
923 wake_up_interruptible(&hiddev->wait); 931 wake_up_interruptible(&hiddev->wait);
924 } else { 932 } else {
933 mutex_unlock(&hiddev->existancelock);
925 kfree(hiddev); 934 kfree(hiddev);
926 } 935 }
927} 936}
928
929/* Currently this driver is a USB driver. It's not a conventional one in
930 * the sense that it doesn't probe at the USB level. Instead it waits to
931 * be connected by HID through the hiddev_connect / hiddev_disconnect
932 * routines. The reason to register as a USB device is to gain part of the
933 * minor number space from the USB major.
934 *
935 * In theory, should the HID code be generalized to more than one physical
936 * medium (say, IEEE 1384), this driver will probably need to register its
937 * own major number, and in doing so, no longer need to register with USB.
938 * At that point the probe routine and hiddev_driver struct below will no
939 * longer be useful.
940 */
941
942
943/* We never attach in this manner, and rely on HID to connect us. This
944 * is why there is no disconnect routine defined in the usb_driver either.
945 */
946static int hiddev_usbd_probe(struct usb_interface *intf,
947 const struct usb_device_id *hiddev_info)
948{
949 return -ENODEV;
950}
951
952static /* const */ struct usb_driver hiddev_driver = {
953 .name = "hiddev",
954 .probe = hiddev_usbd_probe,
955};
956
957int __init hiddev_init(void)
958{
959 return usb_register(&hiddev_driver);
960}
961
962void hiddev_exit(void)
963{
964 usb_deregister(&hiddev_driver);
965}