mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 01:15:09 +00:00
[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. svn path=/trunk/; revision=44993
This commit is contained in:
parent
4a5921d8fa
commit
86cc8888f0
8 changed files with 2054 additions and 0 deletions
147
reactos/drivers/usb/usbehci/common.c
Normal file
147
reactos/drivers/usb/usbehci/common.c
Normal file
|
@ -0,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;
|
||||
}
|
||||
|
819
reactos/drivers/usb/usbehci/fdo.c
Normal file
819
reactos/drivers/usb/usbehci/fdo.c
Normal file
|
@ -0,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;
|
||||
}
|
232
reactos/drivers/usb/usbehci/misc.c
Normal file
232
reactos/drivers/usb/usbehci/misc.c
Normal file
|
@ -0,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;
|
||||
}
|
||||
|
424
reactos/drivers/usb/usbehci/pdo.c
Normal file
424
reactos/drivers/usb/usbehci/pdo.c
Normal file
|
@ -0,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;
|
||||
}
|
||||
|
138
reactos/drivers/usb/usbehci/usbehci.c
Normal file
138
reactos/drivers/usb/usbehci/usbehci.c
Normal file
|
@ -0,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;
|
||||
}
|
||||
|
278
reactos/drivers/usb/usbehci/usbehci.h
Normal file
278
reactos/drivers/usb/usbehci/usbehci.h
Normal file
|
@ -0,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
|
11
reactos/drivers/usb/usbehci/usbehci.rbuild
Normal file
11
reactos/drivers/usb/usbehci/usbehci.rbuild
Normal file
|
@ -0,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>
|
5
reactos/drivers/usb/usbehci/usbehci.rc
Normal file
5
reactos/drivers/usb/usbehci/usbehci.rc
Normal file
|
@ -0,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>
|
Loading…
Reference in a new issue