diff options
author | Oliver Neukum <oliver@neukum.org> | 2012-12-17 23:45:29 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-12-19 15:46:40 -0500 |
commit | a1c088e01b71d90852b0df5a77cdae46bd0e0c05 (patch) | |
tree | 5aa6cae3330418b279d8f77d2bb466f75eee9018 | |
parent | 4945106d21926eadaaa1c5465d26d9a0d26a2420 (diff) |
usbnet: handle PM failure gracefully
If a device fails to do remote wakeup, this is no reason
to abort an open totally. This patch just continues without
runtime PM.
Signed-off-by: Oliver Neukum <oneukum@suse.de>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/usb/usbnet.c | 15 | ||||
-rw-r--r-- | include/linux/usb/usbnet.h | 1 |
2 files changed, 9 insertions, 7 deletions
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index c04110ba677..50ed7ab09c9 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c | |||
@@ -719,7 +719,8 @@ int usbnet_stop (struct net_device *net) | |||
719 | dev->flags = 0; | 719 | dev->flags = 0; |
720 | del_timer_sync (&dev->delay); | 720 | del_timer_sync (&dev->delay); |
721 | tasklet_kill (&dev->bh); | 721 | tasklet_kill (&dev->bh); |
722 | if (info->manage_power) | 722 | if (info->manage_power && |
723 | !test_and_clear_bit(EVENT_NO_RUNTIME_PM, &dev->flags)) | ||
723 | info->manage_power(dev, 0); | 724 | info->manage_power(dev, 0); |
724 | else | 725 | else |
725 | usb_autopm_put_interface(dev->intf); | 726 | usb_autopm_put_interface(dev->intf); |
@@ -794,14 +795,14 @@ int usbnet_open (struct net_device *net) | |||
794 | tasklet_schedule (&dev->bh); | 795 | tasklet_schedule (&dev->bh); |
795 | if (info->manage_power) { | 796 | if (info->manage_power) { |
796 | retval = info->manage_power(dev, 1); | 797 | retval = info->manage_power(dev, 1); |
797 | if (retval < 0) | 798 | if (retval < 0) { |
798 | goto done_manage_power_error; | 799 | retval = 0; |
799 | usb_autopm_put_interface(dev->intf); | 800 | set_bit(EVENT_NO_RUNTIME_PM, &dev->flags); |
801 | } else { | ||
802 | usb_autopm_put_interface(dev->intf); | ||
803 | } | ||
800 | } | 804 | } |
801 | return retval; | 805 | return retval; |
802 | |||
803 | done_manage_power_error: | ||
804 | clear_bit(EVENT_DEV_OPEN, &dev->flags); | ||
805 | done: | 806 | done: |
806 | usb_autopm_put_interface(dev->intf); | 807 | usb_autopm_put_interface(dev->intf); |
807 | done_nopm: | 808 | done_nopm: |
diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h index 9bbeabf66c5..288b32aadab 100644 --- a/include/linux/usb/usbnet.h +++ b/include/linux/usb/usbnet.h | |||
@@ -69,6 +69,7 @@ struct usbnet { | |||
69 | # define EVENT_DEV_ASLEEP 6 | 69 | # define EVENT_DEV_ASLEEP 6 |
70 | # define EVENT_DEV_OPEN 7 | 70 | # define EVENT_DEV_OPEN 7 |
71 | # define EVENT_DEVICE_REPORT_IDLE 8 | 71 | # define EVENT_DEVICE_REPORT_IDLE 8 |
72 | # define EVENT_NO_RUNTIME_PM 9 | ||
72 | }; | 73 | }; |
73 | 74 | ||
74 | static inline struct usb_driver *driver_of(struct usb_interface *intf) | 75 | static inline struct usb_driver *driver_of(struct usb_interface *intf) |