mirror of
https://github.com/reactos/reactos.git
synced 2024-08-24 20:28:57 +00:00
[USBEHCI_NEW]
- Create Interface IDispatchIrp which is used to handle ioctl requests - Partly implement IHubController interface svn path=/branches/usb-bringup/; revision=51355
This commit is contained in:
parent
6815708639
commit
a61d852c84
|
@ -10,6 +10,7 @@ add_library(usbehci SHARED
|
||||||
hardware.cpp
|
hardware.cpp
|
||||||
misc.cpp
|
misc.cpp
|
||||||
purecall.cpp
|
purecall.cpp
|
||||||
|
hub_controller.cpp
|
||||||
usbehci.rc)
|
usbehci.rc)
|
||||||
|
|
||||||
target_link_libraries(usbehci
|
target_link_libraries(usbehci
|
||||||
|
|
|
@ -11,7 +11,8 @@
|
||||||
#define INITGUID
|
#define INITGUID
|
||||||
#include "usbehci.h"
|
#include "usbehci.h"
|
||||||
|
|
||||||
class CHCDController : public IHCDController
|
class CHCDController : public IHCDController,
|
||||||
|
public IDispatchIrp
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface);
|
STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface);
|
||||||
|
@ -33,8 +34,10 @@ public:
|
||||||
return m_Ref;
|
return m_Ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
// interface functions
|
// IHCDController interface functions
|
||||||
NTSTATUS Initialize(IN PROOTHDCCONTROLLER RootHCDController, IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject);
|
NTSTATUS Initialize(IN PROOTHDCCONTROLLER RootHCDController, IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject);
|
||||||
|
|
||||||
|
// IDispatchIrp interface functions
|
||||||
NTSTATUS HandlePnp(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp);
|
NTSTATUS HandlePnp(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp);
|
||||||
NTSTATUS HandlePower(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp);
|
NTSTATUS HandlePower(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp);
|
||||||
NTSTATUS HandleDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp);
|
NTSTATUS HandleDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp);
|
||||||
|
@ -42,8 +45,7 @@ public:
|
||||||
// local functions
|
// local functions
|
||||||
NTSTATUS CreateFDO(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT * OutDeviceObject);
|
NTSTATUS CreateFDO(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT * OutDeviceObject);
|
||||||
NTSTATUS CreatePDO(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT * OutDeviceObject);
|
NTSTATUS CreatePDO(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT * OutDeviceObject);
|
||||||
NTSTATUS HandleQueryInterface(PIO_STACK_LOCATION IoStack);
|
NTSTATUS SetSymbolicLink(BOOLEAN Enable);
|
||||||
NTSTATUS SetDeviceInterface(BOOLEAN bEnable);
|
|
||||||
|
|
||||||
// constructor / destructor
|
// constructor / destructor
|
||||||
CHCDController(IUnknown *OuterUnknown){}
|
CHCDController(IUnknown *OuterUnknown){}
|
||||||
|
@ -57,10 +59,7 @@ protected:
|
||||||
PDEVICE_OBJECT m_FunctionalDeviceObject;
|
PDEVICE_OBJECT m_FunctionalDeviceObject;
|
||||||
PDEVICE_OBJECT m_NextDeviceObject;
|
PDEVICE_OBJECT m_NextDeviceObject;
|
||||||
PUSBHARDWAREDEVICE m_Hardware;
|
PUSBHARDWAREDEVICE m_Hardware;
|
||||||
PDEVICE_OBJECT m_BusPDO;
|
PHUBCONTROLLER m_HubController;
|
||||||
UNICODE_STRING m_HubDeviceInterfaceString;
|
|
||||||
BOOLEAN m_InterfaceEnabled;
|
|
||||||
ULONG m_PDODeviceNumber;
|
|
||||||
ULONG m_FDODeviceNumber;
|
ULONG m_FDODeviceNumber;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -73,15 +72,6 @@ CHCDController::QueryInterface(
|
||||||
IN REFIID refiid,
|
IN REFIID refiid,
|
||||||
OUT PVOID* Output)
|
OUT PVOID* Output)
|
||||||
{
|
{
|
||||||
UNICODE_STRING GuidString;
|
|
||||||
|
|
||||||
if (IsEqualGUIDAligned(refiid, IID_IUnknown))
|
|
||||||
{
|
|
||||||
*Output = PVOID(PUNKNOWN(this));
|
|
||||||
PUNKNOWN(*Output)->AddRef();
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
return STATUS_UNSUCCESSFUL;
|
return STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,7 +177,7 @@ CHCDController::Initialize(
|
||||||
//
|
//
|
||||||
DeviceExtension->IsFDO = TRUE;
|
DeviceExtension->IsFDO = TRUE;
|
||||||
DeviceExtension->IsHub = FALSE;
|
DeviceExtension->IsHub = FALSE;
|
||||||
DeviceExtension->HcdController = PHCDCONTROLLER(this);
|
DeviceExtension->Dispatcher = PDISPATCHIRP(this);
|
||||||
|
|
||||||
//
|
//
|
||||||
// device is initialized
|
// device is initialized
|
||||||
|
@ -345,18 +335,18 @@ CHCDController::HandlePnp(
|
||||||
PCM_RESOURCE_LIST RawResourceList;
|
PCM_RESOURCE_LIST RawResourceList;
|
||||||
PCM_RESOURCE_LIST TranslatedResourceList;
|
PCM_RESOURCE_LIST TranslatedResourceList;
|
||||||
PDEVICE_RELATIONS DeviceRelations;
|
PDEVICE_RELATIONS DeviceRelations;
|
||||||
PDEVICE_CAPABILITIES DeviceCapabilities;
|
|
||||||
LPGUID Guid;
|
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
ULONG Index;
|
|
||||||
|
|
||||||
DPRINT("HandlePnp\n");
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// get device extension
|
// get device extension
|
||||||
//
|
//
|
||||||
DeviceExtension = (PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
DeviceExtension = (PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
|
||||||
|
//
|
||||||
|
// sanity check
|
||||||
|
//
|
||||||
|
PC_ASSERT(DeviceExtension->IsFDO);
|
||||||
|
|
||||||
//
|
//
|
||||||
// get current stack location
|
// get current stack location
|
||||||
//
|
//
|
||||||
|
@ -366,10 +356,8 @@ CHCDController::HandlePnp(
|
||||||
{
|
{
|
||||||
case IRP_MN_START_DEVICE:
|
case IRP_MN_START_DEVICE:
|
||||||
{
|
{
|
||||||
DPRINT1("IRP_MN_START FDO: %lu\n", DeviceExtension->IsFDO);
|
DPRINT1("CHCDController::HandlePnp IRP_MN_START FDO\n");
|
||||||
|
|
||||||
if (DeviceExtension->IsFDO)
|
|
||||||
{
|
|
||||||
//
|
//
|
||||||
// first start lower device object
|
// first start lower device object
|
||||||
//
|
//
|
||||||
|
@ -390,66 +378,45 @@ CHCDController::HandlePnp(
|
||||||
//
|
//
|
||||||
Status = m_Hardware->PnpStart(RawResourceList, TranslatedResourceList);
|
Status = m_Hardware->PnpStart(RawResourceList, TranslatedResourceList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// enable symbolic link
|
||||||
|
//
|
||||||
|
Status = SetSymbolicLink(TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
DPRINT1("CHCDController::HandlePnp IRP_MN_START FDO: Status %x\n", Status);
|
||||||
// HACK / FIXME: Windows XP SP3 fails to enumerate the PDO correctly, which
|
|
||||||
// causes the PDO device never to startup.
|
|
||||||
//
|
|
||||||
Status = SetDeviceInterface(TRUE);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// start the PDO device
|
|
||||||
//
|
|
||||||
ASSERT(0);
|
|
||||||
|
|
||||||
//
|
|
||||||
//FIXME create the parent root hub device
|
|
||||||
//
|
|
||||||
|
|
||||||
//
|
|
||||||
// register device interface
|
|
||||||
//
|
|
||||||
Status = SetDeviceInterface(TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
DPRINT1("IRP_MN_START FDO: %lu Status %x\n", DeviceExtension->IsFDO, Status);
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IRP_MN_QUERY_DEVICE_RELATIONS:
|
case IRP_MN_QUERY_DEVICE_RELATIONS:
|
||||||
{
|
{
|
||||||
DPRINT1("IRP_MN_QUERY_DEVICE_RELATIONS Type %lx FDO: \n", IoStack->Parameters.QueryDeviceRelations.Type, DeviceExtension->IsFDO);
|
DPRINT1("CHCDController::HandlePnp IRP_MN_QUERY_DEVICE_RELATIONS Type %lx\n", IoStack->Parameters.QueryDeviceRelations.Type);
|
||||||
|
|
||||||
if (m_BusPDO == NULL)
|
if (m_HubController == NULL)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
// create bus PDO
|
// create hub controller
|
||||||
//
|
//
|
||||||
Status = CreatePDO(m_DriverObject, &m_BusPDO);
|
Status = CreateHubController(&m_HubController);
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
// failed to create bus device object
|
// failed to create hub controller
|
||||||
//
|
//
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// initialize extension
|
// initialize hub controller
|
||||||
//
|
//
|
||||||
DeviceExtension = (PCOMMON_DEVICE_EXTENSION)m_BusPDO->DeviceExtension;
|
Status = m_HubController->Initialize(m_DriverObject, PHCDCONTROLLER(this), m_Hardware, TRUE, 0 /* FIXME*/);
|
||||||
DeviceExtension->IsFDO = FALSE;
|
if (!NT_SUCCESS(Status))
|
||||||
DeviceExtension->IsHub = FALSE;
|
{
|
||||||
DeviceExtension->HcdController = (this);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// clear init flag
|
// failed to initialize hub controller
|
||||||
//
|
//
|
||||||
m_BusPDO->Flags &= ~DO_DEVICE_INITIALIZING;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IoStack->Parameters.QueryDeviceRelations.Type == BusRelations)
|
if (IoStack->Parameters.QueryDeviceRelations.Type == BusRelations)
|
||||||
|
@ -472,9 +439,14 @@ CHCDController::HandlePnp(
|
||||||
// init device relations
|
// init device relations
|
||||||
//
|
//
|
||||||
DeviceRelations->Count = 1;
|
DeviceRelations->Count = 1;
|
||||||
DeviceRelations->Objects [0] = m_BusPDO;
|
Status = m_HubController->GetHubControllerDeviceObject(&DeviceRelations->Objects [0]);
|
||||||
|
|
||||||
ObReferenceObject(m_BusPDO);
|
//
|
||||||
|
// sanity check
|
||||||
|
//
|
||||||
|
PC_ASSERT(Status == STATUS_SUCCESS);
|
||||||
|
|
||||||
|
ObReferenceObject(DeviceRelations->Objects [0]);
|
||||||
|
|
||||||
//
|
//
|
||||||
// store result
|
// store result
|
||||||
|
@ -482,12 +454,19 @@ CHCDController::HandlePnp(
|
||||||
Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations;
|
Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations;
|
||||||
Status = STATUS_SUCCESS;
|
Status = STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// not supported
|
||||||
|
//
|
||||||
|
PC_ASSERT(0);
|
||||||
|
Status = STATUS_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case IRP_MN_STOP_DEVICE:
|
case IRP_MN_STOP_DEVICE:
|
||||||
{
|
{
|
||||||
DPRINT1("IRP_MN_STOP_DEVICE FDO: %lu\n", DeviceExtension->IsFDO);
|
DPRINT1("CHCDController::HandlePnp IRP_MN_STOP_DEVICE\n");
|
||||||
|
|
||||||
if (m_Hardware)
|
if (m_Hardware)
|
||||||
{
|
{
|
||||||
|
@ -513,123 +492,10 @@ CHCDController::HandlePnp(
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IRP_MN_QUERY_CAPABILITIES:
|
|
||||||
{
|
|
||||||
DPRINT1("IRP_MN_QUERY_CAPABILITIES FDO: %lu\n", DeviceExtension->IsFDO);
|
|
||||||
|
|
||||||
if (DeviceExtension->IsFDO == FALSE)
|
|
||||||
{
|
|
||||||
DeviceCapabilities = (PDEVICE_CAPABILITIES)IoStack->Parameters.DeviceCapabilities.Capabilities;
|
|
||||||
|
|
||||||
DeviceCapabilities->LockSupported = FALSE;
|
|
||||||
DeviceCapabilities->EjectSupported = FALSE;
|
|
||||||
DeviceCapabilities->Removable = FALSE;
|
|
||||||
DeviceCapabilities->DockDevice = FALSE;
|
|
||||||
DeviceCapabilities->UniqueID = FALSE;
|
|
||||||
DeviceCapabilities->SilentInstall = FALSE;
|
|
||||||
DeviceCapabilities->RawDeviceOK = FALSE;
|
|
||||||
DeviceCapabilities->SurpriseRemovalOK = FALSE;
|
|
||||||
DeviceCapabilities->Address = 0;
|
|
||||||
DeviceCapabilities->UINumber = 0;
|
|
||||||
DeviceCapabilities->DeviceD2 = 1;
|
|
||||||
|
|
||||||
/* FIXME */
|
|
||||||
DeviceCapabilities->HardwareDisabled = FALSE;
|
|
||||||
DeviceCapabilities->NoDisplayInUI = FALSE;
|
|
||||||
DeviceCapabilities->DeviceState[0] = PowerDeviceD0;
|
|
||||||
for (Index = 0; Index < PowerSystemMaximum; Index++)
|
|
||||||
DeviceCapabilities->DeviceState[Index] = PowerDeviceD3;
|
|
||||||
DeviceCapabilities->DeviceWake = PowerDeviceUnspecified;
|
|
||||||
DeviceCapabilities->D1Latency = 0;
|
|
||||||
DeviceCapabilities->D2Latency = 0;
|
|
||||||
DeviceCapabilities->D3Latency = 0;
|
|
||||||
|
|
||||||
Status = STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// forward irp to next device object
|
|
||||||
//
|
|
||||||
IoSkipCurrentIrpStackLocation(Irp);
|
|
||||||
return IoCallDriver(m_NextDeviceObject, Irp);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case IRP_MN_QUERY_INTERFACE:
|
|
||||||
{
|
|
||||||
DPRINT1("IRP_MN_QUERY_INTERFACE FDO %u\n", DeviceExtension->IsFDO);
|
|
||||||
//
|
|
||||||
// check if the device is FDO
|
|
||||||
//
|
|
||||||
if (DeviceExtension->IsFDO)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// just pass the irp to next device object
|
|
||||||
//
|
|
||||||
IoSkipCurrentIrpStackLocation(Irp);
|
|
||||||
return IoCallDriver(m_NextDeviceObject, Irp);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// handle device interface requests
|
|
||||||
//
|
|
||||||
Status = HandleQueryInterface(IoStack);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case IRP_MN_QUERY_BUS_INFORMATION:
|
|
||||||
{
|
|
||||||
DPRINT1("IRP_MN_QUERY_BUS_INFORMATION FDO %lx\n", DeviceExtension->IsFDO);
|
|
||||||
|
|
||||||
if (DeviceExtension->IsFDO == FALSE)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// allocate buffer for bus guid
|
|
||||||
//
|
|
||||||
Guid = (LPGUID)ExAllocatePool(PagedPool, sizeof(GUID));
|
|
||||||
if (Guid)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// copy BUS guid
|
|
||||||
//
|
|
||||||
RtlMoveMemory(Guid, &GUID_BUS_TYPE_USB, sizeof(GUID));
|
|
||||||
Status = STATUS_SUCCESS;
|
|
||||||
Irp->IoStatus.Information = (ULONG_PTR)Guid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case IRP_MN_REMOVE_DEVICE:
|
case IRP_MN_REMOVE_DEVICE:
|
||||||
{
|
{
|
||||||
DPRINT1("IRP_MN_REMOVE_DEVICE FDO: %lu\n", DeviceExtension->IsFDO);
|
DPRINT1("CHCDController::HandlePnp IRP_MN_REMOVE_DEVICE FDO\n");
|
||||||
|
|
||||||
if (DeviceExtension->IsFDO == FALSE)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// deactivate device interface for BUS PDO
|
|
||||||
//
|
|
||||||
SetDeviceInterface(FALSE);
|
|
||||||
|
|
||||||
//
|
|
||||||
// complete the request first
|
|
||||||
//
|
|
||||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
||||||
|
|
||||||
//
|
|
||||||
// now delete device
|
|
||||||
//
|
|
||||||
IoDeleteDevice(m_BusPDO);
|
|
||||||
|
|
||||||
//
|
|
||||||
// nullify pointer
|
|
||||||
//
|
|
||||||
m_BusPDO = 0;
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//
|
//
|
||||||
// detach device from device stack
|
// detach device from device stack
|
||||||
//
|
//
|
||||||
|
@ -639,28 +505,19 @@ CHCDController::HandlePnp(
|
||||||
// delete device
|
// delete device
|
||||||
//
|
//
|
||||||
IoDeleteDevice(m_FunctionalDeviceObject);
|
IoDeleteDevice(m_FunctionalDeviceObject);
|
||||||
}
|
|
||||||
|
|
||||||
Status = STATUS_SUCCESS;
|
Status = STATUS_SUCCESS;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
if (DeviceExtension->IsFDO)
|
DPRINT1("CHCDController::HandlePnp Dispatch to lower device object %lu\n", IoStack->MinorFunction);
|
||||||
{
|
|
||||||
DPRINT1("HandlePnp> FDO Dispatch to lower device object %lu\n", IoStack->MinorFunction);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// forward irp to next device object
|
// forward irp to next device object
|
||||||
//
|
//
|
||||||
IoSkipCurrentIrpStackLocation(Irp);
|
IoSkipCurrentIrpStackLocation(Irp);
|
||||||
return IoCallDriver(m_NextDeviceObject, Irp);
|
return IoCallDriver(m_NextDeviceObject, Irp);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
DPRINT1("UNHANDLED PDO Request %lu\n", IoStack->MinorFunction);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -685,44 +542,6 @@ CHCDController::HandlePower(
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
CHCDController::HandleQueryInterface(
|
|
||||||
PIO_STACK_LOCATION IoStack)
|
|
||||||
{
|
|
||||||
UNICODE_STRING GuidBuffer;
|
|
||||||
NTSTATUS Status;
|
|
||||||
|
|
||||||
if (IsEqualGUIDAligned(*IoStack->Parameters.QueryInterface.InterfaceType, USB_BUS_INTERFACE_HUB_GUID))
|
|
||||||
{
|
|
||||||
DPRINT1("HandleQueryInterface> UNIMPLEMENTED USB_BUS_INTERFACE_HUB_GUID Version %x\n", IoStack->Parameters.QueryInterface.Version);
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (IsEqualGUIDAligned(*IoStack->Parameters.QueryInterface.InterfaceType, USB_BUS_INTERFACE_USBDI_GUID))
|
|
||||||
{
|
|
||||||
DPRINT1("HandleQueryInterface> UNIMPLEMENTED USB_BUS_INTERFACE_USBDI_GUID Version %x\n", IoStack->Parameters.QueryInterface.Version);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// convert guid to string
|
|
||||||
//
|
|
||||||
Status = RtlStringFromGUID(*IoStack->Parameters.QueryInterface.InterfaceType, &GuidBuffer);
|
|
||||||
if (NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// print interface
|
|
||||||
//
|
|
||||||
DPRINT1("HandleQueryInterface GUID: %wZ Version %x\n", &GuidBuffer, IoStack->Parameters.QueryInterface.Version);
|
|
||||||
|
|
||||||
//
|
|
||||||
// free guid buffer
|
|
||||||
//
|
|
||||||
RtlFreeUnicodeString(&GuidBuffer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return STATUS_NOT_SUPPORTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
CHCDController::CreateFDO(
|
CHCDController::CreateFDO(
|
||||||
PDRIVER_OBJECT DriverObject,
|
PDRIVER_OBJECT DriverObject,
|
||||||
|
@ -796,7 +615,7 @@ CHCDController::CreateFDO(
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
CHCDController::SetDeviceInterface(
|
CHCDController::SetSymbolicLink(
|
||||||
BOOLEAN Enable)
|
BOOLEAN Enable)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
@ -806,28 +625,10 @@ CHCDController::SetDeviceInterface(
|
||||||
|
|
||||||
if (Enable)
|
if (Enable)
|
||||||
{
|
{
|
||||||
//
|
|
||||||
// register device interface
|
|
||||||
//
|
|
||||||
Status = IoRegisterDeviceInterface(m_PhysicalDeviceObject, &GUID_DEVINTERFACE_USB_HUB, 0, &m_HubDeviceInterfaceString);
|
|
||||||
|
|
||||||
if (NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// now enable the device interface
|
|
||||||
//
|
|
||||||
Status = IoSetDeviceInterfaceState(&m_HubDeviceInterfaceString, TRUE);
|
|
||||||
|
|
||||||
//
|
|
||||||
// enable interface
|
|
||||||
//
|
|
||||||
m_InterfaceEnabled = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// create legacy link
|
// create legacy link
|
||||||
//
|
//
|
||||||
swprintf(LinkName, L"\\DosDevices\\HCD%d", m_PDODeviceNumber);
|
swprintf(LinkName, L"\\DosDevices\\HCD%d", m_FDODeviceNumber);
|
||||||
swprintf(FDOName, L"\\Device\\USBFDO-%d", m_FDODeviceNumber);
|
swprintf(FDOName, L"\\Device\\USBFDO-%d", m_FDODeviceNumber);
|
||||||
RtlInitUnicodeString(&Link, LinkName);
|
RtlInitUnicodeString(&Link, LinkName);
|
||||||
RtlInitUnicodeString(&FDO, FDOName);
|
RtlInitUnicodeString(&FDO, FDOName);
|
||||||
|
@ -845,26 +646,26 @@ CHCDController::SetDeviceInterface(
|
||||||
ASSERT(0);
|
ASSERT(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (m_InterfaceEnabled)
|
else
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
// disable device interface
|
// create legacy link
|
||||||
//
|
//
|
||||||
Status = IoSetDeviceInterfaceState(&m_HubDeviceInterfaceString, FALSE);
|
swprintf(LinkName, L"\\DosDevices\\HCD%d", m_FDODeviceNumber);
|
||||||
|
RtlInitUnicodeString(&Link, LinkName);
|
||||||
|
|
||||||
if (NT_SUCCESS(Status))
|
//
|
||||||
|
// now delete the symbolic link
|
||||||
|
//
|
||||||
|
Status = IoDeleteSymbolicLink(&Link);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
// now delete interface string
|
// FIXME: handle me
|
||||||
//
|
//
|
||||||
RtlFreeUnicodeString(&m_HubDeviceInterfaceString);
|
ASSERT(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// disable interface
|
|
||||||
//
|
|
||||||
m_InterfaceEnabled = FALSE;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -873,76 +674,6 @@ CHCDController::SetDeviceInterface(
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
CHCDController::CreatePDO(
|
|
||||||
PDRIVER_OBJECT DriverObject,
|
|
||||||
PDEVICE_OBJECT * OutDeviceObject)
|
|
||||||
{
|
|
||||||
WCHAR CharDeviceName[64];
|
|
||||||
NTSTATUS Status;
|
|
||||||
ULONG UsbDeviceNumber = 0;
|
|
||||||
UNICODE_STRING DeviceName;
|
|
||||||
|
|
||||||
while (TRUE)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// construct device name
|
|
||||||
//
|
|
||||||
swprintf(CharDeviceName, L"\\Device\\USBPDO-%d", UsbDeviceNumber);
|
|
||||||
|
|
||||||
//
|
|
||||||
// initialize device name
|
|
||||||
//
|
|
||||||
RtlInitUnicodeString(&DeviceName, CharDeviceName);
|
|
||||||
|
|
||||||
//
|
|
||||||
// create device
|
|
||||||
//
|
|
||||||
Status = IoCreateDevice(DriverObject,
|
|
||||||
sizeof(COMMON_DEVICE_EXTENSION),
|
|
||||||
&DeviceName,
|
|
||||||
FILE_DEVICE_CONTROLLER,
|
|
||||||
0,
|
|
||||||
FALSE,
|
|
||||||
OutDeviceObject);
|
|
||||||
|
|
||||||
/* check for success */
|
|
||||||
if (NT_SUCCESS(Status))
|
|
||||||
break;
|
|
||||||
|
|
||||||
//
|
|
||||||
// is there a device object with that same name
|
|
||||||
//
|
|
||||||
if ((Status == STATUS_OBJECT_NAME_EXISTS) || (Status == STATUS_OBJECT_NAME_COLLISION))
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// Try the next name
|
|
||||||
//
|
|
||||||
UsbDeviceNumber++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// bail out on other errors
|
|
||||||
//
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT1("CreatePDO: Failed to create %wZ, Status %x\n", &DeviceName, Status);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// store PDO number
|
|
||||||
//
|
|
||||||
m_PDODeviceNumber = UsbDeviceNumber;
|
|
||||||
|
|
||||||
DPRINT1("CreateFDO: DeviceName %wZ\n", &DeviceName);
|
|
||||||
|
|
||||||
/* done */
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
CreateHCDController(
|
CreateHCDController(
|
||||||
PHCDCONTROLLER *OutHcdController)
|
PHCDCONTROLLER *OutHcdController)
|
||||||
|
|
522
drivers/usb/usbehci_new/hub_controller.cpp
Normal file
522
drivers/usb/usbehci_new/hub_controller.cpp
Normal file
|
@ -0,0 +1,522 @@
|
||||||
|
/*
|
||||||
|
* PROJECT: ReactOS Universal Serial Bus Bulk Enhanced Host Controller Interface
|
||||||
|
* LICENSE: GPL - See COPYING in the top level directory
|
||||||
|
* FILE: drivers/usb/usbehci/hub_controller.cpp
|
||||||
|
* PURPOSE: USB EHCI device driver.
|
||||||
|
* PROGRAMMERS:
|
||||||
|
* Michael Martin (michael.martin@reactos.org)
|
||||||
|
* Johannes Anderwald (johannes.anderwald@reactos.org)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define INITGUID
|
||||||
|
#include "usbehci.h"
|
||||||
|
|
||||||
|
class CHubController : public IHubController,
|
||||||
|
public IDispatchIrp
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface);
|
||||||
|
|
||||||
|
STDMETHODIMP_(ULONG) AddRef()
|
||||||
|
{
|
||||||
|
InterlockedIncrement(&m_Ref);
|
||||||
|
return m_Ref;
|
||||||
|
}
|
||||||
|
STDMETHODIMP_(ULONG) Release()
|
||||||
|
{
|
||||||
|
InterlockedDecrement(&m_Ref);
|
||||||
|
|
||||||
|
if (!m_Ref)
|
||||||
|
{
|
||||||
|
delete this;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return m_Ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
// IHubController interface functions
|
||||||
|
virtual NTSTATUS Initialize(IN PDRIVER_OBJECT DriverObject, IN PHCDCONTROLLER Controller, IN PUSBHARDWAREDEVICE Device, IN BOOLEAN IsRootHubDevice, IN ULONG DeviceAddress);
|
||||||
|
|
||||||
|
// IDispatchIrp interface functions
|
||||||
|
virtual NTSTATUS HandlePnp(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp);
|
||||||
|
virtual NTSTATUS HandlePower(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp);
|
||||||
|
virtual NTSTATUS HandleDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp);
|
||||||
|
|
||||||
|
// local functions
|
||||||
|
NTSTATUS HandleQueryInterface(PIO_STACK_LOCATION IoStack);
|
||||||
|
NTSTATUS SetDeviceInterface(BOOLEAN bEnable);
|
||||||
|
NTSTATUS CreatePDO(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT * OutDeviceObject);
|
||||||
|
NTSTATUS GetHubControllerDeviceObject(PDEVICE_OBJECT * HubDeviceObject);
|
||||||
|
|
||||||
|
// constructor / destructor
|
||||||
|
CHubController(IUnknown *OuterUnknown){}
|
||||||
|
virtual ~CHubController(){}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
LONG m_Ref;
|
||||||
|
PHCDCONTROLLER m_Controller;
|
||||||
|
PUSBHARDWAREDEVICE m_Hardware;
|
||||||
|
BOOLEAN m_IsRootHubDevice;
|
||||||
|
ULONG m_DeviceAddress;
|
||||||
|
ULONG m_PDODeviceNumber;
|
||||||
|
BOOLEAN m_InterfaceEnabled;
|
||||||
|
UNICODE_STRING m_HubDeviceInterfaceString;
|
||||||
|
PDEVICE_OBJECT m_HubControllerDeviceObject;
|
||||||
|
PDRIVER_OBJECT m_DriverObject;
|
||||||
|
};
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
NTSTATUS
|
||||||
|
STDMETHODCALLTYPE
|
||||||
|
CHubController::QueryInterface(
|
||||||
|
IN REFIID refiid,
|
||||||
|
OUT PVOID* Output)
|
||||||
|
{
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
NTSTATUS
|
||||||
|
CHubController::Initialize(
|
||||||
|
IN PDRIVER_OBJECT DriverObject,
|
||||||
|
IN PHCDCONTROLLER Controller,
|
||||||
|
IN PUSBHARDWAREDEVICE Device,
|
||||||
|
IN BOOLEAN IsRootHubDevice,
|
||||||
|
IN ULONG DeviceAddress)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
PCOMMON_DEVICE_EXTENSION DeviceExtension;
|
||||||
|
|
||||||
|
DPRINT1("CHubController::Initialize\n");
|
||||||
|
|
||||||
|
//
|
||||||
|
// initialize members
|
||||||
|
//
|
||||||
|
m_Controller = Controller;
|
||||||
|
m_Hardware = Device;
|
||||||
|
m_IsRootHubDevice = IsRootHubDevice;
|
||||||
|
m_DeviceAddress = DeviceAddress;
|
||||||
|
m_DriverObject = DriverObject;
|
||||||
|
|
||||||
|
//
|
||||||
|
// create PDO
|
||||||
|
//
|
||||||
|
Status = CreatePDO(m_DriverObject, &m_HubControllerDeviceObject);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// failed to create hub device object
|
||||||
|
//
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// get device extension
|
||||||
|
//
|
||||||
|
DeviceExtension = (PCOMMON_DEVICE_EXTENSION)m_HubControllerDeviceObject->DeviceExtension;
|
||||||
|
|
||||||
|
//
|
||||||
|
// initialize device extension
|
||||||
|
//
|
||||||
|
DeviceExtension->IsFDO = FALSE;
|
||||||
|
DeviceExtension->IsHub = TRUE; //FIXME
|
||||||
|
DeviceExtension->Dispatcher = PDISPATCHIRP(this);
|
||||||
|
|
||||||
|
//
|
||||||
|
// clear init flag
|
||||||
|
//
|
||||||
|
m_HubControllerDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
|
||||||
|
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------------------
|
||||||
|
NTSTATUS
|
||||||
|
CHubController::GetHubControllerDeviceObject(PDEVICE_OBJECT * HubDeviceObject)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// store controller object
|
||||||
|
//
|
||||||
|
*HubDeviceObject = m_HubControllerDeviceObject;
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
//-----------------------------------------------------------------------------------------
|
||||||
|
NTSTATUS
|
||||||
|
CHubController::HandlePnp(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN OUT PIRP Irp)
|
||||||
|
{
|
||||||
|
PIO_STACK_LOCATION IoStack;
|
||||||
|
PCOMMON_DEVICE_EXTENSION DeviceExtension;
|
||||||
|
PDEVICE_CAPABILITIES DeviceCapabilities;
|
||||||
|
LPGUID Guid;
|
||||||
|
NTSTATUS Status;
|
||||||
|
ULONG Index;
|
||||||
|
|
||||||
|
//
|
||||||
|
// get device extension
|
||||||
|
//
|
||||||
|
DeviceExtension = (PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
|
||||||
|
//
|
||||||
|
// sanity check
|
||||||
|
//
|
||||||
|
ASSERT(DeviceExtension->IsFDO == FALSE);
|
||||||
|
|
||||||
|
//
|
||||||
|
// get current stack location
|
||||||
|
//
|
||||||
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
|
||||||
|
switch(IoStack->MinorFunction)
|
||||||
|
{
|
||||||
|
case IRP_MN_START_DEVICE:
|
||||||
|
{
|
||||||
|
DPRINT1("CHubController::HandlePnp IRP_MN_START_DEVICE\n");
|
||||||
|
//
|
||||||
|
// register device interface
|
||||||
|
//
|
||||||
|
Status = SetDeviceInterface(TRUE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case IRP_MN_QUERY_CAPABILITIES:
|
||||||
|
{
|
||||||
|
DPRINT1("CHubController::HandlePnp IRP_MN_QUERY_CAPABILITIES\n");
|
||||||
|
|
||||||
|
DeviceCapabilities = (PDEVICE_CAPABILITIES)IoStack->Parameters.DeviceCapabilities.Capabilities;
|
||||||
|
|
||||||
|
DeviceCapabilities->LockSupported = FALSE;
|
||||||
|
DeviceCapabilities->EjectSupported = FALSE;
|
||||||
|
DeviceCapabilities->Removable = FALSE;
|
||||||
|
DeviceCapabilities->DockDevice = FALSE;
|
||||||
|
DeviceCapabilities->UniqueID = FALSE;
|
||||||
|
DeviceCapabilities->SilentInstall = FALSE;
|
||||||
|
DeviceCapabilities->RawDeviceOK = FALSE;
|
||||||
|
DeviceCapabilities->SurpriseRemovalOK = FALSE;
|
||||||
|
DeviceCapabilities->Address = 0;
|
||||||
|
DeviceCapabilities->UINumber = 0;
|
||||||
|
DeviceCapabilities->DeviceD2 = 1;
|
||||||
|
|
||||||
|
/* FIXME */
|
||||||
|
DeviceCapabilities->HardwareDisabled = FALSE;
|
||||||
|
DeviceCapabilities->NoDisplayInUI = FALSE;
|
||||||
|
DeviceCapabilities->DeviceState[0] = PowerDeviceD0;
|
||||||
|
for (Index = 0; Index < PowerSystemMaximum; Index++)
|
||||||
|
DeviceCapabilities->DeviceState[Index] = PowerDeviceD3;
|
||||||
|
DeviceCapabilities->DeviceWake = PowerDeviceUnspecified;
|
||||||
|
DeviceCapabilities->D1Latency = 0;
|
||||||
|
DeviceCapabilities->D2Latency = 0;
|
||||||
|
DeviceCapabilities->D3Latency = 0;
|
||||||
|
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case IRP_MN_QUERY_INTERFACE:
|
||||||
|
{
|
||||||
|
DPRINT1("CHubController::HandlePnp IRP_MN_QUERY_INTERFACE\n");
|
||||||
|
|
||||||
|
//
|
||||||
|
// handle device interface requests
|
||||||
|
//
|
||||||
|
Status = HandleQueryInterface(IoStack);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case IRP_MN_REMOVE_DEVICE:
|
||||||
|
{
|
||||||
|
DPRINT1("CHubController::HandlePnp IRP_MN_REMOVE_DEVICE\n");
|
||||||
|
|
||||||
|
//
|
||||||
|
// deactivate device interface for BUS PDO
|
||||||
|
//
|
||||||
|
SetDeviceInterface(FALSE);
|
||||||
|
|
||||||
|
//
|
||||||
|
// complete the request first
|
||||||
|
//
|
||||||
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||||
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
|
||||||
|
//
|
||||||
|
// now delete device
|
||||||
|
//
|
||||||
|
IoDeleteDevice(m_HubControllerDeviceObject);
|
||||||
|
|
||||||
|
//
|
||||||
|
// nullify pointer
|
||||||
|
//
|
||||||
|
m_HubControllerDeviceObject = 0;
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
case IRP_MN_QUERY_BUS_INFORMATION:
|
||||||
|
{
|
||||||
|
DPRINT1("CHubController::HandlePnp IRP_MN_QUERY_BUS_INFORMATION\n");
|
||||||
|
|
||||||
|
//
|
||||||
|
// allocate buffer for bus guid
|
||||||
|
//
|
||||||
|
Guid = (LPGUID)ExAllocatePool(PagedPool, sizeof(GUID));
|
||||||
|
if (Guid)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// copy BUS guid
|
||||||
|
//
|
||||||
|
RtlMoveMemory(Guid, &GUID_BUS_TYPE_USB, sizeof(GUID));
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
Irp->IoStatus.Information = (ULONG_PTR)Guid;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// no memory
|
||||||
|
//
|
||||||
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case IRP_MN_STOP_DEVICE:
|
||||||
|
{
|
||||||
|
DPRINT1("CHubController::HandlePnp IRP_MN_STOP_DEVICE\n");
|
||||||
|
//
|
||||||
|
// stop device
|
||||||
|
//
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
DPRINT1("CHubController::HandlePnp Unhandeled %x\n", IoStack->MinorFunction);
|
||||||
|
Status = STATUS_NOT_SUPPORTED;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// complete request
|
||||||
|
//
|
||||||
|
Irp->IoStatus.Status = Status;
|
||||||
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
|
||||||
|
//
|
||||||
|
// done
|
||||||
|
//
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------------------
|
||||||
|
NTSTATUS
|
||||||
|
CHubController::HandlePower(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN OUT PIRP Irp)
|
||||||
|
{
|
||||||
|
UNIMPLEMENTED
|
||||||
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------------------
|
||||||
|
NTSTATUS
|
||||||
|
CHubController::HandleDeviceControl(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN OUT PIRP Irp)
|
||||||
|
{
|
||||||
|
UNIMPLEMENTED
|
||||||
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
CHubController::HandleQueryInterface(
|
||||||
|
PIO_STACK_LOCATION IoStack)
|
||||||
|
{
|
||||||
|
UNICODE_STRING GuidBuffer;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
if (IsEqualGUIDAligned(*IoStack->Parameters.QueryInterface.InterfaceType, USB_BUS_INTERFACE_HUB_GUID))
|
||||||
|
{
|
||||||
|
DPRINT1("HandleQueryInterface> UNIMPLEMENTED USB_BUS_INTERFACE_HUB_GUID Version %x\n", IoStack->Parameters.QueryInterface.Version);
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (IsEqualGUIDAligned(*IoStack->Parameters.QueryInterface.InterfaceType, USB_BUS_INTERFACE_USBDI_GUID))
|
||||||
|
{
|
||||||
|
DPRINT1("HandleQueryInterface> UNIMPLEMENTED USB_BUS_INTERFACE_USBDI_GUID Version %x\n", IoStack->Parameters.QueryInterface.Version);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// convert guid to string
|
||||||
|
//
|
||||||
|
Status = RtlStringFromGUID(*IoStack->Parameters.QueryInterface.InterfaceType, &GuidBuffer);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// print interface
|
||||||
|
//
|
||||||
|
DPRINT1("HandleQueryInterface GUID: %wZ Version %x\n", &GuidBuffer, IoStack->Parameters.QueryInterface.Version);
|
||||||
|
|
||||||
|
//
|
||||||
|
// free guid buffer
|
||||||
|
//
|
||||||
|
RtlFreeUnicodeString(&GuidBuffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return STATUS_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
CHubController::SetDeviceInterface(
|
||||||
|
BOOLEAN Enable)
|
||||||
|
{
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
if (Enable)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// register device interface
|
||||||
|
//
|
||||||
|
Status = IoRegisterDeviceInterface(m_HubControllerDeviceObject, &GUID_DEVINTERFACE_USB_HUB, 0, &m_HubDeviceInterfaceString);
|
||||||
|
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// now enable the device interface
|
||||||
|
//
|
||||||
|
Status = IoSetDeviceInterfaceState(&m_HubDeviceInterfaceString, TRUE);
|
||||||
|
|
||||||
|
//
|
||||||
|
// enable interface
|
||||||
|
//
|
||||||
|
m_InterfaceEnabled = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (m_InterfaceEnabled)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// disable device interface
|
||||||
|
//
|
||||||
|
Status = IoSetDeviceInterfaceState(&m_HubDeviceInterfaceString, FALSE);
|
||||||
|
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// now delete interface string
|
||||||
|
//
|
||||||
|
RtlFreeUnicodeString(&m_HubDeviceInterfaceString);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// disable interface
|
||||||
|
//
|
||||||
|
m_InterfaceEnabled = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// done
|
||||||
|
//
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
CHubController::CreatePDO(
|
||||||
|
PDRIVER_OBJECT DriverObject,
|
||||||
|
PDEVICE_OBJECT * OutDeviceObject)
|
||||||
|
{
|
||||||
|
WCHAR CharDeviceName[64];
|
||||||
|
NTSTATUS Status;
|
||||||
|
ULONG UsbDeviceNumber = 0;
|
||||||
|
UNICODE_STRING DeviceName;
|
||||||
|
|
||||||
|
while (TRUE)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// construct device name
|
||||||
|
//
|
||||||
|
swprintf(CharDeviceName, L"\\Device\\USBPDO-%d", UsbDeviceNumber);
|
||||||
|
|
||||||
|
//
|
||||||
|
// initialize device name
|
||||||
|
//
|
||||||
|
RtlInitUnicodeString(&DeviceName, CharDeviceName);
|
||||||
|
|
||||||
|
//
|
||||||
|
// create device
|
||||||
|
//
|
||||||
|
Status = IoCreateDevice(DriverObject,
|
||||||
|
sizeof(COMMON_DEVICE_EXTENSION),
|
||||||
|
&DeviceName,
|
||||||
|
FILE_DEVICE_CONTROLLER,
|
||||||
|
0,
|
||||||
|
FALSE,
|
||||||
|
OutDeviceObject);
|
||||||
|
|
||||||
|
/* check for success */
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
break;
|
||||||
|
|
||||||
|
//
|
||||||
|
// is there a device object with that same name
|
||||||
|
//
|
||||||
|
if ((Status == STATUS_OBJECT_NAME_EXISTS) || (Status == STATUS_OBJECT_NAME_COLLISION))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Try the next name
|
||||||
|
//
|
||||||
|
UsbDeviceNumber++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// bail out on other errors
|
||||||
|
//
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("CreatePDO: Failed to create %wZ, Status %x\n", &DeviceName, Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// store PDO number
|
||||||
|
//
|
||||||
|
//m_PDODeviceNumber = UsbDeviceNumber;
|
||||||
|
|
||||||
|
DPRINT1("CreateFDO: DeviceName %wZ\n", &DeviceName);
|
||||||
|
|
||||||
|
/* done */
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
CreateHubController(
|
||||||
|
PHUBCONTROLLER *OutHcdController)
|
||||||
|
{
|
||||||
|
PHUBCONTROLLER This;
|
||||||
|
|
||||||
|
//
|
||||||
|
// allocate controller
|
||||||
|
//
|
||||||
|
This = new(NonPagedPool, TAG_USBEHCI) CHubController(0);
|
||||||
|
if (!This)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// failed to allocate
|
||||||
|
//
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// add reference count
|
||||||
|
//
|
||||||
|
This->AddRef();
|
||||||
|
|
||||||
|
//
|
||||||
|
// return result
|
||||||
|
//
|
||||||
|
*OutHcdController = (PHUBCONTROLLER)This;
|
||||||
|
|
||||||
|
//
|
||||||
|
// done
|
||||||
|
//
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
|
@ -103,33 +103,6 @@ DECLARE_INTERFACE_(IHCDController, IUnknown)
|
||||||
IN PDRIVER_OBJECT DriverObject,
|
IN PDRIVER_OBJECT DriverObject,
|
||||||
IN PDEVICE_OBJECT PhysicalDeviceObject) = 0;
|
IN PDEVICE_OBJECT PhysicalDeviceObject) = 0;
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// HandlePnp
|
|
||||||
//
|
|
||||||
// Description: This function handles all pnp requests
|
|
||||||
|
|
||||||
virtual NTSTATUS HandlePnp(IN PDEVICE_OBJECT DeviceObject,
|
|
||||||
IN OUT PIRP Irp) = 0;
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// HandlePower
|
|
||||||
//
|
|
||||||
// Description: This function handles all power pnp requests
|
|
||||||
//
|
|
||||||
virtual NTSTATUS HandlePower(IN PDEVICE_OBJECT DeviceObject,
|
|
||||||
IN OUT PIRP Irp) = 0;
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// HandleDeviceControl
|
|
||||||
//
|
|
||||||
// Description: handles device io control requests
|
|
||||||
|
|
||||||
virtual NTSTATUS HandleDeviceControl(IN PDEVICE_OBJECT DeviceObject,
|
|
||||||
IN OUT PIRP Irp) = 0;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef IHCDController *PHCDCONTROLLER;
|
typedef IHCDController *PHCDCONTROLLER;
|
||||||
|
@ -178,14 +151,6 @@ DECLARE_INTERFACE_(IUSBHardwareDevice, IUnknown)
|
||||||
|
|
||||||
virtual NTSTATUS PnpStop(void) = 0;
|
virtual NTSTATUS PnpStop(void) = 0;
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// HandlePower
|
|
||||||
//
|
|
||||||
// Description: handles power requests
|
|
||||||
|
|
||||||
virtual NTSTATUS HandlePower(PIRP Irp) = 0;
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// GetDeviceDetails
|
// GetDeviceDetails
|
||||||
|
@ -451,11 +416,35 @@ DECLARE_INTERFACE_(IHubController, IUnknown)
|
||||||
//
|
//
|
||||||
// Description: Initializes the hub controller
|
// Description: Initializes the hub controller
|
||||||
|
|
||||||
virtual NTSTATUS Initialize(IN PHCDCONTROLLER Controller,
|
virtual NTSTATUS Initialize(IN PDRIVER_OBJECT DriverObject,
|
||||||
|
IN PHCDCONTROLLER Controller,
|
||||||
IN PUSBHARDWAREDEVICE Device,
|
IN PUSBHARDWAREDEVICE Device,
|
||||||
IN BOOLEAN IsRootHubDevice,
|
IN BOOLEAN IsRootHubDevice,
|
||||||
IN ULONG DeviceAddress) = 0;
|
IN ULONG DeviceAddress) = 0;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// GetHubControllerDeviceObject
|
||||||
|
//
|
||||||
|
// Description: Returns the hub controller device object
|
||||||
|
|
||||||
|
virtual NTSTATUS GetHubControllerDeviceObject(PDEVICE_OBJECT * HubDeviceObject) = 0;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef IHubController *PHUBCONTROLLER;
|
||||||
|
|
||||||
|
//=========================================================================================
|
||||||
|
//
|
||||||
|
// class IDispatchIrp
|
||||||
|
//
|
||||||
|
// Description: This class is used to handle irp dispatch requests
|
||||||
|
//
|
||||||
|
|
||||||
|
DECLARE_INTERFACE_(IDispatchIrp, IUnknown)
|
||||||
|
{
|
||||||
|
DEFINE_ABSTRACT_UNKNOWN()
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// HandlePnp
|
// HandlePnp
|
||||||
|
@ -484,7 +473,6 @@ DECLARE_INTERFACE_(IHubController, IUnknown)
|
||||||
IN OUT PIRP Irp) = 0;
|
IN OUT PIRP Irp) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef IHubController *PHUBCONTROLLER;
|
typedef IDispatchIrp *PDISPATCHIRP;
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -79,12 +79,7 @@ EHCI_Dispatch(
|
||||||
//
|
//
|
||||||
// sanity checks
|
// sanity checks
|
||||||
//
|
//
|
||||||
PC_ASSERT(DeviceExtension->HcdController);
|
PC_ASSERT(DeviceExtension->Dispatcher);
|
||||||
|
|
||||||
//
|
|
||||||
// FIXME: support bus device
|
|
||||||
//
|
|
||||||
PC_ASSERT(DeviceExtension->IsHub == FALSE);
|
|
||||||
|
|
||||||
switch(IoStack->MajorFunction)
|
switch(IoStack->MajorFunction)
|
||||||
{
|
{
|
||||||
|
@ -93,7 +88,7 @@ EHCI_Dispatch(
|
||||||
//
|
//
|
||||||
// dispatch pnp
|
// dispatch pnp
|
||||||
//
|
//
|
||||||
return DeviceExtension->HcdController->HandlePnp(DeviceObject, Irp);
|
return DeviceExtension->Dispatcher->HandlePnp(DeviceObject, Irp);
|
||||||
}
|
}
|
||||||
|
|
||||||
case IRP_MJ_POWER:
|
case IRP_MJ_POWER:
|
||||||
|
@ -101,7 +96,7 @@ EHCI_Dispatch(
|
||||||
//
|
//
|
||||||
// dispatch pnp
|
// dispatch pnp
|
||||||
//
|
//
|
||||||
return DeviceExtension->HcdController->HandlePower(DeviceObject, Irp);
|
return DeviceExtension->Dispatcher->HandlePower(DeviceObject, Irp);
|
||||||
}
|
}
|
||||||
case IRP_MJ_SYSTEM_CONTROL:
|
case IRP_MJ_SYSTEM_CONTROL:
|
||||||
case IRP_MJ_DEVICE_CONTROL:
|
case IRP_MJ_DEVICE_CONTROL:
|
||||||
|
@ -109,7 +104,7 @@ EHCI_Dispatch(
|
||||||
//
|
//
|
||||||
// dispatch pnp
|
// dispatch pnp
|
||||||
//
|
//
|
||||||
return DeviceExtension->HcdController->HandleDeviceControl(DeviceObject, Irp);
|
return DeviceExtension->Dispatcher->HandleDeviceControl(DeviceObject, Irp);
|
||||||
}
|
}
|
||||||
case IRP_MJ_CREATE:
|
case IRP_MJ_CREATE:
|
||||||
{
|
{
|
||||||
|
@ -134,7 +129,6 @@ EHCI_Dispatch(
|
||||||
Irp->IoStatus.Status = Status;
|
Irp->IoStatus.Status = Status;
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,11 +25,7 @@ typedef struct
|
||||||
{
|
{
|
||||||
BOOLEAN IsFDO; // is device a FDO or PDO
|
BOOLEAN IsFDO; // is device a FDO or PDO
|
||||||
BOOLEAN IsHub; // is device a hub / child - not yet used
|
BOOLEAN IsHub; // is device a hub / child - not yet used
|
||||||
union
|
PDISPATCHIRP Dispatcher; // dispatches the code
|
||||||
{
|
|
||||||
PHCDCONTROLLER HcdController; // hcd controller
|
|
||||||
PHUBCONTROLLER HubController; // hub controller
|
|
||||||
};
|
|
||||||
}COMMON_DEVICE_EXTENSION, *PCOMMON_DEVICE_EXTENSION;
|
}COMMON_DEVICE_EXTENSION, *PCOMMON_DEVICE_EXTENSION;
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -62,6 +58,6 @@ NTSTATUS NTAPI SyncForwardIrp(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
||||||
//
|
//
|
||||||
// root_hub_controller.cpp
|
// root_hub_controller.cpp
|
||||||
//
|
//
|
||||||
NTSTATUS CreateRootHubController(PHUBCONTROLLER * OutHubController);
|
NTSTATUS CreateHubController(PHUBCONTROLLER * OutHubController);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue