hardware.cpp
misc.cpp
purecall.cpp
+ hub_controller.cpp
usbehci.rc)
target_link_libraries(usbehci
#define INITGUID
#include "usbehci.h"
-class CHCDController : public IHCDController
+class CHCDController : public IHCDController,
+ public IDispatchIrp
{
public:
STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface);
return m_Ref;
}
- // interface functions
+ // IHCDController interface functions
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 HandlePower(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp);
NTSTATUS HandleDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp);
// local functions
NTSTATUS CreateFDO(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT * OutDeviceObject);
NTSTATUS CreatePDO(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT * OutDeviceObject);
- NTSTATUS HandleQueryInterface(PIO_STACK_LOCATION IoStack);
- NTSTATUS SetDeviceInterface(BOOLEAN bEnable);
+ NTSTATUS SetSymbolicLink(BOOLEAN Enable);
// constructor / destructor
CHCDController(IUnknown *OuterUnknown){}
PDEVICE_OBJECT m_FunctionalDeviceObject;
PDEVICE_OBJECT m_NextDeviceObject;
PUSBHARDWAREDEVICE m_Hardware;
- PDEVICE_OBJECT m_BusPDO;
- UNICODE_STRING m_HubDeviceInterfaceString;
- BOOLEAN m_InterfaceEnabled;
- ULONG m_PDODeviceNumber;
+ PHUBCONTROLLER m_HubController;
ULONG m_FDODeviceNumber;
};
IN REFIID refiid,
OUT PVOID* Output)
{
- UNICODE_STRING GuidString;
-
- if (IsEqualGUIDAligned(refiid, IID_IUnknown))
- {
- *Output = PVOID(PUNKNOWN(this));
- PUNKNOWN(*Output)->AddRef();
- return STATUS_SUCCESS;
- }
-
return STATUS_UNSUCCESSFUL;
}
//
DeviceExtension->IsFDO = TRUE;
DeviceExtension->IsHub = FALSE;
- DeviceExtension->HcdController = PHCDCONTROLLER(this);
+ DeviceExtension->Dispatcher = PDISPATCHIRP(this);
//
// device is initialized
PCM_RESOURCE_LIST RawResourceList;
PCM_RESOURCE_LIST TranslatedResourceList;
PDEVICE_RELATIONS DeviceRelations;
- PDEVICE_CAPABILITIES DeviceCapabilities;
- LPGUID Guid;
NTSTATUS Status;
- ULONG Index;
-
- DPRINT("HandlePnp\n");
//
// get device extension
//
DeviceExtension = (PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ //
+ // sanity check
+ //
+ PC_ASSERT(DeviceExtension->IsFDO);
+
//
// get current stack location
//
{
case IRP_MN_START_DEVICE:
{
- DPRINT1("IRP_MN_START FDO: %lu\n", DeviceExtension->IsFDO);
+ DPRINT1("CHCDController::HandlePnp IRP_MN_START FDO\n");
+
+ //
+ // first start lower device object
+ //
+ Status = SyncForwardIrp(m_NextDeviceObject, Irp);
- if (DeviceExtension->IsFDO)
+ if (NT_SUCCESS(Status))
{
//
- // first start lower device object
+ // operation succeeded, lets start the device
//
- Status = SyncForwardIrp(m_NextDeviceObject, Irp);
+ RawResourceList = IoStack->Parameters.StartDevice.AllocatedResources;
+ TranslatedResourceList = IoStack->Parameters.StartDevice.AllocatedResourcesTranslated;
- if (NT_SUCCESS(Status))
+ if (m_Hardware)
{
//
- // operation succeeded, lets start the device
+ // start the hardware
//
- RawResourceList = IoStack->Parameters.StartDevice.AllocatedResources;
- TranslatedResourceList = IoStack->Parameters.StartDevice.AllocatedResourcesTranslated;
-
- if (m_Hardware)
- {
- //
- // start the hardware
- //
- Status = m_Hardware->PnpStart(RawResourceList, TranslatedResourceList);
- }
+ Status = m_Hardware->PnpStart(RawResourceList, TranslatedResourceList);
}
//
- // HACK / FIXME: Windows XP SP3 fails to enumerate the PDO correctly, which
- // causes the PDO device never to startup.
+ // enable symbolic link
//
- Status = SetDeviceInterface(TRUE);
+ Status = SetSymbolicLink(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);
+ DPRINT1("CHCDController::HandlePnp IRP_MN_START FDO: Status %x\n", Status);
break;
}
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))
{
//
- // failed to create bus device object
+ // failed to create hub controller
//
break;
}
//
- // initialize extension
+ // initialize hub controller
//
- DeviceExtension = (PCOMMON_DEVICE_EXTENSION)m_BusPDO->DeviceExtension;
- DeviceExtension->IsFDO = FALSE;
- DeviceExtension->IsHub = FALSE;
- DeviceExtension->HcdController = (this);
-
- //
- // clear init flag
- //
- m_BusPDO->Flags &= ~DO_DEVICE_INITIALIZING;
+ Status = m_HubController->Initialize(m_DriverObject, PHCDCONTROLLER(this), m_Hardware, TRUE, 0 /* FIXME*/);
+ if (!NT_SUCCESS(Status))
+ {
+ //
+ // failed to initialize hub controller
+ //
+ break;
+ }
}
if (IoStack->Parameters.QueryDeviceRelations.Type == BusRelations)
// init device relations
//
DeviceRelations->Count = 1;
- DeviceRelations->Objects [0] = m_BusPDO;
+ Status = m_HubController->GetHubControllerDeviceObject(&DeviceRelations->Objects [0]);
+
+ //
+ // sanity check
+ //
+ PC_ASSERT(Status == STATUS_SUCCESS);
- ObReferenceObject(m_BusPDO);
+ ObReferenceObject(DeviceRelations->Objects [0]);
//
// store result
Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations;
Status = STATUS_SUCCESS;
}
+ else
+ {
+ //
+ // not supported
+ //
+ PC_ASSERT(0);
+ Status = STATUS_NOT_SUPPORTED;
+ }
break;
}
-
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)
{
}
break;
}
- case IRP_MN_QUERY_CAPABILITIES:
+ case IRP_MN_REMOVE_DEVICE:
{
- 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);
- }
+ DPRINT1("CHCDController::HandlePnp IRP_MN_REMOVE_DEVICE FDO\n");
- break;
- }
- case IRP_MN_QUERY_INTERFACE:
- {
- DPRINT1("IRP_MN_QUERY_INTERFACE FDO %u\n", DeviceExtension->IsFDO);
//
- // check if the device is FDO
+ // detach device from device stack
//
- if (DeviceExtension->IsFDO)
- {
- //
- // just pass the irp to next device object
- //
- IoSkipCurrentIrpStackLocation(Irp);
- return IoCallDriver(m_NextDeviceObject, Irp);
- }
+ IoDetachDevice(m_NextDeviceObject);
//
- // handle device interface requests
+ // delete device
//
- 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:
- {
- DPRINT1("IRP_MN_REMOVE_DEVICE FDO: %lu\n", DeviceExtension->IsFDO);
-
- 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
- //
- IoDetachDevice(m_NextDeviceObject);
-
- //
- // delete device
- //
- IoDeleteDevice(m_FunctionalDeviceObject);
- }
+ IoDeleteDevice(m_FunctionalDeviceObject);
Status = STATUS_SUCCESS;
break;
}
default:
{
- if (DeviceExtension->IsFDO)
- {
- DPRINT1("HandlePnp> FDO Dispatch to lower device object %lu\n", IoStack->MinorFunction);
-
- //
- // forward irp to next device object
- //
- IoSkipCurrentIrpStackLocation(Irp);
- return IoCallDriver(m_NextDeviceObject, Irp);
- }
- else
- {
- DPRINT1("UNHANDLED PDO Request %lu\n", IoStack->MinorFunction);
- }
+ DPRINT1("CHCDController::HandlePnp Dispatch to lower device object %lu\n", IoStack->MinorFunction);
+ //
+ // forward irp to next device object
+ //
+ IoSkipCurrentIrpStackLocation(Irp);
+ return IoCallDriver(m_NextDeviceObject, Irp);
}
}
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
CHCDController::CreateFDO(
PDRIVER_OBJECT DriverObject,
}
NTSTATUS
-CHCDController::SetDeviceInterface(
+CHCDController::SetSymbolicLink(
BOOLEAN Enable)
{
NTSTATUS Status;
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
//
- swprintf(LinkName, L"\\DosDevices\\HCD%d", m_PDODeviceNumber);
+ swprintf(LinkName, L"\\DosDevices\\HCD%d", m_FDODeviceNumber);
swprintf(FDOName, L"\\Device\\USBFDO-%d", m_FDODeviceNumber);
RtlInitUnicodeString(&Link, LinkName);
RtlInitUnicodeString(&FDO, FDOName);
ASSERT(0);
}
}
- 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
-CHCDController::CreatePDO(
- PDRIVER_OBJECT DriverObject,
- PDEVICE_OBJECT * OutDeviceObject)
-{
- WCHAR CharDeviceName[64];
- NTSTATUS Status;
- ULONG UsbDeviceNumber = 0;
- UNICODE_STRING DeviceName;
-
- while (TRUE)
+ else
{
//
- // construct device name
- //
- swprintf(CharDeviceName, L"\\Device\\USBPDO-%d", UsbDeviceNumber);
-
- //
- // initialize device name
+ // create legacy link
//
- RtlInitUnicodeString(&DeviceName, CharDeviceName);
+ swprintf(LinkName, L"\\DosDevices\\HCD%d", m_FDODeviceNumber);
+ RtlInitUnicodeString(&Link, LinkName);
//
- // create device
+ // now delete the symbolic link
//
- Status = IoCreateDevice(DriverObject,
- sizeof(COMMON_DEVICE_EXTENSION),
- &DeviceName,
- FILE_DEVICE_CONTROLLER,
- 0,
- FALSE,
- OutDeviceObject);
+ Status = IoDeleteSymbolicLink(&Link);
- /* 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))
+ if (!NT_SUCCESS(Status))
{
//
- // Try the next name
+ // FIXME: handle me
//
- UsbDeviceNumber++;
- continue;
- }
-
- //
- // bail out on other errors
- //
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CreatePDO: Failed to create %wZ, Status %x\n", &DeviceName, Status);
- return Status;
+ ASSERT(0);
}
}
//
- // store PDO number
+ // done
//
- m_PDODeviceNumber = UsbDeviceNumber;
-
- DPRINT1("CreateFDO: DeviceName %wZ\n", &DeviceName);
-
- /* done */
return Status;
}
--- /dev/null
+/*
+ * 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;
+}
IN PDRIVER_OBJECT DriverObject,
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;
virtual NTSTATUS PnpStop(void) = 0;
-//-----------------------------------------------------------------------------------------
-//
-// HandlePower
-//
-// Description: handles power requests
-
- virtual NTSTATUS HandlePower(PIRP Irp) = 0;
-
//-----------------------------------------------------------------------------------------
//
// GetDeviceDetails
//
// 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 BOOLEAN IsRootHubDevice,
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
IN OUT PIRP Irp) = 0;
};
-typedef IHubController *PHUBCONTROLLER;
-
+typedef IDispatchIrp *PDISPATCHIRP;
#endif
//
// sanity checks
//
- PC_ASSERT(DeviceExtension->HcdController);
-
- //
- // FIXME: support bus device
- //
- PC_ASSERT(DeviceExtension->IsHub == FALSE);
+ PC_ASSERT(DeviceExtension->Dispatcher);
switch(IoStack->MajorFunction)
{
//
// dispatch pnp
//
- return DeviceExtension->HcdController->HandlePnp(DeviceObject, Irp);
+ return DeviceExtension->Dispatcher->HandlePnp(DeviceObject, Irp);
}
case IRP_MJ_POWER:
//
// dispatch pnp
//
- return DeviceExtension->HcdController->HandlePower(DeviceObject, Irp);
+ return DeviceExtension->Dispatcher->HandlePower(DeviceObject, Irp);
}
case IRP_MJ_SYSTEM_CONTROL:
case IRP_MJ_DEVICE_CONTROL:
//
// dispatch pnp
//
- return DeviceExtension->HcdController->HandleDeviceControl(DeviceObject, Irp);
+ return DeviceExtension->Dispatcher->HandleDeviceControl(DeviceObject, Irp);
}
case IRP_MJ_CREATE:
{
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
return Status;
}
{
BOOLEAN IsFDO; // is device a FDO or PDO
BOOLEAN IsHub; // is device a hub / child - not yet used
- union
- {
- PHCDCONTROLLER HcdController; // hcd controller
- PHUBCONTROLLER HubController; // hub controller
- };
+ PDISPATCHIRP Dispatcher; // dispatches the code
}COMMON_DEVICE_EXTENSION, *PCOMMON_DEVICE_EXTENSION;
//
//
// root_hub_controller.cpp
//
-NTSTATUS CreateRootHubController(PHUBCONTROLLER * OutHubController);
+NTSTATUS CreateHubController(PHUBCONTROLLER * OutHubController);
#endif