aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2008-06-23 16:00:40 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2008-07-21 18:16:40 -0400
commit78d9a487ee961c356e1a934d9a92eca38ffb3a70 (patch)
treea49a862bf45b1aae6ecd746ac8aa0f48fdfa0917 /drivers
parent64b3d6d11948cc71ff12124dcb693392a32f1bf4 (diff)
USB: Force unbinding of drivers lacking reset_resume or other methods
This patch (as1024) takes care of a FIXME issue: Drivers that don't have the necessary suspend, resume, reset_resume, pre_reset, or post_reset methods will be unbound and their interface reprobed when one of the unsupported events occurs. This is made slightly more difficult by the fact that bind operations won't work during a system sleep transition. So instead the code has to defer the operation until the transition ends. 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.c131
-rw-r--r--drivers/usb/core/hub.c27
-rw-r--r--drivers/usb/core/usb.h2
3 files changed, 139 insertions, 21 deletions
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index 8da1a56659be..ddb54e14a5c5 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -201,6 +201,7 @@ static int usb_probe_interface(struct device *dev)
201 201
202 intf = to_usb_interface(dev); 202 intf = to_usb_interface(dev);
203 udev = interface_to_usbdev(intf); 203 udev = interface_to_usbdev(intf);
204 intf->needs_binding = 0;
204 205
205 if (udev->authorized == 0) { 206 if (udev->authorized == 0) {
206 dev_err(&intf->dev, "Device is not authorized for usage\n"); 207 dev_err(&intf->dev, "Device is not authorized for usage\n");
@@ -311,6 +312,7 @@ int usb_driver_claim_interface(struct usb_driver *driver,
311 312
312 dev->driver = &driver->drvwrap.driver; 313 dev->driver = &driver->drvwrap.driver;
313 usb_set_intfdata(iface, priv); 314 usb_set_intfdata(iface, priv);
315 iface->needs_binding = 0;
314 316
315 usb_pm_lock(udev); 317 usb_pm_lock(udev);
316 iface->condition = USB_INTERFACE_BOUND; 318 iface->condition = USB_INTERFACE_BOUND;
@@ -772,6 +774,104 @@ void usb_deregister(struct usb_driver *driver)
772} 774}
773EXPORT_SYMBOL_GPL(usb_deregister); 775EXPORT_SYMBOL_GPL(usb_deregister);
774 776
777
778/* Forced unbinding of a USB interface driver, either because
779 * it doesn't support pre_reset/post_reset/reset_resume or
780 * because it doesn't support suspend/resume.
781 *
782 * The caller must hold @intf's device's lock, but not its pm_mutex
783 * and not @intf->dev.sem.
784 */
785void usb_forced_unbind_intf(struct usb_interface *intf)
786{
787 struct usb_driver *driver = to_usb_driver(intf->dev.driver);
788
789 dev_dbg(&intf->dev, "forced unbind\n");
790 usb_driver_release_interface(driver, intf);
791
792 /* Mark the interface for later rebinding */
793 intf->needs_binding = 1;
794}
795
796/* Delayed forced unbinding of a USB interface driver and scan
797 * for rebinding.
798 *
799 * The caller must hold @intf's device's lock, but not its pm_mutex
800 * and not @intf->dev.sem.
801 *
802 * FIXME: The caller must block system sleep transitions.
803 */
804void usb_rebind_intf(struct usb_interface *intf)
805{
806 int rc;
807
808 /* Delayed unbind of an existing driver */
809 if (intf->dev.driver) {
810 struct usb_driver *driver =
811 to_usb_driver(intf->dev.driver);
812
813 dev_dbg(&intf->dev, "forced unbind\n");
814 usb_driver_release_interface(driver, intf);
815 }
816
817 /* Try to rebind the interface */
818 intf->needs_binding = 0;
819 rc = device_attach(&intf->dev);
820 if (rc < 0)
821 dev_warn(&intf->dev, "rebind failed: %d\n", rc);
822}
823
824#define DO_UNBIND 0
825#define DO_REBIND 1
826
827/* Unbind drivers for @udev's interfaces that don't support suspend/resume,
828 * or rebind interfaces that have been unbound, according to @action.
829 *
830 * The caller must hold @udev's device lock.
831 * FIXME: For rebinds, the caller must block system sleep transitions.
832 */
833static void do_unbind_rebind(struct usb_device *udev, int action)
834{
835 struct usb_host_config *config;
836 int i;
837 struct usb_interface *intf;
838 struct usb_driver *drv;
839
840 config = udev->actconfig;
841 if (config) {
842 for (i = 0; i < config->desc.bNumInterfaces; ++i) {
843 intf = config->interface[i];
844 switch (action) {
845 case DO_UNBIND:
846 if (intf->dev.driver) {
847 drv = to_usb_driver(intf->dev.driver);
848 if (!drv->suspend || !drv->resume)
849 usb_forced_unbind_intf(intf);
850 }
851 break;
852 case DO_REBIND:
853 if (intf->needs_binding) {
854
855 /* FIXME: The next line is needed because we are going to probe
856 * the interface, but as far as the PM core is concerned the
857 * interface is still suspended. The problem wouldn't exist
858 * if we could rebind the interface during the interface's own
859 * resume() call, but at the time the usb_device isn't locked!
860 *
861 * The real solution will be to carry this out during the device's
862 * complete() callback. Until that is implemented, we have to
863 * use this hack.
864 */
865// intf->dev.power.sleeping = 0;
866
867 usb_rebind_intf(intf);
868 }
869 break;
870 }
871 }
872 }
873}
874
775#ifdef CONFIG_PM 875#ifdef CONFIG_PM
776 876
777/* Caller has locked udev's pm_mutex */ 877/* Caller has locked udev's pm_mutex */
@@ -841,7 +941,7 @@ static int usb_suspend_interface(struct usb_interface *intf, pm_message_t msg)
841 goto done; 941 goto done;
842 driver = to_usb_driver(intf->dev.driver); 942 driver = to_usb_driver(intf->dev.driver);
843 943
844 if (driver->suspend && driver->resume) { 944 if (driver->suspend) {
845 status = driver->suspend(intf, msg); 945 status = driver->suspend(intf, msg);
846 if (status == 0) 946 if (status == 0)
847 mark_quiesced(intf); 947 mark_quiesced(intf);
@@ -849,12 +949,10 @@ static int usb_suspend_interface(struct usb_interface *intf, pm_message_t msg)
849 dev_err(&intf->dev, "%s error %d\n", 949 dev_err(&intf->dev, "%s error %d\n",
850 "suspend", status); 950 "suspend", status);
851 } else { 951 } else {
852 /* 952 /* Later we will unbind the driver and reprobe */
853 * FIXME else if there's no suspend method, disconnect... 953 intf->needs_binding = 1;
854 * Not possible if auto_pm is set... 954 dev_warn(&intf->dev, "no %s for driver %s?\n",
855 */ 955 "suspend", driver->name);
856 dev_warn(&intf->dev, "no suspend for driver %s?\n",
857 driver->name);
858 mark_quiesced(intf); 956 mark_quiesced(intf);
859 } 957 }
860 958
@@ -878,10 +976,12 @@ static int usb_resume_interface(struct usb_interface *intf, int reset_resume)
878 goto done; 976 goto done;
879 977
880 /* Can't resume it if it doesn't have a driver. */ 978 /* Can't resume it if it doesn't have a driver. */
881 if (intf->condition == USB_INTERFACE_UNBOUND) { 979 if (intf->condition == USB_INTERFACE_UNBOUND)
882 status = -ENOTCONN; 980 goto done;
981
982 /* Don't resume if the interface is marked for rebinding */
983 if (intf->needs_binding)
883 goto done; 984 goto done;
884 }
885 driver = to_usb_driver(intf->dev.driver); 985 driver = to_usb_driver(intf->dev.driver);
886 986
887 if (reset_resume) { 987 if (reset_resume) {
@@ -891,7 +991,7 @@ static int usb_resume_interface(struct usb_interface *intf, int reset_resume)
891 dev_err(&intf->dev, "%s error %d\n", 991 dev_err(&intf->dev, "%s error %d\n",
892 "reset_resume", status); 992 "reset_resume", status);
893 } else { 993 } else {
894 /* status = -EOPNOTSUPP; */ 994 intf->needs_binding = 1;
895 dev_warn(&intf->dev, "no %s for driver %s?\n", 995 dev_warn(&intf->dev, "no %s for driver %s?\n",
896 "reset_resume", driver->name); 996 "reset_resume", driver->name);
897 } 997 }
@@ -902,7 +1002,7 @@ static int usb_resume_interface(struct usb_interface *intf, int reset_resume)
902 dev_err(&intf->dev, "%s error %d\n", 1002 dev_err(&intf->dev, "%s error %d\n",
903 "resume", status); 1003 "resume", status);
904 } else { 1004 } else {
905 /* status = -EOPNOTSUPP; */ 1005 intf->needs_binding = 1;
906 dev_warn(&intf->dev, "no %s for driver %s?\n", 1006 dev_warn(&intf->dev, "no %s for driver %s?\n",
907 "resume", driver->name); 1007 "resume", driver->name);
908 } 1008 }
@@ -910,11 +1010,10 @@ static int usb_resume_interface(struct usb_interface *intf, int reset_resume)
910 1010
911done: 1011done:
912 dev_vdbg(&intf->dev, "%s: status %d\n", __func__, status); 1012 dev_vdbg(&intf->dev, "%s: status %d\n", __func__, status);
913 if (status == 0) 1013 if (status == 0 && intf->condition == USB_INTERFACE_BOUND)
914 mark_active(intf); 1014 mark_active(intf);
915 1015
916 /* FIXME: Unbind the driver and reprobe if the resume failed 1016 /* Later we will unbind the driver and/or reprobe, if necessary */
917 * (not possible if auto_pm is set) */
918 return status; 1017 return status;
919} 1018}
920 1019
@@ -1470,6 +1569,7 @@ int usb_external_suspend_device(struct usb_device *udev, pm_message_t msg)
1470{ 1569{
1471 int status; 1570 int status;
1472 1571
1572 do_unbind_rebind(udev, DO_UNBIND);
1473 usb_pm_lock(udev); 1573 usb_pm_lock(udev);
1474 udev->auto_pm = 0; 1574 udev->auto_pm = 0;
1475 status = usb_suspend_both(udev, msg); 1575 status = usb_suspend_both(udev, msg);
@@ -1497,6 +1597,7 @@ int usb_external_resume_device(struct usb_device *udev)
1497 status = usb_resume_both(udev); 1597 status = usb_resume_both(udev);
1498 udev->last_busy = jiffies; 1598 udev->last_busy = jiffies;
1499 usb_pm_unlock(udev); 1599 usb_pm_unlock(udev);
1600 do_unbind_rebind(udev, DO_REBIND);
1500 1601
1501 /* Now that the device is awake, we can start trying to autosuspend 1602 /* Now that the device is awake, we can start trying to autosuspend
1502 * it again. */ 1603 * it again. */
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index bb3ecc4c08f2..f1efabbc1ca2 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -3367,6 +3367,11 @@ re_enumerate:
3367 * this from a driver probe() routine after downloading new firmware. 3367 * this from a driver probe() routine after downloading new firmware.
3368 * For calls that might not occur during probe(), drivers should lock 3368 * For calls that might not occur during probe(), drivers should lock
3369 * the device using usb_lock_device_for_reset(). 3369 * the device using usb_lock_device_for_reset().
3370 *
3371 * If an interface is currently being probed or disconnected, we assume
3372 * its driver knows how to handle resets. For all other interfaces,
3373 * if the driver doesn't have pre_reset and post_reset methods then
3374 * we attempt to unbind it and rebind afterward.
3370 */ 3375 */
3371int usb_reset_device(struct usb_device *udev) 3376int usb_reset_device(struct usb_device *udev)
3372{ 3377{
@@ -3388,12 +3393,17 @@ int usb_reset_device(struct usb_device *udev)
3388 for (i = 0; i < config->desc.bNumInterfaces; ++i) { 3393 for (i = 0; i < config->desc.bNumInterfaces; ++i) {
3389 struct usb_interface *cintf = config->interface[i]; 3394 struct usb_interface *cintf = config->interface[i];
3390 struct usb_driver *drv; 3395 struct usb_driver *drv;
3396 int unbind = 0;
3391 3397
3392 if (cintf->dev.driver) { 3398 if (cintf->dev.driver) {
3393 drv = to_usb_driver(cintf->dev.driver); 3399 drv = to_usb_driver(cintf->dev.driver);
3394 if (drv->pre_reset) 3400 if (drv->pre_reset && drv->post_reset)
3395 (drv->pre_reset)(cintf); 3401 unbind = (drv->pre_reset)(cintf);
3396 /* FIXME: Unbind if pre_reset returns an error or isn't defined */ 3402 else if (cintf->condition ==
3403 USB_INTERFACE_BOUND)
3404 unbind = 1;
3405 if (unbind)
3406 usb_forced_unbind_intf(cintf);
3397 } 3407 }
3398 } 3408 }
3399 } 3409 }
@@ -3404,13 +3414,18 @@ int usb_reset_device(struct usb_device *udev)
3404 for (i = config->desc.bNumInterfaces - 1; i >= 0; --i) { 3414 for (i = config->desc.bNumInterfaces - 1; i >= 0; --i) {
3405 struct usb_interface *cintf = config->interface[i]; 3415 struct usb_interface *cintf = config->interface[i];
3406 struct usb_driver *drv; 3416 struct usb_driver *drv;
3417 int rebind = cintf->needs_binding;
3407 3418
3408 if (cintf->dev.driver) { 3419 if (!rebind && cintf->dev.driver) {
3409 drv = to_usb_driver(cintf->dev.driver); 3420 drv = to_usb_driver(cintf->dev.driver);
3410 if (drv->post_reset) 3421 if (drv->post_reset)
3411 (drv->post_reset)(cintf); 3422 rebind = (drv->post_reset)(cintf);
3412 /* FIXME: Unbind if post_reset returns an error or isn't defined */ 3423 else if (cintf->condition ==
3424 USB_INTERFACE_BOUND)
3425 rebind = 1;
3413 } 3426 }
3427 if (rebind)
3428 usb_rebind_intf(cintf);
3414 } 3429 }
3415 } 3430 }
3416 3431
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h
index 1a8bc21c335e..d3eb0a29bca1 100644
--- a/drivers/usb/core/usb.h
+++ b/drivers/usb/core/usb.h
@@ -29,6 +29,8 @@ extern int usb_choose_configuration(struct usb_device *udev);
29extern void usb_kick_khubd(struct usb_device *dev); 29extern void usb_kick_khubd(struct usb_device *dev);
30extern int usb_match_device(struct usb_device *dev, 30extern int usb_match_device(struct usb_device *dev,
31 const struct usb_device_id *id); 31 const struct usb_device_id *id);
32extern void usb_forced_unbind_intf(struct usb_interface *intf);
33extern void usb_rebind_intf(struct usb_interface *intf);
32 34
33extern int usb_hub_init(void); 35extern int usb_hub_init(void);
34extern void usb_hub_cleanup(void); 36extern void usb_hub_cleanup(void);