mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-14 06:35:12 +00:00
USB: remove __usb_port_suspend
This patch (as915b) combines the public routine usb_port_suspend() and the private routine __usb_port_suspend() into a single function. By removing the explicit mention of otg_port in the call to __usb_port_suspend(), we prevent a possible error in which the system tries to perform HNP on the wrong port when a non-targeted device is plugged into a non-OTG port. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
d576bb9f27
commit
4956eccdd6
2 changed files with 42 additions and 45 deletions
|
@ -1333,7 +1333,6 @@ static inline void show_string(struct usb_device *udev, char *id, char *string)
|
||||||
|
|
||||||
#ifdef CONFIG_USB_OTG
|
#ifdef CONFIG_USB_OTG
|
||||||
#include "otg_whitelist.h"
|
#include "otg_whitelist.h"
|
||||||
static int __usb_port_suspend(struct usb_device *, int port1);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1439,7 +1438,7 @@ int usb_new_device(struct usb_device *udev)
|
||||||
* (Includes HNP test device.)
|
* (Includes HNP test device.)
|
||||||
*/
|
*/
|
||||||
if (udev->bus->b_hnp_enable || udev->bus->is_b_host) {
|
if (udev->bus->b_hnp_enable || udev->bus->is_b_host) {
|
||||||
err = __usb_port_suspend(udev, udev->bus->otg_port);
|
err = usb_port_suspend(udev);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
dev_dbg(&udev->dev, "HNP fail, %d\n", err);
|
dev_dbg(&udev->dev, "HNP fail, %d\n", err);
|
||||||
}
|
}
|
||||||
|
@ -1682,46 +1681,6 @@ static int hub_port_suspend(struct usb_hub *hub, int port1,
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Devices on USB hub ports have only one "suspend" state, corresponding
|
|
||||||
* to ACPI D2, "may cause the device to lose some context".
|
|
||||||
* State transitions include:
|
|
||||||
*
|
|
||||||
* - suspend, resume ... when the VBUS power link stays live
|
|
||||||
* - suspend, disconnect ... VBUS lost
|
|
||||||
*
|
|
||||||
* Once VBUS drop breaks the circuit, the port it's using has to go through
|
|
||||||
* normal re-enumeration procedures, starting with enabling VBUS power.
|
|
||||||
* Other than re-initializing the hub (plug/unplug, except for root hubs),
|
|
||||||
* Linux (2.6) currently has NO mechanisms to initiate that: no khubd
|
|
||||||
* timer, no SRP, no requests through sysfs.
|
|
||||||
*
|
|
||||||
* If CONFIG_USB_SUSPEND isn't enabled, devices only really suspend when
|
|
||||||
* the root hub for their bus goes into global suspend ... so we don't
|
|
||||||
* (falsely) update the device power state to say it suspended.
|
|
||||||
*/
|
|
||||||
static int __usb_port_suspend (struct usb_device *udev, int port1)
|
|
||||||
{
|
|
||||||
int status = 0;
|
|
||||||
|
|
||||||
/* caller owns the udev device lock */
|
|
||||||
if (port1 < 0)
|
|
||||||
return port1;
|
|
||||||
|
|
||||||
/* we change the device's upstream USB link,
|
|
||||||
* but root hubs have no upstream USB link.
|
|
||||||
*/
|
|
||||||
if (udev->parent)
|
|
||||||
status = hub_port_suspend(hdev_to_hub(udev->parent), port1,
|
|
||||||
udev);
|
|
||||||
else {
|
|
||||||
dev_dbg(&udev->dev, "usb %ssuspend\n",
|
|
||||||
udev->auto_pm ? "auto-" : "");
|
|
||||||
usb_set_device_state(udev, USB_STATE_SUSPENDED);
|
|
||||||
}
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* usb_port_suspend - suspend a usb device's upstream port
|
* usb_port_suspend - suspend a usb device's upstream port
|
||||||
* @udev: device that's no longer in active use
|
* @udev: device that's no longer in active use
|
||||||
|
@ -1740,11 +1699,41 @@ static int __usb_port_suspend (struct usb_device *udev, int port1)
|
||||||
* between a pair of dual-role devices. That will change roles, such
|
* between a pair of dual-role devices. That will change roles, such
|
||||||
* as from A-Host to A-Peripheral or from B-Host back to B-Peripheral.
|
* as from A-Host to A-Peripheral or from B-Host back to B-Peripheral.
|
||||||
*
|
*
|
||||||
|
* Devices on USB hub ports have only one "suspend" state, corresponding
|
||||||
|
* to ACPI D2, "may cause the device to lose some context".
|
||||||
|
* State transitions include:
|
||||||
|
*
|
||||||
|
* - suspend, resume ... when the VBUS power link stays live
|
||||||
|
* - suspend, disconnect ... VBUS lost
|
||||||
|
*
|
||||||
|
* Once VBUS drop breaks the circuit, the port it's using has to go through
|
||||||
|
* normal re-enumeration procedures, starting with enabling VBUS power.
|
||||||
|
* Other than re-initializing the hub (plug/unplug, except for root hubs),
|
||||||
|
* Linux (2.6) currently has NO mechanisms to initiate that: no khubd
|
||||||
|
* timer, no SRP, no requests through sysfs.
|
||||||
|
*
|
||||||
|
* If CONFIG_USB_SUSPEND isn't enabled, devices only really suspend when
|
||||||
|
* the root hub for their bus goes into global suspend ... so we don't
|
||||||
|
* (falsely) update the device power state to say it suspended.
|
||||||
|
*
|
||||||
* Returns 0 on success, else negative errno.
|
* Returns 0 on success, else negative errno.
|
||||||
*/
|
*/
|
||||||
int usb_port_suspend(struct usb_device *udev)
|
int usb_port_suspend(struct usb_device *udev)
|
||||||
{
|
{
|
||||||
return __usb_port_suspend(udev, udev->portnum);
|
int status = 0;
|
||||||
|
|
||||||
|
/* we change the device's upstream USB link,
|
||||||
|
* but root hubs have no upstream USB link.
|
||||||
|
*/
|
||||||
|
if (udev->parent)
|
||||||
|
status = hub_port_suspend(hdev_to_hub(udev->parent),
|
||||||
|
udev->portnum, udev);
|
||||||
|
else {
|
||||||
|
dev_dbg(&udev->dev, "usb %ssuspend\n",
|
||||||
|
udev->auto_pm ? "auto-" : "");
|
||||||
|
usb_set_device_state(udev, USB_STATE_SUSPENDED);
|
||||||
|
}
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -53,8 +53,16 @@ static inline void usb_pm_unlock(struct usb_device *udev)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define usb_port_suspend(dev) 0
|
static inline int usb_port_suspend(struct usb_device *udev)
|
||||||
#define usb_port_resume(dev) 0
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int usb_port_resume(struct usb_device *udev)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static inline void usb_pm_lock(struct usb_device *udev) {}
|
static inline void usb_pm_lock(struct usb_device *udev) {}
|
||||||
static inline void usb_pm_unlock(struct usb_device *udev) {}
|
static inline void usb_pm_unlock(struct usb_device *udev) {}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue