From 55a468820cfb785e1434275161558c4375a432fb Mon Sep 17 00:00:00 2001 From: Augustin Cavalier Date: Tue, 30 May 2023 13:48:30 -0400 Subject: [PATCH] USB: Support physical-vector bulk requests. Introduce a new utility method, "generic_memcpy", which takes generic_addr_t plus indications of whether these specify virtual or physical addresses (and potentially user addresess) and calls the appropriate memcpy variant depending. All bus drivers adjusted to support this at once. We don't actually take advantage of the physical addresses in any way (yet), as USB controllers have some pretty specific requirements that would have to be carefully validated to use these directly. All bus drivers tested and confirmed to still be working. Change-Id: I66326667e148091147bb2b3d0843a26fb7e5bda6 Reviewed-on: https://review.haiku-os.org/c/haiku/+/6479 Reviewed-by: waddlesplash --- headers/os/drivers/USB3.h | 14 +++--- headers/private/kernel/util/iovec_support.h | 26 +++++++++++ src/add-ons/kernel/bus_managers/usb/Pipe.cpp | 25 +++++++++-- .../kernel/bus_managers/usb/Transfer.cpp | 29 +++++++++++- src/add-ons/kernel/bus_managers/usb/usb.cpp | 16 +++---- .../kernel/bus_managers/usb/usb_private.h | 15 ++++--- src/add-ons/kernel/busses/usb/ehci.cpp | 37 +++++++++------- src/add-ons/kernel/busses/usb/ehci.h | 9 ++-- src/add-ons/kernel/busses/usb/ohci.cpp | 44 +++++++++++-------- src/add-ons/kernel/busses/usb/ohci.h | 12 +++-- src/add-ons/kernel/busses/usb/uhci.cpp | 26 ++++++----- src/add-ons/kernel/busses/usb/uhci.h | 4 +- src/add-ons/kernel/busses/usb/xhci.cpp | 31 ++++++++----- src/add-ons/kernel/busses/usb/xhci.h | 4 +- 14 files changed, 199 insertions(+), 93 deletions(-) diff --git a/headers/os/drivers/USB3.h b/headers/os/drivers/USB3.h index e02ba5a3e0..091c93da64 100644 --- a/headers/os/drivers/USB3.h +++ b/headers/os/drivers/USB3.h @@ -182,6 +182,11 @@ struct usb_module_info { usb_callback_func callback, void *callbackCookie); + status_t (*queue_bulk_v_physical)(usb_pipe pipe, + physical_entry *vectors, size_t vectorCount, + usb_callback_func callback, + void *callbackCookie); + status_t (*queue_isochronous)(usb_pipe pipe, void *data, size_t dataLength, usb_iso_packet_descriptor *packetDesc, @@ -206,6 +211,9 @@ struct usb_module_info { /* Cancel all pending async requests in a pipe */ status_t (*cancel_queued_transfers)(usb_pipe pipe); + /* Cancel all pending async requests in a device control pipe */ + status_t (*cancel_queued_requests)(usb_device device); + /* Tuning, configuration of timeouts, etc */ status_t (*usb_ioctl)(uint32 opcode, void *buffer, size_t bufferSize); @@ -247,14 +255,10 @@ struct usb_module_info { uint8 portIndex); status_t (*disable_port)(usb_device hub, uint8 portIndex); - - /* Cancel all pending async requests in a device control pipe */ - status_t (*cancel_queued_requests)(usb_device device); - }; -#define B_USB_MODULE_NAME "bus_managers/usb/v3" +#define B_USB_MODULE_NAME "bus_managers/usb/v3.1" #ifdef __cplusplus diff --git a/headers/private/kernel/util/iovec_support.h b/headers/private/kernel/util/iovec_support.h index 29a6653d33..22b46e8859 100644 --- a/headers/private/kernel/util/iovec_support.h +++ b/headers/private/kernel/util/iovec_support.h @@ -15,7 +15,32 @@ typedef struct generic_io_vec { } generic_io_vec; +#ifdef _KERNEL_VM_VM_H + +static inline status_t +generic_memcpy(generic_addr_t dest, bool destPhysical, generic_addr_t src, bool srcPhysical, + generic_size_t size, bool user = false) +{ + if (!srcPhysical && !destPhysical) { + if (user) + return user_memcpy((void*)dest, (void*)src, size); + memcpy((void*)dest, (void*)src, size); + return B_OK; + } else if (destPhysical && !srcPhysical) { + return vm_memcpy_to_physical(dest, (const void*)src, size, user); + } else if (!destPhysical && srcPhysical) { + return vm_memcpy_from_physical((void*)dest, src, size, user); + } + + panic("generic_memcpy: physical -> physical not supported!"); + return B_NOT_SUPPORTED; +} + +#endif + + #ifdef IS_USER_ADDRESS + static inline status_t get_iovecs_from_user(const iovec* userVecs, size_t vecCount, iovec*& vecs, bool permitNull = false) @@ -53,6 +78,7 @@ get_iovecs_from_user(const iovec* userVecs, size_t vecCount, iovec*& vecs, return B_OK; } + #endif diff --git a/src/add-ons/kernel/bus_managers/usb/Pipe.cpp b/src/add-ons/kernel/bus_managers/usb/Pipe.cpp index 0b91c788dd..624437a30e 100644 --- a/src/add-ons/kernel/bus_managers/usb/Pipe.cpp +++ b/src/add-ons/kernel/bus_managers/usb/Pipe.cpp @@ -227,7 +227,28 @@ BulkPipe::QueueBulk(void *data, size_t dataLength, usb_callback_func callback, status_t BulkPipe::QueueBulkV(iovec *vector, size_t vectorCount, - usb_callback_func callback, void *callbackCookie, bool physical) + usb_callback_func callback, void *callbackCookie) +{ + if (vectorCount > 0 && vector == NULL) + return B_BAD_VALUE; + + Transfer *transfer = new(std::nothrow) Transfer(this); + if (!transfer) + return B_NO_MEMORY; + + transfer->SetVector(vector, vectorCount); + transfer->SetCallback(callback, callbackCookie); + + status_t result = GetBusManager()->SubmitTransfer(transfer); + if (result < B_OK) + delete transfer; + return result; +} + + +status_t +BulkPipe::QueueBulkV(physical_entry *vector, size_t vectorCount, + usb_callback_func callback, void *callbackCookie) { if (vectorCount > 0 && vector == NULL) return B_BAD_VALUE; @@ -235,8 +256,6 @@ BulkPipe::QueueBulkV(iovec *vector, size_t vectorCount, Transfer *transfer = new(std::nothrow) Transfer(this); if (!transfer) return B_NO_MEMORY; - if (physical) - return B_NOT_SUPPORTED; transfer->SetVector(vector, vectorCount); transfer->SetCallback(callback, callbackCookie); diff --git a/src/add-ons/kernel/bus_managers/usb/Transfer.cpp b/src/add-ons/kernel/bus_managers/usb/Transfer.cpp index f8a8532e5a..268c17bfd8 100644 --- a/src/add-ons/kernel/bus_managers/usb/Transfer.cpp +++ b/src/add-ons/kernel/bus_managers/usb/Transfer.cpp @@ -85,6 +85,7 @@ void Transfer::SetVector(iovec *vector, size_t vectorCount) { fPhysical = false; + fVector = new(std::nothrow) generic_io_vec[vectorCount]; for (size_t i = 0; i < vectorCount; i++) { fVector[i].base = (generic_addr_t)vector[i].iov_base; @@ -93,6 +94,30 @@ Transfer::SetVector(iovec *vector, size_t vectorCount) fVectorCount = vectorCount; fBaseAddress = vector[0].iov_base; + _CheckFragmented(); +} + + +void +Transfer::SetVector(physical_entry *vector, size_t vectorCount) +{ + fPhysical = true; + + fVector = new(std::nothrow) generic_io_vec[vectorCount]; + for (size_t i = 0; i < vectorCount; i++) { + fVector[i].base = (generic_addr_t)vector[i].address; + fVector[i].length = vector[i].size; + } + fVectorCount = vectorCount; + fBaseAddress = NULL; + + _CheckFragmented(); +} + + +void +Transfer::_CheckFragmented() +{ size_t length = 0; for (size_t i = 0; i < fVectorCount && length <= USB_MAX_FRAGMENT_SIZE; i++) length += fVector[i].length; @@ -138,8 +163,8 @@ Transfer::AdvanceByFragment(size_t actualLength) status_t Transfer::InitKernelAccess() { - // nothing to do if we are already prepared - if (fClonedArea >= B_OK) + // nothing to do if we are already prepared, or have a physical request + if (fClonedArea >= B_OK || fPhysical) return B_OK; // we might need to access a buffer in userspace. this will not diff --git a/src/add-ons/kernel/bus_managers/usb/usb.cpp b/src/add-ons/kernel/bus_managers/usb/usb.cpp index 0706530705..ac1a70c7c3 100644 --- a/src/add-ons/kernel/bus_managers/usb/usb.cpp +++ b/src/add-ons/kernel/bus_managers/usb/usb.cpp @@ -462,12 +462,12 @@ queue_bulk_v(usb_pipe pipe, iovec *vector, size_t vectorCount, return B_DEV_INVALID_PIPE; return ((BulkPipe *)object.Get())->QueueBulkV(vector, vectorCount, - callback, callbackCookie, false); + callback, callbackCookie); } status_t -queue_bulk_v_physical(usb_pipe pipe, iovec *vector, size_t vectorCount, +queue_bulk_v_physical(usb_pipe pipe, physical_entry *vector, size_t vectorCount, usb_callback_func callback, void *callbackCookie) { TRACE_MODULE("queue_bulk_v_physical(%" B_PRId32 ", %p, %" B_PRIuSIZE @@ -477,7 +477,7 @@ queue_bulk_v_physical(usb_pipe pipe, iovec *vector, size_t vectorCount, return B_DEV_INVALID_PIPE; return ((BulkPipe *)object.Get())->QueueBulkV(vector, vectorCount, - callback, callbackCookie, true); + callback, callbackCookie); } @@ -667,7 +667,7 @@ struct usb_module_info gModuleInfoV3 = { // First the bus_manager_info: { { - "bus_managers/usb/v3", + "bus_managers/usb/v3.1", B_KEEP_LOADED, // Keep loaded, even if no driver requires it bus_std_ops }, @@ -690,18 +690,18 @@ struct usb_module_info gModuleInfoV3 = { queue_interrupt, // queue_interrupt queue_bulk, // queue_bulk queue_bulk_v, // queue_bulk_v + queue_bulk_v_physical, // queue_bulk_v_physical queue_isochronous, // queue_isochronous queue_request, // queue_request set_pipe_policy, // set_pipe_policy cancel_queued_transfers, // cancel_queued_transfers + cancel_queued_requests, // cancel_queued_requests usb_ioctl, // usb_ioctl get_nth_roothub, // get_nth_roothub get_nth_child, // get_nth_child get_device_parent, // get_device_parent reset_port, // reset_port disable_port, // disable_port - cancel_queued_requests // cancel_queued_requests - //queue_bulk_v_physical // queue_bulk_v_physical }; @@ -955,10 +955,10 @@ device_std_ops(int32 op, ...) // functions directly instead via official interface, so this // pointer is never read. module_info *dummy; - return get_module("bus_managers/usb/v3", &dummy); + return get_module(B_USB_MODULE_NAME, &dummy); } case B_MODULE_UNINIT: - return put_module("bus_managers/usb/v3"); + return put_module(B_USB_MODULE_NAME); default: return B_ERROR; 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 55aede9453..ccc28e8fa0 100644 --- a/src/add-ons/kernel/bus_managers/usb/usb_private.h +++ b/src/add-ons/kernel/bus_managers/usb/usb_private.h @@ -16,6 +16,9 @@ #include "usbspec_private.h" #include #include + +// include vm.h before iovec_support.h for generic_memcpy, which is used by the bus drivers. +#include #include @@ -475,12 +478,10 @@ virtual const char * TypeName() const { return "bulk pipe"; } size_t dataLength, usb_callback_func callback, void *callbackCookie); - status_t QueueBulkV(iovec *vector, - size_t vectorCount, - usb_callback_func callback, - void *callbackCookie, - bool physical); -}; + status_t QueueBulkV(iovec *vector, size_t vectorCount, + usb_callback_func callback, void *callbackCookie); + status_t QueueBulkV(physical_entry *vector, size_t vectorCount, + usb_callback_func callback, void *callbackCookie);}; class IsochronousPipe : public Pipe { @@ -721,6 +722,7 @@ public: bool IsPhysical() const { return fPhysical; } void SetVector(iovec *vector, size_t vectorCount); + void SetVector(physical_entry *vector, size_t vectorCount); generic_io_vec * Vector() { return fVector; } size_t VectorCount() const { return fVectorCount; } @@ -747,6 +749,7 @@ public: const char * TypeName() const { return "transfer"; } private: + void _CheckFragmented(); status_t _CalculateBandwidth(); // Data that is related to the transfer diff --git a/src/add-ons/kernel/busses/usb/ehci.cpp b/src/add-ons/kernel/busses/usb/ehci.cpp index 327b18b0eb..934581dbcc 100644 --- a/src/add-ons/kernel/busses/usb/ehci.cpp +++ b/src/add-ons/kernel/busses/usb/ehci.cpp @@ -1023,7 +1023,7 @@ EHCI::CheckDebugTransfer(Transfer *transfer) size_t vectorCount = transfer->VectorCount(); ReadDescriptorChain(transferData->data_descriptor, - vector, vectorCount, &nextDataToggle); + vector, vectorCount, transfer->IsPhysical(), &nextDataToggle); } else if (transferData->data_descriptor != NULL) ReadActualLength(transferData->data_descriptor, &nextDataToggle); @@ -2010,7 +2010,7 @@ EHCI::FinishTransfers() if (callbackStatus == B_OK) { actualLength = ReadDescriptorChain( transfer->data_descriptor, - vector, vectorCount, + vector, vectorCount, transfer->transfer->IsPhysical(), &nextDataToggle); } } else if (transfer->data_descriptor) { @@ -2448,7 +2448,7 @@ EHCI::FillQueueWithRequest(Transfer *transfer, ehci_qh *queueHead, generic_io_vec vector; vector.base = (generic_addr_t)requestData; vector.length = sizeof(usb_request_data); - WriteDescriptorChain(setupDescriptor, &vector, 1); + WriteDescriptorChain(setupDescriptor, &vector, 1, false); ehci_qtd *strayDescriptor = queueHead->stray_log; statusDescriptor->token |= EHCI_QTD_IOC | EHCI_QTD_DATA_TOGGLE; @@ -2476,7 +2476,7 @@ EHCI::FillQueueWithRequest(Transfer *transfer, ehci_qh *queueHead, } } WriteDescriptorChain(dataDescriptor, transfer->Vector(), - transfer->VectorCount()); + transfer->VectorCount(), transfer->IsPhysical()); } LinkDescriptors(setupDescriptor, dataDescriptor, strayDescriptor); @@ -2523,7 +2523,7 @@ EHCI::FillQueueWithData(Transfer *transfer, ehci_qh *queueHead, } } WriteDescriptorChain(firstDescriptor, transfer->Vector(), - transfer->VectorCount()); + transfer->VectorCount(), transfer->IsPhysical()); } queueHead->element_log = firstDescriptor; @@ -2785,7 +2785,7 @@ EHCI::UnlinkSITDescriptors(ehci_sitd *sitd, ehci_sitd **last) size_t EHCI::WriteDescriptorChain(ehci_qtd *topDescriptor, generic_io_vec *vector, - size_t vectorCount) + size_t vectorCount, bool physical) { ehci_qtd *current = topDescriptor; size_t actualLength = 0; @@ -2801,8 +2801,10 @@ EHCI::WriteDescriptorChain(ehci_qtd *topDescriptor, generic_io_vec *vector, size_t length = min_c(current->buffer_size - bufferOffset, vector[vectorIndex].length - vectorOffset); - memcpy((uint8 *)current->buffer_log + bufferOffset, - (uint8 *)vector[vectorIndex].base + vectorOffset, length); + status_t status = generic_memcpy( + (generic_addr_t)current->buffer_log + bufferOffset, false, + vector[vectorIndex].base + vectorOffset, physical, length); + ASSERT(status == B_OK); actualLength += length; vectorOffset += length; @@ -2837,7 +2839,7 @@ EHCI::WriteDescriptorChain(ehci_qtd *topDescriptor, generic_io_vec *vector, size_t EHCI::ReadDescriptorChain(ehci_qtd *topDescriptor, generic_io_vec *vector, - size_t vectorCount, bool *nextDataToggle) + size_t vectorCount, bool physical, bool *nextDataToggle) { uint32 dataToggle = 0; ehci_qtd *current = topDescriptor; @@ -2859,8 +2861,10 @@ EHCI::ReadDescriptorChain(ehci_qtd *topDescriptor, generic_io_vec *vector, size_t length = min_c(bufferSize - bufferOffset, vector[vectorIndex].length - vectorOffset); - memcpy((uint8 *)vector[vectorIndex].base + vectorOffset, - (uint8 *)current->buffer_log + bufferOffset, length); + status_t status = generic_memcpy( + vector[vectorIndex].base + vectorOffset, physical, + (generic_addr_t)current->buffer_log + bufferOffset, false, length); + ASSERT(status == B_OK); actualLength += length; vectorOffset += length; @@ -2922,8 +2926,7 @@ EHCI::ReadActualLength(ehci_qtd *topDescriptor, bool *nextDataToggle) size_t -EHCI::WriteIsochronousDescriptorChain(isochronous_transfer_data *transfer, - uint32 packetCount, generic_io_vec *vector) +EHCI::WriteIsochronousDescriptorChain(isochronous_transfer_data *transfer) { // TODO implement return 0; @@ -2935,6 +2938,7 @@ EHCI::ReadIsochronousDescriptorChain(isochronous_transfer_data *transfer) { generic_io_vec *vector = transfer->transfer->Vector(); size_t vectorCount = transfer->transfer->VectorCount(); + const bool physical = transfer->transfer->IsPhysical(); size_t vectorOffset = 0; size_t vectorIndex = 0; usb_isochronous_data *isochronousData @@ -2972,8 +2976,11 @@ EHCI::ReadIsochronousDescriptorChain(isochronous_transfer_data *transfer) while (bufferSize > 0) { size_t length = min_c(bufferSize, vector[vectorIndex].length - vectorOffset); - memcpy((uint8 *)vector[vectorIndex].base + vectorOffset, - (uint8 *)transfer->buffer_log + bufferOffset, length); + status_t status = generic_memcpy( + vector[vectorIndex].base + vectorOffset, physical, + (generic_addr_t)transfer->buffer_log + bufferOffset, false, length); + ASSERT(status == B_OK); + offset += length; vectorOffset += length; bufferSize -= length; diff --git a/src/add-ons/kernel/busses/usb/ehci.h b/src/add-ons/kernel/busses/usb/ehci.h index f9bc64a16c..eaba43d881 100644 --- a/src/add-ons/kernel/busses/usb/ehci.h +++ b/src/add-ons/kernel/busses/usb/ehci.h @@ -178,16 +178,15 @@ static int32 FinishIsochronousThread(void *data); size_t WriteDescriptorChain( ehci_qtd *topDescriptor, - generic_io_vec *vector, size_t vectorCount); + generic_io_vec *vector, size_t vectorCount, + bool physical); size_t ReadDescriptorChain(ehci_qtd *topDescriptor, generic_io_vec *vector, size_t vectorCount, - bool *nextDataToggle); + bool physical, bool *nextDataToggle); size_t ReadActualLength(ehci_qtd *topDescriptor, bool *nextDataToggle); size_t WriteIsochronousDescriptorChain( - isochronous_transfer_data *transfer, - uint32 packetCount, - generic_io_vec *vector); + isochronous_transfer_data *transfer); size_t ReadIsochronousDescriptorChain( isochronous_transfer_data *transfer); diff --git a/src/add-ons/kernel/busses/usb/ohci.cpp b/src/add-ons/kernel/busses/usb/ohci.cpp index ca64a06f64..9599d9e666 100644 --- a/src/add-ons/kernel/busses/usb/ohci.cpp +++ b/src/add-ons/kernel/busses/usb/ohci.cpp @@ -1267,7 +1267,7 @@ OHCI::_FinishTransfers() transfer->transfer->PrepareKernelAccess(); actualLength = _ReadDescriptorChain( transfer->data_descriptor, - vector, vectorCount); + vector, vectorCount, transfer->transfer->IsPhysical()); } else if (transfer->data_descriptor) { // read the actual length that was sent actualLength = _ReadActualLength( @@ -1436,7 +1436,7 @@ OHCI::_FinishIsochronousTransfer(transfer_data *transfer, transfer->transfer->PrepareKernelAccess(); _ReadIsochronousDescriptorChain( (ohci_isochronous_td*)transfer->data_descriptor, - vector, vectorCount); + vector, vectorCount, transfer->transfer->IsPhysical()); } } @@ -1485,7 +1485,7 @@ OHCI::_SubmitRequest(Transfer *transfer) generic_io_vec vector; vector.base = (generic_addr_t)requestData; vector.length = sizeof(usb_request_data); - _WriteDescriptorChain(setupDescriptor, &vector, 1); + _WriteDescriptorChain(setupDescriptor, &vector, 1, false); status_t result; ohci_general_td *dataDescriptor = NULL; @@ -1502,7 +1502,7 @@ OHCI::_SubmitRequest(Transfer *transfer) if (!directionIn) { _WriteDescriptorChain(dataDescriptor, transfer->Vector(), - transfer->VectorCount()); + transfer->VectorCount(), transfer->IsPhysical()); } _LinkDescriptors(setupDescriptor, dataDescriptor); @@ -1562,7 +1562,7 @@ OHCI::_SubmitTransfer(Transfer *transfer) if (!directionIn) { _WriteDescriptorChain(firstDescriptor, transfer->Vector(), - transfer->VectorCount()); + transfer->VectorCount(), transfer->IsPhysical()); } // Add to the transfer list @@ -1631,7 +1631,7 @@ OHCI::_SubmitIsochronousTransfer(Transfer *transfer) // If direction is out set every descriptor data if (pipe->Direction() == Pipe::Out) _WriteIsochronousDescriptorChain(firstDescriptor, - transfer->Vector(), transfer->VectorCount()); + transfer->Vector(), transfer->VectorCount(), transfer->IsPhysical()); else // Initialize the packet descriptors for (uint32 i = 0; i < isochronousData->packet_count; i++) { @@ -2279,7 +2279,7 @@ OHCI::_FreeIsochronousDescriptorChain(ohci_isochronous_td *topDescriptor) size_t OHCI::_WriteDescriptorChain(ohci_general_td *topDescriptor, generic_io_vec *vector, - size_t vectorCount) + size_t vectorCount, bool physical) { ohci_general_td *current = topDescriptor; size_t actualLength = 0; @@ -2298,8 +2298,10 @@ OHCI::_WriteDescriptorChain(ohci_general_td *topDescriptor, generic_io_vec *vect TRACE("copying %ld bytes to bufferOffset %ld from" " vectorOffset %ld at index %ld of %ld\n", length, bufferOffset, vectorOffset, vectorIndex, vectorCount); - memcpy((uint8 *)current->buffer_logical + bufferOffset, - (uint8 *)vector[vectorIndex].base + vectorOffset, length); + status_t status = generic_memcpy( + (generic_addr_t)current->buffer_logical + bufferOffset, false, + vector[vectorIndex].base + vectorOffset, physical, length); + ASSERT(status == B_OK); actualLength += length; vectorOffset += length; @@ -2334,7 +2336,7 @@ OHCI::_WriteDescriptorChain(ohci_general_td *topDescriptor, generic_io_vec *vect size_t OHCI::_WriteIsochronousDescriptorChain(ohci_isochronous_td *topDescriptor, - generic_io_vec *vector, size_t vectorCount) + generic_io_vec *vector, size_t vectorCount, bool physical) { ohci_isochronous_td *current = topDescriptor; size_t actualLength = 0; @@ -2353,8 +2355,10 @@ OHCI::_WriteIsochronousDescriptorChain(ohci_isochronous_td *topDescriptor, TRACE("copying %ld bytes to bufferOffset %ld from" " vectorOffset %ld at index %ld of %ld\n", length, bufferOffset, vectorOffset, vectorIndex, vectorCount); - memcpy((uint8 *)current->buffer_logical + bufferOffset, - (uint8 *)vector[vectorIndex].base + vectorOffset, length); + status_t status = generic_memcpy( + (generic_addr_t)current->buffer_logical + bufferOffset, false, + vector[vectorIndex].base + vectorOffset, physical, length); + ASSERT(status == B_OK); actualLength += length; vectorOffset += length; @@ -2389,7 +2393,7 @@ OHCI::_WriteIsochronousDescriptorChain(ohci_isochronous_td *topDescriptor, size_t OHCI::_ReadDescriptorChain(ohci_general_td *topDescriptor, generic_io_vec *vector, - size_t vectorCount) + size_t vectorCount, bool physical) { ohci_general_td *current = topDescriptor; size_t actualLength = 0; @@ -2415,8 +2419,10 @@ OHCI::_ReadDescriptorChain(ohci_general_td *topDescriptor, generic_io_vec *vecto TRACE("copying %ld bytes to vectorOffset %ld from" " bufferOffset %ld at index %ld of %ld\n", length, vectorOffset, bufferOffset, vectorIndex, vectorCount); - memcpy((uint8 *)vector[vectorIndex].base + vectorOffset, - (uint8 *)current->buffer_logical + bufferOffset, length); + status_t status = generic_memcpy( + vector[vectorIndex].base + vectorOffset, physical, + (generic_addr_t)current->buffer_logical + bufferOffset, false, length); + ASSERT(status == B_OK); actualLength += length; vectorOffset += length; @@ -2448,7 +2454,7 @@ OHCI::_ReadDescriptorChain(ohci_general_td *topDescriptor, generic_io_vec *vecto void OHCI::_ReadIsochronousDescriptorChain(ohci_isochronous_td *topDescriptor, - generic_io_vec *vector, size_t vectorCount) + generic_io_vec *vector, size_t vectorCount, bool physical) { ohci_isochronous_td *current = topDescriptor; size_t actualLength = 0; @@ -2467,8 +2473,10 @@ OHCI::_ReadIsochronousDescriptorChain(ohci_isochronous_td *topDescriptor, TRACE("copying %ld bytes to vectorOffset %ld from bufferOffset" " %ld at index %ld of %ld\n", length, vectorOffset, bufferOffset, vectorIndex, vectorCount); - memcpy((uint8 *)vector[vectorIndex].base + vectorOffset, - (uint8 *)current->buffer_logical + bufferOffset, length); + status_t status = generic_memcpy( + vector[vectorIndex].base + vectorOffset, physical, + (generic_addr_t)current->buffer_logical + bufferOffset, false, length); + ASSERT(status == B_OK); actualLength += length; vectorOffset += length; diff --git a/src/add-ons/kernel/busses/usb/ohci.h b/src/add-ons/kernel/busses/usb/ohci.h index 8a790f6b44..cf3e43efa4 100644 --- a/src/add-ons/kernel/busses/usb/ohci.h +++ b/src/add-ons/kernel/busses/usb/ohci.h @@ -135,17 +135,21 @@ static int32 _FinishThread(void *data); size_t _WriteDescriptorChain( ohci_general_td *topDescriptor, - generic_io_vec *vector, size_t vectorCount); + generic_io_vec *vector, size_t vectorCount, + bool physical); size_t _ReadDescriptorChain( ohci_general_td *topDescriptor, - generic_io_vec *vector, size_t vectorCount); + generic_io_vec *vector, size_t vectorCount, + bool physical); size_t _WriteIsochronousDescriptorChain( ohci_isochronous_td *topDescriptor, - generic_io_vec *vector, size_t vectorCount); + generic_io_vec *vector, size_t vectorCount, + bool physical); void _ReadIsochronousDescriptorChain( ohci_isochronous_td *topDescriptor, - generic_io_vec *vector, size_t vectorCount); + generic_io_vec *vector, size_t vectorCount, + bool physical); size_t _ReadActualLength( ohci_general_td *topDescriptor); diff --git a/src/add-ons/kernel/busses/usb/uhci.cpp b/src/add-ons/kernel/busses/usb/uhci.cpp index 527bb4f2f6..303cb86369 100644 --- a/src/add-ons/kernel/busses/usb/uhci.cpp +++ b/src/add-ons/kernel/busses/usb/uhci.cpp @@ -934,7 +934,7 @@ UHCI::CheckDebugTransfer(Transfer *transfer) size_t vectorCount = transfer->VectorCount(); ReadDescriptorChain(transferData->first_descriptor, - vector, vectorCount, &lastDataToggle); + vector, vectorCount, transfer->IsPhysical(), &lastDataToggle); } else { // read the actual length that was sent ReadActualLength(transferData->first_descriptor, &lastDataToggle); @@ -1094,7 +1094,7 @@ UHCI::SubmitRequest(Transfer *transfer) generic_io_vec vector; vector.base = (generic_addr_t)requestData; vector.length = sizeof(usb_request_data); - WriteDescriptorChain(setupDescriptor, &vector, 1); + WriteDescriptorChain(setupDescriptor, &vector, 1, false); statusDescriptor->status |= TD_CONTROL_IOC; statusDescriptor->token |= TD_TOKEN_DATA1; @@ -1116,7 +1116,7 @@ UHCI::SubmitRequest(Transfer *transfer) if (!directionIn) { WriteDescriptorChain(dataDescriptor, transfer->Vector(), - transfer->VectorCount()); + transfer->VectorCount(), transfer->IsPhysical()); } LinkDescriptors(setupDescriptor, dataDescriptor); @@ -1619,7 +1619,7 @@ UHCI::FinishTransfers() transfer->transfer->PrepareKernelAccess(); actualLength = ReadDescriptorChain( transfer->data_descriptor, - vector, vectorCount, + vector, vectorCount, transfer->transfer->IsPhysical(), &lastDataToggle); } else if (transfer->data_descriptor) { // read the actual length that was sent @@ -2104,7 +2104,7 @@ UHCI::CreateFilledTransfer(Transfer *transfer, uhci_td **_firstDescriptor, if (!directionIn) { WriteDescriptorChain(firstDescriptor, transfer->Vector(), - transfer->VectorCount()); + transfer->VectorCount(), transfer->IsPhysical()); } uhci_qh *transferQueue = CreateTransferQueue(firstDescriptor); @@ -2277,7 +2277,7 @@ UHCI::LinkDescriptors(uhci_td *first, uhci_td *second) size_t UHCI::WriteDescriptorChain(uhci_td *topDescriptor, generic_io_vec *vector, - size_t vectorCount) + size_t vectorCount, bool physical) { uhci_td *current = topDescriptor; size_t actualLength = 0; @@ -2296,8 +2296,10 @@ UHCI::WriteDescriptorChain(uhci_td *topDescriptor, generic_io_vec *vector, TRACE("copying %ld bytes to bufferOffset %ld from" " vectorOffset %ld at index %ld of %ld\n", length, bufferOffset, vectorOffset, vectorIndex, vectorCount); - memcpy((uint8 *)current->buffer_log + bufferOffset, - (uint8 *)vector[vectorIndex].base + vectorOffset, length); + status_t status = generic_memcpy( + (generic_addr_t)current->buffer_log + bufferOffset, false, + vector[vectorIndex].base + vectorOffset, physical, length); + ASSERT(status == B_OK); actualLength += length; vectorOffset += length; @@ -2332,7 +2334,7 @@ UHCI::WriteDescriptorChain(uhci_td *topDescriptor, generic_io_vec *vector, size_t UHCI::ReadDescriptorChain(uhci_td *topDescriptor, generic_io_vec *vector, - size_t vectorCount, uint8 *lastDataToggle) + size_t vectorCount, bool physical, uint8 *lastDataToggle) { uint8 dataToggle = 0; uhci_td *current = topDescriptor; @@ -2355,8 +2357,10 @@ UHCI::ReadDescriptorChain(uhci_td *topDescriptor, generic_io_vec *vector, TRACE("copying %ld bytes to vectorOffset %ld from" " bufferOffset %ld at index %ld of %ld\n", length, vectorOffset, bufferOffset, vectorIndex, vectorCount); - memcpy((uint8 *)vector[vectorIndex].base + vectorOffset, - (uint8 *)current->buffer_log + bufferOffset, length); + status_t status = generic_memcpy( + vector[vectorIndex].base + vectorOffset, physical, + (generic_addr_t)current->buffer_log + bufferOffset, false, length); + ASSERT(status == B_OK); actualLength += length; vectorOffset += length; diff --git a/src/add-ons/kernel/busses/usb/uhci.h b/src/add-ons/kernel/busses/usb/uhci.h index a8e79b2bca..61046567b9 100644 --- a/src/add-ons/kernel/busses/usb/uhci.h +++ b/src/add-ons/kernel/busses/usb/uhci.h @@ -184,9 +184,9 @@ static int32 FinishIsochronousThread(void *data); uhci_td *second); size_t WriteDescriptorChain(uhci_td *topDescriptor, - generic_io_vec *vector, size_t vectorCount); + generic_io_vec *vector, size_t vectorCount, bool physical); size_t ReadDescriptorChain(uhci_td *topDescriptor, - generic_io_vec *vector, size_t vectorCount, + generic_io_vec *vector, size_t vectorCount, bool physical, uint8 *lastDataToggle); size_t ReadActualLength(uhci_td *topDescriptor, uint8 *lastDataToggle); diff --git a/src/add-ons/kernel/busses/usb/xhci.cpp b/src/add-ons/kernel/busses/usb/xhci.cpp index 3e15fd7767..cd8a1b4754 100644 --- a/src/add-ons/kernel/busses/usb/xhci.cpp +++ b/src/add-ons/kernel/busses/usb/xhci.cpp @@ -877,8 +877,8 @@ XHCI::SubmitControlRequest(Transfer *transfer) if (!directionIn) { transfer->PrepareKernelAccess(); - memcpy(descriptor->buffers[0], - (uint8 *)transfer->Vector()[0].base, requestData->Length); + WriteDescriptor(descriptor, transfer->Vector(), + transfer->VectorCount(), transfer->IsPhysical()); } index++; @@ -1045,7 +1045,8 @@ XHCI::SubmitNormalRequest(Transfer *transfer) FreeDescriptor(td); return status; } - WriteDescriptor(td, transfer->Vector(), transfer->VectorCount()); + WriteDescriptor(td, transfer->Vector(), + transfer->VectorCount(), transfer->IsPhysical()); } td->transfer = transfer; @@ -1236,8 +1237,10 @@ XHCI::CheckDebugTransfer(Transfer *transfer) status_t status = (td->trb_completion_code == COMP_SUCCESS || td->trb_completion_code == COMP_SHORT_PACKET) ? B_OK : B_ERROR; - if (status == B_OK && directionIn) - ReadDescriptor(td, transfer->Vector(), transfer->VectorCount()); + if (status == B_OK && directionIn) { + ReadDescriptor(td, transfer->Vector(), transfer->VectorCount(), + transfer->IsPhysical()); + } FreeDescriptor(td); transfer->SetCallback(NULL, NULL); @@ -1427,7 +1430,7 @@ XHCI::FreeDescriptor(xhci_td *descriptor) size_t -XHCI::WriteDescriptor(xhci_td *descriptor, generic_io_vec *vector, size_t vectorCount) +XHCI::WriteDescriptor(xhci_td *descriptor, generic_io_vec *vector, size_t vectorCount, bool physical) { size_t written = 0; @@ -1437,9 +1440,11 @@ XHCI::WriteDescriptor(xhci_td *descriptor, generic_io_vec *vector, size_t vector while (length > 0 && bufIdx < descriptor->buffer_count) { size_t toCopy = min_c(length, descriptor->buffer_size - bufUsed); - memcpy((uint8 *)descriptor->buffers[bufIdx] + bufUsed, - (uint8 *)vector[vecIdx].base + (vector[vecIdx].length - length), + status_t status = generic_memcpy( + (generic_addr_t)descriptor->buffers[bufIdx] + bufUsed, false, + vector[vecIdx].base + (vector[vecIdx].length - length), physical, toCopy); + ASSERT(status == B_OK); written += toCopy; bufUsed += toCopy; @@ -1457,7 +1462,7 @@ XHCI::WriteDescriptor(xhci_td *descriptor, generic_io_vec *vector, size_t vector size_t -XHCI::ReadDescriptor(xhci_td *descriptor, generic_io_vec *vector, size_t vectorCount) +XHCI::ReadDescriptor(xhci_td *descriptor, generic_io_vec *vector, size_t vectorCount, bool physical) { size_t read = 0; @@ -1467,8 +1472,10 @@ XHCI::ReadDescriptor(xhci_td *descriptor, generic_io_vec *vector, size_t vectorC while (length > 0 && bufIdx < descriptor->buffer_count) { size_t toCopy = min_c(length, descriptor->buffer_size - bufUsed); - memcpy((uint8 *)vector[vecIdx].base + (vector[vecIdx].length - length), - (uint8 *)descriptor->buffers[bufIdx] + bufUsed, toCopy); + status_t status = generic_memcpy( + vector[vecIdx].base + (vector[vecIdx].length - length), physical, + (generic_addr_t)descriptor->buffers[bufIdx] + bufUsed, false, toCopy); + ASSERT(status == B_OK); read += toCopy; bufUsed += toCopy; @@ -3116,7 +3123,7 @@ XHCI::FinishTransfers() status_t status = transfer->PrepareKernelAccess(); if (status == B_OK) { ReadDescriptor(td, transfer->Vector(), - transfer->VectorCount()); + transfer->VectorCount(), transfer->IsPhysical()); } else { callbackStatus = status; } diff --git a/src/add-ons/kernel/busses/usb/xhci.h b/src/add-ons/kernel/busses/usb/xhci.h index f52f998687..2c9da35c5e 100644 --- a/src/add-ons/kernel/busses/usb/xhci.h +++ b/src/add-ons/kernel/busses/usb/xhci.h @@ -162,9 +162,9 @@ private: void FreeDescriptor(xhci_td *descriptor); size_t WriteDescriptor(xhci_td *descriptor, - generic_io_vec *vector, size_t vectorCount); + generic_io_vec *vector, size_t vectorCount, bool physical); size_t ReadDescriptor(xhci_td *descriptor, - generic_io_vec *vector, size_t vectorCount); + generic_io_vec *vector, size_t vectorCount, bool physical); status_t _LinkDescriptorForPipe(xhci_td *descriptor, xhci_endpoint *endpoint);