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:
parent
99626c2908
commit
55a468820c
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue