Greg:

We don't want khubd to start interfering in the device-resume process
merely because the PORT_STATUS_C_SUSPEND feature happens to be set.
Ports need to be marked as busy while a resume is taking place.

In addition, so long as ports are marked as busy, khubd won't be able
to clear their various status-change features.  On an interrupt-driven
root hub this could lead to an interrupt storm.  Root hub IRQs should
not be re-enabled until the busy_bits value is equal to 0.

This patch (as765) fixes these two potential problems.

Alan Stern



Signed-off-by: Alan Stern <[EMAIL PROTECTED]>

---

Index: usb-2.6/drivers/usb/core/hub.c
===================================================================
--- usb-2.6.orig/drivers/usb/core/hub.c
+++ usb-2.6/drivers/usb/core/hub.c
@@ -1668,6 +1668,8 @@ hub_port_resume(struct usb_hub *hub, int
 
        // dev_dbg(hub->intfdev, "resume port %d\n", port1);
 
+       set_bit(port1, hub->busy_bits);
+
        /* see 7.1.7.7; affects power usage, but not budgeting */
        status = clear_port_feature(hub->hdev,
                        port1, USB_PORT_FEAT_SUSPEND);
@@ -1717,6 +1719,10 @@ hub_port_resume(struct usb_hub *hub, int
        if (status < 0)
                hub_port_logical_disconnect(hub, port1);
 
+       clear_bit(port1, hub->busy_bits);
+       if (!hub->hdev->parent && !hub->busy_bits[0])
+               usb_enable_root_hub_irq(hub->hdev->bus);
+
        return status;
 }
 
@@ -2700,7 +2706,7 @@ static void hub_events(void)
 
                /* If this is a root hub, tell the HCD it's okay to
                 * re-enable port-change interrupts now. */
-               if (!hdev->parent)
+               if (!hdev->parent && !hub->busy_bits[0])
                        usb_enable_root_hub_irq(hdev->bus);
 
 loop:
@@ -2875,6 +2881,9 @@ int usb_reset_device(struct usb_device *
                        break;
        }
        clear_bit(port1, parent_hub->busy_bits);
+       if (!parent_hdev->parent && !parent_hub->busy_bits[0])
+               usb_enable_root_hub_irq(parent_hdev->bus);
+
        if (ret < 0)
                goto re_enumerate;
  
Index: usb-2.6/drivers/usb/core/hub.h
===================================================================
--- usb-2.6.orig/drivers/usb/core/hub.h
+++ usb-2.6/drivers/usb/core/hub.h
@@ -212,7 +212,8 @@ struct usb_hub {
        unsigned long           event_bits[1];  /* status change bitmask */
        unsigned long           change_bits[1]; /* ports with logical connect
                                                        status change */
-       unsigned long           busy_bits[1];   /* ports being reset */
+       unsigned long           busy_bits[1];   /* ports being reset or
+                                                       resumed */
 #if USB_MAXCHILDREN > 31 /* 8*sizeof(unsigned long) - 1 */
 #error event_bits[] is too short!
 #endif


-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
[email protected]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to