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>
This commit is contained in:
parent
43ff3a48c1
commit
e3e14de50d
1 changed files with 8 additions and 0 deletions
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue