On Wed, 8 Jul 2009, Yang Fei-AFY095 wrote: > 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. Yes, okay. > >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. I see. > >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. No, you are wrong. The issue really is coming from hub_port_connect_change. > 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. That isn't true. There is a visible change because hub_thread sees portchange=0x0001. Otherwise it wouldn't call hub_port_connect_change at all. > 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. No, the disconnect doesn't get filtered out. The problem is something else: The device starts out suspended, and it remains that way. When a program tries to access the device, it will be resumed and then reenumerated. But this isn't what you want; you want it to be resumed and reenumerated immediately. The patch below should fix the issue. Alan Stern 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 @@ -2932,14 +2932,7 @@ static void hub_port_connect_change(stru /* For a suspended device, treat this as a * remote wakeup event. */ - if (udev->do_remote_wakeup) - status = remote_wakeup(udev); - - /* Otherwise leave it be; devices can't tell the - * difference between suspended and disabled. - */ - else - status = 0; + status = remote_wakeup(udev); #endif } else { -- 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