RE: Regarding hub port debounce

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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...

Alan, hub_activate is called because we suspend the bus for power
management purpose, when device disconnects during the time bus is
suspended, hub_activate gets called first, then hub_thread is kicked off
(at the end of hub_activate) to scan hub ports for connection change,
and hub_port_connect_change gets called by the hub_thread.
Here is the stack dump,
[<c003e0e8>] (dump_stack+0x0/0x14) from [<c02740fc>]
(hub_activate+0x10c/0x2b4)
[<c0273ff0>] (hub_activate+0x0/0x2b4) from [<c0276378>]
(hub_resume+0x18/0x20)
[<c0276360>] (hub_resume+0x0/0x20) from [<c027bbe0>]
(usb_resume_interface+0xf8/0x190)
[<c027bae8>] (usb_resume_interface+0x0/0x190) from [<c027c128>]
(usb_resume_both+0x11c/0x154)
 r5:00000001 r4:cd5da800
[<c027c00c>] (usb_resume_both+0x0/0x154) from [<c027ca50>]
(usb_external_resume_device+0x38/0x78)
 r7:ced4c3c0 r6:cd5da800 r5:cd5daaf0 r4:00000210
[<c027ca18>] (usb_external_resume_device+0x0/0x78) from [<c02777f8>]
(hcd_resume_work+0x34/0x44)
 r7:ced4c3c0 r6:c02777c4 r5:cd5da8e8 r4:cd5da800
[<c02777c4>] (hcd_resume_work+0x0/0x44) from [<c0077ea0>]
(run_workqueue+0xa4/0x120)
 r5:cecde000 r4:ced4c3c0
[<c0077dfc>] (run_workqueue+0x0/0x120) from [<c0078a28>]
(worker_thread+0xf0/0x104)
 r7:ced4c3c0 r6:cecde000 r5:cec67940 r4:cecdffb8
[<c0078938>] (worker_thread+0x0/0x104) from [<c007b838>]
(kthread+0x54/0x80)
 r7:00000000 r6:00000000 r5:c0078938 r4:ced4c3c0
[<c007b7e4>] (kthread+0x0/0x80) from [<c006b5f8>] (do_exit+0x0/0x670)
 r5:00000000 r4:00000000


>> 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"?

I meant the device can re-enumerate with completely different
configurations.
Normally the device would enumerate with one default set of
device/configuration descriptors, but under certain circumstances, the
device could disconnect and try to enumerate with a completely different
set of device/configuration descriptors. 

>> 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.

Agree. But for our case, since the bus is suspend, the issue is really
coming from the debounce in hub_activate as it is the one who wakes up
the hub_thread.

>>  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.

I did not think hub_port_connect_change should always call
usb_disconnect, the issue here is the disconnect event gets filtered out
because of the 100ms debounce in hub_activate, so when hub_thread scan
the ports there doesn't seem to be anything changed.
Anyway I was just trying to get some idea about this 100ms debounce in
hub_activate, to see if we should make change on host side or device
side to resolve our re-enumeration issue. Right now I can resolve it by
having a delay between disconnect and reconnect on the device side.
You mentioned force re-enumeration by changing descriptors, can you
please elaborate on that? When our device disconnect and trying to
re-enumerate, we do have a completely different device descriptor, but
the problem is the host doesn't even start the enumeration process
because disconnect event gets filtered out. It would be really nice if
there is any way to force re-enumeration by simply doing something with
descriptors.


Fei
--
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

[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux