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

Post Reply
theSuess
Posts: 8
Joined: Tue Feb 20, 2024 9:34 am

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

Post by theSuess » Mon Feb 26, 2024 8:27 pm

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

yellows8
Posts: 9
Joined: Wed Jul 02, 2008 5:36 pm
Contact:

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

Post by yellows8 » Tue Feb 27, 2024 7:07 pm

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

theSuess
Posts: 8
Joined: Tue Feb 20, 2024 9:34 am

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

Post by theSuess » Wed Feb 28, 2024 5:30 pm

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

yellows8
Posts: 9
Joined: Wed Jul 02, 2008 5:36 pm
Contact:

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

Post by yellows8 » Wed Feb 28, 2024 7:46 pm

Share your full code? And also the crash-report from sd "/atmosphere/crash_reports/".

theSuess
Posts: 8
Joined: Tue Feb 20, 2024 9:34 am

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

Post by theSuess » Wed Feb 28, 2024 9:51 pm

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

yellows8
Posts: 9
Joined: Wed Jul 02, 2008 5:36 pm
Contact:

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

Post by yellows8 » Wed Feb 28, 2024 10:36 pm

Use id=0 for PostBuffer* since you're only doing a single request at a time.

theSuess
Posts: 8
Joined: Tue Feb 20, 2024 9:34 am

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

Post by theSuess » Wed Feb 28, 2024 11:01 pm

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 :/

yellows8
Posts: 9
Joined: Wed Jul 02, 2008 5:36 pm
Contact:

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

Post by yellows8 » Wed Feb 28, 2024 11:13 pm

Print wMaxPacketSize to make sure your buffer-sizes aren't too large?

theSuess
Posts: 8
Joined: Tue Feb 20, 2024 9:34 am

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

Post by theSuess » Thu Feb 29, 2024 8:20 am

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.

Post Reply

Who is online

Users browsing this forum: No registered users and 23 guests