diff --git a/drivers/usb/usbehci_new/CMakeLists.txt b/drivers/usb/usbehci_new/CMakeLists.txt index a167e30d95f..ab79d54782d 100644 --- a/drivers/usb/usbehci_new/CMakeLists.txt +++ b/drivers/usb/usbehci_new/CMakeLists.txt @@ -10,6 +10,7 @@ add_library(usbehci SHARED hardware.cpp misc.cpp purecall.cpp + hub_controller.cpp usbehci.rc) target_link_libraries(usbehci diff --git a/drivers/usb/usbehci_new/hcd_controller.cpp b/drivers/usb/usbehci_new/hcd_controller.cpp index f0be1430fce..73125137c89 100644 --- a/drivers/usb/usbehci_new/hcd_controller.cpp +++ b/drivers/usb/usbehci_new/hcd_controller.cpp @@ -11,7 +11,8 @@ #define INITGUID #include "usbehci.h" -class CHCDController : public IHCDController +class CHCDController : public IHCDController, + public IDispatchIrp { public: STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); @@ -33,8 +34,10 @@ public: 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); @@ -42,8 +45,7 @@ public: // 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){} @@ -57,10 +59,7 @@ protected: 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; }; @@ -73,15 +72,6 @@ CHCDController::QueryInterface( 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; } @@ -187,7 +177,7 @@ CHCDController::Initialize( // DeviceExtension->IsFDO = TRUE; DeviceExtension->IsHub = FALSE; - DeviceExtension->HcdController = PHCDCONTROLLER(this); + DeviceExtension->Dispatcher = PDISPATCHIRP(this); // // device is initialized @@ -345,18 +335,18 @@ CHCDController::HandlePnp( 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 // @@ -366,90 +356,67 @@ CHCDController::HandlePnp( { 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 + // + Status = SyncForwardIrp(m_NextDeviceObject, Irp); + + 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); - } - else - { - // - // start the PDO device - // - ASSERT(0); - - // - //FIXME create the parent root hub device - // - - // - // register device interface - // - Status = SetDeviceInterface(TRUE); + Status = SetSymbolicLink(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) @@ -472,9 +439,14 @@ CHCDController::HandlePnp( // init device relations // 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 @@ -482,12 +454,19 @@ CHCDController::HandlePnp( 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) { @@ -513,153 +492,31 @@ CHCDController::HandlePnp( } 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: { - 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); + // + // detach device from device stack + // + IoDetachDevice(m_NextDeviceObject); - // - // 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); - } + // + // delete device + // + 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); } } @@ -685,44 +542,6 @@ CHCDController::HandlePower( 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, @@ -796,7 +615,7 @@ CHCDController::CreateFDO( } NTSTATUS -CHCDController::SetDeviceInterface( +CHCDController::SetSymbolicLink( BOOLEAN Enable) { NTSTATUS Status; @@ -806,28 +625,10 @@ CHCDController::SetDeviceInterface( 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); @@ -845,26 +646,26 @@ CHCDController::SetDeviceInterface( 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; } -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 CreateHCDController( PHCDCONTROLLER *OutHcdController) diff --git a/drivers/usb/usbehci_new/hub_controller.cpp b/drivers/usb/usbehci_new/hub_controller.cpp new file mode 100644 index 00000000000..d3cd50645e5 --- /dev/null +++ b/drivers/usb/usbehci_new/hub_controller.cpp @@ -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; +} diff --git a/drivers/usb/usbehci_new/interfaces.h b/drivers/usb/usbehci_new/interfaces.h index ba289fd2ed9..3abb71a8cb7 100644 --- a/drivers/usb/usbehci_new/interfaces.h +++ b/drivers/usb/usbehci_new/interfaces.h @@ -103,33 +103,6 @@ DECLARE_INTERFACE_(IHCDController, IUnknown) 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; @@ -178,14 +151,6 @@ DECLARE_INTERFACE_(IUSBHardwareDevice, IUnknown) virtual NTSTATUS PnpStop(void) = 0; -//----------------------------------------------------------------------------------------- -// -// HandlePower -// -// Description: handles power requests - - virtual NTSTATUS HandlePower(PIRP Irp) = 0; - //----------------------------------------------------------------------------------------- // // GetDeviceDetails @@ -451,11 +416,35 @@ DECLARE_INTERFACE_(IHubController, IUnknown) // // 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 @@ -484,7 +473,6 @@ DECLARE_INTERFACE_(IHubController, IUnknown) IN OUT PIRP Irp) = 0; }; -typedef IHubController *PHUBCONTROLLER; - +typedef IDispatchIrp *PDISPATCHIRP; #endif diff --git a/drivers/usb/usbehci_new/usbehci.cpp b/drivers/usb/usbehci_new/usbehci.cpp index 28bf19b7824..7d535c50720 100644 --- a/drivers/usb/usbehci_new/usbehci.cpp +++ b/drivers/usb/usbehci_new/usbehci.cpp @@ -79,12 +79,7 @@ EHCI_Dispatch( // // sanity checks // - PC_ASSERT(DeviceExtension->HcdController); - - // - // FIXME: support bus device - // - PC_ASSERT(DeviceExtension->IsHub == FALSE); + PC_ASSERT(DeviceExtension->Dispatcher); switch(IoStack->MajorFunction) { @@ -93,7 +88,7 @@ EHCI_Dispatch( // // dispatch pnp // - return DeviceExtension->HcdController->HandlePnp(DeviceObject, Irp); + return DeviceExtension->Dispatcher->HandlePnp(DeviceObject, Irp); } case IRP_MJ_POWER: @@ -101,7 +96,7 @@ EHCI_Dispatch( // // dispatch pnp // - return DeviceExtension->HcdController->HandlePower(DeviceObject, Irp); + return DeviceExtension->Dispatcher->HandlePower(DeviceObject, Irp); } case IRP_MJ_SYSTEM_CONTROL: case IRP_MJ_DEVICE_CONTROL: @@ -109,7 +104,7 @@ EHCI_Dispatch( // // dispatch pnp // - return DeviceExtension->HcdController->HandleDeviceControl(DeviceObject, Irp); + return DeviceExtension->Dispatcher->HandleDeviceControl(DeviceObject, Irp); } case IRP_MJ_CREATE: { @@ -134,7 +129,6 @@ EHCI_Dispatch( Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); - return Status; } diff --git a/drivers/usb/usbehci_new/usbehci.h b/drivers/usb/usbehci_new/usbehci.h index bf651e05451..f602eeb8f0b 100644 --- a/drivers/usb/usbehci_new/usbehci.h +++ b/drivers/usb/usbehci_new/usbehci.h @@ -25,11 +25,7 @@ typedef struct { 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; // @@ -62,6 +58,6 @@ NTSTATUS NTAPI SyncForwardIrp(PDEVICE_OBJECT DeviceObject, PIRP Irp); // // root_hub_controller.cpp // -NTSTATUS CreateRootHubController(PHUBCONTROLLER * OutHubController); +NTSTATUS CreateHubController(PHUBCONTROLLER * OutHubController); #endif