Another point to note, which I think is what prevents the flow Alan suggested from working, is this little snippet in DWC2's hub_control GetPortStatus callback: if (!hsotg->flags.b.port_connect_status) { /* * The port is disconnected, which means the core is * either in device mode or it soon will be. Just * return 0's for the remainder of the port status * since the port register can't be read if the core * is in device mode. */ *(__le32 *)buf = cpu_to_le32(port_status); break; } This is before it actually checks the register state of the port. So it relies on dwc2_hcd_connect() and dwc2_hcd_disconnect() to be called in the right order to give the correct answer for USB_PORT_STAT_CONNECTION. This could maybe be improved but I don't know what kind of weird interactions with device mode operation made that snippet necessary in the first place.