Commit 3df1ba0d authored by Alan Stern's avatar Alan Stern Committed by Greg Kroah-Hartman

HID: fix suspend crash by moving initializations earlier

commit fde4e2f7 upstream.

Although the usbhid driver allocates its usbhid structure in the probe
routine, several critical fields in that structure don't get
initialized until usbhid_start().  However if report descriptor
parsing fails then usbhid_start() is never called.  This leads to
problems during system suspend -- the system will freeze.

This patch (as1378) fixes the bug by moving the initialization
statements up into usbhid_probe().
Signed-off-by: default avatarAlan Stern <stern@rowland.harvard.edu>
Reported-by: default avatarBruno Prémont <bonbons@linux-vserver.org>
Tested-By: default avatarBruno Prémont <bonbons@linux-vserver.org>
Signed-off-by: default avatarJiri Kosina <jkosina@suse.cz>
Cc: maximilian attems <max@stro.at>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent c7260ac8
...@@ -1000,13 +1000,6 @@ static int usbhid_start(struct hid_device *hid) ...@@ -1000,13 +1000,6 @@ static int usbhid_start(struct hid_device *hid)
} }
} }
init_waitqueue_head(&usbhid->wait);
INIT_WORK(&usbhid->reset_work, hid_reset);
INIT_WORK(&usbhid->restart_work, __usbhid_restart_queues);
setup_timer(&usbhid->io_retry, hid_retry_timeout, (unsigned long) hid);
spin_lock_init(&usbhid->lock);
usbhid->urbctrl = usb_alloc_urb(0, GFP_KERNEL); usbhid->urbctrl = usb_alloc_urb(0, GFP_KERNEL);
if (!usbhid->urbctrl) { if (!usbhid->urbctrl) {
ret = -ENOMEM; ret = -ENOMEM;
...@@ -1180,6 +1173,12 @@ static int usbhid_probe(struct usb_interface *intf, const struct usb_device_id * ...@@ -1180,6 +1173,12 @@ static int usbhid_probe(struct usb_interface *intf, const struct usb_device_id *
usbhid->intf = intf; usbhid->intf = intf;
usbhid->ifnum = interface->desc.bInterfaceNumber; usbhid->ifnum = interface->desc.bInterfaceNumber;
init_waitqueue_head(&usbhid->wait);
INIT_WORK(&usbhid->reset_work, hid_reset);
INIT_WORK(&usbhid->restart_work, __usbhid_restart_queues);
setup_timer(&usbhid->io_retry, hid_retry_timeout, (unsigned long) hid);
spin_lock_init(&usbhid->lock);
ret = hid_add_device(hid); ret = hid_add_device(hid);
if (ret) { if (ret) {
if (ret != -ENODEV) if (ret != -ENODEV)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment