aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid
diff options
context:
space:
mode:
authorJiri Slaby <jirislaby@gmail.com>2008-11-01 18:41:46 -0400
committerJiri Kosina <jkosina@suse.cz>2008-11-13 04:31:36 -0500
commite3e14de50dff86331b8f0d701e910146c0049bf5 (patch)
treeb6878bf88a22d12e0cad3fec63e5ccfa7217f921 /drivers/hid
parent43ff3a48c13f3ddc085271c2eea2985d28c8aa08 (diff)
HID: fix start/stop cycle in usbhid driver
`stop' left out usbhid->urb* pointers and so the next `start' thought it needs to allocate nothing and used the memory pointers previously pointed to. This led to memory corruption and device malfunction. Also don't forget to clear disconnect flag on start which was left set by the previous `stop'. This fixes echo DEVICE > /sys/bus/hid/drivers/DRIVER/unbind echo DEVICE > /sys/bus/hid/drivers/DRIVER/bind failures. Signed-off-by: Jiri Slaby <jirislaby@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid')
-rw-r--r--drivers/hid/usbhid/hid-core.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index 18e5ddd722cd..f0339aefc798 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);
@@ -888,6 +890,9 @@ fail:
888 usb_free_urb(usbhid->urbin); 890 usb_free_urb(usbhid->urbin);
889 usb_free_urb(usbhid->urbout); 891 usb_free_urb(usbhid->urbout);
890 usb_free_urb(usbhid->urbctrl); 892 usb_free_urb(usbhid->urbctrl);
893 usbhid->urbin = NULL;
894 usbhid->urbout = NULL;
895 usbhid->urbctrl = NULL;
891 hid_free_buffers(dev, hid); 896 hid_free_buffers(dev, hid);
892 mutex_unlock(&usbhid->setup); 897 mutex_unlock(&usbhid->setup);
893 return ret; 898 return ret;
@@ -924,6 +929,9 @@ static void usbhid_stop(struct hid_device *hid)
924 usb_free_urb(usbhid->urbin); 929 usb_free_urb(usbhid->urbin);
925 usb_free_urb(usbhid->urbctrl); 930 usb_free_urb(usbhid->urbctrl);
926 usb_free_urb(usbhid->urbout); 931 usb_free_urb(usbhid->urbout);
932 usbhid->urbin = NULL; /* don't mess up next start */
933 usbhid->urbctrl = NULL;
934 usbhid->urbout = NULL;
927 935
928 hid_free_buffers(hid_to_usb_dev(hid), hid); 936 hid_free_buffers(hid_to_usb_dev(hid), hid);
929 mutex_unlock(&usbhid->setup); 937 mutex_unlock(&usbhid->setup);