ChangeSet 1.2020.1.25, 2005/03/07 22:35:24-08:00, [EMAIL PROTECTED]

[PATCH] USB: Initialize connected ports on newly-activated hubs

This patch changes the mechanism used for detecting devices that were
already connected to a hub at the time the hub was activated.  This can
occur in several different circumstances:

        when the hub is configured for the first time,

        when the hub is reset following a malfunction,

        when the hub is resumed.

The patch mainly addresses the third possibility, although it also handles
the other two.  The scenario I have in mind is waking up from a system
suspend, where the user has plugged in a new USB device while the system
was asleep, and for some reason the hub no longer has a record of the
connect change on that port.  (Maybe the BIOS or the boot kernel has
interfered.)  At any rate, the patch causes the hub driver to scan all
ports in the reactivated hub, and if it finds a connected port with no
child device already allocated then it pretends there was a connect-change
event on that port.

This will serve to take care of ports with new devices attached that the
driver doesn't know about.  The existing resume code already handles the
case of ports that used to have a device but don't any longer.  The
remaining case, where different devices are attached to the port before
suspending and after resuming, still needs to be handled.  The resume code
should call the same "descriptors changed" check used by usb_reset_device.
That's a patch for another day.


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


 drivers/usb/core/hub.c |   12 +++++++++---
 drivers/usb/core/hub.h |    1 +
 2 files changed, 10 insertions(+), 3 deletions(-)


diff -Nru a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
--- a/drivers/usb/core/hub.c    2005-03-08 16:54:07 -08:00
+++ b/drivers/usb/core/hub.c    2005-03-08 16:54:07 -08:00
@@ -459,6 +459,7 @@
        int     status;
 
        hub->quiescing = 0;
+       hub->activating = 1;
        status = usb_submit_urb(hub->urb, GFP_NOIO);
        if (status < 0)
                dev_err(hub->intfdev, "activate --> %d\n", status);
@@ -466,7 +467,6 @@
                schedule_delayed_work(&hub->leds, LED_CYCLE_PERIOD);
 
        /* scan all ports ASAP */
-       hub->event_bits[0] = (1UL << (hub->descriptor->bNbrPorts + 1)) - 1;
        kick_khubd(hub);
 }
 
@@ -689,7 +689,6 @@
                hub->indicator [0] = INDICATOR_CYCLE;
 
        hub_power_on(hub);
-       hub->change_bits[0] = (1UL << (hub->descriptor->bNbrPorts + 1)) - 2;
        hub_activate(hub);
        return 0;
 
@@ -2638,7 +2637,7 @@
                for (i = 1; i <= hub->descriptor->bNbrPorts; i++) {
                        connect_change = test_bit(i, hub->change_bits);
                        if (!test_and_clear_bit(i, hub->event_bits) &&
-                                       !connect_change)
+                                       !connect_change && !hub->activating)
                                continue;
 
                        ret = hub_port_status(hub, i,
@@ -2646,6 +2645,11 @@
                        if (ret < 0)
                                continue;
 
+                       if (hub->activating && !hdev->children[i-1] &&
+                                       (portstatus &
+                                               USB_PORT_STAT_CONNECTION))
+                               connect_change = 1;
+
                        if (portchange & USB_PORT_STAT_C_CONNECTION) {
                                clear_port_feature(hdev, i,
                                        USB_PORT_FEAT_C_CONNECTION);
@@ -2735,6 +2739,8 @@
                                hub_power_on(hub);
                        }
                }
+
+               hub->activating = 0;
 
 loop:
                usb_unlock_device(hdev);
diff -Nru a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h
--- a/drivers/usb/core/hub.h    2005-03-08 16:54:07 -08:00
+++ b/drivers/usb/core/hub.h    2005-03-08 16:54:07 -08:00
@@ -215,6 +215,7 @@
        u8                      power_budget;   /* in 2mA units; or zero */
 
        unsigned                quiescing:1;
+       unsigned                activating:1;
 
        unsigned                has_indicators:1;
        enum hub_led_mode       indicator[USB_MAXCHILDREN];



-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_ide95&alloc_id396&op=click
_______________________________________________
[email protected]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to