diff options
author | Jiri Slaby <jirislaby@gmail.com> | 2008-05-16 05:49:16 -0400 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2008-10-14 17:50:48 -0400 |
commit | c500c9714011edab021591340042787722db9cf0 (patch) | |
tree | d6bb0fe483c9f1c71c3d757e9c13d261ca01cd5f /drivers | |
parent | 85cdaf524b7ddab627e7d15405693f2511ef7505 (diff) |
HID: hid, make parsing event driven
Next step for complete hid bus, this patch includes:
- call parser either from probe or from hid-core if there is no probe.
- add ll_driver structure and centralize some stuff there (open, close...)
- split and merge usb_hid_configure and hid_probe into several functions
to allow hooks/fixes between them
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/hid/hid-core.c | 24 | ||||
-rw-r--r-- | drivers/hid/hid-input.c | 20 | ||||
-rw-r--r-- | drivers/hid/hidraw.c | 6 | ||||
-rw-r--r-- | drivers/hid/usbhid/hid-core.c | 330 |
4 files changed, 228 insertions, 152 deletions
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 017fc20167d4..3dacbcd7e41c 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
@@ -648,6 +648,9 @@ int hid_parse_report(struct hid_device *device, __u8 *start, | |||
648 | hid_parser_reserved | 648 | hid_parser_reserved |
649 | }; | 649 | }; |
650 | 650 | ||
651 | if (device->driver->report_fixup) | ||
652 | device->driver->report_fixup(device, start, size); | ||
653 | |||
651 | device->rdesc = kmalloc(size, GFP_KERNEL); | 654 | device->rdesc = kmalloc(size, GFP_KERNEL); |
652 | if (device->rdesc == NULL) | 655 | if (device->rdesc == NULL) |
653 | return -ENOMEM; | 656 | return -ENOMEM; |
@@ -1152,15 +1155,20 @@ static int hid_device_probe(struct device *dev) | |||
1152 | int ret = 0; | 1155 | int ret = 0; |
1153 | 1156 | ||
1154 | if (!hdev->driver) { | 1157 | if (!hdev->driver) { |
1155 | if (hdrv->probe) { | 1158 | id = hid_match_id(hdev, hdrv->id_table); |
1156 | ret = -ENODEV; | 1159 | if (id == NULL) |
1160 | return -ENODEV; | ||
1157 | 1161 | ||
1158 | id = hid_match_id(hdev, hdrv->id_table); | 1162 | hdev->driver = hdrv; |
1159 | if (id) | 1163 | if (hdrv->probe) { |
1160 | ret = hdrv->probe(hdev, id); | 1164 | ret = hdrv->probe(hdev, id); |
1165 | } else { /* default probe */ | ||
1166 | ret = hid_parse(hdev); | ||
1167 | if (!ret) | ||
1168 | ret = hid_hw_start(hdev); | ||
1161 | } | 1169 | } |
1162 | if (!ret) | 1170 | if (ret) |
1163 | hdev->driver = hdrv; | 1171 | hdev->driver = NULL; |
1164 | } | 1172 | } |
1165 | return ret; | 1173 | return ret; |
1166 | } | 1174 | } |
@@ -1173,6 +1181,8 @@ static int hid_device_remove(struct device *dev) | |||
1173 | if (hdrv) { | 1181 | if (hdrv) { |
1174 | if (hdrv->remove) | 1182 | if (hdrv->remove) |
1175 | hdrv->remove(hdev); | 1183 | hdrv->remove(hdev); |
1184 | else /* default remove */ | ||
1185 | hid_hw_stop(hdev); | ||
1176 | hdev->driver = NULL; | 1186 | hdev->driver = NULL; |
1177 | } | 1187 | } |
1178 | 1188 | ||
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 4ae5603804e7..9fa7239ab310 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c | |||
@@ -390,6 +390,15 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
390 | if (ret) | 390 | if (ret) |
391 | goto mapped; | 391 | goto mapped; |
392 | 392 | ||
393 | if (device->driver->input_mapping) { | ||
394 | int ret = device->driver->input_mapping(device, hidinput, field, | ||
395 | usage, &bit, &max); | ||
396 | if (ret > 0) | ||
397 | goto mapped; | ||
398 | if (ret < 0) | ||
399 | goto ignore; | ||
400 | } | ||
401 | |||
393 | switch (usage->hid & HID_USAGE_PAGE) { | 402 | switch (usage->hid & HID_USAGE_PAGE) { |
394 | 403 | ||
395 | case HID_UP_UNDEFINED: | 404 | case HID_UP_UNDEFINED: |
@@ -755,6 +764,10 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
755 | } | 764 | } |
756 | 765 | ||
757 | mapped: | 766 | mapped: |
767 | if (device->driver->input_mapped && device->driver->input_mapped(device, | ||
768 | hidinput, field, usage, &bit, &max) < 0) | ||
769 | goto ignore; | ||
770 | |||
758 | if (device->quirks & HID_QUIRK_MIGHTYMOUSE) { | 771 | if (device->quirks & HID_QUIRK_MIGHTYMOUSE) { |
759 | if (usage->hid == HID_GD_Z) | 772 | if (usage->hid == HID_GD_Z) |
760 | map_rel(REL_HWHEEL); | 773 | map_rel(REL_HWHEEL); |
@@ -961,14 +974,14 @@ static int hidinput_open(struct input_dev *dev) | |||
961 | { | 974 | { |
962 | struct hid_device *hid = input_get_drvdata(dev); | 975 | struct hid_device *hid = input_get_drvdata(dev); |
963 | 976 | ||
964 | return hid->hid_open(hid); | 977 | return hid->ll_driver->open(hid); |
965 | } | 978 | } |
966 | 979 | ||
967 | static void hidinput_close(struct input_dev *dev) | 980 | static void hidinput_close(struct input_dev *dev) |
968 | { | 981 | { |
969 | struct hid_device *hid = input_get_drvdata(dev); | 982 | struct hid_device *hid = input_get_drvdata(dev); |
970 | 983 | ||
971 | hid->hid_close(hid); | 984 | hid->ll_driver->close(hid); |
972 | } | 985 | } |
973 | 986 | ||
974 | /* | 987 | /* |
@@ -1019,7 +1032,8 @@ int hidinput_connect(struct hid_device *hid) | |||
1019 | } | 1032 | } |
1020 | 1033 | ||
1021 | input_set_drvdata(input_dev, hid); | 1034 | input_set_drvdata(input_dev, hid); |
1022 | input_dev->event = hid->hidinput_input_event; | 1035 | input_dev->event = |
1036 | hid->ll_driver->hidinput_input_event; | ||
1023 | input_dev->open = hidinput_open; | 1037 | input_dev->open = hidinput_open; |
1024 | input_dev->close = hidinput_close; | 1038 | input_dev->close = hidinput_close; |
1025 | input_dev->setkeycode = hidinput_setkeycode; | 1039 | input_dev->setkeycode = hidinput_setkeycode; |
diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c index c40f0403edaf..4be240e74d4f 100644 --- a/drivers/hid/hidraw.c +++ b/drivers/hid/hidraw.c | |||
@@ -181,7 +181,7 @@ static int hidraw_open(struct inode *inode, struct file *file) | |||
181 | 181 | ||
182 | dev = hidraw_table[minor]; | 182 | dev = hidraw_table[minor]; |
183 | if (!dev->open++) | 183 | if (!dev->open++) |
184 | dev->hid->hid_open(dev->hid); | 184 | dev->hid->ll_driver->open(dev->hid); |
185 | 185 | ||
186 | out_unlock: | 186 | out_unlock: |
187 | spin_unlock(&minors_lock); | 187 | spin_unlock(&minors_lock); |
@@ -207,7 +207,7 @@ static int hidraw_release(struct inode * inode, struct file * file) | |||
207 | dev = hidraw_table[minor]; | 207 | dev = hidraw_table[minor]; |
208 | if (!dev->open--) { | 208 | if (!dev->open--) { |
209 | if (list->hidraw->exist) | 209 | if (list->hidraw->exist) |
210 | dev->hid->hid_close(dev->hid); | 210 | dev->hid->ll_driver->close(dev->hid); |
211 | else | 211 | else |
212 | kfree(list->hidraw); | 212 | kfree(list->hidraw); |
213 | } | 213 | } |
@@ -367,7 +367,7 @@ void hidraw_disconnect(struct hid_device *hid) | |||
367 | device_destroy(hidraw_class, MKDEV(hidraw_major, hidraw->minor)); | 367 | device_destroy(hidraw_class, MKDEV(hidraw_major, hidraw->minor)); |
368 | 368 | ||
369 | if (hidraw->open) { | 369 | if (hidraw->open) { |
370 | hid->hid_close(hid); | 370 | hid->ll_driver->close(hid); |
371 | wake_up_interruptible(&hidraw->wait); | 371 | wake_up_interruptible(&hidraw->wait); |
372 | } else { | 372 | } else { |
373 | kfree(hidraw); | 373 | kfree(hidraw); |
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index 5955d05ae542..d2a3461909a3 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c | |||
@@ -701,17 +701,84 @@ static void hid_fixup_sony_ps3_controller(struct usb_device *dev, int ifnum) | |||
701 | kfree(buf); | 701 | kfree(buf); |
702 | } | 702 | } |
703 | 703 | ||
704 | static struct hid_device *usb_hid_configure(struct usb_interface *intf) | 704 | static int usbhid_start_finish(struct hid_device *hid) |
705 | { | 705 | { |
706 | struct usb_interface *intf = to_usb_interface(hid->dev.parent); | ||
707 | char path[64], *type; | ||
708 | unsigned int i; | ||
709 | |||
710 | usbhid_init_reports(hid); | ||
711 | hid_dump_device(hid); | ||
712 | if (hid->quirks & HID_QUIRK_RESET_LEDS) | ||
713 | usbhid_set_leds(hid); | ||
714 | |||
715 | if (!hidinput_connect(hid)) | ||
716 | hid->claimed |= HID_CLAIMED_INPUT; | ||
717 | if (!hiddev_connect(hid)) | ||
718 | hid->claimed |= HID_CLAIMED_HIDDEV; | ||
719 | if (!hidraw_connect(hid)) | ||
720 | hid->claimed |= HID_CLAIMED_HIDRAW; | ||
721 | |||
722 | if (!hid->claimed) { | ||
723 | printk(KERN_ERR "HID device claimed by neither input, hiddev " | ||
724 | "nor hidraw\n"); | ||
725 | return -ENODEV; | ||
726 | } | ||
727 | |||
728 | if ((hid->claimed & HID_CLAIMED_INPUT)) | ||
729 | hid_ff_init(hid); | ||
730 | |||
731 | if (hid->quirks & HID_QUIRK_SONY_PS3_CONTROLLER) | ||
732 | hid_fixup_sony_ps3_controller(interface_to_usbdev(intf), | ||
733 | intf->cur_altsetting->desc.bInterfaceNumber); | ||
734 | |||
735 | printk(KERN_INFO); | ||
736 | |||
737 | if (hid->claimed & HID_CLAIMED_INPUT) | ||
738 | printk("input"); | ||
739 | if ((hid->claimed & HID_CLAIMED_INPUT) && | ||
740 | ((hid->claimed & HID_CLAIMED_HIDDEV) || | ||
741 | hid->claimed & HID_CLAIMED_HIDRAW)) | ||
742 | printk(","); | ||
743 | if (hid->claimed & HID_CLAIMED_HIDDEV) | ||
744 | printk("hiddev%d", hid->minor); | ||
745 | if ((hid->claimed & HID_CLAIMED_INPUT) && | ||
746 | (hid->claimed & HID_CLAIMED_HIDDEV) && | ||
747 | (hid->claimed & HID_CLAIMED_HIDRAW)) | ||
748 | printk(","); | ||
749 | if (hid->claimed & HID_CLAIMED_HIDRAW) | ||
750 | printk("hidraw%d", ((struct hidraw *)hid->hidraw)->minor); | ||
751 | |||
752 | type = "Device"; | ||
753 | for (i = 0; i < hid->maxcollection; i++) { | ||
754 | if (hid->collection[i].type == HID_COLLECTION_APPLICATION && | ||
755 | (hid->collection[i].usage & HID_USAGE_PAGE) == | ||
756 | HID_UP_GENDESK && | ||
757 | (hid->collection[i].usage & 0xffff) < | ||
758 | ARRAY_SIZE(hid_types)) { | ||
759 | type = hid_types[hid->collection[i].usage & 0xffff]; | ||
760 | break; | ||
761 | } | ||
762 | } | ||
763 | |||
764 | usb_make_path(interface_to_usbdev(intf), path, 63); | ||
765 | |||
766 | printk(": USB HID v%x.%02x %s [%s] on %s\n", | ||
767 | hid->version >> 8, hid->version & 0xff, type, hid->name, path); | ||
768 | |||
769 | return 0; | ||
770 | } | ||
771 | |||
772 | static int usbhid_parse(struct hid_device *hid) | ||
773 | { | ||
774 | struct usb_interface *intf = to_usb_interface(hid->dev.parent); | ||
706 | struct usb_host_interface *interface = intf->cur_altsetting; | 775 | struct usb_host_interface *interface = intf->cur_altsetting; |
707 | struct usb_device *dev = interface_to_usbdev (intf); | 776 | struct usb_device *dev = interface_to_usbdev (intf); |
708 | struct hid_descriptor *hdesc; | 777 | struct hid_descriptor *hdesc; |
709 | struct hid_device *hid; | ||
710 | u32 quirks = 0; | 778 | u32 quirks = 0; |
711 | unsigned int insize = 0, rsize = 0; | 779 | unsigned int rsize = 0; |
712 | char *rdesc; | 780 | char *rdesc; |
713 | int n, len; | 781 | int ret, n; |
714 | struct usbhid_device *usbhid; | ||
715 | 782 | ||
716 | quirks = usbhid_lookup_quirk(le16_to_cpu(dev->descriptor.idVendor), | 783 | quirks = usbhid_lookup_quirk(le16_to_cpu(dev->descriptor.idVendor), |
717 | le16_to_cpu(dev->descriptor.idProduct)); | 784 | le16_to_cpu(dev->descriptor.idProduct)); |
@@ -725,40 +792,44 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) | |||
725 | } | 792 | } |
726 | 793 | ||
727 | if (quirks & HID_QUIRK_IGNORE) | 794 | if (quirks & HID_QUIRK_IGNORE) |
728 | return NULL; | 795 | return -ENODEV; |
729 | 796 | ||
730 | if ((quirks & HID_QUIRK_IGNORE_MOUSE) && | 797 | if ((quirks & HID_QUIRK_IGNORE_MOUSE) && |
731 | (interface->desc.bInterfaceProtocol == USB_INTERFACE_PROTOCOL_MOUSE)) | 798 | (interface->desc.bInterfaceProtocol == USB_INTERFACE_PROTOCOL_MOUSE)) |
732 | return NULL; | 799 | return -ENODEV; |
733 | |||
734 | 800 | ||
735 | if (usb_get_extra_descriptor(interface, HID_DT_HID, &hdesc) && | 801 | if (usb_get_extra_descriptor(interface, HID_DT_HID, &hdesc) && |
736 | (!interface->desc.bNumEndpoints || | 802 | (!interface->desc.bNumEndpoints || |
737 | usb_get_extra_descriptor(&interface->endpoint[0], HID_DT_HID, &hdesc))) { | 803 | usb_get_extra_descriptor(&interface->endpoint[0], HID_DT_HID, &hdesc))) { |
738 | dbg_hid("class descriptor not present\n"); | 804 | dbg_hid("class descriptor not present\n"); |
739 | return NULL; | 805 | return -ENODEV; |
740 | } | 806 | } |
741 | 807 | ||
808 | hid->version = le16_to_cpu(hdesc->bcdHID); | ||
809 | hid->country = hdesc->bCountryCode; | ||
810 | |||
742 | for (n = 0; n < hdesc->bNumDescriptors; n++) | 811 | for (n = 0; n < hdesc->bNumDescriptors; n++) |
743 | if (hdesc->desc[n].bDescriptorType == HID_DT_REPORT) | 812 | if (hdesc->desc[n].bDescriptorType == HID_DT_REPORT) |
744 | rsize = le16_to_cpu(hdesc->desc[n].wDescriptorLength); | 813 | rsize = le16_to_cpu(hdesc->desc[n].wDescriptorLength); |
745 | 814 | ||
746 | if (!rsize || rsize > HID_MAX_DESCRIPTOR_SIZE) { | 815 | if (!rsize || rsize > HID_MAX_DESCRIPTOR_SIZE) { |
747 | dbg_hid("weird size of report descriptor (%u)\n", rsize); | 816 | dbg_hid("weird size of report descriptor (%u)\n", rsize); |
748 | return NULL; | 817 | return -EINVAL; |
749 | } | 818 | } |
750 | 819 | ||
751 | if (!(rdesc = kmalloc(rsize, GFP_KERNEL))) { | 820 | if (!(rdesc = kmalloc(rsize, GFP_KERNEL))) { |
752 | dbg_hid("couldn't allocate rdesc memory\n"); | 821 | dbg_hid("couldn't allocate rdesc memory\n"); |
753 | return NULL; | 822 | return -ENOMEM; |
754 | } | 823 | } |
755 | 824 | ||
756 | hid_set_idle(dev, interface->desc.bInterfaceNumber, 0, 0); | 825 | hid_set_idle(dev, interface->desc.bInterfaceNumber, 0, 0); |
757 | 826 | ||
758 | if ((n = hid_get_class_descriptor(dev, interface->desc.bInterfaceNumber, HID_DT_REPORT, rdesc, rsize)) < 0) { | 827 | ret = hid_get_class_descriptor(dev, interface->desc.bInterfaceNumber, |
828 | HID_DT_REPORT, rdesc, rsize); | ||
829 | if (ret < 0) { | ||
759 | dbg_hid("reading report descriptor failed\n"); | 830 | dbg_hid("reading report descriptor failed\n"); |
760 | kfree(rdesc); | 831 | kfree(rdesc); |
761 | return NULL; | 832 | goto err; |
762 | } | 833 | } |
763 | 834 | ||
764 | usbhid_fixup_report_descriptor(le16_to_cpu(dev->descriptor.idVendor), | 835 | usbhid_fixup_report_descriptor(le16_to_cpu(dev->descriptor.idVendor), |
@@ -770,24 +841,36 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) | |||
770 | dbg_hid_line(" %02x", (unsigned char) rdesc[n]); | 841 | dbg_hid_line(" %02x", (unsigned char) rdesc[n]); |
771 | dbg_hid_line("\n"); | 842 | dbg_hid_line("\n"); |
772 | 843 | ||
773 | hid = hid_allocate_device(); | 844 | ret = hid_parse_report(hid, rdesc, rsize); |
774 | if (IS_ERR(hid)) { | 845 | kfree(rdesc); |
775 | kfree(rdesc); | 846 | if (ret) { |
776 | return NULL; | ||
777 | } | ||
778 | |||
779 | if (hid_parse_report(hid, rdesc, n)) { | ||
780 | dbg_hid("parsing report descriptor failed\n"); | 847 | dbg_hid("parsing report descriptor failed\n"); |
781 | hid_destroy_device(hid); | 848 | goto err; |
782 | kfree(rdesc); | ||
783 | return NULL; | ||
784 | } | 849 | } |
785 | 850 | ||
786 | kfree(rdesc); | ||
787 | hid->quirks = quirks; | 851 | hid->quirks = quirks; |
788 | 852 | ||
789 | if (!(usbhid = kzalloc(sizeof(struct usbhid_device), GFP_KERNEL))) | 853 | return 0; |
790 | goto fail_no_usbhid; | 854 | err: |
855 | return ret; | ||
856 | } | ||
857 | |||
858 | static int usbhid_start(struct hid_device *hid) | ||
859 | { | ||
860 | struct usb_interface *intf = to_usb_interface(hid->dev.parent); | ||
861 | struct usb_host_interface *interface = intf->cur_altsetting; | ||
862 | struct usb_device *dev = interface_to_usbdev(intf); | ||
863 | struct usbhid_device *usbhid; | ||
864 | unsigned int n, insize = 0; | ||
865 | int ret; | ||
866 | |||
867 | WARN_ON(hid->driver_data); | ||
868 | |||
869 | usbhid = kzalloc(sizeof(struct usbhid_device), GFP_KERNEL); | ||
870 | if (usbhid == NULL) { | ||
871 | ret = -ENOMEM; | ||
872 | goto err; | ||
873 | } | ||
791 | 874 | ||
792 | hid->driver_data = usbhid; | 875 | hid->driver_data = usbhid; |
793 | usbhid->hid = hid; | 876 | usbhid->hid = hid; |
@@ -805,27 +888,12 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) | |||
805 | if (insize > HID_MAX_BUFFER_SIZE) | 888 | if (insize > HID_MAX_BUFFER_SIZE) |
806 | insize = HID_MAX_BUFFER_SIZE; | 889 | insize = HID_MAX_BUFFER_SIZE; |
807 | 890 | ||
808 | if (hid_alloc_buffers(dev, hid)) | 891 | if (hid_alloc_buffers(dev, hid)) { |
892 | ret = -ENOMEM; | ||
809 | goto fail; | 893 | goto fail; |
810 | |||
811 | hid->name[0] = 0; | ||
812 | |||
813 | if (dev->manufacturer) | ||
814 | strlcpy(hid->name, dev->manufacturer, sizeof(hid->name)); | ||
815 | |||
816 | if (dev->product) { | ||
817 | if (dev->manufacturer) | ||
818 | strlcat(hid->name, " ", sizeof(hid->name)); | ||
819 | strlcat(hid->name, dev->product, sizeof(hid->name)); | ||
820 | } | 894 | } |
821 | 895 | ||
822 | if (!strlen(hid->name)) | ||
823 | snprintf(hid->name, sizeof(hid->name), "HID %04x:%04x", | ||
824 | le16_to_cpu(dev->descriptor.idVendor), | ||
825 | le16_to_cpu(dev->descriptor.idProduct)); | ||
826 | |||
827 | for (n = 0; n < interface->desc.bNumEndpoints; n++) { | 896 | for (n = 0; n < interface->desc.bNumEndpoints; n++) { |
828 | |||
829 | struct usb_endpoint_descriptor *endpoint; | 897 | struct usb_endpoint_descriptor *endpoint; |
830 | int pipe; | 898 | int pipe; |
831 | int interval; | 899 | int interval; |
@@ -837,7 +905,7 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) | |||
837 | interval = endpoint->bInterval; | 905 | interval = endpoint->bInterval; |
838 | 906 | ||
839 | /* Some vendors give fullspeed interval on highspeed devides */ | 907 | /* Some vendors give fullspeed interval on highspeed devides */ |
840 | if (quirks & HID_QUIRK_FULLSPEED_INTERVAL && | 908 | if (hid->quirks & HID_QUIRK_FULLSPEED_INTERVAL && |
841 | dev->speed == USB_SPEED_HIGH) { | 909 | dev->speed == USB_SPEED_HIGH) { |
842 | interval = fls(endpoint->bInterval*8); | 910 | interval = fls(endpoint->bInterval*8); |
843 | printk(KERN_INFO "%s: Fixing fullspeed to highspeed interval: %d -> %d\n", | 911 | printk(KERN_INFO "%s: Fixing fullspeed to highspeed interval: %d -> %d\n", |
@@ -848,6 +916,7 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) | |||
848 | if (hid->collection->usage == HID_GD_MOUSE && hid_mousepoll_interval > 0) | 916 | if (hid->collection->usage == HID_GD_MOUSE && hid_mousepoll_interval > 0) |
849 | interval = hid_mousepoll_interval; | 917 | interval = hid_mousepoll_interval; |
850 | 918 | ||
919 | ret = -ENOMEM; | ||
851 | if (usb_endpoint_dir_in(endpoint)) { | 920 | if (usb_endpoint_dir_in(endpoint)) { |
852 | if (usbhid->urbin) | 921 | if (usbhid->urbin) |
853 | continue; | 922 | continue; |
@@ -873,6 +942,7 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) | |||
873 | 942 | ||
874 | if (!usbhid->urbin) { | 943 | if (!usbhid->urbin) { |
875 | err_hid("couldn't find an input interrupt endpoint"); | 944 | err_hid("couldn't find an input interrupt endpoint"); |
945 | ret = -ENODEV; | ||
876 | goto fail; | 946 | goto fail; |
877 | } | 947 | } |
878 | 948 | ||
@@ -884,44 +954,26 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) | |||
884 | spin_lock_init(&usbhid->outlock); | 954 | spin_lock_init(&usbhid->outlock); |
885 | spin_lock_init(&usbhid->ctrllock); | 955 | spin_lock_init(&usbhid->ctrllock); |
886 | 956 | ||
887 | hid->version = le16_to_cpu(hdesc->bcdHID); | ||
888 | hid->country = hdesc->bCountryCode; | ||
889 | hid->dev.parent = &intf->dev; | ||
890 | usbhid->intf = intf; | 957 | usbhid->intf = intf; |
891 | usbhid->ifnum = interface->desc.bInterfaceNumber; | 958 | usbhid->ifnum = interface->desc.bInterfaceNumber; |
892 | 959 | ||
893 | hid->bus = BUS_USB; | ||
894 | hid->vendor = le16_to_cpu(dev->descriptor.idVendor); | ||
895 | hid->product = le16_to_cpu(dev->descriptor.idProduct); | ||
896 | |||
897 | usb_make_path(dev, hid->phys, sizeof(hid->phys)); | ||
898 | strlcat(hid->phys, "/input", sizeof(hid->phys)); | ||
899 | len = strlen(hid->phys); | ||
900 | if (len < sizeof(hid->phys) - 1) | ||
901 | snprintf(hid->phys + len, sizeof(hid->phys) - len, | ||
902 | "%d", intf->altsetting[0].desc.bInterfaceNumber); | ||
903 | |||
904 | if (usb_string(dev, dev->descriptor.iSerialNumber, hid->uniq, 64) <= 0) | ||
905 | hid->uniq[0] = 0; | ||
906 | |||
907 | usbhid->urbctrl = usb_alloc_urb(0, GFP_KERNEL); | 960 | usbhid->urbctrl = usb_alloc_urb(0, GFP_KERNEL); |
908 | if (!usbhid->urbctrl) | 961 | if (!usbhid->urbctrl) { |
962 | ret = -ENOMEM; | ||
909 | goto fail; | 963 | goto fail; |
964 | } | ||
910 | 965 | ||
911 | usb_fill_control_urb(usbhid->urbctrl, dev, 0, (void *) usbhid->cr, | 966 | usb_fill_control_urb(usbhid->urbctrl, dev, 0, (void *) usbhid->cr, |
912 | usbhid->ctrlbuf, 1, hid_ctrl, hid); | 967 | usbhid->ctrlbuf, 1, hid_ctrl, hid); |
913 | usbhid->urbctrl->setup_dma = usbhid->cr_dma; | 968 | usbhid->urbctrl->setup_dma = usbhid->cr_dma; |
914 | usbhid->urbctrl->transfer_dma = usbhid->ctrlbuf_dma; | 969 | usbhid->urbctrl->transfer_dma = usbhid->ctrlbuf_dma; |
915 | usbhid->urbctrl->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP); | 970 | usbhid->urbctrl->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP); |
916 | hid->hidinput_input_event = usb_hidinput_input_event; | 971 | |
917 | hid->hid_open = usbhid_open; | 972 | ret = usbhid_start_finish(hid); |
918 | hid->hid_close = usbhid_close; | 973 | if (ret) |
919 | #ifdef CONFIG_USB_HIDDEV | 974 | goto fail; |
920 | hid->hiddev_hid_event = hiddev_hid_event; | 975 | |
921 | hid->hiddev_report_event = hiddev_report_event; | 976 | return 0; |
922 | #endif | ||
923 | hid->hid_output_raw_report = usbhid_output_raw_report; | ||
924 | return hid; | ||
925 | 977 | ||
926 | fail: | 978 | fail: |
927 | usb_free_urb(usbhid->urbin); | 979 | usb_free_urb(usbhid->urbin); |
@@ -929,24 +981,18 @@ fail: | |||
929 | usb_free_urb(usbhid->urbctrl); | 981 | usb_free_urb(usbhid->urbctrl); |
930 | hid_free_buffers(dev, hid); | 982 | hid_free_buffers(dev, hid); |
931 | kfree(usbhid); | 983 | kfree(usbhid); |
932 | fail_no_usbhid: | 984 | err: |
933 | hid_destroy_device(hid); | 985 | return ret; |
934 | |||
935 | return NULL; | ||
936 | } | 986 | } |
937 | 987 | ||
938 | static void hid_disconnect(struct usb_interface *intf) | 988 | static void usbhid_stop(struct hid_device *hid) |
939 | { | 989 | { |
940 | struct hid_device *hid = usb_get_intfdata (intf); | 990 | struct usbhid_device *usbhid = hid->driver_data; |
941 | struct usbhid_device *usbhid; | ||
942 | 991 | ||
943 | if (!hid) | 992 | if (WARN_ON(!usbhid)) |
944 | return; | 993 | return; |
945 | 994 | ||
946 | usbhid = hid->driver_data; | ||
947 | |||
948 | spin_lock_irq(&usbhid->inlock); /* Sync with error handler */ | 995 | spin_lock_irq(&usbhid->inlock); /* Sync with error handler */ |
949 | usb_set_intfdata(intf, NULL); | ||
950 | set_bit(HID_DISCONNECTED, &usbhid->iofl); | 996 | set_bit(HID_DISCONNECTED, &usbhid->iofl); |
951 | spin_unlock_irq(&usbhid->inlock); | 997 | spin_unlock_irq(&usbhid->inlock); |
952 | usb_kill_urb(usbhid->urbin); | 998 | usb_kill_urb(usbhid->urbin); |
@@ -963,93 +1009,99 @@ static void hid_disconnect(struct usb_interface *intf) | |||
963 | if (hid->claimed & HID_CLAIMED_HIDRAW) | 1009 | if (hid->claimed & HID_CLAIMED_HIDRAW) |
964 | hidraw_disconnect(hid); | 1010 | hidraw_disconnect(hid); |
965 | 1011 | ||
1012 | hid->claimed = 0; | ||
1013 | |||
966 | usb_free_urb(usbhid->urbin); | 1014 | usb_free_urb(usbhid->urbin); |
967 | usb_free_urb(usbhid->urbctrl); | 1015 | usb_free_urb(usbhid->urbctrl); |
968 | usb_free_urb(usbhid->urbout); | 1016 | usb_free_urb(usbhid->urbout); |
969 | 1017 | ||
970 | hid_free_buffers(hid_to_usb_dev(hid), hid); | 1018 | hid_free_buffers(hid_to_usb_dev(hid), hid); |
971 | kfree(usbhid); | 1019 | kfree(usbhid); |
972 | hid_destroy_device(hid); | 1020 | hid->driver_data = NULL; |
973 | } | 1021 | } |
974 | 1022 | ||
1023 | static struct hid_ll_driver usb_hid_driver = { | ||
1024 | .parse = usbhid_parse, | ||
1025 | .start = usbhid_start, | ||
1026 | .stop = usbhid_stop, | ||
1027 | .open = usbhid_open, | ||
1028 | .close = usbhid_close, | ||
1029 | .hidinput_input_event = usb_hidinput_input_event, | ||
1030 | }; | ||
1031 | |||
975 | static int hid_probe(struct usb_interface *intf, const struct usb_device_id *id) | 1032 | static int hid_probe(struct usb_interface *intf, const struct usb_device_id *id) |
976 | { | 1033 | { |
1034 | struct usb_device *dev = interface_to_usbdev(intf); | ||
977 | struct hid_device *hid; | 1035 | struct hid_device *hid; |
978 | char path[64]; | 1036 | size_t len; |
979 | int i, ret; | 1037 | int ret; |
980 | char *c; | ||
981 | 1038 | ||
982 | dbg_hid("HID probe called for ifnum %d\n", | 1039 | dbg_hid("HID probe called for ifnum %d\n", |
983 | intf->altsetting->desc.bInterfaceNumber); | 1040 | intf->altsetting->desc.bInterfaceNumber); |
984 | 1041 | ||
985 | if (!(hid = usb_hid_configure(intf))) | 1042 | hid = hid_allocate_device(); |
986 | return -ENODEV; | 1043 | if (IS_ERR(hid)) |
987 | 1044 | return PTR_ERR(hid); | |
988 | usbhid_init_reports(hid); | ||
989 | hid_dump_device(hid); | ||
990 | if (hid->quirks & HID_QUIRK_RESET_LEDS) | ||
991 | usbhid_set_leds(hid); | ||
992 | |||
993 | if (!hidinput_connect(hid)) | ||
994 | hid->claimed |= HID_CLAIMED_INPUT; | ||
995 | if (!hiddev_connect(hid)) | ||
996 | hid->claimed |= HID_CLAIMED_HIDDEV; | ||
997 | if (!hidraw_connect(hid)) | ||
998 | hid->claimed |= HID_CLAIMED_HIDRAW; | ||
999 | 1045 | ||
1000 | usb_set_intfdata(intf, hid); | 1046 | usb_set_intfdata(intf, hid); |
1047 | hid->ll_driver = &usb_hid_driver; | ||
1048 | hid->hid_output_raw_report = usbhid_output_raw_report; | ||
1049 | #ifdef CONFIG_USB_HIDDEV | ||
1050 | hid->hiddev_hid_event = hiddev_hid_event; | ||
1051 | hid->hiddev_report_event = hiddev_report_event; | ||
1052 | #endif | ||
1053 | hid->dev.parent = &intf->dev; | ||
1054 | hid->bus = BUS_USB; | ||
1055 | hid->vendor = le16_to_cpu(dev->descriptor.idVendor); | ||
1056 | hid->product = le16_to_cpu(dev->descriptor.idProduct); | ||
1057 | hid->name[0] = 0; | ||
1001 | 1058 | ||
1002 | if (!hid->claimed) { | 1059 | if (dev->manufacturer) |
1003 | printk ("HID device claimed by neither input, hiddev nor hidraw\n"); | 1060 | strlcpy(hid->name, dev->manufacturer, sizeof(hid->name)); |
1004 | hid_disconnect(intf); | ||
1005 | return -ENODEV; | ||
1006 | } | ||
1007 | |||
1008 | if ((hid->claimed & HID_CLAIMED_INPUT)) | ||
1009 | hid_ff_init(hid); | ||
1010 | |||
1011 | if (hid->quirks & HID_QUIRK_SONY_PS3_CONTROLLER) | ||
1012 | hid_fixup_sony_ps3_controller(interface_to_usbdev(intf), | ||
1013 | intf->cur_altsetting->desc.bInterfaceNumber); | ||
1014 | |||
1015 | printk(KERN_INFO); | ||
1016 | |||
1017 | if (hid->claimed & HID_CLAIMED_INPUT) | ||
1018 | printk("input"); | ||
1019 | if ((hid->claimed & HID_CLAIMED_INPUT) && ((hid->claimed & HID_CLAIMED_HIDDEV) || | ||
1020 | hid->claimed & HID_CLAIMED_HIDRAW)) | ||
1021 | printk(","); | ||
1022 | if (hid->claimed & HID_CLAIMED_HIDDEV) | ||
1023 | printk("hiddev%d", hid->minor); | ||
1024 | if ((hid->claimed & HID_CLAIMED_INPUT) && (hid->claimed & HID_CLAIMED_HIDDEV) && | ||
1025 | (hid->claimed & HID_CLAIMED_HIDRAW)) | ||
1026 | printk(","); | ||
1027 | if (hid->claimed & HID_CLAIMED_HIDRAW) | ||
1028 | printk("hidraw%d", ((struct hidraw*)hid->hidraw)->minor); | ||
1029 | 1061 | ||
1030 | c = "Device"; | 1062 | if (dev->product) { |
1031 | for (i = 0; i < hid->maxcollection; i++) { | 1063 | if (dev->manufacturer) |
1032 | if (hid->collection[i].type == HID_COLLECTION_APPLICATION && | 1064 | strlcat(hid->name, " ", sizeof(hid->name)); |
1033 | (hid->collection[i].usage & HID_USAGE_PAGE) == HID_UP_GENDESK && | 1065 | strlcat(hid->name, dev->product, sizeof(hid->name)); |
1034 | (hid->collection[i].usage & 0xffff) < ARRAY_SIZE(hid_types)) { | ||
1035 | c = hid_types[hid->collection[i].usage & 0xffff]; | ||
1036 | break; | ||
1037 | } | ||
1038 | } | 1066 | } |
1039 | 1067 | ||
1040 | usb_make_path(interface_to_usbdev(intf), path, 63); | 1068 | if (!strlen(hid->name)) |
1069 | snprintf(hid->name, sizeof(hid->name), "HID %04x:%04x", | ||
1070 | le16_to_cpu(dev->descriptor.idVendor), | ||
1071 | le16_to_cpu(dev->descriptor.idProduct)); | ||
1041 | 1072 | ||
1042 | printk(": USB HID v%x.%02x %s [%s] on %s\n", | 1073 | usb_make_path(dev, hid->phys, sizeof(hid->phys)); |
1043 | hid->version >> 8, hid->version & 0xff, c, hid->name, path); | 1074 | strlcat(hid->phys, "/input", sizeof(hid->phys)); |
1075 | len = strlen(hid->phys); | ||
1076 | if (len < sizeof(hid->phys) - 1) | ||
1077 | snprintf(hid->phys + len, sizeof(hid->phys) - len, | ||
1078 | "%d", intf->altsetting[0].desc.bInterfaceNumber); | ||
1079 | |||
1080 | if (usb_string(dev, dev->descriptor.iSerialNumber, hid->uniq, 64) <= 0) | ||
1081 | hid->uniq[0] = 0; | ||
1044 | 1082 | ||
1045 | ret = hid_add_device(hid); | 1083 | ret = hid_add_device(hid); |
1046 | if (ret) { | 1084 | if (ret) { |
1047 | dev_err(&intf->dev, "can't add hid device: %d\n", ret); | 1085 | dev_err(&intf->dev, "can't add hid device: %d\n", ret); |
1048 | hid_disconnect(intf); | 1086 | goto err; |
1049 | } | 1087 | } |
1088 | |||
1089 | return 0; | ||
1090 | err: | ||
1091 | hid_destroy_device(hid); | ||
1050 | return ret; | 1092 | return ret; |
1051 | } | 1093 | } |
1052 | 1094 | ||
1095 | static void hid_disconnect(struct usb_interface *intf) | ||
1096 | { | ||
1097 | struct hid_device *hid = usb_get_intfdata(intf); | ||
1098 | |||
1099 | if (WARN_ON(!hid)) | ||
1100 | return; | ||
1101 | |||
1102 | hid_destroy_device(hid); | ||
1103 | } | ||
1104 | |||
1053 | static int hid_suspend(struct usb_interface *intf, pm_message_t message) | 1105 | static int hid_suspend(struct usb_interface *intf, pm_message_t message) |
1054 | { | 1106 | { |
1055 | struct hid_device *hid = usb_get_intfdata (intf); | 1107 | struct hid_device *hid = usb_get_intfdata (intf); |