From: Johannes Anderwald Date: Thu, 14 Apr 2011 11:35:16 +0000 (+0000) Subject: [USBEHCI_NEW] X-Git-Tag: backups/usb-bringup@55523~153 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=009b2e00df879864ddb795536ec53ec10f4462ce [USBEHCI_NEW] - Create empty USB EHCI driver in c++ - Design & review the interfaces with mjmartin - Create stubs for creating IUSBHardwareDevice / IHCDController classes - Implement DriverEntry, EHCI_AddDevice and EHCI_Dispatch svn path=/branches/usb-bringup/; revision=51335 --- diff --git a/drivers/usb/CMakeLists.txt b/drivers/usb/CMakeLists.txt index 4be624d2bb5..2d351a61899 100644 --- a/drivers/usb/CMakeLists.txt +++ b/drivers/usb/CMakeLists.txt @@ -1,6 +1,6 @@ add_subdirectory(nt4compat) add_subdirectory(usbd) -add_subdirectory(usbehci) +add_subdirectory(usbehci_new) #add_subdirectory(usbhub) Compiles, just skipped in trunk #add_subdirectory(usbstor) Compiles, just skipped in trunk diff --git a/drivers/usb/usbehci_new/CMakeLists.txt b/drivers/usb/usbehci_new/CMakeLists.txt new file mode 100644 index 00000000000..587ad7cb305 --- /dev/null +++ b/drivers/usb/usbehci_new/CMakeLists.txt @@ -0,0 +1,28 @@ + +set_cpp() + +remove_definitions(-D_WIN32_WINNT=0x502) +add_definitions(-D_WIN32_WINNT=0x600) + +add_library(usbehci SHARED + usbehci.cpp + hcd_controller.cpp + hardware.cpp + usbehci.rc) + +target_link_libraries(usbehci + libcntpr + stlport + ${PSEH_LIB}) + +if(MSVC) + set_target_properties(usbehci PROPERTIES COMPILE_FLAGS "/GR-") +else() + target_link_libraries(usbehci -lgcc) + set_target_properties(usbehci PROPERTIES COMPILE_FLAGS "-fno-exceptions -fno-rtti") +endif(MSVC) + +set_module_type(usbehci kernelmodedriver) +add_importlibs(usbehci ntoskrnl ks drmk hal) + +add_cab_target(usbehci 2) \ No newline at end of file diff --git a/drivers/usb/usbehci_new/hardware.cpp b/drivers/usb/usbehci_new/hardware.cpp new file mode 100644 index 00000000000..7c3a4278b66 --- /dev/null +++ b/drivers/usb/usbehci_new/hardware.cpp @@ -0,0 +1,18 @@ +/* + * 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 + * PURPOSE: USB EHCI device driver. + * PROGRAMMERS: + * Michael Martin (michael.martin@reactos.org) + * Johannes Anderwald (johannes.anderwald@reactos.org) + */ + +#include "usbehci.h" + +NTSTATUS +CreateUSBHardware( + PUSBHARDWAREDEVICE *OutHardware) +{ + return STATUS_NOT_IMPLEMENTED; +} diff --git a/drivers/usb/usbehci_new/hcd_controller.cpp b/drivers/usb/usbehci_new/hcd_controller.cpp new file mode 100644 index 00000000000..23460f78970 --- /dev/null +++ b/drivers/usb/usbehci_new/hcd_controller.cpp @@ -0,0 +1,18 @@ +/* + * 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 + * PURPOSE: USB EHCI device driver. + * PROGRAMMERS: + * Michael Martin (michael.martin@reactos.org) + * Johannes Anderwald (johannes.anderwald@reactos.org) + */ + +#include "usbehci.h" + +NTSTATUS +CreateHCDController( + PHCDCONTROLLER *OutHcdController) +{ + return STATUS_NOT_IMPLEMENTED; +} diff --git a/drivers/usb/usbehci_new/interfaces.h b/drivers/usb/usbehci_new/interfaces.h new file mode 100644 index 00000000000..cb90ce3f9e4 --- /dev/null +++ b/drivers/usb/usbehci_new/interfaces.h @@ -0,0 +1,490 @@ + +#ifndef INTERFACES_HPP +#define INTERFACES_HPP + +//--------------------------------------------------------------------------- +// +// Object Hierachy +// -------------------------------------------------------------------- +// | IRootHCDController | +// | IHCDController Intel USB Universal Host Controller - 3A37 | +// | IHCDController - Intel USB Universal HostController - 3A38 | +// | IHCDController - Intel USB Universal HostController - 3A38 | +// |------------------------------------------------------------------| +// +// +// IHCDController Intel USB Universal Host Controller - 3A37 +// IHubController +// IUSBHardwareDevice +// IDMAMemoryManager +// IUSBQueue <- interacts with -> IUSBRequest +// +// +// Each IHCDController creates an IUSBHardwareDevice class upon initialization. The +// IUSBHardwardeDevice class is used to abstract usb controller specifics. The IHubController +// manages all attached devices and handles hub control ioctl requests. +// +// Each IUSBHardwareDevice has one IDMAMemoryManager and one IUSBQueue. The IDMAMemoryManager +// is used to handle dma memory allocations. The IUSBQueue manages requests which are send to the +// usb hardware. See IUSBRequest class for details. +// + + +//========================================================================================= +// +// class IRootHCDController +// +// Description: This class serves as the root host controller. The host controller mantains +// a list of registered controllers and provides support functions for the host controllers + +struct IHCDController; + +DECLARE_INTERFACE_(IRootHCDController, IUnknown) +{ + DEFINE_ABSTRACT_UNKNOWN() + +//----------------------------------------------------------------------------------------- +// +// Initialize +// +// Description: This function initializes the root host controller. It allocates the resources +// required to manage the registered controllers + + virtual NTSTATUS Initialize() = 0; + +//----------------------------------------------------------------------------------------- +// +// RegisterHCD +// +// Description: this function registers a host controller with the root host controller + + virtual NTSTATUS RegisterHCD(struct IHCDController * Controller) = 0; + +//----------------------------------------------------------------------------------------- +// +// UnregisterHCD +// +// Description: this function unregistes a host controller + + virtual NTSTATUS UnregisterHCD(struct IHCDController * Controller) = 0; + +//----------------------------------------------------------------------------------------- +// +// GetControllerCount +// +// Description: returns the number of host controllers registered + + virtual ULONG GetControllerCount() = 0; + +}; + +typedef IRootHCDController *PROOTHDCCONTROLLER; + +//========================================================================================= +// +// class IHCDController +// +// Description: This class is used to manage a single USB host controller +// + +DECLARE_INTERFACE_(IHCDController, IUnknown) +{ + DEFINE_ABSTRACT_UNKNOWN() + +//----------------------------------------------------------------------------------------- +// +// Initialize +// +// Description: This function initializes the IHCDController implementation. +// It creates an IUSBHardwareDevice object and initializes it. It also registeres itself with +// the IRootHCDController +// + virtual NTSTATUS Initialize(IN PROOTHDCCONTROLLER RootHCDController, + 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; + + +//========================================================================================= +// +// class IUSBHardwareDevice +// +// Description: This class provides access to the usb hardware controller +// + +struct IDMAMemoryManager; +struct IUSBQueue; + +DECLARE_INTERFACE_(IUSBHardwareDevice, IUnknown) +{ + DEFINE_ABSTRACT_UNKNOWN() + +//----------------------------------------------------------------------------------------- +// +// Initialize +// +// Description: Initializes the usb device controller + + virtual NTSTATUS Initialize(PDRIVER_OBJECT DriverObject, + PDEVICE_OBJECT FunctionalDeviceObject, + PDEVICE_OBJECT PhysicalDeviceObject, + PDEVICE_OBJECT LowerDeviceObject) = 0; + +//----------------------------------------------------------------------------------------- +// +// PnpStart +// +// Description: handles pnp start request from device. It registeres the interrupt, +// sets up the ports and prepares the device. It then starts the controller + + virtual NTSTATUS PnpStart(PCM_RESOURCE_LIST RawResources, + PCM_RESOURCE_LIST TranslatedResources) = 0; + +//----------------------------------------------------------------------------------------- +// +// PnpStop +// +// Description: handles pnp stop request from device. It unregisteres the interrupt, releases ports and dma object. + + virtual NTSTATUS PnpStop(void) = 0; + +//----------------------------------------------------------------------------------------- +// +// HandlePower +// +// Description: handles power requests + + virtual NTSTATUS HandlePower(PIRP Irp) = 0; + +//----------------------------------------------------------------------------------------- +// +// GetDeviceDetails +// +// Description: returns the device details such as vendor id, device id, number of ports and speed + + virtual NTSTATUS GetDeviceDetails(OUT OPTIONAL PULONG VendorId, + OUT OPTIONAL PULONG DeviceId, + OUT OPTIONAL PULONG NumberOfPorts, + OUT OPTIONAL PULONG Speed) = 0; + +//----------------------------------------------------------------------------------------- +// +// GetDmaMemoryManager +// +// Description: returns interface to DMAMemoryManager +// Interface is reference counted, you need to call Release method when you are done with it +// Do not call Initialize on IDMAMemoryManager, the object is already initialized + + virtual NTSTATUS GetDmaMemoryManager(OUT struct IDMAMemoryManager **OutMemoryManager) = 0; + +//----------------------------------------------------------------------------------------- +// +// GetUSBQueue +// +// Description: returns interface to internal IUSBQueue +// Interface is reference counted, you need to call release method when you are done with it +// Do not call Initialize on IUSBQueue, the object is already initialized + + virtual NTSTATUS GetUSBQueue(OUT struct IUSBQueue **OutUsbQueue) = 0; + +//----------------------------------------------------------------------------------------- +// +// ResetController() +// +// Description: this function resets the controller +// Returns STATUS_SUCCESS when the controller was successfully reset + + virtual NTSTATUS ResetController() = 0; + +//----------------------------------------------------------------------------------------- +// +// ResetPort +// +// Description: this functions resets the port on the controller +// + + virtual NTSTATUS ResetPort(ULONG PortNumber) = 0; + +//----------------------------------------------------------------------------------------- +// +// AcquireDeviceLock +// +// Description: acquires the device lock + + virtual KIRQL AcquireDeviceLock(void) = 0; + +//----------------------------------------------------------------------------------------- +// +// ReleaseLock +// +// Description: releases the device lock + + virtual void ReleaseDeviceLock(KIRQL OldLevel) = 0; +}; + +typedef IUSBHardwareDevice *PUSBHARDWAREDEVICE; + + +//========================================================================================= +// +// class IDMAMemoryManager +// +// Description: This class provides access to the dma buffer. It provides methods to +// allocate and free from the dma buffer +// + +DECLARE_INTERFACE_(IDMAMemoryManager, IUnknown) +{ + DEFINE_ABSTRACT_UNKNOWN() + +//----------------------------------------------------------------------------------------- +// +// Initialize +// +// Description: initializes the memory manager + + virtual NTSTATUS Initialize(IN PUSBHARDWAREDEVICE Device, + IN PKSPIN_LOCK Lock, + IN ULONG DmaBufferSize, + IN PVOID VirtualBase, + IN PHYSICAL_ADDRESS PhysicalAddress, + IN ULONG DefaultBlockSize) = 0; + +//----------------------------------------------------------------------------------------- +// +// Allocate +// +// Description: allocates block of memory from allocator + + virtual NTSTATUS Allocate(IN ULONG Size, + OUT PVOID *OutVirtualBase, + OUT PPHYSICAL_ADDRESS *OutPhysicalAddress) = 0; + + +//----------------------------------------------------------------------------------------- +// +// Free +// +// Description: releases memory block + + virtual NTSTATUS Release(IN PVOID VirtualBase, + IN ULONG Size) = 0; + +}; + +typedef IDMAMemoryManager *PDMAMEMORYMANAGER; + + +//========================================================================================= +// +// class IUSBRequest +// +// Description: This class is used to issue request to usb controller. The class is +// initialized using InitializeXXX methods. You also need to call SetEndpoint to define the endpoint +// In addition you can call SetCompletionDetails if you need to wait for the end of +// the request or want to complete an irp. You call AddUSBRequest to add the request to the queue. +// Once the request is completed the CompletionCallback is invoked. The CompletionCallback +// will take care of any completion details which have been set. If the request is cancelled, the +// CancelCallback routine is invoked. +// + +DECLARE_INTERFACE_(IUSBRequest, IUnknown) +{ + DEFINE_ABSTRACT_UNKNOWN() + +//----------------------------------------------------------------------------------------- +// +// InitializeWithSetupPacket +// +// Description: initializes the request packet with an setup packet +// If there is a TransferBuffer, the TransferBufferLength contains the length of the buffer + + + virtual NTSTATUS InitializeWithSetupPacket(IN PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket, + IN ULONG TransferBufferLength, + IN PVOID TransferBuffer) = 0; + +// +//TODO: find required parameters for different packet types +// + + +//----------------------------------------------------------------------------------------- +// +// SetEndPoint +// +// Description: sets the endpoint of the request. + + virtual NTSTATUS SetEndPoint(PUSB_ENDPOINT_DESCRIPTOR EndPoint); + +//----------------------------------------------------------------------------------------- +// +// SetCompletionDetails +// +// Description: sets up how the request should be completed +// If an irp is passed, then it is completed with status code of the +// CompletionCallback or CancelCallback +// If an event is passed, then the event is signaled + + virtual NTSTATUS SetCompletionDetails(IN OPTIONAL PIRP Irp, + IN OPTIONAL PKEVENT Event) = 0; + +//----------------------------------------------------------------------------------------- +// +// CompletionCallback +// +// Description: called when request has been completed. It is called when +// IUSBQueue completes the request + + virtual VOID CompletionCallback(IN NTSTATUS NtStatusCode, + IN ULONG UrbStatusCode) = 0; + +//----------------------------------------------------------------------------------------- +// +// CancelCallback +// +// Description: called when request is cancelled. Called by IUSBQueue + + virtual VOID CancelCallback(IN NTSTATUS NtStatusCode) = 0; + +}; + +//========================================================================================= +// +// class IUSBQueue +// +// Description: This class manages pending requests +// + +DECLARE_INTERFACE_(IUSBQueue, IUnknown) +{ + DEFINE_ABSTRACT_UNKNOWN() + +//----------------------------------------------------------------------------------------- +// +// Initialize +// +// Description: initializes the object + + virtual NTSTATUS Initialize(IN PUSBHARDWAREDEVICE Hardware, + IN OPTIONAL PKSPIN_LOCK Lock, + IN PDMAMEMORYMANAGER MemoryManager) = 0; + +//----------------------------------------------------------------------------------------- +// +// GetPendingRequestCount +// +// Description: returns the number of pending requests + + virtual ULONG GetPendingRequestCount() = 0; + +//----------------------------------------------------------------------------------------- +// +// AddUSBRequest +// +// Description: adds an usb request to the queue. +// Returns status success when successful + + virtual NTSTATUS AddUSBRequest(IUSBRequest * Request) = 0; + +//----------------------------------------------------------------------------------------- +// +// CancelRequests() +// +// Description: cancels all requests + + virtual NTSTATUS CancelRequests() = 0; + +//----------------------------------------------------------------------------------------- +// +// CreateUSBRequest +// +// Description: creates an usb request + + virtual NTSTATUS CreateUSBRequest(IUSBRequest **OutRequest) = 0; +}; + +//========================================================================================= +// +// class IHubController +// +// Description: This class implements a hub controller +// + +DECLARE_INTERFACE_(IHubController, IUnknown) +{ + DEFINE_ABSTRACT_UNKNOWN() + +//---------------------------------------------------------------------------------------- +// +// Initialize +// +// Description: Initializes the hub controller + + virtual NTSTATUS Initialize(IN PHCDCONTROLLER Controller, + IN PUSBHARDWAREDEVICE Device, + IN BOOLEAN IsRootHubDevice, + IN ULONG DeviceAddress); + +//----------------------------------------------------------------------------------------- +// +// 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 IHubController *PHUBCONTROLLER; + + +#endif diff --git a/drivers/usb/usbehci_new/usbehci.cpp b/drivers/usb/usbehci_new/usbehci.cpp new file mode 100644 index 00000000000..28bf19b7824 --- /dev/null +++ b/drivers/usb/usbehci_new/usbehci.cpp @@ -0,0 +1,161 @@ +/* + * PROJECT: ReactOS Universal Serial Bus Bulk Enhanced Host Controller Interface + * LICENSE: GPL - See COPYING in the top level directory + * FILE: drivers/usb/usbehci/usbehci.cpp + * PURPOSE: USB EHCI device driver. + * PROGRAMMERS: + * Michael Martin (michael.martin@reactos.org) + * Johannes Anderwald (johannes.anderwald@reactos.org) + */ + +#include "usbehci.h" + +// +// driver verifier +// +DRIVER_ADD_DEVICE EHCI_AddDevice; + +NTSTATUS +NTAPI +EHCI_AddDevice( + PDRIVER_OBJECT DriverObject, + PDEVICE_OBJECT PhysicalDeviceObject) +{ + NTSTATUS Status; + PHCDCONTROLLER HcdController; + + DPRINT1("EHCI_AddDevice\n"); + + /* first create the controller object */ + Status = CreateHCDController(&HcdController); + if (!NT_SUCCESS(Status)) + { + /* failed to create hcd */ + DPRINT1("AddDevice: Failed to create hcd with %x\n", Status); + return Status; + } + + /* initialize the hcd */ + Status = HcdController->Initialize(NULL, // FIXME + DriverObject, + PhysicalDeviceObject); + + /* check for success */ + if (!NT_SUCCESS(Status)) + { + /* failed to initialize device */ + DPRINT1("AddDevice: failed to initialize\n"); + + /* release object */ + HcdController->Release(); + } + + return Status; + +} + +NTSTATUS +NTAPI +EHCI_Dispatch( + PDEVICE_OBJECT DeviceObject, + PIRP Irp) +{ + PCOMMON_DEVICE_EXTENSION DeviceExtension; + PIO_STACK_LOCATION IoStack; + NTSTATUS Status; + + DPRINT1("EHCI_Dispatch\n"); + + // + // get common device extension + // + DeviceExtension = (PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + // + // get current stack location + // + IoStack = IoGetCurrentIrpStackLocation(Irp); + + // + // sanity checks + // + PC_ASSERT(DeviceExtension->HcdController); + + // + // FIXME: support bus device + // + PC_ASSERT(DeviceExtension->IsHub == FALSE); + + switch(IoStack->MajorFunction) + { + case IRP_MJ_PNP: + { + // + // dispatch pnp + // + return DeviceExtension->HcdController->HandlePnp(DeviceObject, Irp); + } + + case IRP_MJ_POWER: + { + // + // dispatch pnp + // + return DeviceExtension->HcdController->HandlePower(DeviceObject, Irp); + } + case IRP_MJ_SYSTEM_CONTROL: + case IRP_MJ_DEVICE_CONTROL: + { + // + // dispatch pnp + // + return DeviceExtension->HcdController->HandleDeviceControl(DeviceObject, Irp); + } + case IRP_MJ_CREATE: + { + // + // dispatch create request + // + Status = STATUS_SUCCESS; + + break; + } + default: + { + DPRINT1("EHCI_Dispatch> Major %lu Minor %lu not supported\n", IoStack->MajorFunction, IoStack->MinorFunction); + Status = STATUS_NOT_SUPPORTED; + } + } + + // + // complete request + // + Irp->IoStatus.Information = 0; + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + + return Status; +} + +extern +"C" +NTSTATUS +NTAPI +DriverEntry( + PDRIVER_OBJECT DriverObject, + PUNICODE_STRING RegistryPath) +{ + + /* initialize driver object*/ + DriverObject->DriverExtension->AddDevice = EHCI_AddDevice; + + DriverObject->MajorFunction[IRP_MJ_CREATE] = EHCI_Dispatch; + DriverObject->MajorFunction[IRP_MJ_CLOSE] = EHCI_Dispatch; + DriverObject->MajorFunction[IRP_MJ_CLEANUP] = EHCI_Dispatch; + DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = EHCI_Dispatch; + DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = EHCI_Dispatch; + DriverObject->MajorFunction[IRP_MJ_PNP] = EHCI_Dispatch; + + return STATUS_SUCCESS; +} diff --git a/drivers/usb/usbehci_new/usbehci.h b/drivers/usb/usbehci_new/usbehci.h new file mode 100644 index 00000000000..1ee9d5fb7b9 --- /dev/null +++ b/drivers/usb/usbehci_new/usbehci.h @@ -0,0 +1,53 @@ +#ifndef USBEHCI_H__ +#define USBEHCI_H__ + +#include +#define YDEBUG +#include +#include +#include +#include +#include +#include +#include + +// +// FIXME: +// the following includes are required to get kcom to compile +// +#include +#include +#include + +#include "interfaces.h" + +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 + }; +}COMMON_DEVICE_EXTENSION, *PCOMMON_DEVICE_EXTENSION; + + +// +// assert for c++ - taken from portcls +// +#define PC_ASSERT(exp) \ + (VOID)((!(exp)) ? \ + RtlAssert((PVOID) #exp, (PVOID)__FILE__, __LINE__, NULL ), FALSE : TRUE) + +// +// hcd_controller.cpp +// +NTSTATUS CreateHCDController(PHCDCONTROLLER *HcdController); + +// +// hardware.cpp +// +NTSTATUS CreateUSBHardware(PUSBHARDWAREDEVICE *OutHardware); + +#endif diff --git a/drivers/usb/usbehci_new/usbehci.rc b/drivers/usb/usbehci_new/usbehci.rc new file mode 100644 index 00000000000..7ddce2e638f --- /dev/null +++ b/drivers/usb/usbehci_new/usbehci.rc @@ -0,0 +1,5 @@ +#define REACTOS_VERSION_DLL +#define REACTOS_STR_FILE_DESCRIPTION "USBEHCI Driver API\0" +#define REACTOS_STR_INTERNAL_NAME "usbehci\0" +#define REACTOS_STR_ORIGINAL_FILENAME "usbehci.sys\0" +#include