[ros-diffs] [mjmartin] 44993: [usb/usbehci] - Initial implementation of usbehci, aka USB 2.0. - Implement AddDevice, StartDevice, InterruptService and DPC Routines. - Implement basic IRP queuing and handling. - Implement starting, stopping of EHCI controller and querying port capabilities. - Implement PNP for Query Relations, Query ID, Query BusInfo. - Implement finding the active ports when USB devices are attached and releasing control to companion controller if devices is not a high speed devices. - Implement reporting devices connects to upper Pdo (hub) driver. - Hub driver attaches successfully and sends URBs to query descriptors from USB devices on Windows. - Currently not build enabled as it will cause problems with current UsbDriver in trunk. - Code heavily based on current PCI drivers and UsbDriver from trunk.

mjmartin at svn.reactos.org mjmartin at svn.reactos.org
Fri Jan 8 10:34:36 CET 2010


Author: mjmartin
Date: Fri Jan  8 10:34:36 2010
New Revision: 44993

URL: http://svn.reactos.org/svn/reactos?rev=44993&view=rev
Log:
[usb/usbehci]
- Initial implementation of usbehci, aka USB 2.0.
- Implement AddDevice, StartDevice, InterruptService and DPC Routines.
- Implement basic IRP queuing and handling.
- Implement starting, stopping of EHCI controller and querying port capabilities. 
- Implement PNP for Query Relations, Query ID, Query BusInfo.
- Implement finding the active ports when USB devices are attached and releasing control to companion controller if devices is not a high speed devices.
- Implement reporting devices connects to upper Pdo (hub) driver.
- Hub driver attaches successfully and sends URBs to query descriptors from USB devices on Windows.
- Currently not build enabled as it will cause problems with current UsbDriver in trunk.
- Code heavily based on current PCI drivers and UsbDriver from trunk.

Added:
    trunk/reactos/drivers/usb/usbehci/   (with props)
    trunk/reactos/drivers/usb/usbehci/common.c   (with props)
    trunk/reactos/drivers/usb/usbehci/fdo.c   (with props)
    trunk/reactos/drivers/usb/usbehci/misc.c   (with props)
    trunk/reactos/drivers/usb/usbehci/pdo.c   (with props)
    trunk/reactos/drivers/usb/usbehci/usbehci.c   (with props)
    trunk/reactos/drivers/usb/usbehci/usbehci.h   (with props)
    trunk/reactos/drivers/usb/usbehci/usbehci.rbuild   (with props)
    trunk/reactos/drivers/usb/usbehci/usbehci.rc   (with props)

Propchange: trunk/reactos/drivers/usb/usbehci/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Fri Jan  8 10:34:36 2010
@@ -1,0 +1,7 @@
+GNUmakefile
+*.vcproj
+*.user
+*.cbp
+*.ncb
+*.suo
+*.sln

Added: trunk/reactos/drivers/usb/usbehci/common.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbehci/common.c?rev=44993&view=auto
==============================================================================
--- trunk/reactos/drivers/usb/usbehci/common.c (added)
+++ trunk/reactos/drivers/usb/usbehci/common.c [iso-8859-1] Fri Jan  8 10:34:36 2010
@@ -1,0 +1,147 @@
+
+#define INITGUID
+#include "usbehci.h"
+#include <wdmguid.h>
+#include <stdio.h>
+#define NDEBUG
+#include <debug.h>
+
+/* PUBLIC AND PRIVATE FUNCTIONS ***********************************************/
+
+NTSTATUS NTAPI
+GetBusInterface(PDEVICE_OBJECT DeviceObject, PBUS_INTERFACE_STANDARD busInterface)
+{
+    KEVENT Event;
+    NTSTATUS Status;
+    PIRP Irp;
+    IO_STATUS_BLOCK IoStatus;
+    PIO_STACK_LOCATION Stack;
+
+    if ((!DeviceObject) || (!busInterface))
+        return STATUS_UNSUCCESSFUL;
+
+    KeInitializeEvent(&Event, NotificationEvent, FALSE);
+
+    Irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP,
+                                       DeviceObject,
+                                       NULL,
+                                       0,
+                                       NULL,
+                                       &Event,
+                                       &IoStatus);
+
+    if (Irp == NULL)
+    {
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    Stack=IoGetNextIrpStackLocation(Irp);
+    Stack->MajorFunction = IRP_MJ_PNP;
+    Stack->MinorFunction = IRP_MN_QUERY_INTERFACE;
+    Stack->Parameters.QueryInterface.Size = sizeof(BUS_INTERFACE_STANDARD);
+    Stack->Parameters.QueryInterface.InterfaceType = (LPGUID)&GUID_BUS_INTERFACE_STANDARD;
+    Stack->Parameters.QueryInterface.Version = 1;
+    Stack->Parameters.QueryInterface.Interface = (PINTERFACE)busInterface;
+    Stack->Parameters.QueryInterface.InterfaceSpecificData = NULL;
+    Irp->IoStatus.Status=STATUS_NOT_SUPPORTED ;
+
+    Status=IoCallDriver(DeviceObject, Irp);
+
+    if (Status == STATUS_PENDING)
+    {
+        KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
+
+        Status=IoStatus.Status;
+    }
+
+    return Status;
+}
+
+NTSTATUS NTAPI
+ForwardAndWaitCompletionRoutine(PDEVICE_OBJECT DeviceObject, PIRP Irp, PKEVENT Event)
+{
+    if (Irp->PendingReturned)
+    {
+        KeSetEvent(Event, IO_NO_INCREMENT, FALSE);
+    }
+    return STATUS_MORE_PROCESSING_REQUIRED;
+}
+
+NTSTATUS NTAPI
+ForwardAndWait(PDEVICE_OBJECT DeviceObject, PIRP Irp)
+{
+    PFDO_DEVICE_EXTENSION DeviceExtensions;
+    KEVENT Event;
+    NTSTATUS Status;
+
+
+    DeviceExtensions = DeviceObject->DeviceExtension; 
+    KeInitializeEvent(&Event, NotificationEvent, FALSE);
+    IoCopyCurrentIrpStackLocationToNext(Irp);
+    IoSetCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE)ForwardAndWaitCompletionRoutine, &Event, TRUE, TRUE, TRUE);
+    Status = IoCallDriver(DeviceExtensions->LowerDevice, Irp);
+    if (Status == STATUS_PENDING)
+    {
+        KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
+        Status = Irp->IoStatus.Status;
+    }
+
+    return Status;
+}
+
+NTSTATUS NTAPI
+ForwardIrpAndForget(PDEVICE_OBJECT DeviceObject, PIRP Irp)
+{
+    PDEVICE_OBJECT LowerDevice;
+
+    LowerDevice = ((PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice;
+DPRINT1("DeviceObject %x, LowerDevice %x\n", DeviceObject, LowerDevice);
+    ASSERT(LowerDevice);
+
+    IoSkipCurrentIrpStackLocation(Irp);
+    return IoCallDriver(LowerDevice, Irp);
+}
+
+/* Copied fom trunk PCI drivers */
+NTSTATUS
+DuplicateUnicodeString(ULONG Flags, PCUNICODE_STRING SourceString, PUNICODE_STRING DestinationString)
+{
+    if (SourceString == NULL || DestinationString == NULL
+     || SourceString->Length > SourceString->MaximumLength
+     || (SourceString->Length == 0 && SourceString->MaximumLength > 0 && SourceString->Buffer == NULL)
+     || Flags == RTL_DUPLICATE_UNICODE_STRING_ALLOCATE_NULL_STRING || Flags >= 4)
+    {
+        return STATUS_INVALID_PARAMETER;
+    }
+
+
+    if ((SourceString->Length == 0)
+     && (Flags != (RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE |
+                   RTL_DUPLICATE_UNICODE_STRING_ALLOCATE_NULL_STRING)))
+    {
+        DestinationString->Length = 0;
+        DestinationString->MaximumLength = 0;
+        DestinationString->Buffer = NULL;
+    }
+    else
+    {
+        USHORT DestMaxLength = SourceString->Length;
+
+        if (Flags & RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE)
+            DestMaxLength += sizeof(UNICODE_NULL);
+
+        DestinationString->Buffer = ExAllocatePool(PagedPool, DestMaxLength);
+        if (DestinationString->Buffer == NULL)
+            return STATUS_NO_MEMORY;
+
+        RtlCopyMemory(DestinationString->Buffer, SourceString->Buffer, SourceString->Length);
+        DestinationString->Length = SourceString->Length;
+        DestinationString->MaximumLength = DestMaxLength;
+
+        if (Flags & RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE)
+            DestinationString->Buffer[DestinationString->Length / sizeof(WCHAR)] = 0;
+    }
+
+    return STATUS_SUCCESS;
+}
+

Propchange: trunk/reactos/drivers/usb/usbehci/common.c
------------------------------------------------------------------------------
    svn:eol-style = native

Added: trunk/reactos/drivers/usb/usbehci/fdo.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbehci/fdo.c?rev=44993&view=auto
==============================================================================
--- trunk/reactos/drivers/usb/usbehci/fdo.c (added)
+++ trunk/reactos/drivers/usb/usbehci/fdo.c [iso-8859-1] Fri Jan  8 10:34:36 2010
@@ -1,0 +1,819 @@
+
+/* INCLUDES *******************************************************************/
+#include "usbehci.h"
+#include <stdio.h>
+//#include "ntstrsafe.h"
+
+VOID NTAPI
+EhciDefferedRoutine(PKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2)
+{
+    PFDO_DEVICE_EXTENSION FdoDeviceExtension;
+    ULONG CStatus;
+
+    FdoDeviceExtension = (PFDO_DEVICE_EXTENSION) DeferredContext;
+
+    CStatus = (ULONG) SystemArgument2;
+
+    /* Port Change */
+    if (CStatus & EHCI_STS_PCD)
+    {
+        LONG i;
+        ULONG tmp;
+        ULONG Base;
+
+        Base = (ULONG)FdoDeviceExtension->ResourceMemory;
+
+        /* Loop through the ports */
+        for (i = 0; i < FdoDeviceExtension->ECHICaps.HCSParams.PortCount; i++)
+        {
+            tmp = READ_REGISTER_ULONG((PULONG) ((Base + EHCI_PORTSC) + (4 * i)));
+
+            /* Check for port change on this port */
+            if (tmp & 0x02)
+            {
+                PIO_WORKITEM WorkItem = NULL;
+
+                /* Connect or Disconnect? */
+                if (tmp & 0x01)
+                {
+                    DPRINT1("Device connected on port %d\n", i);
+
+                    /* Check if a companion host controller exists */
+                    if (FdoDeviceExtension->ECHICaps.HCSParams.CHCCount)
+                    {
+                        tmp = READ_REGISTER_ULONG((PULONG)((Base + EHCI_PORTSC) + (4 * i)));
+
+                        /* Port should be in disabled state, as per USB 2.0 specs */
+                        if (tmp & 0x04)
+                        {
+                            DPRINT1("Warning: The port the device has just connected to is not disabled!\n");
+                        }
+
+                        /* Is this non high speed device */
+                        if (tmp & 0x400)
+                        {
+                            DPRINT1("Releasing ownership to companion host controller!\n");
+                            /* Release ownership to companion host controller */
+                            WRITE_REGISTER_ULONG((PULONG) ((Base + EHCI_PORTSC) + (4 * i)), 0x4000);
+                        }
+                    }
+
+                    KeStallExecutionProcessor(30);
+                    DPRINT("port tmp %x\n", tmp);
+
+                    /* As per USB 2.0 Specs, 9.1.2. Reset the port and clear the status change */
+                    tmp |= 0x100 | 0x02;
+                    /* Sanity, Disable port */
+                    tmp &= ~0x04;
+
+                    WRITE_REGISTER_ULONG((PULONG) ((Base + EHCI_PORTSC) + (4 * i)), tmp);
+
+                    KeStallExecutionProcessor(20);
+
+                    tmp = READ_REGISTER_ULONG((PULONG)((Base + EHCI_PORTSC) + (4 * i)));
+
+                    DPRINT("port tmp %x\n", tmp);
+
+                    FdoDeviceExtension->ChildDeviceCount++;
+                    CompletePendingRequest(FdoDeviceExtension);
+
+                    WorkItem = IoAllocateWorkItem(FdoDeviceExtension->Pdo);
+
+                    if (!WorkItem)
+                    {
+                        DPRINT1("WorkItem allocation failed!\n");
+                    }
+
+                    IoQueueWorkItem(WorkItem,
+                                    (PIO_WORKITEM_ROUTINE)DeviceArrivalWorkItem,
+                                    DelayedWorkQueue,
+                                    FdoDeviceExtension);
+                }
+                else
+                {
+                    DPRINT1("Device disconnected on port %d\n", i);
+
+                    /* Clear status change */
+                    tmp = READ_REGISTER_ULONG((PULONG)((Base + EHCI_PORTSC) + (4 * i)));
+                    tmp |= 0x02;
+                    WRITE_REGISTER_ULONG((PULONG) ((Base + EHCI_PORTSC) + (4 * i)), tmp);
+                }
+
+            }
+        }
+    }
+}
+
+BOOLEAN NTAPI
+InterruptService(PKINTERRUPT Interrupt, PVOID ServiceContext)
+{
+    PFDO_DEVICE_EXTENSION FdoDeviceExtension;
+    PDEVICE_OBJECT DeviceObject = (PDEVICE_OBJECT) ServiceContext;
+    ULONG CurrentFrame;
+    ULONG Base;
+    ULONG CStatus = 0;
+
+    FdoDeviceExtension = (PFDO_DEVICE_EXTENSION) DeviceObject->DeviceExtension;
+
+    Base = (ULONG)FdoDeviceExtension->ResourceMemory;
+
+    /* Read device status */
+    CStatus = READ_REGISTER_ULONG ((PULONG) (Base + EHCI_USBSTS));
+    CurrentFrame = READ_REGISTER_ULONG((PULONG) (Base + EHCI_FRINDEX));
+
+    CStatus &= (EHCI_ERROR_INT | EHCI_STS_INT | EHCI_STS_IAA | EHCI_STS_PCD | EHCI_STS_FLR);
+
+    if ((!CStatus) || (FdoDeviceExtension->DeviceState == 0))
+    {
+        /* This interrupt isnt for us or not ready for it. */
+        return FALSE;
+    }
+
+    /* Clear status */
+    WRITE_REGISTER_ULONG((PULONG) (Base + EHCI_USBSTS), CStatus);
+
+    if (CStatus & EHCI_ERROR_INT)
+    {
+        DPRINT1("EHCI Status=0x%x\n", CStatus);
+    }
+
+    if (CStatus & EHCI_STS_FATAL)
+    {
+        DPRINT1("EHCI: Host System Error. Possible PCI problems.\n");
+        ASSERT(FALSE);
+    }
+
+    if (CStatus & EHCI_STS_HALT)
+    {
+        DPRINT("EHCI: Host Controller unexpected halt.\n");
+        /* FIXME: Reset the controller */
+    }
+
+    if (CStatus & EHCI_STS_INT)
+    {
+       FdoDeviceExtension->AsyncComplete = TRUE;
+    }
+
+    KeInsertQueueDpc(&FdoDeviceExtension->DpcObject, FdoDeviceExtension, (PVOID)CStatus);
+
+    return TRUE;
+}
+
+BOOLEAN
+ResetPort(PDEVICE_OBJECT DeviceObject)
+{
+
+    /*FIXME: Implement me */
+
+    return TRUE;
+}
+
+VOID
+StopEhci(PDEVICE_OBJECT DeviceObject)
+{
+    PFDO_DEVICE_EXTENSION FdoDeviceExtension;
+    PEHCI_USBCMD_CONTENT UsbCmd;
+    ULONG base;
+    LONG tmp;
+
+    DPRINT1("Stopping Ehci controller\n");
+    FdoDeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+    base = (ULONG)FdoDeviceExtension->ResourceMemory;
+
+    WRITE_REGISTER_ULONG((PULONG) (base + EHCI_USBINTR), 0);
+
+    tmp = READ_REGISTER_ULONG((PULONG) (base + EHCI_USBCMD));
+    UsbCmd = (PEHCI_USBCMD_CONTENT) & tmp;
+    UsbCmd->Run = 0;
+    WRITE_REGISTER_ULONG((PULONG) (base + EHCI_USBCMD), tmp);
+}
+
+VOID
+StartEhci(PDEVICE_OBJECT DeviceObject)
+{
+    PFDO_DEVICE_EXTENSION FdoDeviceExtension;
+    PEHCI_USBCMD_CONTENT UsbCmd;
+    PEHCI_USBSTS_CONTEXT usbsts;
+    NTSTATUS Status;
+    LONG tmp;
+    LONG tmp2;
+    ULONG base;
+
+    DPRINT1("Starting Ehci controller\n");
+    FdoDeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+    base = (ULONG)FdoDeviceExtension->ResourceMemory;
+
+    tmp = READ_REGISTER_ULONG ((PULONG)(base + EHCI_USBCMD));
+
+    /* Stop the device */
+    UsbCmd = (PEHCI_USBCMD_CONTENT) &tmp;
+    UsbCmd->Run = 0;
+    WRITE_REGISTER_ULONG ((PULONG)(base + EHCI_USBCMD), tmp);
+
+    /* Wait for the device to stop */
+    for (;;)
+    {
+        KeStallExecutionProcessor(10);
+        tmp = READ_REGISTER_ULONG((PULONG)(base + EHCI_USBSTS));
+        usbsts = (PEHCI_USBSTS_CONTEXT)&tmp;
+
+        if (usbsts->HCHalted)
+        {
+            break;
+        }
+        DPRINT("Waiting for Halt, USBSTS: %x\n", READ_REGISTER_ULONG ((PULONG)(base + EHCI_USBSTS)));
+    }
+
+    tmp = READ_REGISTER_ULONG ((PULONG)(base + EHCI_USBCMD));
+
+    /* Reset the device */
+    UsbCmd = (PEHCI_USBCMD_CONTENT) &tmp;
+    UsbCmd->HCReset = TRUE;
+    WRITE_REGISTER_ULONG ((PULONG)(base + EHCI_USBCMD), tmp);
+
+    /* Wait for the device to reset */
+    for (;;)
+    {
+        KeStallExecutionProcessor(10);
+        tmp = READ_REGISTER_ULONG((PULONG)(base + EHCI_USBCMD));
+        UsbCmd = (PEHCI_USBCMD_CONTENT)&tmp;
+
+        if (!UsbCmd->HCReset)
+        {
+            break;
+        }
+        DPRINT("Waiting for reset, USBCMD: %x\n", READ_REGISTER_ULONG ((PULONG)(base + EHCI_USBCMD)));
+    }
+
+    UsbCmd = (PEHCI_USBCMD_CONTENT) &tmp;
+
+    /* Disable Interrupts on the device */
+    WRITE_REGISTER_ULONG((PULONG)(base + EHCI_USBINTR), 0);
+    /* Clear the Status */
+    WRITE_REGISTER_ULONG((PULONG)(base + EHCI_USBSTS), 0x0000001f);
+
+    WRITE_REGISTER_ULONG((PULONG)(base + EHCI_CTRLDSSEGMENT), 0);
+
+    /* Set the Periodic Frame List */
+    WRITE_REGISTER_ULONG((PULONG)(base + EHCI_PERIODICLISTBASE), FdoDeviceExtension->PeriodicFramListPhysAddr.LowPart);
+    /* Set the Async List Queue */
+    WRITE_REGISTER_ULONG((PULONG) (base + EHCI_ASYNCLISTBASE), FdoDeviceExtension->AsyncListQueueHeadPtrPhysAddr.LowPart & ~(0x1f));
+
+    /* Set the ansync and periodic to disable */
+    UsbCmd->PeriodicEnable = 0;
+    UsbCmd->AsyncEnable = 0;
+    WRITE_REGISTER_ULONG((PULONG)(base + EHCI_USBCMD), tmp);
+
+    /* Set the threshold */
+    UsbCmd->IntThreshold = 1;
+    WRITE_REGISTER_ULONG((PULONG)(base + EHCI_USBCMD), tmp);
+
+    KeInitializeDpc(&FdoDeviceExtension->DpcObject,
+                    EhciDefferedRoutine,
+                    FdoDeviceExtension);
+
+    Status = IoConnectInterrupt(&FdoDeviceExtension->EhciInterrupt,
+                       InterruptService,
+                       FdoDeviceExtension->DeviceObject,
+                       NULL,
+                       FdoDeviceExtension->Vector,
+                       FdoDeviceExtension->Irql,
+                       FdoDeviceExtension->Irql,
+                       FdoDeviceExtension->Mode,
+                       FdoDeviceExtension->IrqShared,
+                       FdoDeviceExtension->Affinity,
+                       FALSE);
+
+    /* Turn back on interrupts */
+    WRITE_REGISTER_ULONG((PULONG)(base + EHCI_USBINTR),
+                      EHCI_USBINTR_ERR | EHCI_USBINTR_ASYNC | EHCI_USBINTR_HSERR
+                      | EHCI_USBINTR_FLROVR  | EHCI_USBINTR_PC);
+    WRITE_REGISTER_ULONG((PULONG)(base + EHCI_USBINTR),
+                      EHCI_USBINTR_INTE | EHCI_USBINTR_ERR | EHCI_USBINTR_ASYNC | EHCI_USBINTR_HSERR
+                      | EHCI_USBINTR_FLROVR  | EHCI_USBINTR_PC);
+
+    //UsbCmd = (PEHCI_USBCMD_CONTENT) &tmp;
+
+    UsbCmd->Run = 1;
+    WRITE_REGISTER_ULONG((PULONG)(base + EHCI_USBCMD), tmp);
+
+    /* Wait for the device to start */
+    for (;;)
+    {
+        KeStallExecutionProcessor(10);
+        tmp2 = READ_REGISTER_ULONG((PULONG)(base + EHCI_USBSTS));
+        usbsts = (PEHCI_USBSTS_CONTEXT)&tmp2;
+
+        if (!usbsts->HCHalted)
+        {
+            break;
+        }
+        DPRINT("Waiting for start, USBSTS: %x\n", READ_REGISTER_ULONG ((PULONG)(base + EHCI_USBSTS)));
+    }
+
+    /* Set all port routing to ECHI controller */
+    WRITE_REGISTER_ULONG((PULONG)(base + EHCI_CONFIGFLAG), 1);
+}
+
+VOID
+GetCapabilities(PFDO_DEVICE_EXTENSION DeviceExtension, ULONG Base)
+{
+    PEHCI_CAPS PCap;
+    PEHCI_HCS_CONTENT PHCS;
+    LONG i;
+
+    if (!DeviceExtension)
+        return;
+
+    PCap = &DeviceExtension->ECHICaps;
+
+    PCap->Length = READ_REGISTER_UCHAR((PUCHAR)Base);
+    PCap->Reserved = READ_REGISTER_UCHAR((PUCHAR)(Base + 1));
+    PCap->HCIVersion = READ_REGISTER_USHORT((PUSHORT)(Base + 2));
+    PCap->HCSParamsLong = READ_REGISTER_ULONG((PULONG)(Base + 4));
+    PCap->HCCParams = READ_REGISTER_ULONG((PULONG)(Base + 8));
+
+
+    DPRINT("Length %d\n", PCap->Length);
+    DPRINT("Reserved %d\n", PCap->Reserved);
+    DPRINT("HCIVersion %x\n", PCap->HCIVersion);
+    DPRINT("HCSParams %x\n", PCap->HCSParamsLong);
+    DPRINT("HCCParams %x\n", PCap->HCCParams);
+
+
+    if (PCap->HCCParams & 0x02)
+        DPRINT1("Frame list size is configurable\n");
+
+    if (PCap->HCCParams & 0x01)
+        DPRINT1("64bit address mode not supported!\n");
+
+    DPRINT1("Number of Ports: %d\n", PCap->HCSParams.PortCount);
+
+    if (PCap->HCSParams.PortPowerControl)
+        DPRINT1("Port Power Control is enabled\n");
+
+    if (!PCap->HCSParams.CHCCount)
+    {
+        DPRINT1("Number of Companion Host controllers %x\n", PCap->HCSParams.CHCCount);
+        DPRINT1("Number of Ports Per CHC: %d\n", PCap->HCSParams.PortPerCHC);
+    }
+
+    /* Copied from USBDRIVER in trunk */
+    PHCS = (PEHCI_HCS_CONTENT)&DeviceExtension->ECHICaps.HCSParams;
+    if (PHCS->PortRouteRules)
+    {
+        for (i = 0; i < 8; i++)
+        {
+            PCap->PortRoute[i] = READ_REGISTER_UCHAR((PUCHAR) (Base + 12 + i));
+        }
+    }
+}
+
+NTSTATUS
+StartDevice(PDEVICE_OBJECT DeviceObject, PCM_PARTIAL_RESOURCE_LIST raw, PCM_PARTIAL_RESOURCE_LIST translated)
+{
+    PFDO_DEVICE_EXTENSION FdoDeviceExtension;
+    PCM_PARTIAL_RESOURCE_DESCRIPTOR resource;
+    DEVICE_DESCRIPTION DeviceDescription;
+    ULONG NumberResources;
+    ULONG iCount;
+    ULONG DeviceAddress;
+    ULONG PropertySize;
+    ULONG BusNumber;
+    NTSTATUS Status;
+
+    FdoDeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+
+    RtlZeroMemory(&DeviceDescription, sizeof(DEVICE_DESCRIPTION));
+    DeviceDescription.Version = DEVICE_DESCRIPTION_VERSION;
+    DeviceDescription.Master = TRUE;
+    DeviceDescription.ScatterGather = TRUE;
+    DeviceDescription.Dma32BitAddresses = TRUE;
+    DeviceDescription.DmaWidth = 2;
+    DeviceDescription.InterfaceType = PCIBus;
+    DeviceDescription.MaximumLength = EHCI_MAX_SIZE_TRANSFER;
+
+    FdoDeviceExtension->pDmaAdapter = IoGetDmaAdapter(FdoDeviceExtension->LowerDevice,
+                                                    &DeviceDescription,
+                                                    &FdoDeviceExtension->MapRegisters);
+
+    if (FdoDeviceExtension->pDmaAdapter == NULL)
+    {
+        DPRINT1("IoGetDmaAdapter failed!\n");
+        ASSERT(FALSE);
+    }
+
+    /* Allocate Common Buffer for Periodic Frame List */
+    FdoDeviceExtension->PeriodicFramList =
+        FdoDeviceExtension->pDmaAdapter->DmaOperations->AllocateCommonBuffer(FdoDeviceExtension->pDmaAdapter,
+        sizeof(ULONG) * 1024, &FdoDeviceExtension->PeriodicFramListPhysAddr, FALSE);
+
+    if (FdoDeviceExtension->PeriodicFramList == NULL)
+    {
+        DPRINT1("FdoDeviceExtension->PeriodicFramList is null\n");
+        return STATUS_UNSUCCESSFUL;
+    }
+
+    /* Zeroize it */
+    RtlZeroMemory(FdoDeviceExtension->PeriodicFramList, sizeof(ULONG) * 1024);
+
+    /* Allocate Common Buffer for Async List Head Queue */
+    FdoDeviceExtension->AsyncListQueueHeadPtr =
+        FdoDeviceExtension->pDmaAdapter->DmaOperations->AllocateCommonBuffer(FdoDeviceExtension->pDmaAdapter,
+        /* FIXME: Memory Size should be calculated using
+                  structures sizes needed for queue head + 20480 (max data transfer */
+        20800,
+        &FdoDeviceExtension->AsyncListQueueHeadPtrPhysAddr, FALSE);
+
+    if (FdoDeviceExtension->AsyncListQueueHeadPtr == NULL)
+    {
+        DPRINT1("Failed to allocate common buffer for AsyncListQueueHeadPtr!\n");
+        return STATUS_UNSUCCESSFUL;
+    }
+
+    /* Zeroize it */
+    RtlZeroMemory(FdoDeviceExtension->AsyncListQueueHeadPtr,
+                  /* FIXME: Same as FIXME above */
+                  20800);
+
+    Status = IoGetDeviceProperty(FdoDeviceExtension->LowerDevice,
+                                 DevicePropertyAddress,
+                                 sizeof(ULONG),
+                                 &DeviceAddress,
+                                 &PropertySize);
+    if (NT_SUCCESS(Status))
+    {
+        DPRINT1("--->DeviceAddress: %x\n", DeviceAddress);
+    }
+
+    Status = IoGetDeviceProperty(FdoDeviceExtension->LowerDevice,
+                                 DevicePropertyBusNumber,
+                                 sizeof(ULONG),
+                                 &BusNumber,
+                                 &PropertySize);
+    if (NT_SUCCESS(Status))
+    {
+        DPRINT1("--->BusNumber: %x\n", BusNumber);
+    }
+
+    /* Get the resources the PNP Manager gave */
+    NumberResources = translated->Count;
+    DPRINT("NumberResources %d\n", NumberResources);
+    for (iCount = 0; iCount < NumberResources; iCount++)
+    {
+        DPRINT("Resource Info %d:\n", iCount);
+        resource = &translated->PartialDescriptors[iCount];
+        switch(resource->Type)
+        {
+            case CmResourceTypePort:
+            {
+                DPRINT("Port Start: %x\n", resource->u.Port.Start);
+                DPRINT("Port Length %d\n", resource->u.Port.Length);
+                /* FIXME: Handle Ports */
+                break;
+            }
+            case CmResourceTypeInterrupt:
+            {
+                DPRINT("Interrupt Vector: %x\n", resource->u.Interrupt.Vector);
+                FdoDeviceExtension->Vector = resource->u.Interrupt.Vector;
+                FdoDeviceExtension->Irql = resource->u.Interrupt.Level;
+                FdoDeviceExtension->Affinity = resource->u.Interrupt.Affinity;
+                FdoDeviceExtension->Mode = (resource->Flags == CM_RESOURCE_INTERRUPT_LATCHED) ? Latched : LevelSensitive;
+                FdoDeviceExtension->IrqShared = resource->ShareDisposition == CmResourceShareShared;
+                break;
+            }
+            case CmResourceTypeMemory:
+            {
+                ULONG ResourceBase = 0;
+                ULONG MemLength;
+
+                DPRINT("Mem Start: %x\n", resource->u.Memory.Start);
+                DPRINT("Mem Length: %d\n", resource->u.Memory.Length);
+
+                ResourceBase = (ULONG) MmMapIoSpace(resource->u.Memory.Start, resource->u.Memory.Length, FALSE);
+                DPRINT("ResourceBase %x\n", ResourceBase);
+
+                FdoDeviceExtension->ResourceBase = (PULONG) ResourceBase;
+                GetCapabilities(FdoDeviceExtension, (ULONG)ResourceBase);
+                FdoDeviceExtension->ResourceMemory = (PULONG)((ULONG)ResourceBase + FdoDeviceExtension->ECHICaps.Length);
+                DPRINT("ResourceMemory %x\n", FdoDeviceExtension->ResourceMemory);
+                if (FdoDeviceExtension->ResourceBase  == NULL)
+                {
+                    DPRINT1("MmMapIoSpace failed!!!!!!!!!\n");
+                }
+                MemLength = resource->u.Memory.Length;
+                FdoDeviceExtension->Size = MemLength;
+
+                break;
+            }
+            case CmResourceTypeDma:
+            {
+                DPRINT("Dma Channel: %x\n", resource->u.Dma.Channel);
+                DPRINT("Dma Port: %d\n", resource->u.Dma.Port);
+                break;
+            }
+            default:
+            {
+                DPRINT1("PNP Manager gave invalid resource type!! Notify Developers!\n");
+                ASSERT(FALSE);
+                break;
+            }
+        }
+    }
+
+    StartEhci(DeviceObject);
+    FdoDeviceExtension->DeviceState = DEVICESTARTED;
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+FdoQueryBusRelations(
+    PDEVICE_OBJECT DeviceObject,
+    PDEVICE_RELATIONS* pDeviceRelations)
+{
+    PFDO_DEVICE_EXTENSION DeviceExtension;
+    PDEVICE_RELATIONS DeviceRelations = NULL;
+    PDEVICE_OBJECT Pdo;
+    PPDO_DEVICE_EXTENSION PdoDeviceExtension;
+    NTSTATUS Status;
+    ULONG UsbDeviceNumber = 0;
+    WCHAR CharDeviceName[64];
+    UNICODE_STRING DeviceName;
+
+    DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+    /* Create the PDO */
+    while (TRUE)
+    {
+        /* FIXME: Use safe string sprintf*/
+        /* RtlStringCchPrintfW(CharDeviceName, 64, L"USBFDO-%d", UsbDeviceNumber); */
+        swprintf(CharDeviceName, L"\\Device\\USBPDO-%d", UsbDeviceNumber);
+        RtlInitUnicodeString(&DeviceName, CharDeviceName);
+        DPRINT("DeviceName %wZ\n", &DeviceName);
+
+        Status = IoCreateDevice(DeviceObject->DriverObject,
+                                sizeof(PDO_DEVICE_EXTENSION),
+                                &DeviceName,
+                                FILE_DEVICE_BUS_EXTENDER,
+                                0,
+                                FALSE,
+                                &Pdo);
+
+        if (NT_SUCCESS(Status))
+            break;
+
+        if ((Status == STATUS_OBJECT_NAME_EXISTS) || (Status == STATUS_OBJECT_NAME_COLLISION))
+        {
+            /* Try the next name */
+            UsbDeviceNumber++;
+            continue;
+        }
+
+        /* Bail on any other error */
+        if (!NT_SUCCESS(Status))
+        {
+            DPRINT1("UsbEhci: Failed to create PDO %wZ, Status %x\n", &DeviceName, Status);
+            return Status;
+        }
+    }
+
+    PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)Pdo->DeviceExtension;
+    RtlZeroMemory(PdoDeviceExtension, sizeof(PDO_DEVICE_EXTENSION));
+    PdoDeviceExtension->Common.IsFdo = FALSE;
+
+    PdoDeviceExtension->ControllerFdo = DeviceObject;
+
+    Pdo->Flags &= ~DO_DEVICE_INITIALIZING;
+    DeviceExtension->Pdo = Pdo;
+
+    /*swprintf(CharSymLinkName, L"\\Device\\HCD%d", UsbDeviceNumber);
+    RtlInitUnicodeString(&SymLinkName, CharSymLinkName);
+    Status = IoCreateSymbolicLink(&SymLinkName, &DeviceName);
+
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Warning: Unable to create symbolic link for ehci usb device!\n");
+    }*/
+
+    DeviceRelations = (PDEVICE_RELATIONS)ExAllocatePool(PagedPool, sizeof(DEVICE_RELATIONS));
+    if (!DeviceRelations)
+    {
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    DeviceRelations->Count = 1;
+    DeviceRelations->Objects[0] = Pdo;
+    ObReferenceObject(Pdo);
+
+    *pDeviceRelations = DeviceRelations;
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS NTAPI
+FdoDispatchPnp(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
+{
+    NTSTATUS Status;
+    PIO_STACK_LOCATION Stack = NULL;
+    PCM_PARTIAL_RESOURCE_LIST raw;
+    PCM_PARTIAL_RESOURCE_LIST translated;
+    ULONG_PTR Information = 0;
+
+    Stack =  IoGetCurrentIrpStackLocation(Irp);
+
+    switch(Stack->MinorFunction)
+    {
+        case IRP_MN_START_DEVICE:
+        {
+            DPRINT("START_DEVICE\n");
+            Irp->IoStatus.Status = STATUS_SUCCESS;
+            Status = ForwardAndWait(DeviceObject, Irp);
+
+            raw = &Stack->Parameters.StartDevice.AllocatedResources->List[0].PartialResourceList;
+            translated = &Stack->Parameters.StartDevice.AllocatedResourcesTranslated->List[0].PartialResourceList;
+            Status = StartDevice(DeviceObject, raw, translated);
+            break;
+        }
+        case IRP_MN_QUERY_DEVICE_RELATIONS:
+        {
+            DPRINT("IRP_MN_QUERY_DEVICE_RELATIONS\n");
+            switch(Stack->Parameters.QueryDeviceRelations.Type)
+            {
+                case BusRelations:
+                {
+                    PDEVICE_RELATIONS DeviceRelations = NULL;
+                    DPRINT("BusRelations\n");
+                    Status = FdoQueryBusRelations(DeviceObject, &DeviceRelations);
+                    Information = (ULONG_PTR)DeviceRelations;
+                    break;
+                }
+                default:
+                {
+                    DPRINT("Unknown query device relations type\n");
+                    Status = STATUS_NOT_IMPLEMENTED;
+                    break;
+                }
+             }
+             break;
+        }
+        case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
+        {
+            DPRINT("IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n");
+            return ForwardIrpAndForget(DeviceObject, Irp);
+            break;
+        }
+        case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
+        {
+            DPRINT("IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n");
+        }
+        default:
+        {
+            DPRINT1("IRP_MJ_PNP / Unhandled minor function 0x%lx\n", Stack->MinorFunction);
+            return ForwardIrpAndForget(DeviceObject, Irp);
+        }
+    }
+
+    Irp->IoStatus.Information = Information;
+    Irp->IoStatus.Status = Status;
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    return Status;
+}
+
+NTSTATUS NTAPI
+AddDevice(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT Pdo)
+{
+    NTSTATUS Status = STATUS_UNSUCCESSFUL;
+    PDEVICE_OBJECT Fdo;
+    ULONG UsbDeviceNumber = 0;
+    WCHAR CharDeviceName[64];
+    WCHAR CharSymLinkName[64];
+    UNICODE_STRING DeviceName;
+    UNICODE_STRING SymLinkName;
+    ULONG BytesRead;
+    PCI_COMMON_CONFIG PciConfig;
+
+    PFDO_DEVICE_EXTENSION FdoDeviceExtension;
+
+    DPRINT1("Ehci AddDevice\n");
+
+    /* Create the FDO */
+    while (TRUE)
+    {
+        /* FIXME: Use safe string sprintf*/
+        /* RtlStringCchPrintfW(CharDeviceName, 64, L"USBFDO-%d", UsbDeviceNumber); */
+        swprintf(CharDeviceName, L"\\Device\\USBFDO-%d", UsbDeviceNumber);
+        RtlInitUnicodeString(&DeviceName, CharDeviceName);
+        DPRINT1("DeviceName %wZ\n", &DeviceName);
+
+        Status = IoCreateDevice(DriverObject,
+                                sizeof(FDO_DEVICE_EXTENSION),
+                                &DeviceName,
+                                FILE_DEVICE_CONTROLLER,
+                                0,
+                                FALSE,
+                                &Fdo);
+
+       if (NT_SUCCESS(Status))
+           break;
+
+        if ((Status == STATUS_OBJECT_NAME_EXISTS) || (Status == STATUS_OBJECT_NAME_COLLISION))
+        {
+            /* Try the next name */
+            UsbDeviceNumber++;
+            continue;
+        }
+
+        /* Bail on any other error */
+        if (!NT_SUCCESS(Status))
+        {
+            DPRINT1("UsbEhci: Failed to create %wZ, Status %x\n", &DeviceName, Status);
+            return Status;
+        }
+    }
+
+    swprintf(CharSymLinkName, L"\\Device\\HCD%d", UsbDeviceNumber);
+    RtlInitUnicodeString(&SymLinkName, CharSymLinkName);
+    Status = IoCreateSymbolicLink(&SymLinkName, &DeviceName);
+
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Warning: Unable to create symbolic link for ehci usb device!\n");
+    }
+
+    DPRINT("Attaching created device %x to %x\n", Fdo, Pdo);
+
+    FdoDeviceExtension = (PFDO_DEVICE_EXTENSION) Fdo->DeviceExtension;
+    RtlZeroMemory(FdoDeviceExtension, sizeof(PFDO_DEVICE_EXTENSION));
+
+    InitializeListHead(&FdoDeviceExtension->IrpQueue);
+    KeInitializeSpinLock(&FdoDeviceExtension->IrpQueueLock);
+
+    FdoDeviceExtension->Common.IsFdo = TRUE;
+    FdoDeviceExtension->DeviceObject = Fdo;
+
+    FdoDeviceExtension->LowerDevice = IoAttachDeviceToDeviceStack(Fdo, Pdo);
+    if (FdoDeviceExtension->LowerDevice == NULL)
+    {
+        DPRINT1("UsbEhci: Failed to attach to device stack!\n");
+        IoDeleteSymbolicLink(&SymLinkName);
+        IoDeleteDevice(Fdo);
+
+        return STATUS_NO_SUCH_DEVICE;
+    }
+
+    Fdo->Flags |= DO_BUFFERED_IO | DO_POWER_PAGABLE;
+
+    DPRINT("Attached %x!\n", FdoDeviceExtension->LowerDevice);
+    ASSERT(FdoDeviceExtension->LowerDevice == Pdo);
+    Status = GetBusInterface(FdoDeviceExtension->LowerDevice, &FdoDeviceExtension->BusInterface);
+
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("GetBusInterface() failed with %x\n", Status);
+        IoDetachDevice(FdoDeviceExtension->LowerDevice);
+        IoDeleteSymbolicLink(&SymLinkName);
+        IoDeleteDevice(Fdo);
+        return Status;
+    }
+
+    DPRINT("Context %x\n", FdoDeviceExtension->BusInterface.Context);
+
+    BytesRead = (*FdoDeviceExtension->BusInterface.GetBusData)(
+        FdoDeviceExtension->BusInterface.Context,
+        PCI_WHICHSPACE_CONFIG,
+        &PciConfig,
+        0,
+        PCI_COMMON_HDR_LENGTH);
+
+
+    if (BytesRead != PCI_COMMON_HDR_LENGTH)
+    {
+        DPRINT1("GetBusData failed!\n");
+        IoDetachDevice(FdoDeviceExtension->LowerDevice);
+        IoDeleteSymbolicLink(&SymLinkName);
+        IoDeleteDevice(Fdo);
+
+        return STATUS_UNSUCCESSFUL;
+    }
+
+    if (PciConfig.Command & PCI_ENABLE_IO_SPACE)
+        DPRINT("PCI_ENABLE_IO_SPACE\n");
+
+    if (PciConfig.Command & PCI_ENABLE_MEMORY_SPACE)
+        DPRINT("PCI_ENABLE_MEMORY_SPACE\n");
+
+    if (PciConfig.Command & PCI_ENABLE_BUS_MASTER)
+        DPRINT("PCI_ENABLE_BUS_MASTER\n");
+
+    DPRINT("BaseAddress[0] %x\n", PciConfig.u.type0.BaseAddresses[0]);
+    DPRINT("Vendor %x\n", PciConfig.VendorID);
+    DPRINT("Device %x\n", PciConfig.DeviceID);
+
+    FdoDeviceExtension->VendorId = PciConfig.VendorID;
+    FdoDeviceExtension->DeviceId = PciConfig.DeviceID;
+
+    DPRINT("FdoDeviceExtension->NextLowerDevice %x\n", FdoDeviceExtension->LowerDevice);
+    FdoDeviceExtension->DeviceState = DEVICEINTIALIZED;
+
+    Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
+
+    return STATUS_SUCCESS;
+}

Propchange: trunk/reactos/drivers/usb/usbehci/fdo.c
------------------------------------------------------------------------------
    svn:eol-style = native

Added: trunk/reactos/drivers/usb/usbehci/misc.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbehci/misc.c?rev=44993&view=auto
==============================================================================
--- trunk/reactos/drivers/usb/usbehci/misc.c (added)
+++ trunk/reactos/drivers/usb/usbehci/misc.c [iso-8859-1] Fri Jan  8 10:34:36 2010
@@ -1,0 +1,232 @@
+
+#include "usbehci.h"
+
+VOID
+QueueRequest(PFDO_DEVICE_EXTENSION DeviceExtension, PIRP Irp)
+{
+    KIRQL oldIrql;
+
+    KeAcquireSpinLock(&DeviceExtension->IrpQueueLock, &oldIrql);
+    InsertTailList(&DeviceExtension->IrpQueue, &Irp->Tail.Overlay.ListEntry);
+    KeReleaseSpinLock(&DeviceExtension->IrpQueueLock, oldIrql);
+}
+
+VOID
+CompletePendingRequest(PFDO_DEVICE_EXTENSION DeviceExtension)
+{
+    PLIST_ENTRY NextIrp = NULL;
+    PIO_STACK_LOCATION Stack;
+    KIRQL oldIrql;
+    PIRP Irp = NULL;
+    URB *Urb;
+
+    KeAcquireSpinLock(&DeviceExtension->IrpQueueLock, &oldIrql);
+
+    /* No Irps in Queue? */
+    if (IsListEmpty(&DeviceExtension->IrpQueue))
+    {
+        KeReleaseSpinLock(&DeviceExtension->IrpQueueLock, oldIrql);
+        return;
+    }
+
+    NextIrp = RemoveHeadList(&DeviceExtension->IrpQueue);
+    while(TRUE)
+    {
+        Irp = CONTAINING_RECORD(NextIrp, IRP, Tail.Overlay.ListEntry);
+
+        if (!Irp)
+            break;
+
+        /* FIXME: Handle cancels */
+        /*if (!IoSetCancelRoutine(Irp, NULL))
+        {
+
+        }*/
+
+
+        Stack = IoGetCurrentIrpStackLocation(Irp);
+
+        Urb = (PURB) Stack->Parameters.Others.Argument1;
+
+        ASSERT(Urb);
+
+        /* FIXME: Fill in information for Argument1/URB */
+
+        DPRINT("TransferBuffer %x\n", Urb->UrbControlDescriptorRequest.TransferBuffer);
+        DPRINT("TransferBufferLength %x\n", Urb->UrbControlDescriptorRequest.TransferBufferLength);
+        DPRINT("Index %x\n", Urb->UrbControlDescriptorRequest.Index);
+        DPRINT("DescriptorType %x\n",     Urb->UrbControlDescriptorRequest.DescriptorType);    
+        DPRINT("LanguageId %x\n", Urb->UrbControlDescriptorRequest.LanguageId);
+
+        KeReleaseSpinLock(&DeviceExtension->IrpQueueLock, oldIrql);
+
+        Irp->IoStatus.Status = STATUS_SUCCESS;
+        Irp->IoStatus.Information = 0;
+
+        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+        return;
+    }
+
+    KeReleaseSpinLock(&DeviceExtension->IrpQueueLock, oldIrql);
+}
+
+NTSTATUS
+NTAPI
+ArrivalNotificationCompletion(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID PContext)
+{
+    IoFreeIrp(Irp);
+    return STATUS_MORE_PROCESSING_REQUIRED;
+}
+
+VOID
+DeviceArrivalWorkItem(PDEVICE_OBJECT DeviceObject, PVOID Context)
+{
+    PFDO_DEVICE_EXTENSION FdoDeviceExtension;
+    PIO_STACK_LOCATION IrpStack = NULL;
+    PDEVICE_OBJECT PortDeviceObject = NULL;
+    PIRP Irp = NULL;
+
+    FdoDeviceExtension = (PFDO_DEVICE_EXTENSION)Context;
+
+    PortDeviceObject = IoGetAttachedDeviceReference(FdoDeviceExtension->Pdo);
+
+    if (!PortDeviceObject)
+    {
+        DPRINT1("Unable to notify Pdos parent of device arrival.\n");
+        return;
+    }
+
+    Irp = IoAllocateIrp(PortDeviceObject->StackSize, FALSE);
+
+    if (!Irp)
+    {
+        DPRINT1("Unable to allocate IRP\n");
+    }
+
+    IoSetCompletionRoutine(Irp,
+                           (PIO_COMPLETION_ROUTINE)ArrivalNotificationCompletion,
+                           NULL,
+                           TRUE,
+                           TRUE,
+                           TRUE);
+
+    IrpStack = IoGetNextIrpStackLocation(Irp);
+    IrpStack->Parameters.QueryDeviceRelations.Type = TargetDeviceRelation;
+    IrpStack->MajorFunction = IRP_MJ_PNP;
+    IrpStack->MinorFunction = IRP_MN_QUERY_DEVICE_RELATIONS;
+
+    IoCallDriver(PortDeviceObject, Irp);
+}
+
+/*
+   Get SymblicName from Parameters in Registry Key
+   Caller is responsible for freeing pool of returned pointer
+*/
+PWSTR
+GetSymbolicName(PDEVICE_OBJECT DeviceObject)
+{
+    NTSTATUS Status;
+    HANDLE DevInstRegKey;
+    UNICODE_STRING SymbolicName;
+    PKEY_VALUE_PARTIAL_INFORMATION KeyPartInfo;
+    ULONG SizeNeeded;
+    PWCHAR SymbolicNameString = NULL;
+
+    Status = IoOpenDeviceRegistryKey(DeviceObject,
+                                     PLUGPLAY_REGKEY_DEVICE,
+                                     STANDARD_RIGHTS_ALL,
+                                     &DevInstRegKey);
+
+    DPRINT("IoOpenDeviceRegistryKey PLUGPLAY_REGKEY_DEVICE Status %x\n", Status);
+
+    if (NT_SUCCESS(Status))
+    {
+        RtlInitUnicodeString(&SymbolicName, L"SymbolicName");
+        Status = ZwQueryValueKey(DevInstRegKey,
+                                 &SymbolicName,
+                                 KeyValuePartialInformation,
+                                 NULL,
+                                 0,
+                                 &SizeNeeded);
+
+        DPRINT("ZwQueryValueKey status %x, %d\n", Status, SizeNeeded);
+
+        if (Status == STATUS_BUFFER_TOO_SMALL)
+        {
+            KeyPartInfo = (PKEY_VALUE_PARTIAL_INFORMATION ) ExAllocatePool(PagedPool, SizeNeeded);
+            if (!KeyPartInfo)
+            {
+                DPRINT1("OUT OF MEMORY\n");
+                return NULL;
+            }
+            else
+            {
+                 Status = ZwQueryValueKey(DevInstRegKey,
+                                          &SymbolicName,
+                                          KeyValuePartialInformation,
+                                          KeyPartInfo,
+                                          SizeNeeded,
+                                          &SizeNeeded);
+
+                 SymbolicNameString = ExAllocatePool(PagedPool, (KeyPartInfo->DataLength + sizeof(WCHAR)));
+                 if (!SymbolicNameString)
+                 {
+                     return NULL;
+                 }
+                 RtlZeroMemory(SymbolicNameString, KeyPartInfo->DataLength + 2);
+                 RtlCopyMemory(SymbolicNameString, KeyPartInfo->Data, KeyPartInfo->DataLength);
+            }
+
+            ExFreePool(KeyPartInfo);
+        }
+
+        ZwClose(DevInstRegKey);
+    }
+
+    return SymbolicNameString;
+}
+
+/*
+   Get Physical Device Object Name from registry
+   Caller is responsible for freeing pool
+*/
+PWSTR
+GetPhysicalDeviceObjectName(PDEVICE_OBJECT DeviceObject)
+{
+    NTSTATUS Status;
+    PWSTR ObjectName = NULL;
+    ULONG SizeNeeded;
+
+    Status = IoGetDeviceProperty(DeviceObject,
+                                 DevicePropertyPhysicalDeviceObjectName,
+                                 0,
+                                 NULL,
+                                 &SizeNeeded);
+
+    if (Status != STATUS_BUFFER_TOO_SMALL)
+    {
+        DPRINT1("Expected STATUS_BUFFER_TOO_SMALL, got %x!\n", Status);
+        return NULL;
+    }
+
+    ObjectName = (PWSTR) ExAllocatePool(PagedPool, SizeNeeded + sizeof(WCHAR));
+    if (!ObjectName)
+    {
+        DPRINT1("Out of memory\n");
+        return NULL;
+    }
+
+    Status = IoGetDeviceProperty(DeviceObject,
+                                 DevicePropertyPhysicalDeviceObjectName,
+                                 SizeNeeded,
+                                 ObjectName,
+                                 &SizeNeeded);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Failed to Get Property\n");
+        return NULL;
+    }
+
+    return ObjectName;
+}
+

Propchange: trunk/reactos/drivers/usb/usbehci/misc.c
------------------------------------------------------------------------------
    svn:eol-style = native

Added: trunk/reactos/drivers/usb/usbehci/pdo.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbehci/pdo.c?rev=44993&view=auto
==============================================================================
--- trunk/reactos/drivers/usb/usbehci/pdo.c (added)
+++ trunk/reactos/drivers/usb/usbehci/pdo.c [iso-8859-1] Fri Jan  8 10:34:36 2010
@@ -1,0 +1,424 @@
+
+/* INCLUDES *******************************************************************/
+#define INITGUID
+#include "usbehci.h"
+#include <wdmguid.h>
+#include <stdio.h>
+
+#define NDEBUG
+#include <debug.h>
+
+NTSTATUS NTAPI
+PdoDispatchInternalDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
+{
+    PPDO_DEVICE_EXTENSION PdoDeviceExtension;
+    PFDO_DEVICE_EXTENSION FdoDeviceExtension;
+    PIO_STACK_LOCATION Stack = NULL;
+    NTSTATUS Status = STATUS_UNSUCCESSFUL;
+    ULONG_PTR Information = 0;
+    DPRINT("PdoDispatchInternalDeviceControl\n");
+
+    PdoDeviceExtension = (PPDO_DEVICE_EXTENSION) DeviceObject->DeviceExtension;
+    FdoDeviceExtension = (PFDO_DEVICE_EXTENSION) PdoDeviceExtension->ControllerFdo->DeviceExtension;
+
+    ASSERT(PdoDeviceExtension->Common.IsFdo == FALSE);
+    Stack =  IoGetCurrentIrpStackLocation(Irp);
+    DPRINT("IoControlCode %x\n", Stack->Parameters.DeviceIoControl.IoControlCode);
+    switch(Stack->Parameters.DeviceIoControl.IoControlCode)
+    {
+        case IOCTL_INTERNAL_USB_SUBMIT_URB:
+        {
+            URB *Urb;
+
+            DPRINT1("IOCTL_INTERNAL_USB_SUBMIT_URB\n");
+            DPRINT("Stack->Parameters.DeviceIoControl.InputBufferLength %d\n",
+                     Stack->Parameters.DeviceIoControl.InputBufferLength);
+            DPRINT("Stack->Parameters.Others.Argument1 %x\n", Stack->Parameters.Others.Argument1);
+
+            Urb = (PURB) Stack->Parameters.Others.Argument1;
+            DPRINT("Header Size %d\n", Urb->UrbHeader.Length);
+            DPRINT("Header Type %d\n", Urb->UrbHeader.Function);
+            DPRINT("Index %x\n", Urb->UrbControlDescriptorRequest.Index);
+
+            /* Check the type */
+            switch(Urb->UrbHeader.Function)
+            {
+                case URB_FUNCTION_SELECT_CONFIGURATION:
+                {
+                    DPRINT1("URB_FUNCTION_SELECT_CONFIGURATION\n");
+                    break;
+                }
+                case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE:
+                {
+                    URB *Urb;
+                    DPRINT1("URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE\n");
+                    Urb = (PURB) Stack->Parameters.Others.Argument1;
+                    Urb->UrbHeader.Status = 0;
+
+                    /* Check for ChildDevices */
+                    if (!FdoDeviceExtension->ChildDeviceCount)
+                    {
+                        /* No device has been plugged in yet. So just queue
+                           the irp and complete it when a device is connected */
+                        if (FdoDeviceExtension->DeviceState)
+                            QueueRequest(FdoDeviceExtension, Irp);
+
+                        Information = 0;
+
+                        IoMarkIrpPending(Irp);
+                        Status = STATUS_PENDING;
+                    }
+                    else
+                    {
+                        DPRINT1("Reporting of device connects not implemented yet.\n");
+                        Status = STATUS_SUCCESS;
+                    }
+                    break;
+                }
+                /* FIXME: Handle all other Functions */
+                default:
+                    DPRINT1("Not handled yet!\n");
+            }
+            break;
+        }
+        case IOCTL_INTERNAL_USB_CYCLE_PORT:
+        {
+            DPRINT("IOCTL_INTERNAL_USB_CYCLE_PORT\n");
+            break;
+        }
+        case IOCTL_INTERNAL_USB_ENABLE_PORT:
+        {
+            DPRINT("IOCTL_INTERNAL_USB_ENABLE_PORT\n");
+            break;
+        }
+        case IOCTL_INTERNAL_USB_GET_BUS_INFO:
+        {
+            DPRINT("IOCTL_INTERNAL_USB_GET_BUS_INFO\n");
+            break;
+        }
+        case IOCTL_INTERNAL_USB_GET_BUSGUID_INFO:
+        {
+            DPRINT("IOCTL_INTERNAL_USB_GET_BUSGUID_INFO\n");
+            break;
+        }
+        case IOCTL_INTERNAL_USB_GET_CONTROLLER_NAME:
+        {
+            DPRINT("IOCTL_INTERNAL_USB_GET_CONTROLLER_NAME\n");
+            break;
+        }
+        case IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE:
+        {
+            DPRINT("IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE\n");
+            break;
+        }
+        case IOCTL_INTERNAL_USB_GET_HUB_COUNT:
+        {
+            DPRINT("IOCTL_INTERNAL_USB_GET_HUB_COUNT\n");
+            break;
+        }
+        case IOCTL_INTERNAL_USB_GET_HUB_NAME:
+        {
+            DPRINT("IOCTL_INTERNAL_USB_GET_HUB_NAME\n");
+            break;
+        }
+        case IOCTL_INTERNAL_USB_GET_PARENT_HUB_INFO:
+        {
+            DPRINT("IOCTL_INTERNAL_USB_GET_PARENT_HUB_INFO\n");
+            break;
+        }
+        case IOCTL_INTERNAL_USB_GET_PORT_STATUS:
+        {
+            DPRINT("IOCTL_INTERNAL_USB_GET_PORT_STATUS\n");
+            break;
+        }
+        case IOCTL_INTERNAL_USB_RESET_PORT:
+        {
+            DPRINT("IOCTL_INTERNAL_USB_RESET_PORT\n");
+            break;
+        }
+        case IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO:
+        {
+            DPRINT("IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO\n");
+            /* This is document as Argument1 = PDO and Argument2 = FDO.
+               Its actually reversed, the FDO goes in Argument1 and PDO goes in Argument2 */
+            if (Stack->Parameters.Others.Argument1)
+                Stack->Parameters.Others.Argument1 = FdoDeviceExtension->DeviceObject;
+            if (Stack->Parameters.Others.Argument2)
+                Stack->Parameters.Others.Argument2 = FdoDeviceExtension->Pdo;
+
+            Irp->IoStatus.Information = 0;
+            Irp->IoStatus.Status = STATUS_SUCCESS;
+            return STATUS_SUCCESS;
+            break;
+        }
+        case IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION:
+        {
+            DPRINT("IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION\n");
+            break;
+        }
+        default:
+        {
+            DPRINT("Unhandled IoControlCode %x\n", Stack->Parameters.DeviceIoControl.IoControlCode);
+            break;
+        }
+    }
+
+    Irp->IoStatus.Information = Information;
+    if (Status != STATUS_PENDING)
+        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+    return Status;
+}
+
+NTSTATUS
+PdoQueryId(PDEVICE_OBJECT DeviceObject, PIRP Irp, ULONG_PTR* Information)
+{
+    PPDO_DEVICE_EXTENSION PdoDeviceExtension;
+    PFDO_DEVICE_EXTENSION FdoDeviceExtension;
+    WCHAR Buffer[256];
+    ULONG Index = 0;
+    ULONG IdType;
+    UNICODE_STRING SourceString;
+    UNICODE_STRING String;
+    NTSTATUS Status;
+
+    IdType = IoGetCurrentIrpStackLocation(Irp)->Parameters.QueryId.IdType;
+    PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+    FdoDeviceExtension = (PFDO_DEVICE_EXTENSION)PdoDeviceExtension->ControllerFdo->DeviceExtension;
+
+    /* FIXME: Read values from registry */
+
+    switch (IdType)
+    {
+        case BusQueryDeviceID:
+        {
+            DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryDeviceID\n");
+            RtlInitUnicodeString(&SourceString, L"USB\\ROOT_HUB20");
+            break;
+        }
+        case BusQueryHardwareIDs:
+        {
+            DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryHardwareIDs\n");
+
+            Index += swprintf(&Buffer[Index], L"USB\\ROOT_HUB20&VID8086&PID265C&REV0000") + 1;
+            Index += swprintf(&Buffer[Index], L"USB\\ROOT_HUB20&VID8086&PID265") + 1;
+            Index += swprintf(&Buffer[Index], L"USB\\ROOT_HUB20") + 1;
+
+            Buffer[Index] = UNICODE_NULL;
+            SourceString.Length = SourceString.MaximumLength = Index * sizeof(WCHAR);
+            SourceString.Buffer = Buffer;
+            break;
+        }
+        case BusQueryCompatibleIDs:
+        {
+            DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryCompatibleIDs\n");
+                        /* We have none */
+            return STATUS_SUCCESS;
+            break;
+        }
+        case BusQueryInstanceID:
+        {
+            DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryInstanceID\n");
+
+               /*
+               Do we need to implement this?
+               At one point I hade DeviceCapabilities->UniqueID set to TRUE.
+               And caused usbhub to fail attaching
+               to the PDO. Setting UniqueID to FALSE, it works
+               */
+
+            return STATUS_SUCCESS;
+            break;
+        }
+        default:
+        {
+            DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_ID / unknown query id type 0x%lx\n", IdType);
+            return STATUS_NOT_SUPPORTED;
+        }
+    }
+
+    /* Lifted from hpoussin */
+    Status = DuplicateUnicodeString(RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE,
+                                    &SourceString,
+                                    &String);
+
+    *Information = (ULONG_PTR)String.Buffer;
+    return Status;
+}
+
+NTSTATUS
+PdoQueryDeviceRelations(PDEVICE_OBJECT DeviceObject, PDEVICE_RELATIONS* pDeviceRelations)
+{
+    PFDO_DEVICE_EXTENSION DeviceExtension;
+    PDEVICE_RELATIONS DeviceRelations;
+
+    DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+
+    DeviceRelations = (PDEVICE_RELATIONS)ExAllocatePool(PagedPool, sizeof(DEVICE_RELATIONS));
+    if (!DeviceRelations)
+        return STATUS_INSUFFICIENT_RESOURCES;
+
+    ObReferenceObject(DeviceObject);
+    DeviceRelations->Count = 1;
+    DeviceRelations->Objects[0] = DeviceObject;
+
+    *pDeviceRelations = DeviceRelations;
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS NTAPI
+PdoDispatchPnp(
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PIRP Irp)
+{
+    ULONG MinorFunction;
+    PIO_STACK_LOCATION Stack;
+    ULONG_PTR Information = 0;
+    NTSTATUS Status;
+
+    Stack = IoGetCurrentIrpStackLocation(Irp);
+    MinorFunction = Stack->MinorFunction;
+
+    switch (MinorFunction)
+    {
+        case IRP_MN_QUERY_REMOVE_DEVICE:
+        case IRP_MN_REMOVE_DEVICE:
+        case IRP_MN_CANCEL_REMOVE_DEVICE:
+        case IRP_MN_STOP_DEVICE:
+        case IRP_MN_QUERY_STOP_DEVICE:
+        case IRP_MN_QUERY_DEVICE_TEXT:
+        case IRP_MN_SURPRISE_REMOVAL:
+        {
+            Information = Irp->IoStatus.Information;
+            Status = STATUS_SUCCESS;
+            break;
+        }
+
+        case IRP_MN_START_DEVICE:
+        {
+            DPRINT("IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
+            Status = STATUS_SUCCESS;
+            break;
+        }
+        case IRP_MN_QUERY_DEVICE_RELATIONS:
+        {
+            switch (Stack->Parameters.QueryDeviceRelations.Type)
+            {
+                case TargetDeviceRelation:
+                {
+                    PDEVICE_RELATIONS DeviceRelations = NULL;
+                    DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / TargetDeviceRelation\n");
+                    Status = PdoQueryDeviceRelations(DeviceObject, &DeviceRelations);
+                    Information = (ULONG_PTR)DeviceRelations;
+                    break;
+                }
+                default:
+                {
+                    DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / Unhandled type 0x%lx\n",
+                        Stack->Parameters.QueryDeviceRelations.Type);
+                    //ASSERT(FALSE);
+                    Status = STATUS_NOT_SUPPORTED;
+                    break;
+                }
+            }
+            break;
+        }
+        case IRP_MN_QUERY_CAPABILITIES:
+        {
+            PDEVICE_CAPABILITIES DeviceCapabilities;
+            ULONG i;
+            DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_CAPABILITIES\n");
+            DeviceCapabilities = (PDEVICE_CAPABILITIES)Stack->Parameters.DeviceCapabilities.Capabilities;
+            /* FIXME: capabilities can change with connected device */
+            DeviceCapabilities->LockSupported = FALSE;
+            DeviceCapabilities->EjectSupported = FALSE;
+            DeviceCapabilities->Removable = FALSE;
+            DeviceCapabilities->DockDevice = FALSE;
+            DeviceCapabilities->UniqueID = FALSE;//TRUE;
+            DeviceCapabilities->SilentInstall = FALSE;
+            DeviceCapabilities->RawDeviceOK = TRUE;
+            DeviceCapabilities->SurpriseRemovalOK = FALSE;
+
+             /* FIXME */
+            DeviceCapabilities->HardwareDisabled = FALSE;
+            //DeviceCapabilities->NoDisplayInUI = FALSE;
+            DeviceCapabilities->DeviceState[0] = PowerDeviceD0;
+            for (i = 0; i < PowerSystemMaximum; i++)
+                DeviceCapabilities->DeviceState[i] = PowerDeviceD3;
+            //DeviceCapabilities->DeviceWake = PowerDeviceUndefined;
+            DeviceCapabilities->D1Latency = 0;
+            DeviceCapabilities->D2Latency = 0;
+            DeviceCapabilities->D3Latency = 0;
+            Status = STATUS_SUCCESS;
+            break;
+        }
+        case IRP_MN_QUERY_RESOURCES:
+        {
+            Information = Irp->IoStatus.Information;
+            Status = Irp->IoStatus.Status;
+            break;
+        }
+        case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
+        {
+            DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n");
+            Information = Irp->IoStatus.Information;
+            Status = Irp->IoStatus.Status;
+            break;
+        }
+        /*case IRP_MN_QUERY_DEVICE_TEXT:
+        {
+            Status = STATUS_NOT_SUPPORTED;
+            break;
+        }*/
+        case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
+        {
+            DPRINT("IRP_MJ_PNP / IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n");
+            Information = Irp->IoStatus.Information;
+            Status = Irp->IoStatus.Status;
+            break;
+        }
+        case IRP_MN_QUERY_ID:
+        {
+            Status = PdoQueryId(DeviceObject, Irp, &Information);
+            break;
+        }
+        case IRP_MN_QUERY_BUS_INFORMATION:
+        {
+            PPNP_BUS_INFORMATION BusInfo;
+            DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_BUS_INFORMATION\n");
+
+            BusInfo = (PPNP_BUS_INFORMATION)ExAllocatePool(PagedPool, sizeof(PNP_BUS_INFORMATION));
+            if (!BusInfo)
+                Status = STATUS_INSUFFICIENT_RESOURCES;
+            else
+            {
+                /* FIXME */
+                /*RtlCopyMemory(
+                    &BusInfo->BusTypeGuid,
+                    &GUID_DEVINTERFACE_XXX,
+                    sizeof(GUID));*/
+
+                BusInfo->LegacyBusType = PNPBus;
+                BusInfo->BusNumber = 0;
+                Information = (ULONG_PTR)BusInfo;
+                Status = STATUS_SUCCESS;
+            }
+            break;
+        }
+        default:
+        {
+            /* We are the PDO. So ignore */
+            DPRINT1("IRP_MJ_PNP / Unknown minor function 0x%lx\n", MinorFunction);
+
+            Information = Irp->IoStatus.Information;
+            Status = Irp->IoStatus.Status;
+            break;
+        }
+    }
+
+    Irp->IoStatus.Information = Information;
+    Irp->IoStatus.Status = Status;
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    return Status;
+}
+

Propchange: trunk/reactos/drivers/usb/usbehci/pdo.c
------------------------------------------------------------------------------
    svn:eol-style = native

Added: trunk/reactos/drivers/usb/usbehci/usbehci.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbehci/usbehci.c?rev=44993&view=auto
==============================================================================
--- trunk/reactos/drivers/usb/usbehci/usbehci.c (added)
+++ trunk/reactos/drivers/usb/usbehci/usbehci.c [iso-8859-1] Fri Jan  8 10:34:36 2010
@@ -1,0 +1,138 @@
+/*
+ * ReactOS USB ehci driver
+ * Copyright (C) 2009 Michael Martin
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ */
+
+/* DEFINES *******************************************************************/
+#include "usbehci.h"
+#define NDEBUG
+
+/* INCLUDES *******************************************************************/
+#include <debug.h>
+
+
+static NTSTATUS NTAPI
+IrpStub(PDEVICE_OBJECT DeviceObject, PIRP Irp)
+{
+    NTSTATUS Status;
+
+    if (((PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFdo)
+    {
+        DPRINT1("ehci: FDO stub for major function 0x%lx\n",
+            IoGetCurrentIrpStackLocation(Irp)->MajorFunction);
+        return ForwardIrpAndForget(DeviceObject, Irp);
+    }
+
+    /* We are lower driver, So complete */
+    DPRINT1("ehci: PDO stub for major function 0x%lx\n",
+    IoGetCurrentIrpStackLocation(Irp)->MajorFunction);
+
+    Status = Irp->IoStatus.Status;
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    return Status;
+}
+
+NTSTATUS NTAPI
+DispatchDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
+{
+    DPRINT("DispatchDeviceControl\n");
+    Irp->IoStatus.Information = 0;
+    Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
+
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    return STATUS_UNSUCCESSFUL;
+}
+
+NTSTATUS NTAPI
+DispatchInternalDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
+{
+    DPRINT("DispatchInternalDeviceControl\n");
+    if (((PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFdo)
+        return IrpStub(DeviceObject, Irp);
+    else
+        return PdoDispatchInternalDeviceControl(DeviceObject, Irp);
+}
+
+NTSTATUS NTAPI
+UsbEhciCleanup(PDEVICE_OBJECT DeviceObject, PIRP Irp)
+{
+    DPRINT1("UsbEhciCleanup\n");
+    Irp->IoStatus.Information = 0;
+    Irp->IoStatus.Status = STATUS_SUCCESS;
+
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS NTAPI
+UsbEhciCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp)
+{
+    DPRINT1("UsbEhciCreate\n");
+    Irp->IoStatus.Information = 0;
+    Irp->IoStatus.Status = STATUS_SUCCESS;
+
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS NTAPI
+UsbEhciClose(PDEVICE_OBJECT DeviceObject, PIRP Irp)
+{
+    DPRINT1("Close\n");
+    Irp->IoStatus.Information = 0;
+    Irp->IoStatus.Status = STATUS_SUCCESS;
+
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    return STATUS_SUCCESS;
+}
+
+VOID NTAPI
+DriverUnload(PDRIVER_OBJECT DriverObject)
+{
+    DPRINT1("Unloading Driver\n");
+}
+
+NTSTATUS NTAPI
+DispatchPnp(PDEVICE_OBJECT DeviceObject, PIRP Irp)
+{
+    if (((PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFdo)
+        return FdoDispatchPnp(DeviceObject, Irp);
+    else
+        return PdoDispatchPnp(DeviceObject, Irp);
+}
+
+NTSTATUS NTAPI
+DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
+{
+    DPRINT1("Driver Entry %wZ!\n", RegistryPath);
+
+    DriverObject->DriverExtension->AddDevice = AddDevice;
+
+    DriverObject->MajorFunction[IRP_MJ_CREATE] = UsbEhciCreate;
+    DriverObject->MajorFunction[IRP_MJ_CLOSE] = UsbEhciClose;
+    DriverObject->MajorFunction[IRP_MJ_CLEANUP] = UsbEhciCleanup;
+    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchDeviceControl;
+    DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = DispatchInternalDeviceControl;
+    DriverObject->MajorFunction[IRP_MJ_PNP] = DispatchPnp;
+
+    DriverObject->DriverUnload = DriverUnload;
+    DPRINT1("Driver entry done\n");
+
+    return STATUS_SUCCESS;
+}
+

Propchange: trunk/reactos/drivers/usb/usbehci/usbehci.c
------------------------------------------------------------------------------
    svn:eol-style = native

Added: trunk/reactos/drivers/usb/usbehci/usbehci.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbehci/usbehci.h?rev=44993&view=auto
==============================================================================
--- trunk/reactos/drivers/usb/usbehci/usbehci.h (added)
+++ trunk/reactos/drivers/usb/usbehci/usbehci.h [iso-8859-1] Fri Jan  8 10:34:36 2010
@@ -1,0 +1,278 @@
+
+#ifndef __EHCI_H__
+#define __EHCI_H__
+
+#include <ntifs.h>
+#include <ntddk.h>
+#include <stdio.h>
+#define	NDEBUG
+#include <debug.h>
+#include <usbioctl.h>
+#include <usb.h>
+
+#define	DEVICEINTIALIZED		0x01
+#define	DEVICESTARTED			0x02
+#define	DEVICEBUSY			0x04
+#define DEVICESTOPPED			0x08
+
+
+#define	MAX_USB_DEVICES			127
+#define	EHCI_MAX_SIZE_TRANSFER		0x100000
+
+/* USB Command Register */
+#define	EHCI_USBCMD			0x00
+#define	EHCI_USBSTS			0x04
+#define	EHCI_USBINTR			0x08
+#define	EHCI_FRINDEX			0x0C
+#define	EHCI_CTRLDSSEGMENT		0x10
+#define	EHCI_PERIODICLISTBASE		0x14
+#define	EHCI_ASYNCLISTBASE		0x18
+#define	EHCI_CONFIGFLAG			0x40
+#define	EHCI_PORTSC			0x44
+
+/* USB Interrupt Register Flags 32 Bits */
+#define	EHCI_USBINTR_INTE		0x01
+#define	EHCI_USBINTR_ERR		0x02
+#define	EHCI_USBINTR_PC			0x04
+#define	EHCI_USBINTR_FLROVR		0x08
+#define	EHCI_USBINTR_HSERR		0x10
+#define	EHCI_USBINTR_ASYNC		0x20
+/* Bits 6:31 Reserved */
+
+/* Status Register Flags 32 Bits */
+#define	EHCI_STS_INT			0x01
+#define	EHCI_STS_ERR			0x02
+#define	EHCI_STS_PCD			0x04
+#define	EHCI_STS_FLR			0x08
+#define	EHCI_STS_FATAL			0x10
+#define	EHCI_STS_IAA			0x20
+/* Bits 11:6 Reserved */
+#define	EHCI_STS_HALT			0x1000
+#define	EHCI_STS_RECL			0x2000
+#define	EHCI_STS_PSS			0x4000
+#define	EHCI_STS_ASS			0x8000
+#define	EHCI_ERROR_INT ( EHCI_STS_FATAL | EHCI_STS_ERR )
+
+typedef struct _EHCI_HCS_CONTENT
+{
+    ULONG PortCount : 4;
+    ULONG PortPowerControl: 1;
+    ULONG Reserved : 2;
+    ULONG PortRouteRules : 1;
+    ULONG PortPerCHC : 4;
+    ULONG CHCCount : 4;
+    ULONG PortIndicator : 1;
+    ULONG Reserved2 : 3;
+    ULONG DbgPortNum : 4;
+    ULONG Reserved3 : 8;
+
+} EHCI_HCS_CONTENT, *PEHCI_HCS_CONTENT;
+
+typedef struct _EHCI_HCC_CONTENT
+{
+    ULONG CurAddrBits : 1;
+    ULONG VarFrameList : 1;
+    ULONG ParkMode : 1;
+    ULONG Reserved : 1;
+    ULONG IsoSchedThreshold : 4;
+    ULONG EECPCapable : 8;
+    ULONG Reserved2 : 16;
+
+} EHCI_HCC_CONTENT, *PEHCI_HCC_CONTENT;
+
+typedef struct _EHCI_CAPS {
+    UCHAR        Length;
+    UCHAR        Reserved;
+    USHORT        HCIVersion;
+    union
+    {
+        EHCI_HCS_CONTENT        HCSParams;
+        ULONG    HCSParamsLong;
+    };
+    ULONG        HCCParams;
+    UCHAR        PortRoute [8];
+} EHCI_CAPS, *PEHCI_CAPS;
+
+
+typedef struct _COMMON_DEVICE_EXTENSION
+{
+    BOOLEAN IsFdo;
+    PDRIVER_OBJECT DriverObject;
+    PDEVICE_OBJECT DeviceObject;
+} COMMON_DEVICE_EXTENSION, *PCOMMON_DEVICE_EXTENSION;
+
+typedef struct _FDO_DEVICE_EXTENSION
+{
+    COMMON_DEVICE_EXTENSION Common;
+    PDRIVER_OBJECT DriverObject;
+    PDEVICE_OBJECT DeviceObject;
+    PDEVICE_OBJECT LowerDevice;
+    PDEVICE_OBJECT Pdo;
+    ULONG DeviceState;
+
+    /* USB Specs says a max of 127 devices */
+    ULONG ChildDeviceCount;
+
+    PDMA_ADAPTER pDmaAdapter;
+
+    ULONG Vector;
+    KIRQL Irql;
+
+    KINTERRUPT_MODE Mode;
+    BOOLEAN IrqShared;
+    PKINTERRUPT EhciInterrupt;
+    KDPC DpcObject;
+    KAFFINITY Affinity;
+
+    LIST_ENTRY IrpQueue;
+    KSPIN_LOCK IrpQueueLock;
+    PIRP CurrentIrp;
+
+    ULONG MapRegisters;
+
+    ULONG BusNumber;
+    ULONG BusAddress;
+    ULONG PCIAddress;
+    USHORT VendorId;
+    USHORT DeviceId;
+
+    BUS_INTERFACE_STANDARD BusInterface;
+
+    EHCI_CAPS ECHICaps;
+
+    union
+    {
+        PULONG ResourcePort;
+        PULONG ResourceMemory;
+    };
+
+    PULONG PeriodicFramList;
+    PULONG AsyncListQueueHeadPtr;
+    PHYSICAL_ADDRESS    PeriodicFramListPhysAddr;
+    PHYSICAL_ADDRESS    AsyncListQueueHeadPtrPhysAddr;
+
+    BOOLEAN AsyncComplete;
+
+    PULONG ResourceBase;
+    ULONG Size;
+
+} FDO_DEVICE_EXTENSION, *PFDO_DEVICE_EXTENSION;
+
+typedef struct _PDO_DEVICE_EXTENSION
+{
+    COMMON_DEVICE_EXTENSION Common;
+    PDEVICE_OBJECT DeviceObject;
+    PDEVICE_OBJECT ControllerFdo;
+
+} PDO_DEVICE_EXTENSION, *PPDO_DEVICE_EXTENSION;
+
+
+/* USBCMD register 32 bits */
+typedef struct _EHCI_USBCMD_CONTENT
+{
+    ULONG Run : 1;
+    ULONG HCReset : 1;
+    ULONG FrameListSize : 2;
+    ULONG PeriodicEnable : 1;
+    ULONG AsyncEnable : 1;
+    ULONG DoorBell : 1;
+    ULONG LightReset : 1;
+    ULONG AsyncParkCount : 2;
+    ULONG Reserved : 1;
+    ULONG AsyncParkEnable : 1;
+    ULONG Reserved1 : 4;
+    ULONG IntThreshold : 8;
+    ULONG Reserved2 : 8;
+
+} EHCI_USBCMD_CONTENT, *PEHCI_USBCMD_CONTENT;
+
+typedef struct _EHCI_USBSTS_CONTENT
+{
+    ULONG USBInterrupt:1;
+    ULONG ErrorInterrupt:1;
+    ULONG DetectChangeInterrupt:1;
+    ULONG FrameListRolloverInterrupt:1;
+    ULONG HostSystemErrorInterrupt:1;
+    ULONG AsyncAdvanceInterrupt:1;
+    ULONG Reserved:6;
+    ULONG HCHalted:1;
+    ULONG Reclamation:1;
+    ULONG PeriodicScheduleStatus:1;
+    ULONG AsynchronousScheduleStatus:1;
+} EHCI_USBSTS_CONTEXT, *PEHCI_USBSTS_CONTEXT;
+
+typedef struct _EHCI_USBPORTSC_CONTENT
+{
+    ULONG CurrentConnectStatus:1;
+    ULONG ConnectStatusChange:1;
+    ULONG PortEnabled:1;
+    ULONG PortEnableChanged:1;
+    ULONG OverCurrentActive:1;
+    ULONG OverCurrentChange:1;
+    ULONG ForcePortResume:1;
+    ULONG Suspend:1;
+    ULONG PortReset:1;
+    ULONG Reserved:1;
+    ULONG LineStatus:2;
+    ULONG PortPower:1;
+    ULONG PortOwner:1;
+} EHCI_USBPORTSC_CONTENT, *PEHCI_USBPORTSC_CONTENT;
+
+NTSTATUS NTAPI
+GetBusInterface(PDEVICE_OBJECT pcifido, PBUS_INTERFACE_STANDARD busInterface);
+
+NTSTATUS NTAPI
+ForwardAndWaitCompletionRoutine(PDEVICE_OBJECT DeviceObject, PIRP Irp, PKEVENT Event);
+
+NTSTATUS NTAPI
+ForwardAndWait(PDEVICE_OBJECT DeviceObject, PIRP Irp);
+
+NTSTATUS NTAPI
+ForwardIrpAndForget(PDEVICE_OBJECT DeviceObject,PIRP Irp);
+
+NTSTATUS NTAPI
+FdoDispatchPnp(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
+
+NTSTATUS NTAPI
+PdoDispatchPnp(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
+
+NTSTATUS NTAPI
+AddDevice(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT Pdo);
+
+NTSTATUS
+DuplicateUnicodeString(ULONG Flags, PCUNICODE_STRING SourceString, PUNICODE_STRING DestinationString);
+
+PWSTR
+GetSymbolicName(PDEVICE_OBJECT DeviceObject);
+
+PWSTR
+GetPhysicalDeviceObjectName(PDEVICE_OBJECT DeviceObject);
+
+NTSTATUS NTAPI
+PdoDispatchInternalDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp);
+
+BOOLEAN
+GetDeviceDescriptor(PFDO_DEVICE_EXTENSION DeviceExtension, USHORT Port);
+
+BOOLEAN
+GetDeviceDescriptor2(PFDO_DEVICE_EXTENSION DeviceExtension, USHORT Port);
+
+BOOLEAN
+GetStringDescriptor(PFDO_DEVICE_EXTENSION DeviceExtension, ULONG DecriptorStringNumber);
+
+VOID
+CompletePendingRequest(PFDO_DEVICE_EXTENSION DeviceExtension);
+
+VOID
+QueueRequest(PFDO_DEVICE_EXTENSION DeviceExtension, PIRP Irp);
+
+VOID
+QueueRequest(PFDO_DEVICE_EXTENSION DeviceExtension, PIRP Irp);
+
+VOID
+CompletePendingRequest(PFDO_DEVICE_EXTENSION DeviceExtension);
+
+VOID
+DeviceArrivalWorkItem(PDEVICE_OBJECT DeviceObject, PVOID Context);
+
+#endif

Propchange: trunk/reactos/drivers/usb/usbehci/usbehci.h
------------------------------------------------------------------------------
    svn:eol-style = native

Added: trunk/reactos/drivers/usb/usbehci/usbehci.rbuild
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbehci/usbehci.rbuild?rev=44993&view=auto
==============================================================================
--- trunk/reactos/drivers/usb/usbehci/usbehci.rbuild (added)
+++ trunk/reactos/drivers/usb/usbehci/usbehci.rbuild [iso-8859-1] Fri Jan  8 10:34:36 2010
@@ -1,0 +1,11 @@
+<?xml version="1.0"?>
+<!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd">
+<module name="usbehci" type="kernelmodedriver" installbase="system32/drivers" installname="usbehci.sys">
+	<library>ntoskrnl</library>
+	<library>hal</library>
+	<file>usbehci.c</file>
+	<file>fdo.c</file>
+	<file>pdo.c</file>
+	<file>common.c</file>
+	<file>misc.c</file>
+</module>

Propchange: trunk/reactos/drivers/usb/usbehci/usbehci.rbuild
------------------------------------------------------------------------------
    svn:eol-style = native

Added: trunk/reactos/drivers/usb/usbehci/usbehci.rc
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbehci/usbehci.rc?rev=44993&view=auto
==============================================================================
--- trunk/reactos/drivers/usb/usbehci/usbehci.rc (added)
+++ trunk/reactos/drivers/usb/usbehci/usbehci.rc [iso-8859-1] Fri Jan  8 10:34:36 2010
@@ -1,0 +1,5 @@
+#define REACTOS_VERSION_DLL
+#define REACTOS_STR_FILE_DESCRIPTION	"USB Ehci Driver\0"
+#define REACTOS_STR_INTERNAL_NAME	"usbehci\0"
+#define REACTOS_STR_ORIGINAL_FILENAME	"usbehci.sys\0"
+#include <reactos/version.rc>

Propchange: trunk/reactos/drivers/usb/usbehci/usbehci.rc
------------------------------------------------------------------------------
    svn:eol-style = native




More information about the Ros-diffs mailing list