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 <waddlesplash@gmail.com>
This commit is contained in:
Augustin Cavalier 2023-05-30 13:48:30 -04:00 committed by waddlesplash
parent 99626c2908
commit 55a468820c
14 changed files with 199 additions and 93 deletions

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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

View File

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

View File

@ -16,6 +16,9 @@
#include "usbspec_private.h"
#include <lock.h>
#include <util/Vector.h>
// include vm.h before iovec_support.h for generic_memcpy, which is used by the bus drivers.
#include <vm/vm.h>
#include <util/iovec_support.h>
@ -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

View File

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

View File

@ -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);

View File

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

View File

@ -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);

View File

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

View File

@ -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);

View File

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

View File

@ -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);