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?r... ============================================================================== --- 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?r... ============================================================================== --- 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... ============================================================================== --- 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... ============================================================================== --- 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... ============================================================================== --- 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... ============================================================================== --- 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