From: Alan Stern Date: Fri, 7 May 2010 14:41:10 +0000 (-0400) Subject: HID: fix suspend crash by moving initializations earlier X-Git-Tag: firefly_0821_release~10186^2~1013 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=3df1ba0d074919fef36e919220aec1b379d82684;p=firefly-linux-kernel-4.4.55.git HID: fix suspend crash by moving initializations earlier commit fde4e2f73208b8f34f123791e39c0cb6bc74b32a 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: Alan Stern Reported-by: Bruno Prémont Tested-By: Bruno Prémont Signed-off-by: Jiri Kosina Cc: maximilian attems Signed-off-by: Greg Kroah-Hartman --- diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index adfaa7d760d7..e9add5b3481d 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c @@ -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); if (!usbhid->urbctrl) { ret = -ENOMEM; @@ -1180,6 +1173,12 @@ static int usbhid_probe(struct usb_interface *intf, const struct usb_device_id * usbhid->intf = intf; 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); if (ret) { if (ret != -ENODEV)