On Wed, 8 Jul 2009, Yang Fei-AFY095 wrote: > Hello All, > > I'm trying to understand the debounce introduced in function > hub_activate, in file drivers/usb/core/hub.c. > This used to be a very simple function which doesn't do much except > submitting an URB to query port status and kicking off hub_thread. (in > some early 2.6.27 versions or older) > The function became more complicated in recent releases (such as > 2.6.29), and the most significant change I noticed is the 100ms debounce > for port status change. > > ------ snip ------ > #define HUB_DEBOUNCE_STABLE 100 > ...... > > if (need_debounce_delay) > msleep(HUB_DEBOUNCE_STABLE); > ------ snip ------ > > Here are my questions, You are looking at the wrong code. To answer question 4, you need to look at hub_port_connect_change, not hub_activate. I will answer your other questions anyway... > 1. My understanding is port debounce is done in the hub_thread when > there is a connection change detected. In the run time hub_activate gets > called when there is a remote wakeup or device detach (there are other > cases too, but these are my concern for now). I'm wondering if there is > any USB specification or documentation explains the debounce in function > hub_activate. If not, is this designed to cover certain use cases? I > would like to get some background knowledge about this code. Debouncing is explained in the USB 2.0 spec, section 7.1.7.3 (Figure 7-29) and section 11.8.2. > 2. Why is this HUB_DEBOUNCE_STABLE set to 100? Is it set to cover > certain worst case? Is it possible for this value to be adjusted from > time to time? See Figure 7.29 and Table 7.14 (Tattdb). The value cannot be adjusted. > 3. Is the timing control in this driver mostly considering > transceiver/cable connection case? From USB standard perspective, should > we follow the same timing control for transceiverless case as well? As far as I know, it doesn't matter whether a transceiver is present or not. > 4. To be more specific, please allow me to present an issue I'm dealing > with. In this system, there is an EHCI controller connected to the > device through TLL (12pin ULPI interface). The device could switch mode What do you mean by "switch mode"? > anytime by disconnect and reconnect to the host controller in a very > short time. It used to work with older linux versions before the > debounce was introduced into hub_activate function. However, with recent > releases, the hub_activate function sees portstatus=0x0100 and > portchange=0x0001 which indicates device disconnected, because of this > 100ms debounce and the device switch mode very quickly, by the time > hub_thread is started, the device reconnect already and the portstatus > becomes 0x0501 and portchange=0x0001, the hub_port_connect_change > function returns before even calling usb_disconnect, That is where you should be looking. This sequence of events has nothing to do with hub_activate or debouncing. > thus enumeration > for the second mode doesn't even happen. As I'm not clear about the > reasoning behind this debounce in hub_activate function, I don't know if > this problem should be fixed from the host driver side or the device > side. If this should be fixed on the device side, how do we decide the > interval between disconnect and connect, which is directly related to > the question #2. You seem to think that hub_port_connect_change should always call usb_disconnect. To see why it doesn't, examine the code following the comment /* Try to resuscitate an existing device */ To the hub driver, it looks like the device's connection was momentarily broken and then reestablished. Since the device is unchanged between before and after, there's no need to go through disconnect and reenumeration. If you really want the device to be reenumerated, you have to make it clear that something has changed. For example, changing any part of the device or configuration descriptors would be enough to force reenumeration. Alan Stern -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html