Index: 2.6.24/drivers/usb/core/hub.c
===================================================================
--- 2.6.24.orig/drivers/usb/core/hub.c
+++ 2.6.24/drivers/usb/core/hub.c
@@ -1987,51 +1987,76 @@ static int hub_suspend(struct usb_interf
 	return 0;
 }

-static int hub_resume(struct usb_interface *intf)
-{
-	struct usb_hub		*hub = usb_get_intfdata (intf);
-
-	dev_dbg(&intf->dev, "%s\n", __FUNCTION__);
-
-	/* tell khubd to look for changes on this hub */
-	hub_activate(hub);
-	return 0;
-}
-
-static int hub_reset_resume(struct usb_interface *intf)
+static void hub_resume_common(struct usb_hub *hub, bool reset_resume)
 {
-	struct usb_hub *hub = usb_get_intfdata(intf);
 	struct usb_device *hdev = hub->hdev;
 	int port1;

-	hub_power_on(hub);
-
+	/* Check each of the children to see if they require
+	 * USB_PERSIST handling or disconnection.
+	 */
 	for (port1 = 1; port1 <= hdev->maxchild; ++port1) {
-		struct usb_device *child = hdev->children[port1-1];
+		struct usb_device *udev = hdev->children[port1-1];
+		int status;
+		u16 portstatus, portchange;
+
+		if (!udev)
+			continue;

-		if (child) {
+		/* Was the power session lost while we were suspended? */
+		if (reset_resume) {
+			status = 0;
+			portstatus = 0;
+			portchange = USB_PORT_STAT_C_CONNECTION;
+		} else {
+			status = hub_port_status(hub, port1,
+					&portstatus, &portchange);
+		}

-			/* For "USB_PERSIST"-enabled children we must
-			 * mark the child device for reset-resume and
-			 * turn off the connect-change status to prevent
-			 * khubd from disconnecting it later.
-			 */
-			if (USB_PERSIST && child->persist_enabled) {
-				child->reset_resume = 1;
-				clear_port_feature(hdev, port1,
+		/* For "USB_PERSIST"-enabled children we must
+		 * mark the child device for reset-resume and
+		 * turn off the various status changes to prevent
+		 * khubd from disconnecting it later.
+		 */
+		if (USB_PERSIST && udev->persist_enabled && status == 0 &&
+				!(portstatus & USB_PORT_STAT_ENABLE)) {
+			if (portchange & USB_PORT_STAT_C_ENABLE)
+				clear_port_feature(hub->hdev, port1,
+						USB_PORT_FEAT_C_ENABLE);
+			if (portchange & USB_PORT_STAT_C_CONNECTION)
+				clear_port_feature(hub->hdev, port1,
 						USB_PORT_FEAT_C_CONNECTION);
+			udev->reset_resume = 1;
+		}

-			/* Otherwise we must disconnect the child,
-			 * but as we may not lock the child device here
-			 * we have to do a "logical" disconnect.
-			 */
-			} else {
-				hub_port_logical_disconnect(hub, port1);
-			}
+		/* Otherwise for a reset_resume we must disconnect the child,
+		 * but as we may not lock the child device here
+		 * we have to do a "logical" disconnect.
+		 */
+		else if (reset_resume) {
+			hub_port_logical_disconnect(hub, port1);
 		}
 	}

 	hub_activate(hub);
+}
+
+static int hub_resume(struct usb_interface *intf)
+{
+	struct usb_hub *hub = usb_get_intfdata(intf);
+
+	dev_dbg(&intf->dev, "%s\n", __func__);
+	hub_resume_common(hub, false);
+	return 0;
+}
+
+static int hub_reset_resume(struct usb_interface *intf)
+{
+	struct usb_hub *hub = usb_get_intfdata(intf);
+
+	dev_dbg(&intf->dev, "%s\n", __func__);
+	hub_power_on(hub);
+	hub_resume_common(hub, true);
 	return 0;
 }


