aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/core/hub.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/core/hub.c')
-rw-r--r--drivers/usb/core/hub.c59
1 files changed, 29 insertions, 30 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 1fa5c0f29c64..a56c75e09786 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -103,8 +103,7 @@ EXPORT_SYMBOL_GPL(ehci_cf_port_reset_rwsem);
103 103
104static void hub_release(struct kref *kref); 104static void hub_release(struct kref *kref);
105static int usb_reset_and_verify_device(struct usb_device *udev); 105static int usb_reset_and_verify_device(struct usb_device *udev);
106static void hub_usb3_port_prepare_disable(struct usb_hub *hub, 106static int hub_port_disable(struct usb_hub *hub, int port1, int set_state);
107 struct usb_port *port_dev);
108 107
109static inline char *portspeed(struct usb_hub *hub, int portstatus) 108static inline char *portspeed(struct usb_hub *hub, int portstatus)
110{ 109{
@@ -903,34 +902,6 @@ static int hub_set_port_link_state(struct usb_hub *hub, int port1,
903} 902}
904 903
905/* 904/*
906 * USB-3 does not have a similar link state as USB-2 that will avoid negotiating
907 * a connection with a plugged-in cable but will signal the host when the cable
908 * is unplugged. Disable remote wake and set link state to U3 for USB-3 devices
909 */
910static int hub_port_disable(struct usb_hub *hub, int port1, int set_state)
911{
912 struct usb_port *port_dev = hub->ports[port1 - 1];
913 struct usb_device *hdev = hub->hdev;
914 int ret = 0;
915
916 if (!hub->error) {
917 if (hub_is_superspeed(hub->hdev)) {
918 hub_usb3_port_prepare_disable(hub, port_dev);
919 ret = hub_set_port_link_state(hub, port_dev->portnum,
920 USB_SS_PORT_LS_U3);
921 } else {
922 ret = usb_clear_port_feature(hdev, port1,
923 USB_PORT_FEAT_ENABLE);
924 }
925 }
926 if (port_dev->child && set_state)
927 usb_set_device_state(port_dev->child, USB_STATE_NOTATTACHED);
928 if (ret && ret != -ENODEV)
929 dev_err(&port_dev->dev, "cannot disable (err = %d)\n", ret);
930 return ret;
931}
932
933/*
934 * Disable a port and mark a logical connect-change event, so that some 905 * Disable a port and mark a logical connect-change event, so that some
935 * time later hub_wq will disconnect() any existing usb_device on the port 906 * time later hub_wq will disconnect() any existing usb_device on the port
936 * and will re-enumerate if there actually is a device attached. 907 * and will re-enumerate if there actually is a device attached.
@@ -4162,6 +4133,34 @@ static int hub_handle_remote_wakeup(struct usb_hub *hub, unsigned int port,
4162 4133
4163#endif /* CONFIG_PM */ 4134#endif /* CONFIG_PM */
4164 4135
4136/*
4137 * USB-3 does not have a similar link state as USB-2 that will avoid negotiating
4138 * a connection with a plugged-in cable but will signal the host when the cable
4139 * is unplugged. Disable remote wake and set link state to U3 for USB-3 devices
4140 */
4141static int hub_port_disable(struct usb_hub *hub, int port1, int set_state)
4142{
4143 struct usb_port *port_dev = hub->ports[port1 - 1];
4144 struct usb_device *hdev = hub->hdev;
4145 int ret = 0;
4146
4147 if (!hub->error) {
4148 if (hub_is_superspeed(hub->hdev)) {
4149 hub_usb3_port_prepare_disable(hub, port_dev);
4150 ret = hub_set_port_link_state(hub, port_dev->portnum,
4151 USB_SS_PORT_LS_U3);
4152 } else {
4153 ret = usb_clear_port_feature(hdev, port1,
4154 USB_PORT_FEAT_ENABLE);
4155 }
4156 }
4157 if (port_dev->child && set_state)
4158 usb_set_device_state(port_dev->child, USB_STATE_NOTATTACHED);
4159 if (ret && ret != -ENODEV)
4160 dev_err(&port_dev->dev, "cannot disable (err = %d)\n", ret);
4161 return ret;
4162}
4163
4165 4164
4166/* USB 2.0 spec, 7.1.7.3 / fig 7-29: 4165/* USB 2.0 spec, 7.1.7.3 / fig 7-29:
4167 * 4166 *