hathach / tinyusb

An open source cross-platform USB stack for embedded system
https://www.tinyusb.org
MIT License
5.02k stars 1.05k forks source link

TinyUSB with cdc_msc causes macbook pro to not wake from sleep #241

Closed jeremyherbert closed 4 years ago

jeremyherbert commented 4 years ago

While trying to investigate #179 further, I have discovered that a certain combination of devices causes my laptop to never wake from sleep. As soon as I unplug the tinyUSB device, the wakeup works fine.

Set up:

To Reproduce I have a MBP (16" late 2019) connected to a thunderbolt 3 dock (Caldigit TS3 Plus). I then have a Orico 10 port USB3 hub (A3H10, VL812 chipset I believe) connected to the dock and the tinyUSB device is plugged into the hub via a USB analyser.

On a separate PC I have a Beagle 480 analyser (which is inline with the tinyUSB device) and an ST-Link which is connected to the STM32F042 via SWD. This PC also has a USB to serial converter which I have connected to the STM32F042 and enabled level 2 debugging.

To trigger the problem, I put the laptop to sleep, wait a minute or two for it to actually go to sleep, and then try to wake it (pressing keys on the keyboard, etc). Laptop is totally unresponsive until I unplug the tinyUSB device, after which everything goes back to normal.

Expected behavior The MBP should be able to wake up.

Additional context The log output roughly shows this (note that I have commented out the SETUP_RECEIVED dump as it was taking too long to print)

USBD: event SUSPEND
USBD: event RESUME
USBD: event SETUP_RECEIVED
    Get Status
process_control_request 620: assert failed
                                            Stall EP0
USBD: event BUS_RESET
USBD: event SETUP_RECEIVED
    Set Address
USBD: event XFER_COMPLETE
  Endpoint: 0x80, Bytes: 0
  EP Addr = 0x80, len = 0
USBD: event SETUP_RECEIVED
    Get Descriptor
...

full log is here: https://gist.github.com/jeremyherbert/adf841bfdad76d621fea0cdd7e43ce20

tannewt commented 4 years ago

I saw an issue where CircuitPython (which uses TinyUSB) would actually crash Catalina due to a timeout trying to set the SCSI power state. To fix it I had to make sure and respond to a start command with an error. This is done in a callback so I didn't actually need to change TinyUSB. The fix for CircuitPython is here: https://github.com/adafruit/circuitpython/pull/2406/files#diff-880d63a1c107dd299a7ed80251505a9eL200

It was looping between "TEST UNIT READY" which returned false, "REQUEST SENSE" which gave an unknown issue and "START/STOP" with the start bit set which TinyUSB responded that it was ok.

jeremyherbert commented 4 years ago

Thanks @tannewt I do see a SUSPEND timeout in my beagle log and then an immediate RESUME, but the SCSI Start/Stop appears to be fine. Is this what you were referring to? I don't have any TEST_UNIT_READY commands.

Looking closer at the capture, it seems there is a control transfer stall which appears to correspond to the assertion error, and it's during a write to endpoint 0. I'm assuming this is a problem, because endpoint 0 should always be available?

control-stall

Shortly after this, the bus is reset, and then enumeration completes, at which point the device is blasted with about 15k OUT requests per second, all of which are NAKed. It seems likely at this point that these NAKs are why the OS is unable to wake.

out-packets

tannewt commented 4 years ago

That looks like a different scenario than what I saw. Perhaps it is related to https://github.com/hathach/tinyusb/pull/244 instead?

hathach commented 4 years ago

it could be the same issue as #213 as well, dcd_fsdev driver somehow skip a setup packet. When in low power mode, it may prevent host to function properly.

jeremyherbert commented 4 years ago

This should be fixed now :)