diff options
author | Ingo Molnar <mingo@elte.hu> | 2008-11-23 04:52:33 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-11-23 04:52:33 -0500 |
commit | 9f1441644213e5f6faa150206399fe511eba2eb6 (patch) | |
tree | e59d4e6475aa84f7e821a8c607deb56b85e19e95 /drivers/hid/usbhid/hid-core.c | |
parent | 3ff68a6a106c362a6811d3e51bced58e6fc87de7 (diff) | |
parent | 13d428afc007fcfcd6deeb215618f54cf9c0cae6 (diff) |
Merge commit 'v2.6.28-rc6' into irq/urgent
Diffstat (limited to 'drivers/hid/usbhid/hid-core.c')
-rw-r--r-- | drivers/hid/usbhid/hid-core.c | 25 |
1 files changed, 19 insertions, 6 deletions
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index 18e5ddd722cd..d746bf8284dd 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c | |||
@@ -781,6 +781,8 @@ static int usbhid_start(struct hid_device *hid) | |||
781 | unsigned int n, insize = 0; | 781 | unsigned int n, insize = 0; |
782 | int ret; | 782 | int ret; |
783 | 783 | ||
784 | clear_bit(HID_DISCONNECTED, &usbhid->iofl); | ||
785 | |||
784 | usbhid->bufsize = HID_MIN_BUFFER_SIZE; | 786 | usbhid->bufsize = HID_MIN_BUFFER_SIZE; |
785 | hid_find_max_report(hid, HID_INPUT_REPORT, &usbhid->bufsize); | 787 | hid_find_max_report(hid, HID_INPUT_REPORT, &usbhid->bufsize); |
786 | hid_find_max_report(hid, HID_OUTPUT_REPORT, &usbhid->bufsize); | 788 | hid_find_max_report(hid, HID_OUTPUT_REPORT, &usbhid->bufsize); |
@@ -847,12 +849,6 @@ static int usbhid_start(struct hid_device *hid) | |||
847 | } | 849 | } |
848 | } | 850 | } |
849 | 851 | ||
850 | if (!usbhid->urbin) { | ||
851 | err_hid("couldn't find an input interrupt endpoint"); | ||
852 | ret = -ENODEV; | ||
853 | goto fail; | ||
854 | } | ||
855 | |||
856 | init_waitqueue_head(&usbhid->wait); | 852 | init_waitqueue_head(&usbhid->wait); |
857 | INIT_WORK(&usbhid->reset_work, hid_reset); | 853 | INIT_WORK(&usbhid->reset_work, hid_reset); |
858 | setup_timer(&usbhid->io_retry, hid_retry_timeout, (unsigned long) hid); | 854 | setup_timer(&usbhid->io_retry, hid_retry_timeout, (unsigned long) hid); |
@@ -888,6 +884,9 @@ fail: | |||
888 | usb_free_urb(usbhid->urbin); | 884 | usb_free_urb(usbhid->urbin); |
889 | usb_free_urb(usbhid->urbout); | 885 | usb_free_urb(usbhid->urbout); |
890 | usb_free_urb(usbhid->urbctrl); | 886 | usb_free_urb(usbhid->urbctrl); |
887 | usbhid->urbin = NULL; | ||
888 | usbhid->urbout = NULL; | ||
889 | usbhid->urbctrl = NULL; | ||
891 | hid_free_buffers(dev, hid); | 890 | hid_free_buffers(dev, hid); |
892 | mutex_unlock(&usbhid->setup); | 891 | mutex_unlock(&usbhid->setup); |
893 | return ret; | 892 | return ret; |
@@ -924,6 +923,9 @@ static void usbhid_stop(struct hid_device *hid) | |||
924 | usb_free_urb(usbhid->urbin); | 923 | usb_free_urb(usbhid->urbin); |
925 | usb_free_urb(usbhid->urbctrl); | 924 | usb_free_urb(usbhid->urbctrl); |
926 | usb_free_urb(usbhid->urbout); | 925 | usb_free_urb(usbhid->urbout); |
926 | usbhid->urbin = NULL; /* don't mess up next start */ | ||
927 | usbhid->urbctrl = NULL; | ||
928 | usbhid->urbout = NULL; | ||
927 | 929 | ||
928 | hid_free_buffers(hid_to_usb_dev(hid), hid); | 930 | hid_free_buffers(hid_to_usb_dev(hid), hid); |
929 | mutex_unlock(&usbhid->setup); | 931 | mutex_unlock(&usbhid->setup); |
@@ -940,15 +942,26 @@ static struct hid_ll_driver usb_hid_driver = { | |||
940 | 942 | ||
941 | static int hid_probe(struct usb_interface *intf, const struct usb_device_id *id) | 943 | static int hid_probe(struct usb_interface *intf, const struct usb_device_id *id) |
942 | { | 944 | { |
945 | struct usb_host_interface *interface = intf->cur_altsetting; | ||
943 | struct usb_device *dev = interface_to_usbdev(intf); | 946 | struct usb_device *dev = interface_to_usbdev(intf); |
944 | struct usbhid_device *usbhid; | 947 | struct usbhid_device *usbhid; |
945 | struct hid_device *hid; | 948 | struct hid_device *hid; |
949 | unsigned int n, has_in = 0; | ||
946 | size_t len; | 950 | size_t len; |
947 | int ret; | 951 | int ret; |
948 | 952 | ||
949 | dbg_hid("HID probe called for ifnum %d\n", | 953 | dbg_hid("HID probe called for ifnum %d\n", |
950 | intf->altsetting->desc.bInterfaceNumber); | 954 | intf->altsetting->desc.bInterfaceNumber); |
951 | 955 | ||
956 | for (n = 0; n < interface->desc.bNumEndpoints; n++) | ||
957 | if (usb_endpoint_is_int_in(&interface->endpoint[n].desc)) | ||
958 | has_in++; | ||
959 | if (!has_in) { | ||
960 | dev_err(&intf->dev, "couldn't find an input interrupt " | ||
961 | "endpoint\n"); | ||
962 | return -ENODEV; | ||
963 | } | ||
964 | |||
952 | hid = hid_allocate_device(); | 965 | hid = hid_allocate_device(); |
953 | if (IS_ERR(hid)) | 966 | if (IS_ERR(hid)) |
954 | return PTR_ERR(hid); | 967 | return PTR_ERR(hid); |