[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:
Johannes Anderwald 2011-04-15 17:57:24 +00:00
parent 6815708639
commit a61d852c84
6 changed files with 643 additions and 411 deletions

View file

@ -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

View file

@ -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)

View 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;
}

View file

@ -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

View file

@ -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;
} }

View file

@ -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