mirror of
https://github.com/reactos/reactos.git
synced 2024-07-11 07:05:12 +00:00
[USBOHCI]
- Add sanity checks - Preserve command status value when notifying the hc that a control / bulk endpoint was added - Re-enable root hub notification interrupt when reset port has been completed - Dispatch processing to USBQeueu when DoneHead event arrives - Scan endpoints to find the logical endpoint which was completed by the hardware - Signal completion to IUSBRequest by calling CompletionCallback - Create a final transfer descriptor which is linked to the endpoint descriptor - Control transfers now appear to be working (Device retrieves device descriptor / configuration descriptor and succeeds in setting device address) - Configuration parsing code needs more work now (currently fails there due to invalid / unexpected configuration descriptor from device) svn path=/branches/usb-bringup/; revision=51888
This commit is contained in:
parent
b275073474
commit
e24bfbfa91
|
@ -540,6 +540,7 @@ CUSBHardwareDevice::StartController(void)
|
||||||
// assert that the controller has been started
|
// assert that the controller has been started
|
||||||
//
|
//
|
||||||
ASSERT((Control & OHCI_HC_FUNCTIONAL_STATE_MASK) == OHCI_HC_FUNCTIONAL_STATE_OPERATIONAL);
|
ASSERT((Control & OHCI_HC_FUNCTIONAL_STATE_MASK) == OHCI_HC_FUNCTIONAL_STATE_OPERATIONAL);
|
||||||
|
ASSERT((Control & OHCI_ENABLE_LIST) == OHCI_ENABLE_LIST);
|
||||||
|
|
||||||
//
|
//
|
||||||
// get frame interval
|
// get frame interval
|
||||||
|
@ -689,20 +690,30 @@ VOID
|
||||||
CUSBHardwareDevice::HeadEndpointDescriptorModified(
|
CUSBHardwareDevice::HeadEndpointDescriptorModified(
|
||||||
ULONG Type)
|
ULONG Type)
|
||||||
{
|
{
|
||||||
|
ULONG Value = READ_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_COMMAND_STATUS_OFFSET));
|
||||||
|
|
||||||
if (Type == USB_ENDPOINT_TYPE_CONTROL)
|
if (Type == USB_ENDPOINT_TYPE_CONTROL)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
// notify controller
|
// notify controller
|
||||||
//
|
//
|
||||||
WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_COMMAND_STATUS_OFFSET), OHCI_CONTROL_LIST_FILLED);
|
//WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_CONTROL_HEAD_ED_OFFSET), m_ControlEndpointDescriptor->NextPhysicalEndpoint);
|
||||||
|
//WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_CONTROL_CURRENT_ED_OFFSET), m_ControlEndpointDescriptor->NextPhysicalEndpoint);
|
||||||
|
WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_COMMAND_STATUS_OFFSET), Value | OHCI_CONTROL_LIST_FILLED);
|
||||||
}
|
}
|
||||||
else if (Type == USB_ENDPOINT_TYPE_BULK)
|
else if (Type == USB_ENDPOINT_TYPE_BULK)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
// notify controller
|
// notify controller
|
||||||
//
|
//
|
||||||
WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_COMMAND_STATUS_OFFSET), OHCI_BULK_LIST_FILLED);
|
WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_COMMAND_STATUS_OFFSET), Value | OHCI_BULK_LIST_FILLED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Value = READ_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_COMMAND_STATUS_OFFSET));
|
||||||
|
|
||||||
|
|
||||||
|
DPRINT1("HeadEndpointDescriptorModified Value %x Type %x\n", Value, Type);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
@ -1035,7 +1046,9 @@ CUSBHardwareDevice::ClearPortStatus(
|
||||||
//
|
//
|
||||||
// re-enable root hub change
|
// re-enable root hub change
|
||||||
//
|
//
|
||||||
WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_INTERRUPT_ENABLE_OFFSET), OHCI_ROOT_HUB_STATUS_CHANGE);
|
Value = READ_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_INTERRUPT_ENABLE_OFFSET));
|
||||||
|
WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_INTERRUPT_ENABLE_OFFSET), Value | OHCI_ROOT_HUB_STATUS_CHANGE);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Status == C_PORT_CONNECTION)
|
if (Status == C_PORT_CONNECTION)
|
||||||
|
@ -1232,11 +1245,6 @@ InterruptServiceRoutine(
|
||||||
//
|
//
|
||||||
// head completed
|
// head completed
|
||||||
//
|
//
|
||||||
DPRINT1("InterruptServiceRoutine> Done Head completion\n");
|
|
||||||
ASSERT(FALSE);
|
|
||||||
//
|
|
||||||
// FIXME: handle event
|
|
||||||
//
|
|
||||||
Acknowledge |= OHCI_WRITEBACK_DONE_HEAD;
|
Acknowledge |= OHCI_WRITEBACK_DONE_HEAD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1307,6 +1315,8 @@ OhciDefferedRoutine(
|
||||||
{
|
{
|
||||||
CUSBHardwareDevice *This;
|
CUSBHardwareDevice *This;
|
||||||
ULONG CStatus, Index, PortStatus;
|
ULONG CStatus, Index, PortStatus;
|
||||||
|
POHCI_ENDPOINT_DESCRIPTOR EndpointDescriptor;
|
||||||
|
ULONG DoneHead;
|
||||||
|
|
||||||
//
|
//
|
||||||
// get parameters
|
// get parameters
|
||||||
|
@ -1314,6 +1324,25 @@ OhciDefferedRoutine(
|
||||||
This = (CUSBHardwareDevice*) SystemArgument1;
|
This = (CUSBHardwareDevice*) SystemArgument1;
|
||||||
CStatus = (ULONG) SystemArgument2;
|
CStatus = (ULONG) SystemArgument2;
|
||||||
|
|
||||||
|
DPRINT1("OhciDefferedRoutine Status %x\n", CStatus);
|
||||||
|
|
||||||
|
if (CStatus & OHCI_WRITEBACK_DONE_HEAD)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// descriptor completion, get done head
|
||||||
|
//
|
||||||
|
DoneHead = This->m_HCCA->DoneHead;
|
||||||
|
|
||||||
|
//
|
||||||
|
// clear out lower bits, ed are 16 byte aligned
|
||||||
|
//
|
||||||
|
DoneHead &= ~0xF;
|
||||||
|
|
||||||
|
//
|
||||||
|
// notify queue of event
|
||||||
|
//
|
||||||
|
This->m_UsbQueue->TransferDescriptorCompletionCallback(DoneHead);
|
||||||
|
}
|
||||||
if (CStatus & OHCI_ROOT_HUB_STATUS_CHANGE)
|
if (CStatus & OHCI_ROOT_HUB_STATUS_CHANGE)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
|
|
|
@ -202,8 +202,9 @@ typedef struct _OHCI_ENDPOINT_DESCRIPTOR
|
||||||
|
|
||||||
// Software part
|
// Software part
|
||||||
PHYSICAL_ADDRESS PhysicalAddress;
|
PHYSICAL_ADDRESS PhysicalAddress;
|
||||||
PVOID Request;
|
PVOID HeadLogicalDescriptor;
|
||||||
PVOID NextDescriptor;
|
PVOID NextDescriptor;
|
||||||
|
PVOID Request;
|
||||||
}OHCI_ENDPOINT_DESCRIPTOR, *POHCI_ENDPOINT_DESCRIPTOR;
|
}OHCI_ENDPOINT_DESCRIPTOR, *POHCI_ENDPOINT_DESCRIPTOR;
|
||||||
|
|
||||||
|
|
||||||
|
@ -238,9 +239,9 @@ typedef struct
|
||||||
ULONG LastPhysicalByteAddress; // Physical pointer to buffer end
|
ULONG LastPhysicalByteAddress; // Physical pointer to buffer end
|
||||||
// Software part
|
// Software part
|
||||||
PHYSICAL_ADDRESS PhysicalAddress; // Physical address of this descriptor
|
PHYSICAL_ADDRESS PhysicalAddress; // Physical address of this descriptor
|
||||||
|
PVOID NextLogicalDescriptor;
|
||||||
ULONG BufferSize; // Size of the buffer
|
ULONG BufferSize; // Size of the buffer
|
||||||
PVOID BufferLogical; // Logical pointer to the buffer
|
PVOID BufferLogical; // Logical pointer to the buffer
|
||||||
PVOID Request; // pointer to IUSBRequest
|
|
||||||
}OHCI_GENERAL_TD, *POHCI_GENERAL_TD;
|
}OHCI_GENERAL_TD, *POHCI_GENERAL_TD;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -436,6 +436,13 @@ DECLARE_INTERFACE_(IUSBRequest, IUnknown)
|
||||||
|
|
||||||
virtual BOOLEAN IsRequestInitialized() = 0;
|
virtual BOOLEAN IsRequestInitialized() = 0;
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// CompletionCallback
|
||||||
|
//
|
||||||
|
// Description: notifies request that the endpoint descriptor is complete
|
||||||
|
|
||||||
|
virtual VOID CompletionCallback(struct _OHCI_ENDPOINT_DESCRIPTOR * OutDescriptor) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -496,6 +503,14 @@ DECLARE_INTERFACE_(IUSBQueue, IUnknown)
|
||||||
|
|
||||||
virtual NTSTATUS CreateUSBRequest(IUSBRequest **OutRequest) = 0;
|
virtual NTSTATUS CreateUSBRequest(IUSBRequest **OutRequest) = 0;
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// TransferDescriptorCompletionCallback
|
||||||
|
//
|
||||||
|
// Description: notifies the queue that a transfer was completed
|
||||||
|
|
||||||
|
virtual VOID TransferDescriptorCompletionCallback(ULONG TransferDescriptorLogicalAddress) = 0;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef IUSBQueue *PUSBQUEUE;
|
typedef IUSBQueue *PUSBQUEUE;
|
||||||
|
|
|
@ -706,6 +706,11 @@ CUSBDevice::CreateConfigurationDescriptor(
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// zero buffer
|
||||||
|
//
|
||||||
|
RtlZeroMemory(Buffer, PAGE_SIZE);
|
||||||
|
|
||||||
//
|
//
|
||||||
// build setup packet
|
// build setup packet
|
||||||
//
|
//
|
||||||
|
|
|
@ -33,11 +33,17 @@ public:
|
||||||
return m_Ref;
|
return m_Ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// com
|
||||||
virtual NTSTATUS Initialize(IN PUSBHARDWAREDEVICE Hardware, PDMA_ADAPTER AdapterObject, IN PDMAMEMORYMANAGER MemManager, IN OPTIONAL PKSPIN_LOCK Lock);
|
virtual NTSTATUS Initialize(IN PUSBHARDWAREDEVICE Hardware, PDMA_ADAPTER AdapterObject, IN PDMAMEMORYMANAGER MemManager, IN OPTIONAL PKSPIN_LOCK Lock);
|
||||||
virtual ULONG GetPendingRequestCount();
|
virtual ULONG GetPendingRequestCount();
|
||||||
virtual NTSTATUS AddUSBRequest(IUSBRequest * Request);
|
virtual NTSTATUS AddUSBRequest(IUSBRequest * Request);
|
||||||
virtual NTSTATUS CancelRequests();
|
virtual NTSTATUS CancelRequests();
|
||||||
virtual NTSTATUS CreateUSBRequest(IUSBRequest **OutRequest);
|
virtual NTSTATUS CreateUSBRequest(IUSBRequest **OutRequest);
|
||||||
|
virtual VOID TransferDescriptorCompletionCallback(ULONG TransferDescriptorLogicalAddress);
|
||||||
|
|
||||||
|
// local functions
|
||||||
|
BOOLEAN IsTransferDescriptorInEndpoint(IN POHCI_ENDPOINT_DESCRIPTOR EndpointDescriptor, IN ULONG TransferDescriptorLogicalAddress);
|
||||||
|
NTSTATUS FindTransferDescriptorInEndpoint(IN POHCI_ENDPOINT_DESCRIPTOR EndpointDescriptor, IN ULONG TransferDescriptorLogicalAddress, OUT POHCI_ENDPOINT_DESCRIPTOR *OutEndpointDescriptor, OUT POHCI_ENDPOINT_DESCRIPTOR *OutPreviousEndpointDescriptor);
|
||||||
|
|
||||||
// constructor / destructor
|
// constructor / destructor
|
||||||
CUSBQueue(IUnknown *OuterUnknown){}
|
CUSBQueue(IUnknown *OuterUnknown){}
|
||||||
|
@ -218,13 +224,14 @@ CUSBQueue::AddUSBRequest(
|
||||||
// set descriptor active
|
// set descriptor active
|
||||||
//
|
//
|
||||||
Descriptor->Flags &= ~OHCI_ENDPOINT_SKIP;
|
Descriptor->Flags &= ~OHCI_ENDPOINT_SKIP;
|
||||||
|
//HeadDescriptor->Flags &= ~OHCI_ENDPOINT_SKIP;
|
||||||
|
|
||||||
//
|
//
|
||||||
// notify hardware of our request
|
// notify hardware of our request
|
||||||
//
|
//
|
||||||
m_Hardware->HeadEndpointDescriptorModified(Type);
|
m_Hardware->HeadEndpointDescriptorModified(Type);
|
||||||
|
|
||||||
DPRINT1("Request added to queue\n");
|
DPRINT1("Request %x %x added to queue\n", Descriptor, Descriptor->PhysicalAddress);
|
||||||
|
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
|
@ -255,6 +262,142 @@ CUSBQueue::CreateUSBRequest(
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
CUSBQueue::FindTransferDescriptorInEndpoint(
|
||||||
|
IN POHCI_ENDPOINT_DESCRIPTOR EndpointDescriptor,
|
||||||
|
IN ULONG TransferDescriptorLogicalAddress,
|
||||||
|
OUT POHCI_ENDPOINT_DESCRIPTOR *OutEndpointDescriptor,
|
||||||
|
OUT POHCI_ENDPOINT_DESCRIPTOR *OutPreviousEndpointDescriptor)
|
||||||
|
{
|
||||||
|
POHCI_ENDPOINT_DESCRIPTOR LastDescriptor = EndpointDescriptor;
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// skip first endpoint head
|
||||||
|
//
|
||||||
|
EndpointDescriptor = (POHCI_ENDPOINT_DESCRIPTOR)EndpointDescriptor->NextDescriptor;
|
||||||
|
|
||||||
|
while(EndpointDescriptor)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// check if the transfer descriptor is inside the list
|
||||||
|
//
|
||||||
|
if (IsTransferDescriptorInEndpoint(EndpointDescriptor, TransferDescriptorLogicalAddress))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// found endpoint
|
||||||
|
//
|
||||||
|
*OutEndpointDescriptor = EndpointDescriptor;
|
||||||
|
*OutPreviousEndpointDescriptor = LastDescriptor;
|
||||||
|
|
||||||
|
//
|
||||||
|
// done
|
||||||
|
//
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// store last endpoint
|
||||||
|
//
|
||||||
|
LastDescriptor = EndpointDescriptor;
|
||||||
|
|
||||||
|
//
|
||||||
|
// move to next
|
||||||
|
//
|
||||||
|
EndpointDescriptor = (POHCI_ENDPOINT_DESCRIPTOR)EndpointDescriptor->NextDescriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// failed to endpoint
|
||||||
|
//
|
||||||
|
return STATUS_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
CUSBQueue::IsTransferDescriptorInEndpoint(
|
||||||
|
IN POHCI_ENDPOINT_DESCRIPTOR EndpointDescriptor,
|
||||||
|
IN ULONG TransferDescriptorLogicalAddress)
|
||||||
|
{
|
||||||
|
POHCI_GENERAL_TD Descriptor;
|
||||||
|
|
||||||
|
//
|
||||||
|
// get first general transfer descriptor
|
||||||
|
//
|
||||||
|
Descriptor = (POHCI_GENERAL_TD)EndpointDescriptor->HeadLogicalDescriptor;
|
||||||
|
|
||||||
|
//
|
||||||
|
// sanity check
|
||||||
|
//
|
||||||
|
ASSERT(Descriptor);
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (Descriptor->PhysicalAddress.LowPart == TransferDescriptorLogicalAddress)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// found descriptor
|
||||||
|
//
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// move to next
|
||||||
|
//
|
||||||
|
Descriptor = (POHCI_GENERAL_TD)Descriptor->NextLogicalDescriptor;
|
||||||
|
}while(Descriptor);
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// no descriptor found
|
||||||
|
//
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VOID
|
||||||
|
CUSBQueue::TransferDescriptorCompletionCallback(
|
||||||
|
ULONG TransferDescriptorLogicalAddress)
|
||||||
|
{
|
||||||
|
POHCI_ENDPOINT_DESCRIPTOR EndpointDescriptor, PreviousEndpointDescriptor;
|
||||||
|
NTSTATUS Status;
|
||||||
|
PUSBREQUEST Request;
|
||||||
|
|
||||||
|
//
|
||||||
|
// find transfer descriptor in control list
|
||||||
|
//
|
||||||
|
Status = FindTransferDescriptorInEndpoint(m_ControlHeadEndpointDescriptor, TransferDescriptorLogicalAddress, &EndpointDescriptor, &PreviousEndpointDescriptor);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// FIXME: make sure this is ok
|
||||||
|
// unlink descriptor
|
||||||
|
//
|
||||||
|
PreviousEndpointDescriptor->NextDescriptor = EndpointDescriptor->NextDescriptor;
|
||||||
|
PreviousEndpointDescriptor->NextPhysicalEndpoint = EndpointDescriptor->NextPhysicalEndpoint;
|
||||||
|
|
||||||
|
//
|
||||||
|
// get corresponding request
|
||||||
|
//
|
||||||
|
Request = PUSBREQUEST(EndpointDescriptor->Request);
|
||||||
|
|
||||||
|
//
|
||||||
|
// notify of completion
|
||||||
|
//
|
||||||
|
Request->CompletionCallback(EndpointDescriptor);
|
||||||
|
|
||||||
|
//
|
||||||
|
// FIXME: check if complete
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
// release request
|
||||||
|
//
|
||||||
|
Request->Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
CreateUSBQueue(
|
CreateUSBQueue(
|
||||||
|
|
|
@ -44,7 +44,7 @@ public:
|
||||||
virtual VOID GetResultStatus(OUT OPTIONAL NTSTATUS *NtStatusCode, OUT OPTIONAL PULONG UrbStatusCode);
|
virtual VOID GetResultStatus(OUT OPTIONAL NTSTATUS *NtStatusCode, OUT OPTIONAL PULONG UrbStatusCode);
|
||||||
virtual BOOLEAN IsRequestInitialized();
|
virtual BOOLEAN IsRequestInitialized();
|
||||||
virtual BOOLEAN IsQueueHeadComplete(struct _QUEUE_HEAD * QueueHead);
|
virtual BOOLEAN IsQueueHeadComplete(struct _QUEUE_HEAD * QueueHead);
|
||||||
|
virtual VOID CompletionCallback(struct _OHCI_ENDPOINT_DESCRIPTOR * OutDescriptor);
|
||||||
|
|
||||||
// local functions
|
// local functions
|
||||||
ULONG InternalGetTransferType();
|
ULONG InternalGetTransferType();
|
||||||
|
@ -635,7 +635,7 @@ NTSTATUS
|
||||||
CUSBRequest::BuildControlTransferDescriptor(
|
CUSBRequest::BuildControlTransferDescriptor(
|
||||||
POHCI_ENDPOINT_DESCRIPTOR * OutEndpointDescriptor)
|
POHCI_ENDPOINT_DESCRIPTOR * OutEndpointDescriptor)
|
||||||
{
|
{
|
||||||
POHCI_GENERAL_TD SetupDescriptor, StatusDescriptor, DataDescriptor = NULL;
|
POHCI_GENERAL_TD SetupDescriptor, StatusDescriptor, DataDescriptor = NULL, LastDescriptor;
|
||||||
POHCI_ENDPOINT_DESCRIPTOR EndpointDescriptor;
|
POHCI_ENDPOINT_DESCRIPTOR EndpointDescriptor;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
@ -680,6 +680,22 @@ CUSBRequest::BuildControlTransferDescriptor(
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// finally create the last descriptor
|
||||||
|
//
|
||||||
|
Status = CreateGeneralTransferDescriptor(&LastDescriptor, 0);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// failed to create status descriptor
|
||||||
|
//
|
||||||
|
FreeDescriptor(SetupDescriptor);
|
||||||
|
FreeDescriptor(StatusDescriptor);
|
||||||
|
m_DmaManager->Release(EndpointDescriptor, sizeof(OHCI_ENDPOINT_DESCRIPTOR));
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (m_TransferBufferLength)
|
if (m_TransferBufferLength)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
|
@ -690,7 +706,7 @@ CUSBRequest::BuildControlTransferDescriptor(
|
||||||
//
|
//
|
||||||
// now create the data descriptor
|
// now create the data descriptor
|
||||||
//
|
//
|
||||||
Status = CreateGeneralTransferDescriptor(&DataDescriptor, 0);
|
Status = CreateGeneralTransferDescriptor(&DataDescriptor, m_TransferBufferLength);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
|
@ -699,6 +715,7 @@ CUSBRequest::BuildControlTransferDescriptor(
|
||||||
m_DmaManager->Release(EndpointDescriptor, sizeof(OHCI_ENDPOINT_DESCRIPTOR));
|
m_DmaManager->Release(EndpointDescriptor, sizeof(OHCI_ENDPOINT_DESCRIPTOR));
|
||||||
FreeDescriptor(SetupDescriptor);
|
FreeDescriptor(SetupDescriptor);
|
||||||
FreeDescriptor(StatusDescriptor);
|
FreeDescriptor(StatusDescriptor);
|
||||||
|
FreeDescriptor(LastDescriptor);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -762,11 +779,20 @@ CUSBRequest::BuildControlTransferDescriptor(
|
||||||
// link setup descriptor to data descriptor
|
// link setup descriptor to data descriptor
|
||||||
//
|
//
|
||||||
SetupDescriptor->NextPhysicalDescriptor = DataDescriptor->PhysicalAddress.LowPart;
|
SetupDescriptor->NextPhysicalDescriptor = DataDescriptor->PhysicalAddress.LowPart;
|
||||||
|
SetupDescriptor->NextLogicalDescriptor = DataDescriptor;
|
||||||
|
|
||||||
//
|
//
|
||||||
// FIXME: should link to last data descriptor to status descriptor
|
// link data descriptor to status descriptor
|
||||||
|
// FIXME: check if there are more data descriptors
|
||||||
//
|
//
|
||||||
DataDescriptor->NextPhysicalDescriptor = StatusDescriptor->PhysicalAddress.LowPart;
|
DataDescriptor->NextPhysicalDescriptor = StatusDescriptor->PhysicalAddress.LowPart;
|
||||||
|
DataDescriptor->NextLogicalDescriptor = StatusDescriptor;
|
||||||
|
|
||||||
|
//
|
||||||
|
// link status descriptor to last descriptor
|
||||||
|
//
|
||||||
|
StatusDescriptor->NextPhysicalDescriptor = LastDescriptor->PhysicalAddress.LowPart;
|
||||||
|
StatusDescriptor->NextLogicalDescriptor = LastDescriptor;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -774,14 +800,21 @@ CUSBRequest::BuildControlTransferDescriptor(
|
||||||
// link setup descriptor to status descriptor
|
// link setup descriptor to status descriptor
|
||||||
//
|
//
|
||||||
SetupDescriptor->NextPhysicalDescriptor = StatusDescriptor->PhysicalAddress.LowPart;
|
SetupDescriptor->NextPhysicalDescriptor = StatusDescriptor->PhysicalAddress.LowPart;
|
||||||
|
SetupDescriptor->NextLogicalDescriptor = StatusDescriptor;
|
||||||
|
|
||||||
|
//
|
||||||
|
// link status descriptor to last descriptor
|
||||||
|
//
|
||||||
|
StatusDescriptor->NextPhysicalDescriptor = LastDescriptor->PhysicalAddress.LowPart;
|
||||||
|
StatusDescriptor->NextLogicalDescriptor = LastDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// now link descriptor to endpoint
|
// now link descriptor to endpoint
|
||||||
//
|
//
|
||||||
EndpointDescriptor->HeadPhysicalDescriptor = SetupDescriptor->PhysicalAddress.LowPart;
|
EndpointDescriptor->HeadPhysicalDescriptor = SetupDescriptor->PhysicalAddress.LowPart;
|
||||||
EndpointDescriptor->TailPhysicalDescriptor = SetupDescriptor->PhysicalAddress.LowPart;
|
EndpointDescriptor->TailPhysicalDescriptor = LastDescriptor->PhysicalAddress.LowPart;
|
||||||
DPRINT1("CUSBRequest::BuildControlTransferDescriptor done\n");
|
EndpointDescriptor->HeadLogicalDescriptor = SetupDescriptor;
|
||||||
|
|
||||||
//
|
//
|
||||||
// store result
|
// store result
|
||||||
|
@ -887,6 +920,32 @@ CUSBRequest::GetResultStatus(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VOID
|
||||||
|
CUSBRequest::CompletionCallback(
|
||||||
|
struct _OHCI_ENDPOINT_DESCRIPTOR * OutDescriptor)
|
||||||
|
{
|
||||||
|
DPRINT1("CUSBRequest::CompletionCallback\n");
|
||||||
|
|
||||||
|
//
|
||||||
|
// set status code
|
||||||
|
//
|
||||||
|
m_NtStatusCode = STATUS_SUCCESS;
|
||||||
|
m_UrbStatusCode = USBD_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
ASSERT(!m_Irp);
|
||||||
|
|
||||||
|
//
|
||||||
|
// FIXME: cleanup descriptors
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
// signal completion event
|
||||||
|
//
|
||||||
|
PC_ASSERT(m_CompletionEvent);
|
||||||
|
KeSetEvent(m_CompletionEvent, 0, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------------
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
CUSBRequest::IsRequestInitialized()
|
CUSBRequest::IsRequestInitialized()
|
||||||
|
|
Loading…
Reference in a new issue