Correct way of handling writes to USB device which awaits response from usbHsEpPostBufferAsync
Posted: 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:
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
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;
}