mirror of
https://github.com/reactos/reactos.git
synced 2024-08-03 01:50:57 +00:00
[USBEHCI_NEW]
- Implement CHCDController::Initialize, CHCDController::HandlePnp for PDO / FDO, - Partly implement CHCDController::HandleDeviceControl - Based on mjmartin usbehci sources - Driver now startups and acquires pnp resources - Fails in HandleDeviceControl with IOCTL_GET_HCD_DRIVERKEY_NAME when usbview is launched - Tested in Windows XP SP2 + Vmware Server 2.0.2 svn path=/branches/usb-bringup/; revision=51343
This commit is contained in:
parent
6ba926eecc
commit
24188364ec
|
@ -8,6 +8,7 @@ add_library(usbehci SHARED
|
|||
usbehci.cpp
|
||||
hcd_controller.cpp
|
||||
hardware.cpp
|
||||
misc.cpp
|
||||
usbehci.rc)
|
||||
|
||||
target_link_libraries(usbehci
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Universal Serial Bus Bulk Enhanced Host Controller Interface
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* FILE: drivers/usb/usbehci_new/hcd_controller.cpp
|
||||
* FILE: drivers/usb/usbehci/hcd_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 CHCDController : public IHCDController
|
||||
|
@ -38,12 +39,29 @@ public:
|
|||
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);
|
||||
|
||||
// constructor / destructor
|
||||
CHCDController(IUnknown *OuterUnknown){}
|
||||
virtual ~CHCDController(){}
|
||||
|
||||
protected:
|
||||
LONG m_Ref;
|
||||
PROOTHDCCONTROLLER m_RootController;
|
||||
PDRIVER_OBJECT m_DriverObject;
|
||||
PDEVICE_OBJECT m_PhysicalDeviceObject;
|
||||
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;
|
||||
ULONG m_FDODeviceNumber;
|
||||
};
|
||||
|
||||
//=================================================================================================
|
||||
|
@ -67,23 +85,237 @@ CHCDController::QueryInterface(
|
|||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
NTSTATUS
|
||||
CHCDController::Initialize(
|
||||
IN PROOTHDCCONTROLLER RootHCDController,
|
||||
IN PDRIVER_OBJECT DriverObject,
|
||||
IN PDEVICE_OBJECT PhysicalDeviceObject)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
NTSTATUS Status;
|
||||
PCOMMON_DEVICE_EXTENSION DeviceExtension;
|
||||
|
||||
//
|
||||
// create usb hardware
|
||||
//
|
||||
Status = CreateUSBHardware(&m_Hardware);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
//
|
||||
// failed to create hardware object
|
||||
//
|
||||
DPRINT1("Failed to create hardware object\n");
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
//
|
||||
// initialize members
|
||||
//
|
||||
m_DriverObject = DriverObject;
|
||||
m_PhysicalDeviceObject = PhysicalDeviceObject;
|
||||
m_RootController = RootHCDController;
|
||||
|
||||
//
|
||||
// create FDO
|
||||
//
|
||||
Status = CreateFDO(m_DriverObject, &m_FunctionalDeviceObject);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
//
|
||||
// failed to create PDO
|
||||
//
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// now attach to device stack
|
||||
//
|
||||
m_NextDeviceObject = IoAttachDeviceToDeviceStack(m_FunctionalDeviceObject, m_PhysicalDeviceObject);
|
||||
if (!m_NextDeviceObject)
|
||||
{
|
||||
//
|
||||
// failed to attach to device stack
|
||||
//
|
||||
IoDeleteDevice(m_FunctionalDeviceObject);
|
||||
m_FunctionalDeviceObject = 0;
|
||||
|
||||
return STATUS_NO_SUCH_DEVICE;
|
||||
}
|
||||
|
||||
//
|
||||
// initialize hardware object
|
||||
//
|
||||
Status = m_Hardware->Initialize(m_DriverObject, m_FunctionalDeviceObject, m_PhysicalDeviceObject, m_NextDeviceObject);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Failed to initialize hardware object %x\n", Status);
|
||||
|
||||
//
|
||||
// failed to initialize hardware object, detach from device stack
|
||||
//
|
||||
IoDetachDevice(m_NextDeviceObject);
|
||||
|
||||
//
|
||||
// now delete the device
|
||||
//
|
||||
IoDeleteDevice(m_FunctionalDeviceObject);
|
||||
|
||||
//
|
||||
// nullify pointers :)
|
||||
//
|
||||
m_FunctionalDeviceObject = 0;
|
||||
m_NextDeviceObject = 0;
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// set device flags
|
||||
//
|
||||
m_FunctionalDeviceObject->Flags |= DO_BUFFERED_IO | DO_POWER_PAGABLE;
|
||||
|
||||
|
||||
//
|
||||
// get device extension
|
||||
//
|
||||
DeviceExtension = (PCOMMON_DEVICE_EXTENSION)m_FunctionalDeviceObject->DeviceExtension;
|
||||
PC_ASSERT(DeviceExtension);
|
||||
|
||||
//
|
||||
// initialize device extension
|
||||
//
|
||||
DeviceExtension->IsFDO = TRUE;
|
||||
DeviceExtension->IsHub = FALSE;
|
||||
DeviceExtension->HcdController = PHCDCONTROLLER(this);
|
||||
|
||||
//
|
||||
// device is initialized
|
||||
//
|
||||
m_FunctionalDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
|
||||
|
||||
|
||||
//
|
||||
// is there a root controller
|
||||
//
|
||||
if (m_RootController)
|
||||
{
|
||||
//
|
||||
// add reference
|
||||
//
|
||||
m_RootController->AddRef();
|
||||
|
||||
//
|
||||
// register with controller
|
||||
//
|
||||
m_RootController->RegisterHCD(this);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// done
|
||||
//
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
NTSTATUS
|
||||
CHCDController::HandleDeviceControl(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
PIO_STACK_LOCATION IoStack;
|
||||
PCOMMON_DEVICE_EXTENSION DeviceExtension;
|
||||
NTSTATUS Status = STATUS_NOT_IMPLEMENTED;
|
||||
PUSB_HCD_DRIVERKEY_NAME DriverKey;
|
||||
ULONG ResultLength;
|
||||
|
||||
//
|
||||
// get current stack location
|
||||
//
|
||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
//
|
||||
// get device extension
|
||||
//
|
||||
DeviceExtension = (PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
|
||||
|
||||
DPRINT1("HandleDeviceControl>Type: FDO %u IoCtl %x InputBufferLength %lu OutputBufferLength %lu NOT IMPLEMENTED\n",
|
||||
DeviceExtension->IsFDO,
|
||||
IoStack->Parameters.DeviceIoControl.IoControlCode,
|
||||
IoStack->Parameters.DeviceIoControl.InputBufferLength,
|
||||
IoStack->Parameters.DeviceIoControl.OutputBufferLength);
|
||||
|
||||
//
|
||||
// get device type
|
||||
//
|
||||
if (DeviceExtension->IsFDO)
|
||||
{
|
||||
//
|
||||
// perform ioctl for FDO
|
||||
//
|
||||
if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_GET_HCD_DRIVERKEY_NAME)
|
||||
{
|
||||
//
|
||||
// check if sizee is at least >= USB_HCD_DRIVERKEY_NAME
|
||||
//
|
||||
if(IoStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(USB_HCD_DRIVERKEY_NAME))
|
||||
{
|
||||
//
|
||||
// get device property size
|
||||
//
|
||||
Status = IoGetDeviceProperty(m_PhysicalDeviceObject, DevicePropertyDriverKeyName, 0, NULL, &ResultLength);
|
||||
|
||||
DriverKey = (PUSB_HCD_DRIVERKEY_NAME)Irp->AssociatedIrp.SystemBuffer;
|
||||
|
||||
//
|
||||
// check result
|
||||
//
|
||||
if (Status == STATUS_BUFFER_TOO_SMALL)
|
||||
{
|
||||
//
|
||||
// does the caller provide enough buffer space
|
||||
//
|
||||
if (IoStack->Parameters.DeviceIoControl.OutputBufferLength >= ResultLength)
|
||||
{
|
||||
//
|
||||
// it does
|
||||
//
|
||||
Status = IoGetDeviceProperty(m_PhysicalDeviceObject, DevicePropertyDriverKeyName, IoStack->Parameters.DeviceIoControl.OutputBufferLength, DriverKey->DriverKeyName, &ResultLength);
|
||||
|
||||
//DPRINT1("Result %S\n", DriverKey->DriverKeyName);
|
||||
}
|
||||
|
||||
//
|
||||
// FIXME
|
||||
//
|
||||
|
||||
//
|
||||
// store result
|
||||
//
|
||||
DriverKey->ActualLength = ResultLength;
|
||||
Irp->IoStatus.Information = IoStack->Parameters.DeviceIoControl.OutputBufferLength;
|
||||
Status = STATUS_BUFFER_OVERFLOW;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// buffer is certainly too small
|
||||
//
|
||||
Status = STATUS_BUFFER_OVERFLOW;
|
||||
Irp->IoStatus.Information = sizeof(USB_HCD_DRIVERKEY_NAME);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
|
@ -91,12 +323,336 @@ CHCDController::HandlePnp(
|
|||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
PIO_STACK_LOCATION IoStack;
|
||||
PCOMMON_DEVICE_EXTENSION DeviceExtension;
|
||||
PCM_RESOURCE_LIST RawResourceList;
|
||||
PCM_RESOURCE_LIST TranslatedResourceList;
|
||||
PDEVICE_RELATIONS DeviceRelations;
|
||||
PDEVICE_CAPABILITIES DeviceCapabilities;
|
||||
LPGUID Guid;
|
||||
NTSTATUS Status;
|
||||
ULONG Index;
|
||||
|
||||
Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
|
||||
DPRINT("HandlePnp\n");
|
||||
|
||||
//
|
||||
// get device extension
|
||||
//
|
||||
DeviceExtension = (PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
|
||||
//
|
||||
// get current stack location
|
||||
//
|
||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
switch(IoStack->MinorFunction)
|
||||
{
|
||||
case IRP_MN_START_DEVICE:
|
||||
{
|
||||
DPRINT1("IRP_MN_START FDO: %lu\n", DeviceExtension->IsFDO);
|
||||
|
||||
if (DeviceExtension->IsFDO)
|
||||
{
|
||||
//
|
||||
// first start lower device object
|
||||
//
|
||||
Status = SyncForwardIrp(m_NextDeviceObject, Irp);
|
||||
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
//
|
||||
// operation succeeded, lets start the device
|
||||
//
|
||||
RawResourceList = IoStack->Parameters.StartDevice.AllocatedResources;
|
||||
TranslatedResourceList = IoStack->Parameters.StartDevice.AllocatedResourcesTranslated;
|
||||
|
||||
if (m_Hardware)
|
||||
{
|
||||
//
|
||||
// start the hardware
|
||||
//
|
||||
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.
|
||||
//
|
||||
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;
|
||||
}
|
||||
case IRP_MN_QUERY_DEVICE_RELATIONS:
|
||||
{
|
||||
DPRINT1("IRP_MN_QUERY_DEVICE_RELATIONS Type %lx FDO: \n", IoStack->Parameters.QueryDeviceRelations.Type, DeviceExtension->IsFDO);
|
||||
|
||||
if (m_BusPDO == NULL)
|
||||
{
|
||||
//
|
||||
// create bus PDO
|
||||
//
|
||||
Status = CreatePDO(m_DriverObject, &m_BusPDO);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
//
|
||||
// failed to create bus device object
|
||||
//
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// initialize extension
|
||||
//
|
||||
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;
|
||||
}
|
||||
|
||||
if (IoStack->Parameters.QueryDeviceRelations.Type == BusRelations)
|
||||
{
|
||||
//
|
||||
// allocate device relations
|
||||
//
|
||||
DeviceRelations = (PDEVICE_RELATIONS)ExAllocatePool(PagedPool, sizeof(DEVICE_RELATIONS));
|
||||
|
||||
if (!DeviceRelations)
|
||||
{
|
||||
//
|
||||
// no memory
|
||||
//
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// init device relations
|
||||
//
|
||||
DeviceRelations->Count = 1;
|
||||
DeviceRelations->Objects [0] = m_BusPDO;
|
||||
|
||||
ObReferenceObject(m_BusPDO);
|
||||
|
||||
//
|
||||
// store result
|
||||
//
|
||||
Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations;
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case IRP_MN_STOP_DEVICE:
|
||||
{
|
||||
DPRINT1("IRP_MN_STOP_DEVICE FDO: %lu\n", DeviceExtension->IsFDO);
|
||||
|
||||
if (m_Hardware)
|
||||
{
|
||||
//
|
||||
// stop the hardware
|
||||
//
|
||||
Status = m_Hardware->PnpStop();
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// fake success
|
||||
//
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
//
|
||||
// stop lower device
|
||||
//
|
||||
Status = SyncForwardIrp(m_NextDeviceObject, Irp);
|
||||
}
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// store result and complete request
|
||||
//
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
|
@ -112,8 +668,263 @@ 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,
|
||||
PDEVICE_OBJECT * OutDeviceObject)
|
||||
{
|
||||
WCHAR CharDeviceName[64];
|
||||
NTSTATUS Status;
|
||||
ULONG UsbDeviceNumber = 0;
|
||||
UNICODE_STRING DeviceName;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
//
|
||||
// construct device name
|
||||
//
|
||||
swprintf(CharDeviceName, L"\\Device\\USBFDO-%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("CreateFDO: Failed to create %wZ, Status %x\n", &DeviceName, Status);
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// store FDO number
|
||||
//
|
||||
m_FDODeviceNumber = UsbDeviceNumber;
|
||||
|
||||
DPRINT1("CreateFDO: DeviceName %wZ\n", &DeviceName);
|
||||
|
||||
/* done */
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
CHCDController::SetDeviceInterface(
|
||||
BOOLEAN Enable)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
WCHAR LinkName[32];
|
||||
WCHAR FDOName[32];
|
||||
UNICODE_STRING Link, FDO;
|
||||
|
||||
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(FDOName, L"\\Device\\USBFDO-%d", m_FDODeviceNumber);
|
||||
RtlInitUnicodeString(&Link, LinkName);
|
||||
RtlInitUnicodeString(&FDO, FDOName);
|
||||
|
||||
//
|
||||
// create symbolic link
|
||||
//
|
||||
Status = IoCreateSymbolicLink(&Link, &FDO);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
//
|
||||
// FIXME: handle me
|
||||
//
|
||||
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)
|
||||
{
|
||||
//
|
||||
// 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(
|
||||
|
@ -121,14 +932,30 @@ CreateHCDController(
|
|||
{
|
||||
PHCDCONTROLLER This;
|
||||
|
||||
//
|
||||
// allocate controller
|
||||
//
|
||||
This = new(NonPagedPool, 0) CHCDController(0);
|
||||
if (!This)
|
||||
{
|
||||
//
|
||||
// failed to allocate
|
||||
//
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
//
|
||||
// add reference count
|
||||
//
|
||||
This->AddRef();
|
||||
|
||||
//
|
||||
// return result
|
||||
//
|
||||
*OutHcdController = (PHCDCONTROLLER)This;
|
||||
|
||||
//
|
||||
// done
|
||||
//
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
|
82
drivers/usb/usbehci_new/misc.cpp
Normal file
82
drivers/usb/usbehci_new/misc.cpp
Normal file
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Universal Serial Bus Bulk Enhanced Host Controller Interface
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* FILE: drivers/usb/usbehci/misc.cpp
|
||||
* PURPOSE: USB EHCI device driver.
|
||||
* PROGRAMMERS:
|
||||
* Michael Martin (michael.martin@reactos.org)
|
||||
* Johannes Anderwald (johannes.anderwald@reactos.org)
|
||||
*/
|
||||
|
||||
#include "usbehci.h"
|
||||
|
||||
//
|
||||
// driver verifier
|
||||
//
|
||||
IO_COMPLETION_ROUTINE SyncForwardIrpCompletionRoutine;
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
SyncForwardIrpCompletionRoutine(
|
||||
PDEVICE_OBJECT DeviceObject,
|
||||
PIRP Irp,
|
||||
PVOID Context)
|
||||
{
|
||||
if (Irp->PendingReturned)
|
||||
{
|
||||
KeSetEvent((PKEVENT)Context, IO_NO_INCREMENT, FALSE);
|
||||
}
|
||||
return STATUS_MORE_PROCESSING_REQUIRED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
SyncForwardIrp(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
{
|
||||
KEVENT Event;
|
||||
NTSTATUS Status;
|
||||
|
||||
//
|
||||
// initialize event
|
||||
//
|
||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||
|
||||
//
|
||||
// copy irp stack location
|
||||
//
|
||||
IoCopyCurrentIrpStackLocationToNext(Irp);
|
||||
|
||||
//
|
||||
// set completion routine
|
||||
//
|
||||
IoSetCompletionRoutine(Irp, SyncForwardIrpCompletionRoutine, &Event, TRUE, TRUE, TRUE);
|
||||
|
||||
|
||||
//
|
||||
// call driver
|
||||
//
|
||||
Status = IoCallDriver(DeviceObject, Irp);
|
||||
|
||||
|
||||
//
|
||||
// check if pending
|
||||
//
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
//
|
||||
// wait for the request to finish
|
||||
//
|
||||
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
||||
|
||||
//
|
||||
// copy status code
|
||||
//
|
||||
Status = Irp->IoStatus.Status;
|
||||
}
|
||||
|
||||
//
|
||||
// done
|
||||
//
|
||||
return Status;
|
||||
}
|
||||
|
|
@ -50,4 +50,9 @@ NTSTATUS CreateHCDController(PHCDCONTROLLER *HcdController);
|
|||
//
|
||||
NTSTATUS CreateUSBHardware(PUSBHARDWAREDEVICE *OutHardware);
|
||||
|
||||
//
|
||||
// misc.cpp
|
||||
//
|
||||
NTSTATUS NTAPI SyncForwardIrp(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue