X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=drivers%2Fusb%2Fcore%2Fdriver.c;h=3cd9af2638fc6a209bc0d1cb3cb128b54a751a72;hb=f07600cf9eb3ee92777b2001e564faa413144a99;hp=6c62a6d9148488ebb00fd6187cf79d57c1ee76bf;hpb=20dfdad74a2baabeecc2896c770efcbf698b9b8d;p=safe%2Fjmp%2Flinux-2.6 diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index 6c62a6d..3cd9af2 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -915,21 +915,37 @@ static int usb_resume_interface(struct usb_interface *intf, int reset_resume) } driver = to_usb_driver(intf->dev.driver); - if (reset_resume && driver->post_reset) - driver->post_reset(intf, reset_resume); - else if (driver->resume) { - status = driver->resume(intf); - if (status) - dev_err(&intf->dev, "%s error %d\n", - "resume", status); - } else - dev_warn(&intf->dev, "no resume for driver %s?\n", - driver->name); + if (reset_resume) { + if (driver->reset_resume) { + status = driver->reset_resume(intf); + if (status) + dev_err(&intf->dev, "%s error %d\n", + "reset_resume", status); + } else { + // status = -EOPNOTSUPP; + dev_warn(&intf->dev, "no %s for driver %s?\n", + "reset_resume", driver->name); + } + } else { + if (driver->resume) { + status = driver->resume(intf); + if (status) + dev_err(&intf->dev, "%s error %d\n", + "resume", status); + } else { + // status = -EOPNOTSUPP; + dev_warn(&intf->dev, "no %s for driver %s?\n", + "resume", driver->name); + } + } done: dev_vdbg(&intf->dev, "%s: status %d\n", __FUNCTION__, status); if (status == 0) mark_active(intf); + + /* FIXME: Unbind the driver and reprobe if the resume failed + * (not possible if auto_pm is set) */ return status; } @@ -966,6 +982,18 @@ static int autosuspend_check(struct usb_device *udev) "for autosuspend\n"); return -EOPNOTSUPP; } + + /* Don't allow autosuspend if the device will need + * a reset-resume and any of its interface drivers + * doesn't include support. + */ + if (udev->quirks & USB_QUIRK_RESET_RESUME) { + struct usb_driver *driver; + + driver = to_usb_driver(intf->dev.driver); + if (!driver->reset_resume) + return -EOPNOTSUPP; + } } } @@ -1146,7 +1174,8 @@ static int usb_resume_both(struct usb_device *udev) status = usb_autoresume_device(parent); if (status == 0) { status = usb_resume_device(udev); - if (status) { + if (status || udev->state == + USB_STATE_NOTATTACHED) { usb_autosuspend_device(parent); /* It's possible usb_resume_device()