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;
}