mirror of
https://github.com/reactos/reactos.git
synced 2024-09-12 22:02:18 +00:00
[USBEHCI_NEW]
hub_controller: - Implement StatusChangeEndpointCallBack called by HardwareDevice class when port status has changed on controller. - Move Status Change Endpoint query code to IQueryStatusChageEndpoint as it is also needed by StatusChangeEndpointCallBack. usb_request: - Implement InternalCreateUsbRequest. usb_queue: - Implement CreateUsbRequest and AddUsbRequest hardware: - Implement GetAsyncListRegister and GetPeriodicListRegister. - Implement SetStatusChangeEndpointCallBack for setting callback and context. Call the callback when a port status changes. - Initialize the UsbQueue after creating the AsyncQueueHead, as the UsbQueue calls will call back with GetAsyncListRegister. svn path=/branches/usb-bringup/; revision=51407
This commit is contained in:
parent
d4f7a44a18
commit
4dff45da57
|
@ -12,6 +12,8 @@
|
||||||
#include "usbehci.h"
|
#include "usbehci.h"
|
||||||
#include "hardware.h"
|
#include "hardware.h"
|
||||||
|
|
||||||
|
typedef VOID __stdcall HD_INIT_CALLBACK(IN PVOID CallBackContext);
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
NTAPI
|
NTAPI
|
||||||
InterruptServiceRoutine(
|
InterruptServiceRoutine(
|
||||||
|
@ -66,6 +68,10 @@ public:
|
||||||
|
|
||||||
VOID SetAsyncListRegister(ULONG PhysicalAddress);
|
VOID SetAsyncListRegister(ULONG PhysicalAddress);
|
||||||
VOID SetPeriodicListRegister(ULONG PhysicalAddress);
|
VOID SetPeriodicListRegister(ULONG PhysicalAddress);
|
||||||
|
ULONG GetAsyncListRegister();
|
||||||
|
ULONG GetPeriodicListRegister();
|
||||||
|
|
||||||
|
VOID SetStatusChangeEndpointCallBack(PVOID CallBack, PVOID Context);
|
||||||
|
|
||||||
KIRQL AcquireDeviceLock(void);
|
KIRQL AcquireDeviceLock(void);
|
||||||
VOID ReleaseDeviceLock(KIRQL OldLevel);
|
VOID ReleaseDeviceLock(KIRQL OldLevel);
|
||||||
|
@ -100,7 +106,8 @@ protected:
|
||||||
PQUEUE_HEAD AsyncQueueHead;
|
PQUEUE_HEAD AsyncQueueHead;
|
||||||
PUSBQUEUE m_UsbQueue;
|
PUSBQUEUE m_UsbQueue;
|
||||||
PDMAMEMORYMANAGER m_MemoryManager;
|
PDMAMEMORYMANAGER m_MemoryManager;
|
||||||
|
HD_INIT_CALLBACK* m_SCECallBack;
|
||||||
|
PVOID m_SCEContext;
|
||||||
VOID SetCommandRegister(PEHCI_USBCMD_CONTENT UsbCmd);
|
VOID SetCommandRegister(PEHCI_USBCMD_CONTENT UsbCmd);
|
||||||
VOID GetCommandRegister(PEHCI_USBCMD_CONTENT UsbCmd);
|
VOID GetCommandRegister(PEHCI_USBCMD_CONTENT UsbCmd);
|
||||||
ULONG EHCI_READ_REGISTER_ULONG(ULONG Offset);
|
ULONG EHCI_READ_REGISTER_ULONG(ULONG Offset);
|
||||||
|
@ -385,16 +392,6 @@ CUSBHardwareDevice::PnpStart(
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Initialize the UsbQueue now that we have an AdapterObject.
|
|
||||||
//
|
|
||||||
Status = m_UsbQueue->Initialize(PUSBHARDWAREDEVICE(this), m_Adapter, NULL);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT1("Failed to Initialize the UsbQueue\n");
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Create a queuehead for the Async Register
|
// Create a queuehead for the Async Register
|
||||||
//
|
//
|
||||||
|
@ -413,8 +410,20 @@ CUSBHardwareDevice::PnpStart(
|
||||||
AsyncQueueHead->EndPointCharacteristics.EndPointSpeed = QH_ENDPOINT_HIGHSPEED;
|
AsyncQueueHead->EndPointCharacteristics.EndPointSpeed = QH_ENDPOINT_HIGHSPEED;
|
||||||
AsyncQueueHead->EndPointCapabilities.NumberOfTransactionPerFrame = 0x03;
|
AsyncQueueHead->EndPointCapabilities.NumberOfTransactionPerFrame = 0x03;
|
||||||
|
|
||||||
|
InitializeListHead(&AsyncQueueHead->LinkedQueueHeads);
|
||||||
|
|
||||||
SetAsyncListRegister(AsyncQueueHead->PhysicalAddr);
|
SetAsyncListRegister(AsyncQueueHead->PhysicalAddr);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialize the UsbQueue now that we have an AdapterObject.
|
||||||
|
//
|
||||||
|
Status = m_UsbQueue->Initialize(PUSBHARDWAREDEVICE(this), m_Adapter, NULL);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("Failed to Initialize the UsbQueue\n");
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Start the controller
|
// Start the controller
|
||||||
//
|
//
|
||||||
|
@ -838,6 +847,26 @@ CUSBHardwareDevice::SetPeriodicListRegister(
|
||||||
EHCI_WRITE_REGISTER_ULONG(EHCI_PERIODICLISTBASE, PhysicalAddress);
|
EHCI_WRITE_REGISTER_ULONG(EHCI_PERIODICLISTBASE, PhysicalAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ULONG
|
||||||
|
CUSBHardwareDevice::GetAsyncListRegister()
|
||||||
|
{
|
||||||
|
return PhysicalAddress.LowPart;
|
||||||
|
}
|
||||||
|
|
||||||
|
ULONG CUSBHardwareDevice::GetPeriodicListRegister()
|
||||||
|
{
|
||||||
|
UNIMPLEMENTED
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID CUSBHardwareDevice::SetStatusChangeEndpointCallBack(
|
||||||
|
PVOID CallBack,
|
||||||
|
PVOID Context)
|
||||||
|
{
|
||||||
|
m_SCECallBack = (HD_INIT_CALLBACK*)CallBack;
|
||||||
|
m_SCEContext = Context;
|
||||||
|
}
|
||||||
|
|
||||||
KIRQL
|
KIRQL
|
||||||
CUSBHardwareDevice::AcquireDeviceLock(void)
|
CUSBHardwareDevice::AcquireDeviceLock(void)
|
||||||
{
|
{
|
||||||
|
@ -937,7 +966,7 @@ EhciDefferedRoutine(
|
||||||
//
|
//
|
||||||
// Clear the port change status
|
// Clear the port change status
|
||||||
//
|
//
|
||||||
This->EHCI_WRITE_REGISTER_ULONG(EHCI_PORTSC + (4 * i), PortStatus | EHCI_PRT_CONNECTSTATUSCHANGE);
|
//This->EHCI_WRITE_REGISTER_ULONG(EHCI_PORTSC + (4 * i), PortStatus | EHCI_PRT_CONNECTSTATUSCHANGE);
|
||||||
|
|
||||||
if (PortStatus & EHCI_PRT_CONNECTED)
|
if (PortStatus & EHCI_PRT_CONNECTED)
|
||||||
{
|
{
|
||||||
|
@ -964,6 +993,7 @@ EhciDefferedRoutine(
|
||||||
// FIXME: Is a port reset needed, or does hub driver request this?
|
// FIXME: Is a port reset needed, or does hub driver request this?
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
This->m_SCECallBack(This->m_SCEContext);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -11,6 +11,9 @@
|
||||||
#define INITGUID
|
#define INITGUID
|
||||||
#include "usbehci.h"
|
#include "usbehci.h"
|
||||||
|
|
||||||
|
VOID StatusChangeEndpointCallBack(
|
||||||
|
PVOID Context);
|
||||||
|
|
||||||
class CHubController : public IHubController,
|
class CHubController : public IHubController,
|
||||||
public IDispatchIrp
|
public IDispatchIrp
|
||||||
{
|
{
|
||||||
|
@ -63,6 +66,7 @@ public:
|
||||||
NTSTATUS HandleClassOther(IN OUT PIRP Irp, PURB Urb);
|
NTSTATUS HandleClassOther(IN OUT PIRP Irp, PURB Urb);
|
||||||
NTSTATUS HandleBulkOrInterruptTransfer(IN OUT PIRP Irp, PURB Urb);
|
NTSTATUS HandleBulkOrInterruptTransfer(IN OUT PIRP Irp, PURB Urb);
|
||||||
|
|
||||||
|
friend VOID StatusChangeEndpointCallBack(PVOID Context);
|
||||||
|
|
||||||
// constructor / destructor
|
// constructor / destructor
|
||||||
CHubController(IUnknown *OuterUnknown){}
|
CHubController(IUnknown *OuterUnknown){}
|
||||||
|
@ -91,6 +95,9 @@ protected:
|
||||||
PULONG m_DeviceAddressBitmapBuffer;
|
PULONG m_DeviceAddressBitmapBuffer;
|
||||||
LIST_ENTRY m_UsbDeviceList;
|
LIST_ENTRY m_UsbDeviceList;
|
||||||
PIRP m_PendingSCEIrp;
|
PIRP m_PendingSCEIrp;
|
||||||
|
|
||||||
|
//Internal Functions
|
||||||
|
BOOLEAN QueryStatusChageEndpoint(PIRP Irp);
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
@ -253,6 +260,10 @@ CHubController::Initialize(
|
||||||
m_DeviceDescriptor.bcdUSB = 0x200; //FIXME
|
m_DeviceDescriptor.bcdUSB = 0x200; //FIXME
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set the SCE Callback that the Hardware Device will call on port status change
|
||||||
|
//
|
||||||
|
Device->SetStatusChangeEndpointCallBack((PVOID)StatusChangeEndpointCallBack, this);
|
||||||
//
|
//
|
||||||
// clear init flag
|
// clear init flag
|
||||||
//
|
//
|
||||||
|
@ -262,6 +273,62 @@ CHubController::Initialize(
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Queries the ports to see if there has been a device connected or removed.
|
||||||
|
//
|
||||||
|
BOOLEAN
|
||||||
|
CHubController::QueryStatusChageEndpoint(
|
||||||
|
PIRP Irp)
|
||||||
|
{
|
||||||
|
ULONG PortCount, PortId;
|
||||||
|
PIO_STACK_LOCATION IoStack;
|
||||||
|
USHORT PortStatus, PortChange;
|
||||||
|
PURB Urb;
|
||||||
|
|
||||||
|
//
|
||||||
|
// get current stack location
|
||||||
|
//
|
||||||
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
ASSERT(IoStack);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Get the Urb
|
||||||
|
//
|
||||||
|
Urb = (PURB)IoStack->Parameters.Others.Argument1;
|
||||||
|
ASSERT(Urb);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Get the number of ports and check each one for device connected
|
||||||
|
//
|
||||||
|
m_Hardware->GetDeviceDetails(NULL, NULL, &PortCount, NULL);
|
||||||
|
DPRINT1("SCE Request\n");
|
||||||
|
((PULONG)Urb->UrbBulkOrInterruptTransfer.TransferBuffer)[0] = 0;
|
||||||
|
for (PortId = 0; PortId < PortCount; PortId++)
|
||||||
|
{
|
||||||
|
m_Hardware->GetPortStatus(PortId, &PortStatus, &PortChange);
|
||||||
|
|
||||||
|
DPRINT1("Port %d: Status %x, Change %x\n", PortId, PortStatus, PortChange);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Loop the ports
|
||||||
|
//
|
||||||
|
if ((PortStatus & USB_PORT_STATUS_CONNECT) && (PortChange & USB_PORT_STATUS_CONNECT))
|
||||||
|
{
|
||||||
|
DPRINT1("Device is connected on port %d\n", PortId);
|
||||||
|
// Set the value for the port number
|
||||||
|
((PUCHAR)Urb->UrbBulkOrInterruptTransfer.TransferBuffer)[0] = 1 << ((PortId + 1) & 7);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// If there were changes then return TRUE
|
||||||
|
//
|
||||||
|
if (((PULONG)Urb->UrbBulkOrInterruptTransfer.TransferBuffer)[0] != 0)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------------
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
CHubController::GetHubControllerDeviceObject(PDEVICE_OBJECT * HubDeviceObject)
|
CHubController::GetHubControllerDeviceObject(PDEVICE_OBJECT * HubDeviceObject)
|
||||||
|
@ -693,9 +760,6 @@ CHubController::HandleBulkOrInterruptTransfer(
|
||||||
IN OUT PIRP Irp,
|
IN OUT PIRP Irp,
|
||||||
PURB Urb)
|
PURB Urb)
|
||||||
{
|
{
|
||||||
ULONG PortCount, PortId;
|
|
||||||
USHORT PortStatus, PortChange;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// First check if the request is for the Status Change Endpoint
|
// First check if the request is for the Status Change Endpoint
|
||||||
//
|
//
|
||||||
|
@ -705,40 +769,11 @@ CHubController::HandleBulkOrInterruptTransfer(
|
||||||
//
|
//
|
||||||
if (Urb->UrbHeader.UsbdDeviceHandle == 0)
|
if (Urb->UrbHeader.UsbdDeviceHandle == 0)
|
||||||
{
|
{
|
||||||
//
|
|
||||||
// There should only be one SCE request pending at a time
|
|
||||||
//
|
|
||||||
ASSERT(m_PendingSCEIrp == NULL);
|
ASSERT(m_PendingSCEIrp == NULL);
|
||||||
|
if (QueryStatusChageEndpoint(Irp))
|
||||||
//
|
|
||||||
// Get the number of ports and check each one for device connected
|
|
||||||
//
|
|
||||||
m_Hardware->GetDeviceDetails(NULL, NULL, &PortCount, NULL);
|
|
||||||
DPRINT1("SCE Request\n");
|
|
||||||
DPRINT1("PortCount %d\n", PortCount);
|
|
||||||
((PULONG)Urb->UrbBulkOrInterruptTransfer.TransferBuffer)[0] = 0;
|
|
||||||
for (PortId = 0; PortId < PortCount; PortId++)
|
|
||||||
{
|
{
|
||||||
m_Hardware->GetPortStatus(PortId, &PortStatus, &PortChange);
|
|
||||||
|
|
||||||
DPRINT1("Port %d: Status %x, Change %x\n", PortId, PortStatus, PortChange);
|
|
||||||
|
|
||||||
//
|
|
||||||
// FIXME: Verify that this is correct.
|
|
||||||
//
|
|
||||||
if ((PortStatus & USB_PORT_STATUS_CONNECT) && (PortChange & USB_PORT_STATUS_CONNECT))
|
|
||||||
{
|
|
||||||
DPRINT1("Device is connected on port %d\n", PortId);
|
|
||||||
((PUCHAR)Urb->UrbBulkOrInterruptTransfer.TransferBuffer)[0] = 1 << ((PortId + 1) & 7);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// If there were changes then return SUCCESS
|
|
||||||
//
|
|
||||||
if (((PULONG)Urb->UrbBulkOrInterruptTransfer.TransferBuffer)[0] != 0)
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Else pend the IRP, to be completed when a device connects or disconnects.
|
// Else pend the IRP, to be completed when a device connects or disconnects.
|
||||||
|
@ -747,6 +782,7 @@ CHubController::HandleBulkOrInterruptTransfer(
|
||||||
IoMarkIrpPending(Irp);
|
IoMarkIrpPending(Irp);
|
||||||
return STATUS_PENDING;
|
return STATUS_PENDING;
|
||||||
}
|
}
|
||||||
|
|
||||||
UNIMPLEMENTED
|
UNIMPLEMENTED
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
@ -2843,3 +2879,22 @@ CreateHubController(
|
||||||
//
|
//
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID StatusChangeEndpointCallBack(PVOID Context)
|
||||||
|
{
|
||||||
|
CHubController* This;
|
||||||
|
PIRP Irp;
|
||||||
|
This = (CHubController*)Context;
|
||||||
|
|
||||||
|
ASSERT(This);
|
||||||
|
|
||||||
|
DPRINT1("SCE Notification!\n");
|
||||||
|
Irp = This->m_PendingSCEIrp;
|
||||||
|
This->m_PendingSCEIrp = NULL;
|
||||||
|
|
||||||
|
This->QueryStatusChageEndpoint(Irp);
|
||||||
|
|
||||||
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||||
|
Irp->IoStatus.Information = 0;
|
||||||
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
}
|
||||||
|
|
|
@ -262,6 +262,30 @@ DECLARE_INTERFACE_(IUSBHardwareDevice, IUnknown)
|
||||||
//
|
//
|
||||||
virtual VOID SetPeriodicListRegister(ULONG PhysicalAddress) = 0;
|
virtual VOID SetPeriodicListRegister(ULONG PhysicalAddress) = 0;
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// GetAsyncListRegister
|
||||||
|
//
|
||||||
|
// Description: Returns the memory address used in the Asynchronous Register
|
||||||
|
//
|
||||||
|
virtual ULONG GetAsyncListRegister() = 0;
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// GetPeriodicListRegister
|
||||||
|
//
|
||||||
|
// Description: Returns the the memory address used in the Periodic Register
|
||||||
|
//
|
||||||
|
virtual ULONG GetPeriodicListRegister() = 0;
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// SetStatusChangeEndpointCallBack
|
||||||
|
//
|
||||||
|
// Description: Used to callback to the hub controller when SCE detected
|
||||||
|
//
|
||||||
|
virtual VOID SetStatusChangeEndpointCallBack(PVOID CallBack,PVOID Context) = 0;
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// AcquireDeviceLock
|
// AcquireDeviceLock
|
||||||
|
|
|
@ -48,8 +48,8 @@ protected:
|
||||||
LONG m_Ref;
|
LONG m_Ref;
|
||||||
KSPIN_LOCK m_Lock;
|
KSPIN_LOCK m_Lock;
|
||||||
PDMA_ADAPTER m_Adapter;
|
PDMA_ADAPTER m_Adapter;
|
||||||
PQUEUE_HEAD AsyncQueueHead;
|
PQUEUE_HEAD AsyncListQueueHead;
|
||||||
PQUEUE_HEAD PendingQueueHead;
|
PQUEUE_HEAD PendingListQueueHead;
|
||||||
|
|
||||||
VOID LinkQueueHead(PQUEUE_HEAD HeadQueueHead, PQUEUE_HEAD NewQueueHead);
|
VOID LinkQueueHead(PQUEUE_HEAD HeadQueueHead, PQUEUE_HEAD NewQueueHead);
|
||||||
VOID UnlinkQueueHead(PQUEUE_HEAD QueueHead);
|
VOID UnlinkQueueHead(PQUEUE_HEAD QueueHead);
|
||||||
|
@ -93,6 +93,26 @@ CUSBQueue::Initialize(
|
||||||
//
|
//
|
||||||
KeInitializeSpinLock(&m_Lock);
|
KeInitializeSpinLock(&m_Lock);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Get the AsyncQueueHead
|
||||||
|
//
|
||||||
|
AsyncListQueueHead = (PQUEUE_HEAD)Hardware->GetAsyncListRegister();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Create the PendingListQueueHead from NONPAGEDPOOL. It will never be linked into the Asynclist Schedule
|
||||||
|
//
|
||||||
|
PendingListQueueHead = (PQUEUE_HEAD)ExAllocatePoolWithTag(NonPagedPool, sizeof(QUEUE_HEAD), TAG_USBEHCI);
|
||||||
|
if (!PendingListQueueHead)
|
||||||
|
{
|
||||||
|
DPRINT1("Pool Allocation failed!\n");
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialize the List Head
|
||||||
|
//
|
||||||
|
InitializeListHead(&PendingListQueueHead->LinkedQueueHeads);
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,8 +132,17 @@ NTSTATUS
|
||||||
CUSBQueue::AddUSBRequest(
|
CUSBQueue::AddUSBRequest(
|
||||||
IUSBRequest * Request)
|
IUSBRequest * Request)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED
|
PQUEUE_HEAD QueueHead;
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
ASSERT(Request != NULL);
|
||||||
|
|
||||||
|
Request->GetQueueHead(&QueueHead);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Add it to the pending list
|
||||||
|
//
|
||||||
|
LinkQueueHead(PendingListQueueHead, QueueHead);
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
@ -135,8 +164,18 @@ NTSTATUS
|
||||||
CUSBQueue::CreateUSBRequest(
|
CUSBQueue::CreateUSBRequest(
|
||||||
IUSBRequest **OutRequest)
|
IUSBRequest **OutRequest)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED
|
PUSBREQUEST UsbRequest;
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
*OutRequest = NULL;
|
||||||
|
Status = InternalCreateUSBRequest(&UsbRequest);
|
||||||
|
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
*OutRequest = UsbRequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -935,3 +935,37 @@ CUSBRequest::ShouldReleaseRequestAfterCompletion()
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
InternalCreateUSBRequest(
|
||||||
|
PUSBREQUEST *OutRequest)
|
||||||
|
{
|
||||||
|
PUSBREQUEST This;
|
||||||
|
|
||||||
|
//
|
||||||
|
// allocate requests
|
||||||
|
//
|
||||||
|
This = new(NonPagedPool, TAG_USBEHCI) CUSBRequest(0);
|
||||||
|
if (!This)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// failed to allocate
|
||||||
|
//
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// add reference count
|
||||||
|
//
|
||||||
|
This->AddRef();
|
||||||
|
|
||||||
|
//
|
||||||
|
// return result
|
||||||
|
//
|
||||||
|
*OutRequest = (PUSBREQUEST)This;
|
||||||
|
|
||||||
|
//
|
||||||
|
// done
|
||||||
|
//
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
|
@ -95,4 +95,9 @@ NTSTATUS CreateUSBDevice(PUSBDEVICE *OutDevice);
|
||||||
//
|
//
|
||||||
NTSTATUS CreateUSBQueue(PUSBQUEUE *OutUsbQueue);
|
NTSTATUS CreateUSBQueue(PUSBQUEUE *OutUsbQueue);
|
||||||
|
|
||||||
|
//
|
||||||
|
// usb_request.cpp
|
||||||
|
//
|
||||||
|
NTSTATUS InternalCreateUSBRequest(PUSBREQUEST *OutRequest);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue