aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOliver Neukum <oliver@neukum.org>2012-12-17 23:45:29 -0500
committerDavid S. Miller <davem@davemloft.net>2012-12-19 15:46:40 -0500
commita1c088e01b71d90852b0df5a77cdae46bd0e0c05 (patch)
tree5aa6cae3330418b279d8f77d2bb466f75eee9018
parent4945106d21926eadaaa1c5465d26d9a0d26a2420 (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.c15
-rw-r--r--include/linux/usb/usbnet.h1
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
803done_manage_power_error:
804 clear_bit(EVENT_DEV_OPEN, &dev->flags);
805done: 806done:
806 usb_autopm_put_interface(dev->intf); 807 usb_autopm_put_interface(dev->intf);
807done_nopm: 808done_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
74static inline struct usb_driver *driver_of(struct usb_interface *intf) 75static inline struct usb_driver *driver_of(struct usb_interface *intf)