aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2008-08-12 14:34:14 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2008-08-21 13:26:37 -0400
commit5096aedcd2eb70fbea83f09281f97f9ec973d9de (patch)
treea1ed2e8486837fd2f0751802e7602c33f3b9fe8c /drivers
parentf2189c477c986db47ac7f9cc32d05f6df18bfe9e (diff)
USB: Don't rebind before "complete" callback
This patch (as1130) fixes an incompatibility between the new PM infrastructure and USB power management. We are not allowed to call drivers' probe routines during a system sleep transition between the "prepare" and "complete" callbacks, but that's exactly what we do when a driver doesn't have full suspend/resume support. Such drivers are unbound during the "suspend" call and reprobed during the "resume" call. The patch causes the reprobe step to be skipped if the "complete" callback hasn't been issued yet, i.e., if the interface's dev.power.status field is not equal to DPM_ON. Thus during the "resume" callback nothing bad will happen, and during the final "complete" callback the reprobing will occur as desired. This fixes the problem reported in Bugzilla #11263. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/usb/core/driver.c30
1 files changed, 9 insertions, 21 deletions
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index 2da70b4d33fe..5a7fa6f09958 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -814,7 +814,8 @@ void usb_forced_unbind_intf(struct usb_interface *intf)
814 * The caller must hold @intf's device's lock, but not its pm_mutex 814 * The caller must hold @intf's device's lock, but not its pm_mutex
815 * and not @intf->dev.sem. 815 * and not @intf->dev.sem.
816 * 816 *
817 * FIXME: The caller must block system sleep transitions. 817 * Note: Rebinds will be skipped if a system sleep transition is in
818 * progress and the PM "complete" callback hasn't occurred yet.
818 */ 819 */
819void usb_rebind_intf(struct usb_interface *intf) 820void usb_rebind_intf(struct usb_interface *intf)
820{ 821{
@@ -830,10 +831,12 @@ void usb_rebind_intf(struct usb_interface *intf)
830 } 831 }
831 832
832 /* Try to rebind the interface */ 833 /* Try to rebind the interface */
833 intf->needs_binding = 0; 834 if (intf->dev.power.status == DPM_ON) {
834 rc = device_attach(&intf->dev); 835 intf->needs_binding = 0;
835 if (rc < 0) 836 rc = device_attach(&intf->dev);
836 dev_warn(&intf->dev, "rebind failed: %d\n", rc); 837 if (rc < 0)
838 dev_warn(&intf->dev, "rebind failed: %d\n", rc);
839 }
837} 840}
838 841
839#ifdef CONFIG_PM 842#ifdef CONFIG_PM
@@ -845,7 +848,6 @@ void usb_rebind_intf(struct usb_interface *intf)
845 * or rebind interfaces that have been unbound, according to @action. 848 * or rebind interfaces that have been unbound, according to @action.
846 * 849 *
847 * The caller must hold @udev's device lock. 850 * The caller must hold @udev's device lock.
848 * FIXME: For rebinds, the caller must block system sleep transitions.
849 */ 851 */
850static void do_unbind_rebind(struct usb_device *udev, int action) 852static void do_unbind_rebind(struct usb_device *udev, int action)
851{ 853{
@@ -867,22 +869,8 @@ static void do_unbind_rebind(struct usb_device *udev, int action)
867 } 869 }
868 break; 870 break;
869 case DO_REBIND: 871 case DO_REBIND:
870 if (intf->needs_binding) { 872 if (intf->needs_binding)
871
872 /* FIXME: The next line is needed because we are going to probe
873 * the interface, but as far as the PM core is concerned the
874 * interface is still suspended. The problem wouldn't exist
875 * if we could rebind the interface during the interface's own
876 * resume() call, but at the time the usb_device isn't locked!
877 *
878 * The real solution will be to carry this out during the device's
879 * complete() callback. Until that is implemented, we have to
880 * use this hack.
881 */
882// intf->dev.power.sleeping = 0;
883
884 usb_rebind_intf(intf); 873 usb_rebind_intf(intf);
885 }
886 break; 874 break;
887 } 875 }
888 } 876 }