diff --git a/drivers/usb/usbehci_new/hardware.cpp b/drivers/usb/usbehci_new/hardware.cpp index fb8394b03de..c1197e1a24a 100644 --- a/drivers/usb/usbehci_new/hardware.cpp +++ b/drivers/usb/usbehci_new/hardware.cpp @@ -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 CUSBHardwareDevice : public IUSBHardwareDevice @@ -40,9 +41,13 @@ public: NTSTATUS GetDmaMemoryManager(OUT struct IDMAMemoryManager **OutMemoryManager); NTSTATUS GetUSBQueue(OUT struct IUSBQueue **OutUsbQueue); NTSTATUS ResetController(); - NTSTATUS ResetPort(ULONG PortIndex); KIRQL AcquireDeviceLock(void); VOID ReleaseDeviceLock(KIRQL OldLevel); + // local + BOOLEAN InterruptService(); + + // friend function + friend BOOLEAN NTAPI InterruptServiceRoutine(IN PKINTERRUPT Interrupt, IN PVOID ServiceContext); // constructor / destructor CUSBHardwareDevice(IUnknown *OuterUnknown){} @@ -50,8 +55,15 @@ public: protected: LONG m_Ref; + PDRIVER_OBJECT m_DriverObject; + PDEVICE_OBJECT m_PhysicalDeviceObject; + PDEVICE_OBJECT m_FunctionalDeviceObject; + PDEVICE_OBJECT m_NextDeviceObject; KSPIN_LOCK m_Lock; - + PKINTERRUPT m_Interrupt; + PULONG m_Base; + PDMA_ADAPTER m_Adapter; + ULONG m_MapRegisters; }; //================================================================================================= @@ -82,8 +94,23 @@ CUSBHardwareDevice::Initialize( PDEVICE_OBJECT PhysicalDeviceObject, PDEVICE_OBJECT LowerDeviceObject) { - UNIMPLEMENTED - return STATUS_NOT_IMPLEMENTED; + + DPRINT1("CUSBHardwareDevice::Initialize\n"); + + // + // store device objects + // + m_DriverObject = DriverObject; + m_FunctionalDeviceObject = FunctionalDeviceObject; + m_PhysicalDeviceObject = PhysicalDeviceObject; + m_NextDeviceObject = LowerDeviceObject; + + // + // initialize device lock + // + KeInitializeSpinLock(&m_Lock); + + return STATUS_SUCCESS; } @@ -92,8 +119,100 @@ CUSBHardwareDevice::PnpStart( PCM_RESOURCE_LIST RawResources, PCM_RESOURCE_LIST TranslatedResources) { - UNIMPLEMENTED - return STATUS_NOT_IMPLEMENTED; + ULONG Index; + PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceDescriptor; + DEVICE_DESCRIPTION DeviceDescription; + PVOID ResourceBase; + NTSTATUS Status; + + DPRINT1("CUSBHardwareDevice::PnpStart\n"); + for(Index = 0; Index < TranslatedResources->List[0].PartialResourceList.Count; Index++) + { + // + // get resource descriptor + // + ResourceDescriptor = &TranslatedResources->List[0].PartialResourceList.PartialDescriptors[Index]; + + switch(ResourceDescriptor->Type) + { + case CmResourceTypeInterrupt: + { + Status = IoConnectInterrupt(&m_Interrupt, + InterruptServiceRoutine, + (PVOID)this, + NULL, + ResourceDescriptor->u.Interrupt.Vector, + (KIRQL)ResourceDescriptor->u.Interrupt.Level, + (KIRQL)ResourceDescriptor->u.Interrupt.Level, + (KINTERRUPT_MODE)(ResourceDescriptor->Flags & CM_RESOURCE_INTERRUPT_LATCHED), + (ResourceDescriptor->ShareDisposition != CmResourceShareDeviceExclusive), + ResourceDescriptor->u.Interrupt.Affinity, + FALSE); + + if (!NT_SUCCESS(Status)) + { + // + // failed to register interrupt + // + DPRINT1("IoConnect Interrupt failed with %x\n", Status); + return Status; + } + break; + } + case CmResourceTypeMemory: + { + // + // get resource base + // + ResourceBase = MmMapIoSpace(ResourceDescriptor->u.Memory.Start, ResourceDescriptor->u.Memory.Length, MmNonCached); + if (!ResourceBase) + { + // + // failed to map registers + // + DPRINT1("MmMapIoSpace failed\n"); + return STATUS_INSUFFICIENT_RESOURCES; + } + + // + //FIXME: query capabilities and update m_Base + // + break; + } + } + } + + + // + // zero device description + // + RtlZeroMemory(&DeviceDescription, sizeof(DEVICE_DESCRIPTION)); + + // + // initialize device description + // + DeviceDescription.Version = DEVICE_DESCRIPTION_VERSION; + DeviceDescription.Master = TRUE; + DeviceDescription.ScatterGather = TRUE; + DeviceDescription.Dma32BitAddresses = TRUE; + DeviceDescription.DmaWidth = Width32Bits; + DeviceDescription.InterfaceType = PCIBus; + DeviceDescription.MaximumLength = MAXULONG; + + // + // get dma adapter + // + m_Adapter = IoGetDmaAdapter(m_PhysicalDeviceObject, &DeviceDescription, &m_MapRegisters); + if (!m_Adapter) + { + // + // failed to get dma adapter + // + DPRINT1("Failed to acquire dma adapter\n"); + return STATUS_INSUFFICIENT_RESOURCES; + } + + return STATUS_SUCCESS; } NTSTATUS @@ -159,12 +278,27 @@ CUSBHardwareDevice::ResetPort( KIRQL CUSBHardwareDevice::AcquireDeviceLock(void) { - KIRQL OldLevel = 0; + KIRQL OldLevel; - UNIMPLEMENTED + // + // acquire lock + // + KeAcquireSpinLock(&m_Lock, &OldLevel); + + // + // return old irql + // return OldLevel; } + +VOID +CUSBHardwareDevice::ReleaseDeviceLock( + KIRQL OldLevel) +{ + KeReleaseSpinLock(&m_Lock, OldLevel); +} + BOOLEAN NTAPI InterruptServiceRoutine( @@ -175,14 +309,6 @@ InterruptServiceRoutine( return FALSE; } -VOID -CUSBHardwareDevice::ReleaseDeviceLock( - KIRQL OldLevel) -{ - UNIMPLEMENTED -} - - NTSTATUS CreateUSBHardware( PUSBHARDWAREDEVICE *OutHardware)