struct usb_device_driver        *udriver;
        int                             status = 0;
 
+       if (udev->state == USB_STATE_NOTATTACHED ||
+                       udev->state == USB_STATE_SUSPENDED)
+               goto done;
+
        if (udev->dev.driver == NULL)
                goto done;
        udriver = to_usb_device_driver(udev->dev.driver);
-       if (udev->dev.power.power_state.event == msg.event)
-               goto done;
        status = udriver->suspend(udev, msg);
 
 done:
        struct usb_device_driver        *udriver;
        int                             status = 0;
 
-       if (udev->dev.power.power_state.event == PM_EVENT_ON)
+       if (udev->state == USB_STATE_NOTATTACHED ||
+                       udev->state != USB_STATE_SUSPENDED)
                goto done;
 
        if (udev->dev.driver == NULL)
                goto done;
        udriver = to_usb_device_driver(udev->dev.driver);
-       if (udev->state == USB_STATE_NOTATTACHED)
-               goto done;
        status = udriver->resume(udev);
 
 done:
        struct usb_driver       *driver;
        int                     status = 0;
 
-       if (intf->dev.driver == NULL)
+       /* with no hardware, USB interfaces only use FREEZE and ON states */
+       if (interface_to_usbdev(intf)->state == USB_STATE_NOTATTACHED ||
+                       !is_active(intf))
                goto done;
 
-       driver = to_usb_driver(intf->dev.driver);
-
-       /* with no hardware, USB interfaces only use FREEZE and ON states */
-       if (!is_active(intf))
+       if (intf->dev.driver == NULL)
                goto done;
+       driver = to_usb_driver(intf->dev.driver);
 
        if (driver->suspend && driver->resume) {
                status = driver->suspend(intf, msg);
 static int resume_interface(struct usb_interface *intf)
 {
        struct usb_driver       *driver;
-       struct usb_device       *udev;
        int                     status = 0;
 
-       if (intf->dev.power.power_state.event == PM_EVENT_ON)
+       if (interface_to_usbdev(intf)->state == USB_STATE_NOTATTACHED ||
+                       is_active(intf))
                goto done;
 
        if (intf->dev.driver == NULL)
                goto done;
-
        driver = to_usb_driver(intf->dev.driver);
 
-       udev = interface_to_usbdev(intf);
-       if (udev->state == USB_STATE_NOTATTACHED)
-               goto done;
-
-       /* if driver was suspended, it has a resume method;
-        * however, sysfs can wrongly mark things as suspended
-        * (on the "no suspend method" FIXME path above)
-        */
        if (driver->resume) {
                status = driver->resume(intf);
                if (status)
        int                     i;
        struct usb_interface    *intf;
 
+       /* Can't resume if the parent is suspended */
+       if (udev->parent && udev->parent->state == USB_STATE_SUSPENDED) {
+               dev_warn(&udev->dev, "can't resume; parent is suspended\n");
+               return -EHOSTUNREACH;
+       }
+
        status = resume_device(udev);
        if (status == 0 && udev->actconfig) {
                for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) {
 
        if (port1 < 0)
                return port1;
 
-       if (udev->state == USB_STATE_SUSPENDED
-                       || udev->state == USB_STATE_NOTATTACHED) {
-               return 0;
-       }
-
-       /* all interfaces must already be suspended */
-       if (udev->actconfig) {
-               int     i;
-
-               for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) {
-                       struct usb_interface    *intf;
-
-                       intf = udev->actconfig->interface[i];
-                       if (is_active(intf)) {
-                               dev_dbg(&intf->dev, "nyet suspended\n");
-                               return -EBUSY;
-                       }
-               }
-       }
-
        /* we change the device's upstream USB link,
         * but root hubs have no upstream USB link.
         */
 int usb_port_suspend(struct usb_device *udev)
 {
 #ifdef CONFIG_USB_SUSPEND
-       if (udev->state == USB_STATE_NOTATTACHED)
-               return -ENODEV;
        return __usb_port_suspend(udev, udev->portnum);
 #else
        return 0;
  */
 int usb_port_resume(struct usb_device *udev)
 {
-       int     status;
-
-       if (udev->state == USB_STATE_NOTATTACHED)
-               return -ENODEV;
+       int     status = 0;
 
        /* we change the device's upstream USB link,
         * but root hubs have no upstream USB link.
         */
        if (udev->parent) {
 #ifdef CONFIG_USB_SUSPEND
-               if (udev->state == USB_STATE_SUSPENDED) {
-                       // NOTE swsusp may bork us, device state being wrong...
-                       // NOTE this fails if parent is also suspended...
-                       status = hub_port_resume(hdev_to_hub(udev->parent),
-                                       udev->portnum, udev);
-               } else
+               // NOTE this fails if parent is also suspended...
+               status = hub_port_resume(hdev_to_hub(udev->parent),
+                               udev->portnum, udev);
 #endif
-                       status = 0;
        } else
                status = finish_port_resume(udev);
        if (status < 0)
                struct usb_device       *udev;
 
                udev = hdev->children [port1-1];
-               if (udev && (udev->dev.power.power_state.event
-                                       == PM_EVENT_ON
+               if (udev && msg.event == PM_EVENT_SUSPEND &&
 #ifdef CONFIG_USB_SUSPEND
-                               || udev->state != USB_STATE_SUSPENDED
+                               udev->state != USB_STATE_SUSPENDED
+#else
+                               udev->dev.power.power_state.event
+                                       == PM_EVENT_ON
 #endif
-                               )) {
+                               ) {
                        dev_dbg(&intf->dev, "port %d nyet suspended\n", port1);
                        return -EBUSY;
                }