Revert "usb : Add sysfs files to control port power."
This reverts commit ca9c9d0c92
.
Rafael wants more time to work on the user api to handle port power
issues, so let's just revert the sysfs changes for now.
Reported-by: Rafael J. Wysocki <rjw@sisk.pl>
Cc: Lan Tianyu <tianyu.lan@intel.com>
Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
64f0d8cd08
commit
a0693bd0aa
@ -227,27 +227,3 @@ Contact: Lan Tianyu <tianyu.lan@intel.com>
|
|||||||
Description:
|
Description:
|
||||||
The /sys/bus/usb/devices/.../(hub interface)/portX
|
The /sys/bus/usb/devices/.../(hub interface)/portX
|
||||||
is usb port device's sysfs directory.
|
is usb port device's sysfs directory.
|
||||||
|
|
||||||
What: /sys/bus/usb/devices/.../(hub interface)/portX/control
|
|
||||||
Date: August 2012
|
|
||||||
Contact: Lan Tianyu <tianyu.lan@intel.com>
|
|
||||||
Description:
|
|
||||||
The /sys/bus/usb/devices/.../(hub interface)/portX/control
|
|
||||||
attribute allows user space to control the power policy on
|
|
||||||
the usb port.
|
|
||||||
|
|
||||||
All ports have one of the following two values for control
|
|
||||||
"on" - port power must be on.
|
|
||||||
"off" - port power must be off.
|
|
||||||
|
|
||||||
What: /sys/bus/usb/devices/.../(hub interface)/portX/state
|
|
||||||
Date: August 2012
|
|
||||||
Contact: Lan Tianyu <tianyu.lan@intel.com>
|
|
||||||
Description:
|
|
||||||
The /sys/bus/usb/devices/.../(hub interface)/portX/state
|
|
||||||
attribute allows user space to check hub port's power state.
|
|
||||||
|
|
||||||
All ports have three following states
|
|
||||||
"on" - port power on
|
|
||||||
"off" - port power off
|
|
||||||
"error" - can't get the hub port's power state
|
|
||||||
|
@ -39,17 +39,11 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
enum port_power_policy {
|
|
||||||
USB_PORT_POWER_ON = 0,
|
|
||||||
USB_PORT_POWER_OFF,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct usb_port {
|
struct usb_port {
|
||||||
struct usb_device *child;
|
struct usb_device *child;
|
||||||
struct device dev;
|
struct device dev;
|
||||||
struct dev_state *port_owner;
|
struct dev_state *port_owner;
|
||||||
enum usb_port_connect_type connect_type;
|
enum usb_port_connect_type connect_type;
|
||||||
enum port_power_policy port_power_policy;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct usb_hub {
|
struct usb_hub {
|
||||||
@ -99,10 +93,6 @@ struct usb_hub {
|
|||||||
struct usb_port **ports;
|
struct usb_port **ports;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char on_string[] = "on";
|
|
||||||
static const char off_string[] = "off";
|
|
||||||
static const struct attribute_group *port_dev_group[];
|
|
||||||
|
|
||||||
static inline int hub_is_superspeed(struct usb_device *hdev)
|
static inline int hub_is_superspeed(struct usb_device *hdev)
|
||||||
{
|
{
|
||||||
return (hdev->descriptor.bDeviceProtocol == USB_HUB_PR_SS);
|
return (hdev->descriptor.bDeviceProtocol == USB_HUB_PR_SS);
|
||||||
@ -855,12 +845,7 @@ static unsigned hub_power_on(struct usb_hub *hub, bool do_delay)
|
|||||||
dev_dbg(hub->intfdev, "trying to enable port power on "
|
dev_dbg(hub->intfdev, "trying to enable port power on "
|
||||||
"non-switchable hub\n");
|
"non-switchable hub\n");
|
||||||
for (port1 = 1; port1 <= hub->descriptor->bNbrPorts; port1++)
|
for (port1 = 1; port1 <= hub->descriptor->bNbrPorts; port1++)
|
||||||
if (hub->ports[port1 - 1]->port_power_policy
|
set_port_feature(hub->hdev, port1, USB_PORT_FEAT_POWER);
|
||||||
== USB_PORT_POWER_ON)
|
|
||||||
set_port_feature(hub->hdev, port1, USB_PORT_FEAT_POWER);
|
|
||||||
else
|
|
||||||
clear_port_feature(hub->hdev, port1,
|
|
||||||
USB_PORT_FEAT_POWER);
|
|
||||||
|
|
||||||
/* Wait at least 100 msec for power to become stable */
|
/* Wait at least 100 msec for power to become stable */
|
||||||
delay = max(pgood_delay, (unsigned) 100);
|
delay = max(pgood_delay, (unsigned) 100);
|
||||||
@ -1278,7 +1263,6 @@ static int usb_hub_create_port_device(struct usb_hub *hub,
|
|||||||
|
|
||||||
hub->ports[port1 - 1] = port_dev;
|
hub->ports[port1 - 1] = port_dev;
|
||||||
port_dev->dev.parent = hub->intfdev;
|
port_dev->dev.parent = hub->intfdev;
|
||||||
port_dev->dev.groups = port_dev_group;
|
|
||||||
port_dev->dev.type = &usb_port_device_type;
|
port_dev->dev.type = &usb_port_device_type;
|
||||||
dev_set_name(&port_dev->dev, "port%d", port1);
|
dev_set_name(&port_dev->dev, "port%d", port1);
|
||||||
|
|
||||||
@ -2644,25 +2628,6 @@ static int port_is_power_on(struct usb_hub *hub, unsigned portstatus)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int usb_get_hub_port_power_state(struct usb_device *hdev, int port1)
|
|
||||||
{
|
|
||||||
struct usb_hub *hub = hdev_to_hub(hdev);
|
|
||||||
struct usb_port_status data;
|
|
||||||
u16 portstatus;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = get_port_status(hub->hdev, port1, &data);
|
|
||||||
if (ret < 4) {
|
|
||||||
dev_err(hub->intfdev,
|
|
||||||
"%s failed (err = %d)\n", __func__, ret);
|
|
||||||
if (ret >= 0)
|
|
||||||
ret = -EIO;
|
|
||||||
return ret;
|
|
||||||
} else
|
|
||||||
portstatus = le16_to_cpu(data.wPortStatus);
|
|
||||||
return port_is_power_on(hub, portstatus);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
|
|
||||||
/* Check if a port is suspended(USB2.0 port) or in U3 state(USB3.0 port) */
|
/* Check if a port is suspended(USB2.0 port) or in U3 state(USB3.0 port) */
|
||||||
@ -4669,102 +4634,6 @@ static int hub_thread(void *__unused)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t show_port_power_state(struct device *dev,
|
|
||||||
struct device_attribute *attr, char *buf)
|
|
||||||
{
|
|
||||||
struct usb_device *udev = to_usb_device(dev->parent->parent);
|
|
||||||
struct usb_interface *intf = to_usb_interface(dev->parent);
|
|
||||||
int port1, power_state;
|
|
||||||
const char *result;
|
|
||||||
|
|
||||||
sscanf(dev_name(dev), "port%d", &port1);
|
|
||||||
usb_autopm_get_interface(intf);
|
|
||||||
power_state = usb_get_hub_port_power_state(udev, port1);
|
|
||||||
usb_autopm_put_interface(intf);
|
|
||||||
if (power_state == 1)
|
|
||||||
result = on_string;
|
|
||||||
else if (!power_state)
|
|
||||||
result = off_string;
|
|
||||||
else
|
|
||||||
result = "error";
|
|
||||||
return sprintf(buf, "%s\n", result);
|
|
||||||
}
|
|
||||||
static DEVICE_ATTR(state, S_IRUGO, show_port_power_state, NULL);
|
|
||||||
|
|
||||||
static ssize_t show_port_power_control(struct device *dev,
|
|
||||||
struct device_attribute *attr, char *buf)
|
|
||||||
{
|
|
||||||
struct usb_port *hub_port = to_usb_port(dev);
|
|
||||||
const char *result;
|
|
||||||
|
|
||||||
switch (hub_port->port_power_policy) {
|
|
||||||
case USB_PORT_POWER_ON:
|
|
||||||
result = on_string;
|
|
||||||
break;
|
|
||||||
case USB_PORT_POWER_OFF:
|
|
||||||
result = off_string;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
return sprintf(buf, "%s\n", result);
|
|
||||||
}
|
|
||||||
|
|
||||||
static ssize_t store_port_power_control(struct device *dev,
|
|
||||||
struct device_attribute *attr, const char *buf, size_t count)
|
|
||||||
{
|
|
||||||
struct usb_device *hdev = to_usb_device(dev->parent->parent);
|
|
||||||
struct usb_interface *intf = to_usb_interface(dev->parent);
|
|
||||||
struct usb_port *hub_port = to_usb_port(dev);
|
|
||||||
int port1, ret, len = count;
|
|
||||||
char *cp;
|
|
||||||
|
|
||||||
sscanf(dev_name(dev), "port%d", &port1);
|
|
||||||
cp = memchr(buf, '\n', count);
|
|
||||||
if (cp)
|
|
||||||
len = cp - buf;
|
|
||||||
if (len == sizeof(on_string) - 1
|
|
||||||
&& strncmp(buf, on_string, len) == 0) {
|
|
||||||
hub_port->port_power_policy = USB_PORT_POWER_ON;
|
|
||||||
usb_autopm_get_interface(intf);
|
|
||||||
ret = set_port_feature(hdev, port1, USB_PORT_FEAT_POWER);
|
|
||||||
usb_autopm_put_interface(intf);
|
|
||||||
if (ret < 0)
|
|
||||||
return -EIO;
|
|
||||||
} else if (len == sizeof(off_string) - 1
|
|
||||||
&& strncmp(buf, off_string, len) == 0) {
|
|
||||||
struct usb_hub *hub = hdev_to_hub(hdev);
|
|
||||||
|
|
||||||
hub_port->port_power_policy = USB_PORT_POWER_OFF;
|
|
||||||
usb_autopm_get_interface(intf);
|
|
||||||
hub_port_logical_disconnect(hub, port1);
|
|
||||||
ret = clear_port_feature(hdev, port1, USB_PORT_FEAT_POWER);
|
|
||||||
usb_autopm_put_interface(intf);
|
|
||||||
if (ret < 0)
|
|
||||||
return -EIO;
|
|
||||||
} else
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
static DEVICE_ATTR(control, S_IWUSR | S_IRUGO, show_port_power_control,
|
|
||||||
store_port_power_control);
|
|
||||||
|
|
||||||
static struct attribute *port_dev_attrs[] = {
|
|
||||||
&dev_attr_control.attr,
|
|
||||||
&dev_attr_state.attr,
|
|
||||||
NULL,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct attribute_group port_dev_attr_grp = {
|
|
||||||
.attrs = port_dev_attrs,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct attribute_group *port_dev_group[] = {
|
|
||||||
&port_dev_attr_grp,
|
|
||||||
NULL,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct usb_device_id hub_id_table[] = {
|
static const struct usb_device_id hub_id_table[] = {
|
||||||
{ .match_flags = USB_DEVICE_ID_MATCH_DEV_CLASS,
|
{ .match_flags = USB_DEVICE_ID_MATCH_DEV_CLASS,
|
||||||
.bDeviceClass = USB_CLASS_HUB},
|
.bDeviceClass = USB_CLASS_HUB},
|
||||||
|
Loading…
Reference in New Issue
Block a user