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…
==============================================================================
--- 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?…
==============================================================================
--- 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…
==============================================================================
--- 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?…
==============================================================================
--- 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/usbehc…
==============================================================================
--- 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/usbehc…
==============================================================================
--- 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/usbehc…
==============================================================================
--- 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/usbehc…
==============================================================================
--- 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