Page 1 of 1

Correct way of handling writes to USB device which awaits response from usbHsEpPostBufferAsync

Posted: Mon Feb 26, 2024 8:27 pm
by theSuess
Continuing my journey to communicate with a serial device over USB, I've managed to establish communications in both directions which is already way more than I expected to ever get running.

The last issue I'm facing happens when posting on the out session after calling usbHsEpPostBufferAsync. If the async call has not yet returned data (because the device does not have anything), the switch crashes with a kernel panic.

A bit more on the flow which triggers my issue:
1. I open the in/out endpoint sessions after discovering the device
2. I write to the out session, signaling the device that I'm ready to receive data
3. I read from the device using the in session until it has no more data to offer (signaled by a timeout)
4. At this point, calling usbHsEpPostBuffer with the out session will trigger a kernel panic

I have tried various combinations of handling this case (using mutexes, closing events in case of timeouts etc.) over the last few days without luck.

Is it possible to signal to the USB service that I want to stop the initial usbHsEpPostBufferAsync after I encounter a timeout?

I'm using this modified version of usbHsEpPostBuffer to implement the timeout logic:

Code: Select all

Result usbHsEpPostBufferWithTimeout(UsbHsClientEpSession *s, void *buffer,
                                    u32 size, u32 *transferredSize,
                                    u64 timeout_ns) {
  Result rc = 0;
  u32 xferId = 0;
  u32 count = 0;
  UsbHsXferReport report;

  rc = usbHsEpPostBufferAsync(s, buffer, size, 0, &xferId);
  if (R_FAILED(rc))
    return rc;
  rc = eventWait(&s->eventXfer, timeout_ns);
  if (rc == 0xea01) {
    // error code for timeout
    return rc;
  }
  if (R_FAILED(rc)) {
    return rc;
  }
  eventClear(&s->eventXfer);

  memset(&report, 0, sizeof(report));
  rc = usbHsEpGetXferReport(s, &report, 1, &count);
  if (R_FAILED(rc))
    return rc;

  if (count < 1)
    return MAKERESULT(Module_Libnx, LibnxError_BadInput);

  *transferredSize = report.transferredSize;
  rc = report.res;

  return rc;
}
My Firmware version is 14.1.2 and the Error code of the panic is 0x4a2 but I'm not sure if that even helps at this point :?

Re: Correct way of handling writes to USB device which awaits response from usbHsEpPostBufferAsync

Posted: Tue Feb 27, 2024 7:07 pm
by yellows8
That's a fatal-error (usb-sysmodule Abort -> creport -> fatal), not kernel-panic.

Why aren't you running latest system-version?(Install latest system update?)

Re: Correct way of handling writes to USB device which awaits response from usbHsEpPostBufferAsync

Posted: Wed Feb 28, 2024 5:30 pm
by theSuess
My sysnand is broken, that's why I was catious to update :lol:

Updated to the latest firmware now and am still encountering the same issue

Re: Correct way of handling writes to USB device which awaits response from usbHsEpPostBufferAsync

Posted: Wed Feb 28, 2024 7:46 pm
by yellows8
Share your full code? And also the crash-report from sd "/atmosphere/crash_reports/".

Re: Correct way of handling writes to USB device which awaits response from usbHsEpPostBufferAsync

Posted: Wed Feb 28, 2024 9:51 pm
by theSuess
The code is still a mess while I'm trying to get it working. The most relevant files would be:

* The main entry point: https://code.kulupu.party/thesuess/m8c/ ... ch_debug.c
* The usb handling code: https://code.kulupu.party/thesuess/m8c/ ... itch_usb.c

switch_debug.c is a debug loop I've written to reproduce this issue. It fetches data from the USB device just like the real code would but just prints it to console instead of rendering it using SDL.

The crash report can be found here: https://code.kulupu.party/thesuess/m8c/ ... shdump.txt

Re: Correct way of handling writes to USB device which awaits response from usbHsEpPostBufferAsync

Posted: Wed Feb 28, 2024 10:36 pm
by yellows8
Use id=0 for PostBuffer* since you're only doing a single request at a time.

Re: Correct way of handling writes to USB device which awaits response from usbHsEpPostBufferAsync

Posted: Wed Feb 28, 2024 11:01 pm
by theSuess
That was the way I initially implemented it. I've added it to see if I maybe need to set different ID's for in/out. Doesn't change anything though :/

Re: Correct way of handling writes to USB device which awaits response from usbHsEpPostBufferAsync

Posted: Wed Feb 28, 2024 11:13 pm
by yellows8
Print wMaxPacketSize to make sure your buffer-sizes aren't too large?

Re: Correct way of handling writes to USB device which awaits response from usbHsEpPostBufferAsync

Posted: Thu Feb 29, 2024 8:20 am
by theSuess
Just tested: wMaxPacketSize is 512 whil I'm sending 1-2 bytes at once so that can't be it.

Transfers before the timeout work. I can send as much as I want without any issues and the device can read it correctly. The writes only fail after reading has timed out.