diff --git a/src/add-ons/kernel/bus_managers/usb/Transfer.cpp b/src/add-ons/kernel/bus_managers/usb/Transfer.cpp index 2b90dfb61c..ad3e3c66aa 100644 --- a/src/add-ons/kernel/bus_managers/usb/Transfer.cpp +++ b/src/add-ons/kernel/bus_managers/usb/Transfer.cpp @@ -92,21 +92,27 @@ Transfer::SetVector(iovec *vector, size_t vectorCount) memcpy(fVector, vector, vectorCount * sizeof(iovec)); fVectorCount = vectorCount; fBaseAddress = fVector[0].iov_base; + + size_t length = 0; + for (size_t i = 0; i < fVectorCount && length < USB_MAX_FRAGMENT_SIZE; i++) + length += fVector[i].iov_len; + + if (length > USB_MAX_FRAGMENT_SIZE) { + // the data is too large and would overflow the allocator + fFragmented = true; + } } size_t -Transfer::VectorLength() +Transfer::FragmentLength() const { size_t length = 0; for (size_t i = 0; i < fVectorCount; i++) length += fVector[i].iov_len; - // the data is to large and would overflow the allocator - if (length > USB_MAX_FRAGMENT_SIZE) { + if (length > USB_MAX_FRAGMENT_SIZE) length = USB_MAX_FRAGMENT_SIZE; - fFragmented = true; - } return length; } diff --git a/src/add-ons/kernel/bus_managers/usb/usb_private.h b/src/add-ons/kernel/bus_managers/usb/usb_private.h index ebe592f1e8..e129393892 100644 --- a/src/add-ons/kernel/bus_managers/usb/usb_private.h +++ b/src/add-ons/kernel/bus_managers/usb/usb_private.h @@ -702,12 +702,12 @@ public: size_t vectorCount); iovec * Vector() { return fVector; } size_t VectorCount() const { return fVectorCount; } - size_t VectorLength(); uint16 Bandwidth() const { return fBandwidth; } bool IsFragmented() const { return fFragmented; } void AdvanceByFragment(size_t actualLength); + size_t FragmentLength() const; status_t InitKernelAccess(); status_t PrepareKernelAccess(); diff --git a/src/add-ons/kernel/busses/usb/ehci.cpp b/src/add-ons/kernel/busses/usb/ehci.cpp index c003bb267c..2be4281c2d 100644 --- a/src/add-ons/kernel/busses/usb/ehci.cpp +++ b/src/add-ons/kernel/busses/usb/ehci.cpp @@ -1889,7 +1889,7 @@ EHCI::FinishTransfers() if (transfer->transfer->IsFragmented()) { // this transfer may still have data left transfer->transfer->AdvanceByFragment(actualLength); - if (transfer->transfer->VectorLength() > 0) { + if (transfer->transfer->FragmentLength() > 0) { FreeDescriptorChain(transfer->data_descriptor); status_t result = FillQueueWithData( transfer->transfer, @@ -2319,7 +2319,7 @@ EHCI::FillQueueWithRequest(Transfer *transfer, ehci_qh *queueHead, if (transfer->VectorCount() > 0) { ehci_qtd *lastDescriptor = NULL; status_t result = CreateDescriptorChain(pipe, &dataDescriptor, - &lastDescriptor, statusDescriptor, transfer->VectorLength(), + &lastDescriptor, statusDescriptor, transfer->FragmentLength(), directionIn ? EHCI_QTD_PID_IN : EHCI_QTD_PID_OUT); if (result != B_OK) { @@ -2363,7 +2363,7 @@ EHCI::FillQueueWithData(Transfer *transfer, ehci_qh *queueHead, ehci_qtd *lastDescriptor = NULL; ehci_qtd *strayDescriptor = queueHead->stray_log; status_t result = CreateDescriptorChain(pipe, &firstDescriptor, - &lastDescriptor, strayDescriptor, transfer->VectorLength(), + &lastDescriptor, strayDescriptor, transfer->FragmentLength(), directionIn ? EHCI_QTD_PID_IN : EHCI_QTD_PID_OUT); if (result != B_OK) diff --git a/src/add-ons/kernel/busses/usb/ohci.cpp b/src/add-ons/kernel/busses/usb/ohci.cpp index d10cb99fa6..d4df19f559 100644 --- a/src/add-ons/kernel/busses/usb/ohci.cpp +++ b/src/add-ons/kernel/busses/usb/ohci.cpp @@ -1164,9 +1164,9 @@ OHCI::_FinishTransfers() // this transfer may still have data left TRACE("advancing fragmented transfer\n"); transfer->transfer->AdvanceByFragment(actualLength); - if (transfer->transfer->VectorLength() > 0) { + if (transfer->transfer->FragmentLength() > 0) { TRACE("still %ld bytes left on transfer\n", - transfer->transfer->VectorLength()); + transfer->transfer->FragmentLength()); // TODO actually resubmit the transfer } @@ -1374,7 +1374,7 @@ OHCI::_SubmitRequest(Transfer *transfer) ohci_general_td *lastDescriptor = NULL; result = _CreateDescriptorChain(&dataDescriptor, &lastDescriptor, directionIn ? OHCI_TD_DIRECTION_PID_IN : OHCI_TD_DIRECTION_PID_OUT, - transfer->VectorLength()); + transfer->FragmentLength()); if (result < B_OK) { _FreeGeneralDescriptor(setupDescriptor); _FreeGeneralDescriptor(statusDescriptor); @@ -1426,7 +1426,7 @@ OHCI::_SubmitTransfer(Transfer *transfer) ohci_general_td *lastDescriptor = NULL; status_t result = _CreateDescriptorChain(&firstDescriptor, &lastDescriptor, directionIn ? OHCI_TD_DIRECTION_PID_IN : OHCI_TD_DIRECTION_PID_OUT, - transfer->VectorLength()); + transfer->FragmentLength()); if (result < B_OK) return result; @@ -2022,7 +2022,7 @@ OHCI::_CreateIsochronousDescriptorChain(ohci_isochronous_td **_firstDescriptor, Pipe *pipe = transfer->TransferPipe(); usb_isochronous_data *isochronousData = transfer->IsochronousData(); - size_t dataLength = transfer->VectorLength(); + size_t dataLength = transfer->FragmentLength(); size_t packet_count = isochronousData->packet_count; if (packet_count == 0) { diff --git a/src/add-ons/kernel/busses/usb/uhci.cpp b/src/add-ons/kernel/busses/usb/uhci.cpp index 95fa32a4d2..644f949a61 100644 --- a/src/add-ons/kernel/busses/usb/uhci.cpp +++ b/src/add-ons/kernel/busses/usb/uhci.cpp @@ -992,7 +992,7 @@ UHCI::SubmitRequest(Transfer *transfer) uhci_td *lastDescriptor = NULL; status_t result = CreateDescriptorChain(pipe, &dataDescriptor, &lastDescriptor, directionIn ? TD_TOKEN_IN : TD_TOKEN_OUT, - transfer->VectorLength()); + transfer->FragmentLength()); if (result < B_OK) { FreeDescriptor(setupDescriptor); @@ -1504,9 +1504,9 @@ UHCI::FinishTransfers() // this transfer may still have data left TRACE("advancing fragmented transfer\n"); transfer->transfer->AdvanceByFragment(actualLength); - if (transfer->transfer->VectorLength() > 0) { + if (transfer->transfer->FragmentLength() > 0) { TRACE("still %ld bytes left on transfer\n", - transfer->transfer->VectorLength()); + transfer->transfer->FragmentLength()); Transfer *resubmit = transfer->transfer; @@ -1962,7 +1962,7 @@ UHCI::CreateFilledTransfer(Transfer *transfer, uhci_td **_firstDescriptor, uhci_td *lastDescriptor = NULL; status_t result = CreateDescriptorChain(pipe, &firstDescriptor, &lastDescriptor, directionIn ? TD_TOKEN_IN : TD_TOKEN_OUT, - transfer->VectorLength()); + transfer->FragmentLength()); if (result < B_OK) return result;