diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 879b66e13370b5fc80fda8709d12dbbb2bd7d788..21b99b4b4082e5563430f464a9f8999bff03b0f4 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1526,18 +1526,6 @@ static int hub_configure(struct usb_hub *hub,
 		dev_dbg(hub_dev, "%umA bus power budget for each child\n",
 				hub->mA_per_port);
 
-	/* Update the HCD's internal representation of this hub before khubd
-	 * starts getting port status changes for devices under the hub.
-	 */
-	if (hcd->driver->update_hub_device) {
-		ret = hcd->driver->update_hub_device(hcd, hdev,
-				&hub->tt, GFP_KERNEL);
-		if (ret < 0) {
-			message = "can't update HCD hub info";
-			goto fail;
-		}
-	}
-
 	ret = hub_hub_status(hub, &hubstatus, &hubchange);
 	if (ret < 0) {
 		message = "can't get hub status";
@@ -1589,10 +1577,28 @@ static int hub_configure(struct usb_hub *hub,
 		}
 	}
 	hdev->maxchild = i;
+	for (i = 0; i < hdev->maxchild; i++) {
+		struct usb_port *port_dev = hub->ports[i];
+
+		pm_runtime_put(&port_dev->dev);
+	}
+
 	mutex_unlock(&usb_port_peer_mutex);
 	if (ret < 0)
 		goto fail;
 
+	/* Update the HCD's internal representation of this hub before khubd
+	 * starts getting port status changes for devices under the hub.
+	 */
+	if (hcd->driver->update_hub_device) {
+		ret = hcd->driver->update_hub_device(hcd, hdev,
+				&hub->tt, GFP_KERNEL);
+		if (ret < 0) {
+			message = "can't update HCD hub info";
+			goto fail;
+		}
+	}
+
 	usb_hub_adjust_deviceremovable(hdev, hub->descriptor);
 
 	hub_activate(hub, HUB_INIT);
@@ -3458,7 +3464,8 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg)
 		struct usb_device *udev = port_dev->child;
 
 		if (udev && udev->can_submit) {
-			dev_warn(&port_dev->dev, "not suspended yet\n");
+			dev_warn(&port_dev->dev, "device %s not suspended yet\n",
+					dev_name(&udev->dev));
 			if (PMSG_IS_AUTO(msg))
 				return -EBUSY;
 		}
diff --git a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h
index 0a7cdc0ef0a9b76913fa98330f363960a217d6ec..326308e53961932e6297d2b9a0007c1ac65f0d3d 100644
--- a/drivers/usb/core/hub.h
+++ b/drivers/usb/core/hub.h
@@ -84,6 +84,7 @@ struct usb_hub {
  * @dev: generic device interface
  * @port_owner: port's owner
  * @peer: related usb2 and usb3 ports (share the same connector)
+ * @req: default pm qos request for hubs without port power control
  * @connect_type: port's connect type
  * @location: opaque representation of platform connector location
  * @status_lock: synchronize port_event() vs usb_port_{suspend|resume}
@@ -95,6 +96,7 @@ struct usb_port {
 	struct device dev;
 	struct usb_dev_state *port_owner;
 	struct usb_port *peer;
+	struct dev_pm_qos_request *req;
 	enum usb_port_connect_type connect_type;
 	usb_port_location_t location;
 	struct mutex status_lock;
diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c
index 62036faf56c00beafc636acbb6509976b7c50f31..fe1b6d0967e32a95e270fcccee8e8b72eb844db3 100644
--- a/drivers/usb/core/port.c
+++ b/drivers/usb/core/port.c
@@ -21,6 +21,8 @@
 
 #include "hub.h"
 
+static int usb_port_block_power_off;
+
 static const struct attribute_group *port_dev_group[];
 
 static ssize_t connect_type_show(struct device *dev,
@@ -66,6 +68,7 @@ static void usb_port_device_release(struct device *dev)
 {
 	struct usb_port *port_dev = to_usb_port(dev);
 
+	kfree(port_dev->req);
 	kfree(port_dev);
 }
 
@@ -142,6 +145,9 @@ static int usb_port_runtime_suspend(struct device *dev)
 			== PM_QOS_FLAGS_ALL)
 		return -EAGAIN;
 
+	if (usb_port_block_power_off)
+		return -EBUSY;
+
 	usb_autopm_get_interface(intf);
 	retval = usb_hub_set_port_power(hdev, hub, port1, false);
 	usb_clear_port_feature(hdev, port1, USB_PORT_FEAT_C_CONNECTION);
@@ -190,11 +196,19 @@ static int link_peers(struct usb_port *left, struct usb_port *right)
 	if (left->peer || right->peer) {
 		struct usb_port *lpeer = left->peer;
 		struct usb_port *rpeer = right->peer;
-
-		WARN(1, "failed to peer %s and %s (%s -> %p) (%s -> %p)\n",
-			dev_name(&left->dev), dev_name(&right->dev),
-			dev_name(&left->dev), lpeer,
-			dev_name(&right->dev), rpeer);
+		char *method;
+
+		if (left->location && left->location == right->location)
+			method = "location";
+		else
+			method = "default";
+
+		pr_warn("usb: failed to peer %s and %s by %s (%s:%s) (%s:%s)\n",
+			dev_name(&left->dev), dev_name(&right->dev), method,
+			dev_name(&left->dev),
+			lpeer ? dev_name(&lpeer->dev) : "none",
+			dev_name(&right->dev),
+			rpeer ? dev_name(&rpeer->dev) : "none");
 		return -EBUSY;
 	}
 
@@ -251,6 +265,7 @@ static void link_peers_report(struct usb_port *left, struct usb_port *right)
 		dev_warn(&left->dev, "failed to peer to %s (%d)\n",
 				dev_name(&right->dev), rc);
 		pr_warn_once("usb: port power management may be unreliable\n");
+		usb_port_block_power_off = 1;
 	}
 }
 
@@ -386,9 +401,13 @@ int usb_hub_create_port_device(struct usb_hub *hub, int port1)
 	int retval;
 
 	port_dev = kzalloc(sizeof(*port_dev), GFP_KERNEL);
-	if (!port_dev) {
-		retval = -ENOMEM;
-		goto exit;
+	if (!port_dev)
+		return -ENOMEM;
+
+	port_dev->req = kzalloc(sizeof(*(port_dev->req)), GFP_KERNEL);
+	if (!port_dev->req) {
+		kfree(port_dev);
+		return -ENOMEM;
 	}
 
 	hub->ports[port1 - 1] = port_dev;
@@ -404,31 +423,53 @@ int usb_hub_create_port_device(struct usb_hub *hub, int port1)
 			port1);
 	mutex_init(&port_dev->status_lock);
 	retval = device_register(&port_dev->dev);
-	if (retval)
-		goto error_register;
+	if (retval) {
+		put_device(&port_dev->dev);
+		return retval;
+	}
+
+	/* Set default policy of port-poweroff disabled. */
+	retval = dev_pm_qos_add_request(&port_dev->dev, port_dev->req,
+			DEV_PM_QOS_FLAGS, PM_QOS_FLAG_NO_POWER_OFF);
+	if (retval < 0) {
+		device_unregister(&port_dev->dev);
+		return retval;
+	}
 
 	find_and_link_peer(hub, port1);
 
+	/*
+	 * Enable runtime pm and hold a refernce that hub_configure()
+	 * will drop once the PM_QOS_NO_POWER_OFF flag state has been set
+	 * and the hub has been fully registered (hdev->maxchild set).
+	 */
 	pm_runtime_set_active(&port_dev->dev);
+	pm_runtime_get_noresume(&port_dev->dev);
+	pm_runtime_enable(&port_dev->dev);
+	device_enable_async_suspend(&port_dev->dev);
 
 	/*
-	 * Do not enable port runtime pm if the hub does not support
-	 * power switching.  Also, userspace must have final say of
-	 * whether a port is permitted to power-off.  Do not enable
-	 * runtime pm if we fail to expose pm_qos_no_power_off.
+	 * Keep hidden the ability to enable port-poweroff if the hub
+	 * does not support power switching.
 	 */
-	if (hub_is_port_power_switchable(hub)
-			&& dev_pm_qos_expose_flags(&port_dev->dev,
-			PM_QOS_FLAG_NO_POWER_OFF) == 0)
-		pm_runtime_enable(&port_dev->dev);
+	if (!hub_is_port_power_switchable(hub))
+		return 0;
 
-	device_enable_async_suspend(&port_dev->dev);
-	return 0;
+	/* Attempt to let userspace take over the policy. */
+	retval = dev_pm_qos_expose_flags(&port_dev->dev,
+			PM_QOS_FLAG_NO_POWER_OFF);
+	if (retval < 0) {
+		dev_warn(&port_dev->dev, "failed to expose pm_qos_no_poweroff\n");
+		return 0;
+	}
 
-error_register:
-	put_device(&port_dev->dev);
-exit:
-	return retval;
+	/* Userspace owns the policy, drop the kernel 'no_poweroff' request. */
+	retval = dev_pm_qos_remove_request(port_dev->req);
+	if (retval >= 0) {
+		kfree(port_dev->req);
+		port_dev->req = NULL;
+	}
+	return 0;
 }
 
 void usb_hub_remove_port_device(struct usb_hub *hub, int port1)
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c
index 4a6d3dd68572b82127b40794aa86b9fa4243e6f7..2f3acebb577ae749aa6c8c23b0e592076b296e6c 100644
--- a/drivers/usb/host/pci-quirks.c
+++ b/drivers/usb/host/pci-quirks.c
@@ -656,6 +656,14 @@ static const struct dmi_system_id ehci_dmi_nohandoff_table[] = {
 			DMI_MATCH(DMI_BIOS_VERSION, "Lucid-"),
 		},
 	},
+	{
+		/* HASEE E200 */
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "HASEE"),
+			DMI_MATCH(DMI_BOARD_NAME, "E210"),
+			DMI_MATCH(DMI_BIOS_VERSION, "6.00"),
+		},
+	},
 	{ }
 };
 
@@ -665,9 +673,14 @@ static void ehci_bios_handoff(struct pci_dev *pdev,
 {
 	int try_handoff = 1, tried_handoff = 0;
 
-	/* The Pegatron Lucid tablet sporadically waits for 98 seconds trying
-	 * the handoff on its unused controller.  Skip it. */
-	if (pdev->vendor == 0x8086 && pdev->device == 0x283a) {
+	/*
+	 * The Pegatron Lucid tablet sporadically waits for 98 seconds trying
+	 * the handoff on its unused controller.  Skip it.
+	 *
+	 * The HASEE E200 hangs when the semaphore is set (bugzilla #77021).
+	 */
+	if (pdev->vendor == 0x8086 && (pdev->device == 0x283a ||
+			pdev->device == 0x27cc)) {
 		if (dmi_check_system(ehci_dmi_nohandoff_table))
 			try_handoff = 0;
 	}
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index 6231ce6aa0c3b05cc41ad714170bb0319aec1a5a..2b998c60faf23089f496c24ccb4355e711337539 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -287,7 +287,7 @@ static int xhci_stop_device(struct xhci_hcd *xhci, int slot_id, int suspend)
 		if (virt_dev->eps[i].ring && virt_dev->eps[i].ring->dequeue) {
 			struct xhci_command *command;
 			command = xhci_alloc_command(xhci, false, false,
-						     GFP_NOIO);
+						     GFP_NOWAIT);
 			if (!command) {
 				spin_unlock_irqrestore(&xhci->lock, flags);
 				xhci_free_command(xhci, cmd);
diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
index 51a6da256772a89fcf56b56e0d42c1adcebbfe99..829f446064ea405d032acf8cb082b07ddeed6dea 100644
--- a/drivers/usb/misc/usbtest.c
+++ b/drivers/usb/misc/usbtest.c
@@ -7,7 +7,7 @@
 #include <linux/moduleparam.h>
 #include <linux/scatterlist.h>
 #include <linux/mutex.h>
-
+#include <linux/timer.h>
 #include <linux/usb.h>
 
 #define SIMPLE_IO_TIMEOUT	10000	/* in milliseconds */
@@ -484,6 +484,14 @@ alloc_sglist(int nents, int max, int vary)
 	return sg;
 }
 
+static void sg_timeout(unsigned long _req)
+{
+	struct usb_sg_request	*req = (struct usb_sg_request *) _req;
+
+	req->status = -ETIMEDOUT;
+	usb_sg_cancel(req);
+}
+
 static int perform_sglist(
 	struct usbtest_dev	*tdev,
 	unsigned		iterations,
@@ -495,6 +503,9 @@ static int perform_sglist(
 {
 	struct usb_device	*udev = testdev_to_usbdev(tdev);
 	int			retval = 0;
+	struct timer_list	sg_timer;
+
+	setup_timer_on_stack(&sg_timer, sg_timeout, (unsigned long) req);
 
 	while (retval == 0 && iterations-- > 0) {
 		retval = usb_sg_init(req, udev, pipe,
@@ -505,7 +516,10 @@ static int perform_sglist(
 
 		if (retval)
 			break;
+		mod_timer(&sg_timer, jiffies +
+				msecs_to_jiffies(SIMPLE_IO_TIMEOUT));
 		usb_sg_wait(req);
+		del_timer_sync(&sg_timer);
 		retval = req->status;
 
 		/* FIXME check resulting data pattern */