mirror of
https://github.com/reactos/reactos.git
synced 2025-08-06 22:02:57 +00:00
[USBEHCI_NEW]
- Fix warning because comparing signed vs unsigned - Implement function for retrieving the device descriptor - Implement function for retrieving a configuration descriptor (including contained interface descriptor and endpoint descriptor) - Cleanup interface for IUSBRequest: - When caller initializes IUSBRequest with an IRP, then the operation mode is asynchronously. Therefore when the request is completed, IUSBRequest::ShouldReleaseRequestAfterCompletion will return true, which makes IUSBQueue call Release on IUSBRequest - When the caller initializes IUSBRequest with an setup packet, the operation mode is synchronously. After submitting the IUSBRequest to queue, the caller should call IUSBRequest::GetResultStatus. This function will then block untill the operation has been completed. However, the caller needs to call Release() as those requests are not cleaned up by the IUSBQueue svn path=/branches/usb-bringup/; revision=51406
This commit is contained in:
parent
9b8bc8512c
commit
d4f7a44a18
4 changed files with 647 additions and 155 deletions
|
@ -38,12 +38,14 @@ public:
|
|||
// IUSBRequest interface functions
|
||||
virtual NTSTATUS InitializeWithSetupPacket(IN PDMAMEMORYMANAGER DmaManager, IN PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket, IN OUT ULONG TransferBufferLength, IN OUT PMDL TransferBuffer);
|
||||
virtual NTSTATUS InitializeWithIrp(IN PDMAMEMORYMANAGER DmaManager, IN OUT PIRP Irp);
|
||||
virtual NTSTATUS SetCompletionEvent(IN PKEVENT Event);
|
||||
virtual VOID CompletionCallback(IN NTSTATUS NtStatusCode, IN ULONG UrbStatusCode);
|
||||
virtual VOID CancelCallback(IN NTSTATUS NtStatusCode);
|
||||
virtual VOID CompletionCallback(IN NTSTATUS NtStatusCode, IN ULONG UrbStatusCode, IN struct _QUEUE_HEAD *QueueHead);
|
||||
virtual VOID CancelCallback(IN NTSTATUS NtStatusCode, IN struct _QUEUE_HEAD *QueueHead);
|
||||
virtual NTSTATUS GetQueueHead(struct _QUEUE_HEAD ** OutHead);
|
||||
virtual BOOLEAN IsRequestComplete();
|
||||
virtual ULONG GetTransferType();
|
||||
virtual VOID GetResultStatus(OUT OPTIONAL NTSTATUS *NtStatusCode, OUT OPTIONAL PULONG UrbStatusCode);
|
||||
virtual BOOLEAN IsRequestInitialized();
|
||||
virtual BOOLEAN ShouldReleaseRequestAfterCompletion();
|
||||
|
||||
// local functions
|
||||
ULONG InternalGetTransferType();
|
||||
|
@ -60,17 +62,60 @@ public:
|
|||
|
||||
protected:
|
||||
LONG m_Ref;
|
||||
|
||||
//
|
||||
// memory manager for allocating setup packet / queue head / transfer descriptors
|
||||
//
|
||||
PDMAMEMORYMANAGER m_DmaManager;
|
||||
PUSB_DEFAULT_PIPE_SETUP_PACKET m_SetupPacket;
|
||||
ULONG m_TransferBufferLength;
|
||||
PMDL m_TransferBufferMDL;
|
||||
|
||||
//
|
||||
// caller provided irp packet containing URB request
|
||||
//
|
||||
PIRP m_Irp;
|
||||
|
||||
//
|
||||
// transfer buffer length
|
||||
//
|
||||
ULONG m_TransferBufferLength;
|
||||
|
||||
//
|
||||
// transfer buffer MDL
|
||||
//
|
||||
PMDL m_TransferBufferMDL;
|
||||
|
||||
|
||||
//
|
||||
// caller provided setup packet
|
||||
//
|
||||
PUSB_DEFAULT_PIPE_SETUP_PACKET m_SetupPacket;
|
||||
|
||||
//
|
||||
// completion event for callers who initialized request with setup packet
|
||||
//
|
||||
PKEVENT m_CompletionEvent;
|
||||
|
||||
//
|
||||
// DMA queue head
|
||||
//
|
||||
PQUEUE_HEAD m_QueueHead;
|
||||
|
||||
//
|
||||
// DMA transfer descriptors linked to the queue head
|
||||
//
|
||||
PQUEUE_TRANSFER_DESCRIPTOR m_TransferDescriptors[3];
|
||||
|
||||
//
|
||||
// allocated setup packet from the DMA pool
|
||||
//
|
||||
PUSB_DEFAULT_PIPE_SETUP_PACKET m_DescriptorPacket;
|
||||
PHYSICAL_ADDRESS m_DescriptorSetupPacket;
|
||||
|
||||
//
|
||||
// stores the result of the operation
|
||||
//
|
||||
NTSTATUS m_NtStatusCode;
|
||||
ULONG m_UrbStatusCode;
|
||||
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
@ -105,6 +150,23 @@ CUSBRequest::InitializeWithSetupPacket(
|
|||
m_TransferBufferLength = TransferBufferLength;
|
||||
m_TransferBufferMDL = TransferBuffer;
|
||||
|
||||
//
|
||||
// allocate completion event
|
||||
//
|
||||
m_CompletionEvent = (PKEVENT)ExAllocatePoolWithTag(NonPagedPool, sizeof(KEVENT), TAG_USBEHCI);
|
||||
if (!m_CompletionEvent)
|
||||
{
|
||||
//
|
||||
// failed to allocate completion event
|
||||
//
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
//
|
||||
// initialize completion event
|
||||
//
|
||||
KeInitializeEvent(m_CompletionEvent, NotificationEvent, FALSE);
|
||||
|
||||
//
|
||||
// done
|
||||
//
|
||||
|
@ -166,7 +228,7 @@ CUSBRequest::InitializeWithIrp(
|
|||
if (Urb->UrbBulkOrInterruptTransfer.TransferBufferLength)
|
||||
{
|
||||
//
|
||||
// it must have an MDL
|
||||
// FIXME: it must have an MDL
|
||||
//
|
||||
PC_ASSERT(Urb->UrbBulkOrInterruptTransfer.TransferBufferMDL);
|
||||
|
||||
|
@ -189,38 +251,27 @@ CUSBRequest::InitializeWithIrp(
|
|||
return STATUS_SUCCESS;
|
||||
|
||||
}
|
||||
//----------------------------------------------------------------------------------------
|
||||
NTSTATUS
|
||||
CUSBRequest::SetCompletionEvent(
|
||||
IN PKEVENT Event)
|
||||
{
|
||||
if (m_QueueHead)
|
||||
{
|
||||
//
|
||||
// WTF? operation is already in progress
|
||||
//
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
//
|
||||
// store completion event
|
||||
//
|
||||
m_CompletionEvent = Event;
|
||||
|
||||
//
|
||||
// done
|
||||
//
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------
|
||||
VOID
|
||||
CUSBRequest::CompletionCallback(
|
||||
IN NTSTATUS NtStatusCode,
|
||||
IN ULONG UrbStatusCode)
|
||||
IN ULONG UrbStatusCode,
|
||||
IN struct _QUEUE_HEAD *QueueHead)
|
||||
{
|
||||
PIO_STACK_LOCATION IoStack;
|
||||
PURB Urb;
|
||||
|
||||
//
|
||||
// FIXME: support linked queue heads
|
||||
//
|
||||
|
||||
//
|
||||
// store completion code
|
||||
//
|
||||
m_NtStatusCode = NtStatusCode;
|
||||
m_UrbStatusCode = UrbStatusCode;
|
||||
|
||||
if (m_Irp)
|
||||
{
|
||||
//
|
||||
|
@ -260,23 +311,33 @@ CUSBRequest::CompletionCallback(
|
|||
//
|
||||
IoCompleteRequest(m_Irp, IO_NO_INCREMENT);
|
||||
}
|
||||
|
||||
if (m_CompletionEvent)
|
||||
else
|
||||
{
|
||||
//
|
||||
// FIXME: make sure the request was not split
|
||||
// signal completion event
|
||||
//
|
||||
PC_ASSERT(m_CompletionEvent);
|
||||
KeSetEvent(m_CompletionEvent, 0, FALSE);
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------------------
|
||||
VOID
|
||||
CUSBRequest::CancelCallback(
|
||||
IN NTSTATUS NtStatusCode)
|
||||
IN NTSTATUS NtStatusCode,
|
||||
IN struct _QUEUE_HEAD *QueueHead)
|
||||
{
|
||||
PIO_STACK_LOCATION IoStack;
|
||||
PURB Urb;
|
||||
|
||||
//
|
||||
// FIXME: support linked queue heads
|
||||
//
|
||||
|
||||
//
|
||||
// store cancelleation code
|
||||
//
|
||||
m_NtStatusCode = NtStatusCode;
|
||||
|
||||
if (m_Irp)
|
||||
{
|
||||
//
|
||||
|
@ -306,12 +367,12 @@ CUSBRequest::CancelCallback(
|
|||
//
|
||||
IoCompleteRequest(m_Irp, IO_NO_INCREMENT);
|
||||
}
|
||||
|
||||
if (m_CompletionEvent)
|
||||
else
|
||||
{
|
||||
//
|
||||
// FIXME: make sure the request was not split
|
||||
// signal completion event
|
||||
//
|
||||
PC_ASSERT(m_CompletionEvent);
|
||||
KeSetEvent(m_CompletionEvent, 0, FALSE);
|
||||
}
|
||||
}
|
||||
|
@ -370,6 +431,7 @@ CUSBRequest::IsRequestComplete()
|
|||
//
|
||||
// FIXME: check if request was split
|
||||
//
|
||||
UNIMPLEMENTED
|
||||
return TRUE;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
@ -452,7 +514,6 @@ CUSBRequest::BuildControlTransferQueueHead(
|
|||
ULONG NumTransferDescriptors, Index;
|
||||
PQUEUE_HEAD QueueHead;
|
||||
|
||||
|
||||
//
|
||||
// first allocate the queue head
|
||||
//
|
||||
|
@ -802,3 +863,75 @@ CUSBRequest::BuildSetupPacket()
|
|||
return Status;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
VOID
|
||||
CUSBRequest::GetResultStatus(
|
||||
OUT OPTIONAL NTSTATUS * NtStatusCode,
|
||||
OUT OPTIONAL PULONG UrbStatusCode)
|
||||
{
|
||||
//
|
||||
// sanity check
|
||||
//
|
||||
PC_ASSERT(m_CompletionEvent);
|
||||
|
||||
//
|
||||
// wait for the operation to complete
|
||||
//
|
||||
KeWaitForSingleObject(m_CompletionEvent, Executive, KernelMode, FALSE, NULL);
|
||||
|
||||
//
|
||||
// copy status
|
||||
//
|
||||
if (NtStatusCode)
|
||||
{
|
||||
*NtStatusCode = m_NtStatusCode;
|
||||
}
|
||||
|
||||
//
|
||||
// copy urb status
|
||||
//
|
||||
if (UrbStatusCode)
|
||||
{
|
||||
*UrbStatusCode = m_UrbStatusCode;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
BOOLEAN
|
||||
CUSBRequest::IsRequestInitialized()
|
||||
{
|
||||
if (m_Irp || m_SetupPacket)
|
||||
{
|
||||
//
|
||||
// request is initialized
|
||||
//
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//
|
||||
// request is not initialized
|
||||
//
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
BOOLEAN
|
||||
CUSBRequest::ShouldReleaseRequestAfterCompletion()
|
||||
{
|
||||
if (m_Irp)
|
||||
{
|
||||
//
|
||||
// the request is completed, release it
|
||||
//
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// created with an setup packet, don't release
|
||||
//
|
||||
return FALSE;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue