usb_rndis: fix handling of canceled transfers

When the transfer is canceled, there is no new data received. So we
should stop the processing and inform the network stack that the
transfer is canceled.

Change-Id: I5c991899292b84e6d9bc589348a5ab32384ea09a
Reviewed-on: https://review.haiku-os.org/c/haiku/+/8577
Haiku-Format: Haiku-format Bot <no-reply+haikuformatbot@haiku-os.org>
Reviewed-by: waddlesplash <waddlesplash@gmail.com>
This commit is contained in:
PulkoMandy 2024-11-17 11:08:57 +01:00 committed by waddlesplash
parent 9548274ed5
commit f0427429e2

View File

@ -273,10 +273,20 @@ RNDISDevice::Read(uint8 *buffer, size_t *numBytes)
return result; return result;
} }
if (fStatusRead != B_OK && fStatusRead != B_CANCELED && !fRemoved) { if (fStatusRead == B_CANCELED) {
// The transfer was canceled, so no data was actually received.
*numBytes = 0;
return fStatusRead;
}
if ((fStatusRead != B_OK) && !fRemoved) {
// In other error cases (triggered by the device), we need to clear the "halt" feature
// so that the next transfers will work.
TRACE_ALWAYS("device status error 0x%08" B_PRIx32 "\n", fStatusRead); TRACE_ALWAYS("device status error 0x%08" B_PRIx32 "\n", fStatusRead);
result = gUSBModule->clear_feature(fReadEndpoint,
USB_FEATURE_ENDPOINT_HALT); gUSBModule->cancel_queued_transfers(fReadEndpoint);
result = gUSBModule->clear_feature(fReadEndpoint, USB_FEATURE_ENDPOINT_HALT);
if (result != B_OK) { if (result != B_OK) {
TRACE_ALWAYS("failed to clear halt state on read\n"); TRACE_ALWAYS("failed to clear halt state on read\n");
*numBytes = 0; *numBytes = 0;
@ -401,10 +411,18 @@ RNDISDevice::Write(const uint8 *buffer, size_t *numBytes)
return result; return result;
} }
if (fStatusWrite != B_OK && fStatusWrite != B_CANCELED && !fRemoved) { if (fStatusWrite == B_CANCELED) {
// The transfer was canceled, so no data was actually sent.
*numBytes = 0;
return fStatusWrite;
}
if ((fStatusWrite != B_OK) && !fRemoved) {
TRACE_ALWAYS("device status error 0x%08" B_PRIx32 "\n", fStatusWrite); TRACE_ALWAYS("device status error 0x%08" B_PRIx32 "\n", fStatusWrite);
result = gUSBModule->clear_feature(fWriteEndpoint,
USB_FEATURE_ENDPOINT_HALT); gUSBModule->cancel_queued_transfers(fReadEndpoint);
result = gUSBModule->clear_feature(fWriteEndpoint, USB_FEATURE_ENDPOINT_HALT);
if (result != B_OK) { if (result != B_OK) {
TRACE_ALWAYS("failed to clear halt state on write\n"); TRACE_ALWAYS("failed to clear halt state on write\n");
*numBytes = 0; *numBytes = 0;
@ -826,6 +844,7 @@ RNDISDevice::_NotifyCallback(void *cookie, int32 status, void *_data,
if (status != B_OK) { if (status != B_OK) {
TRACE_ALWAYS("device status error 0x%08" B_PRIx32 "\n", status); TRACE_ALWAYS("device status error 0x%08" B_PRIx32 "\n", status);
if (gUSBModule->clear_feature(device->fNotifyEndpoint, if (gUSBModule->clear_feature(device->fNotifyEndpoint,
USB_FEATURE_ENDPOINT_HALT) != B_OK) USB_FEATURE_ENDPOINT_HALT) != B_OK)
TRACE_ALWAYS("failed to clear halt state in notify hook\n"); TRACE_ALWAYS("failed to clear halt state in notify hook\n");