| From stable-bounces@linux.kernel.org Thu Jul 19 20:46:46 2007 |
| From: Alan Stern <stern@rowland.harvard.edu> |
| Date: Thu, 19 Jul 2007 20:44:51 -0700 |
| Subject: USB: fix warning caused by autosuspend counter going negative |
| To: linux-usb-devel@lists.sourceforge.net |
| Cc: Greg Kroah-Hartman <gregkh@suse.de>, Alan Stern <stern@rowland.harvard.edu> |
| Message-ID: <1184903162294-git-send-email-gregkh@suse.de> |
| |
| |
| From: Alan Stern <stern@rowland.harvard.edu> |
| |
| This patch (as937) fixes a minor bug in the autosuspend usage-counting |
| code. Each hub's usage counter keeps track of the number of |
| unsuspended children. However the current driver increments the |
| counter after registering a new child, by which time the child may |
| already have been suspended and caused the counter to go negative. |
| The obvious solution is to increment the counter before registering |
| the child. |
| |
| Signed-off-by: Alan Stern <stern@rowland.harvard.edu> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| |
| --- |
| drivers/usb/core/hub.c | 10 ++++++---- |
| 1 file changed, 6 insertions(+), 4 deletions(-) |
| |
| --- a/drivers/usb/core/hub.c |
| +++ b/drivers/usb/core/hub.c |
| @@ -1388,6 +1388,10 @@ int usb_new_device(struct usb_device *ud |
| udev->dev.devt = MKDEV(USB_DEVICE_MAJOR, |
| (((udev->bus->busnum-1) * 128) + (udev->devnum-1))); |
| |
| + /* Increment the parent's count of unsuspended children */ |
| + if (udev->parent) |
| + usb_autoresume_device(udev->parent); |
| + |
| /* Register the device. The device driver is responsible |
| * for adding the device files to sysfs and for configuring |
| * the device. |
| @@ -1395,13 +1399,11 @@ int usb_new_device(struct usb_device *ud |
| err = device_add(&udev->dev); |
| if (err) { |
| dev_err(&udev->dev, "can't device_add, error %d\n", err); |
| + if (udev->parent) |
| + usb_autosuspend_device(udev->parent); |
| goto fail; |
| } |
| |
| - /* Increment the parent's count of unsuspended children */ |
| - if (udev->parent) |
| - usb_autoresume_device(udev->parent); |
| - |
| exit: |
| return err; |
| |