Skip to content

Commit

Permalink
HID: fix start/stop cycle in usbhid driver
Browse files Browse the repository at this point in the history
`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>
  • Loading branch information
Jiri Slaby authored and Jiri Kosina committed Nov 13, 2008
1 parent 43ff3a4 commit e3e14de
Showing 1 changed file with 8 additions and 0 deletions.
8 changes: 8 additions & 0 deletions drivers/hid/usbhid/hid-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -781,6 +781,8 @@ static int usbhid_start(struct hid_device *hid)
unsigned int n, insize = 0;
int ret;

clear_bit(HID_DISCONNECTED, &usbhid->iofl);

usbhid->bufsize = HID_MIN_BUFFER_SIZE;
hid_find_max_report(hid, HID_INPUT_REPORT, &usbhid->bufsize);
hid_find_max_report(hid, HID_OUTPUT_REPORT, &usbhid->bufsize);
Expand Down Expand Up @@ -888,6 +890,9 @@ static int usbhid_start(struct hid_device *hid)
usb_free_urb(usbhid->urbin);
usb_free_urb(usbhid->urbout);
usb_free_urb(usbhid->urbctrl);
usbhid->urbin = NULL;
usbhid->urbout = NULL;
usbhid->urbctrl = NULL;
hid_free_buffers(dev, hid);
mutex_unlock(&usbhid->setup);
return ret;
Expand Down Expand Up @@ -924,6 +929,9 @@ static void usbhid_stop(struct hid_device *hid)
usb_free_urb(usbhid->urbin);
usb_free_urb(usbhid->urbctrl);
usb_free_urb(usbhid->urbout);
usbhid->urbin = NULL; /* don't mess up next start */
usbhid->urbctrl = NULL;
usbhid->urbout = NULL;

hid_free_buffers(hid_to_usb_dev(hid), hid);
mutex_unlock(&usbhid->setup);
Expand Down

0 comments on commit e3e14de

Please sign in to comment.