[USBPORT] Bring-in the usbport driver created by Vadim Galyant. CR-111 GitHub PR #27. This is the first module out of many to come, so stay tuned! Many thanks to everyone involved in the code review. Very special thanks for Thomas as his help, insight and reviews helped tremendously.

svn path=/trunk/; revision=75062
This commit is contained in:
Amine Khaldi 2017-06-16 19:20:03 +00:00
parent 4b0ee92f91
commit 098839afec
20 changed files with 15710 additions and 0 deletions

View file

@ -3,5 +3,6 @@ add_subdirectory(usbd)
add_subdirectory(usbehci)
add_subdirectory(usbhub)
add_subdirectory(usbohci)
add_subdirectory(usbport)
add_subdirectory(usbstor)
add_subdirectory(usbuhci)

View file

@ -0,0 +1,28 @@
spec2def(usbport.sys usbport.spec ADD_IMPORTLIB)
list(APPEND SOURCE
debug.c
device.c
endpoint.c
iface.c
ioctl.c
pnp.c
power.c
queue.c
roothub.c
urb.c
usb2.c
usbport.c
usbport.h)
add_library(usbport SHARED
${SOURCE}
guid.c
usbport.rc
${CMAKE_CURRENT_BINARY_DIR}/usbport.def)
add_pch(usbport usbport.h SOURCE)
set_module_type(usbport kernelmodedriver)
add_importlibs(usbport ntoskrnl hal)
add_cd_file(TARGET usbport DESTINATION reactos/system32/drivers NO_CAB FOR all)

View file

@ -0,0 +1,270 @@
#include "usbport.h"
#define NDEBUG
#include <debug.h>
#define NDEBUG_USBPORT_MINIPORT
#define NDEBUG_USBPORT_URB
#include "usbdebug.h"
ULONG
NTAPI
USBPORT_DbgPrint(IN PVOID Context,
IN ULONG Level,
IN PCH Format,
...)
{
DPRINT("USBPORT_DbgPrint: UNIMPLEMENTED. FIXME. \n");
return 0;
}
ULONG
NTAPI
USBPORT_TestDebugBreak(IN PVOID Context)
{
DPRINT("USBPORT_TestDebugBreak: UNIMPLEMENTED. FIXME. \n");
return 0;
}
ULONG
NTAPI
USBPORT_AssertFailure(PVOID Context,
PVOID FailedAssertion,
PVOID FileName,
ULONG LineNumber,
PCHAR Message)
{
DPRINT("USBPORT_AssertFailure: ... \n");
RtlAssert(FailedAssertion, FileName, LineNumber, Message);
return 0;
}
VOID
NTAPI
USBPORT_BugCheck(IN PVOID Context)
{
DPRINT1("USBPORT_BugCheck: FIXME \n");
//KeBugCheckEx(BUGCODE_USB_DRIVER, ...);
ASSERT(FALSE);
}
ULONG
NTAPI
USBPORT_LogEntry(IN PVOID BusContext,
IN ULONG DriverTag,
IN ULONG EnumTag,
IN ULONG P1,
IN ULONG P2,
IN ULONG P3)
{
DPRINT_MINIPORT("USBPORT_LogEntry: BusContext - %p, EnumTag - %lx, P1 - %lx, P2 - %lx, P3 - %lx\n",
BusContext,
EnumTag,
P1,
P2,
P3);
return 0;
}
VOID
NTAPI
USBPORT_DumpingDeviceDescriptor(IN PUSB_DEVICE_DESCRIPTOR DeviceDescriptor)
{
if (!DeviceDescriptor)
{
return;
}
DPRINT_URB("Dumping Device Descriptor - %p\n", DeviceDescriptor);
DPRINT_URB("bLength - %x\n", DeviceDescriptor->bLength);
DPRINT_URB("bDescriptorType - %x\n", DeviceDescriptor->bDescriptorType);
DPRINT_URB("bcdUSB - %x\n", DeviceDescriptor->bcdUSB);
DPRINT_URB("bDeviceClass - %x\n", DeviceDescriptor->bDeviceClass);
DPRINT_URB("bDeviceSubClass - %x\n", DeviceDescriptor->bDeviceSubClass);
DPRINT_URB("bDeviceProtocol - %x\n", DeviceDescriptor->bDeviceProtocol);
DPRINT_URB("bMaxPacketSize0 - %x\n", DeviceDescriptor->bMaxPacketSize0);
DPRINT_URB("idVendor - %x\n", DeviceDescriptor->idVendor);
DPRINT_URB("idProduct - %x\n", DeviceDescriptor->idProduct);
DPRINT_URB("bcdDevice - %x\n", DeviceDescriptor->bcdDevice);
DPRINT_URB("iManufacturer - %x\n", DeviceDescriptor->iManufacturer);
DPRINT_URB("iProduct - %x\n", DeviceDescriptor->iProduct);
DPRINT_URB("iSerialNumber - %x\n", DeviceDescriptor->iSerialNumber);
DPRINT_URB("bNumConfigurations - %x\n", DeviceDescriptor->bNumConfigurations);
}
VOID
NTAPI
USBPORT_DumpingConfiguration(IN PUSB_CONFIGURATION_DESCRIPTOR ConfigDescriptor)
{
PUSB_INTERFACE_DESCRIPTOR iDescriptor;
PUSB_ENDPOINT_DESCRIPTOR Descriptor;
ULONG ix;
if (!ConfigDescriptor ||
ConfigDescriptor->bLength < sizeof(USB_CONFIGURATION_DESCRIPTOR))
{
return;
}
DPRINT_URB("Dumping ConfigDescriptor - %p\n", ConfigDescriptor);
DPRINT_URB("bLength - %x\n", ConfigDescriptor->bLength);
DPRINT_URB("bDescriptorType - %x\n", ConfigDescriptor->bDescriptorType);
DPRINT_URB("wTotalLength - %x\n", ConfigDescriptor->wTotalLength);
DPRINT_URB("bNumInterfaces - %x\n", ConfigDescriptor->bNumInterfaces);
DPRINT_URB("bConfigurationValue - %x\n", ConfigDescriptor->bConfigurationValue);
DPRINT_URB("iConfiguration - %x\n", ConfigDescriptor->iConfiguration);
DPRINT_URB("bmAttributes - %x\n", ConfigDescriptor->bmAttributes);
DPRINT_URB("MaxPower - %x\n", ConfigDescriptor->MaxPower);
iDescriptor = (PUSB_INTERFACE_DESCRIPTOR)((ULONG_PTR)ConfigDescriptor +
ConfigDescriptor->bLength);
if (iDescriptor->bLength < sizeof(USB_INTERFACE_DESCRIPTOR))
{
return;
}
DPRINT_URB("Dumping iDescriptor - %p\n", iDescriptor);
DPRINT_URB("bLength - %x\n", iDescriptor->bLength);
DPRINT_URB("bDescriptorType - %x\n", iDescriptor->bDescriptorType);
DPRINT_URB("bInterfaceNumber - %x\n", iDescriptor->bInterfaceNumber);
DPRINT_URB("bAlternateSetting - %x\n", iDescriptor->bAlternateSetting);
DPRINT_URB("bNumEndpoints - %x\n", iDescriptor->bNumEndpoints);
DPRINT_URB("bInterfaceClass - %x\n", iDescriptor->bInterfaceClass);
DPRINT_URB("bInterfaceSubClass - %x\n", iDescriptor->bInterfaceSubClass);
DPRINT_URB("bInterfaceProtocol - %x\n", iDescriptor->bInterfaceProtocol);
DPRINT_URB("iInterface - %x\n", iDescriptor->iInterface);
Descriptor = (PUSB_ENDPOINT_DESCRIPTOR)((ULONG_PTR)iDescriptor +
iDescriptor->bLength);
for (ix = 0; ix < iDescriptor->bNumEndpoints; ix++)
{
if (Descriptor->bLength < sizeof(USB_ENDPOINT_DESCRIPTOR))
{
return;
}
DPRINT_URB("Dumping Descriptor - %p\n", Descriptor);
DPRINT_URB("bLength - %x\n", Descriptor->bLength);
DPRINT_URB("bDescriptorType - %x\n", Descriptor->bDescriptorType);
DPRINT_URB("bEndpointAddress - %x\n", Descriptor->bEndpointAddress);
DPRINT_URB("bmAttributes - %x\n", Descriptor->bmAttributes);
DPRINT_URB("wMaxPacketSize - %x\n", Descriptor->wMaxPacketSize);
DPRINT_URB("bInterval - %x\n", Descriptor->bInterval);
Descriptor += 1;
}
}
VOID
NTAPI
USBPORT_DumpingCapabilities(IN PDEVICE_CAPABILITIES Capabilities)
{
if (!Capabilities)
{
return;
}
DPRINT("Capabilities->Size - %x\n", Capabilities->Size);
DPRINT("Capabilities->Version - %x\n", Capabilities->Version);
DPRINT("Capabilities->DeviceD1 - %x\n", Capabilities->DeviceD1);
DPRINT("Capabilities->DeviceD2 - %x\n", Capabilities->DeviceD2);
DPRINT("Capabilities->LockSupported - %x\n", Capabilities->LockSupported);
DPRINT("Capabilities->EjectSupported - %x\n", Capabilities->EjectSupported);
DPRINT("Capabilities->Removable - %x\n", Capabilities->Removable);
DPRINT("Capabilities->DockDevice - %x\n", Capabilities->DockDevice);
DPRINT("Capabilities->UniqueID - %x\n", Capabilities->UniqueID);
DPRINT("Capabilities->SilentInstall - %x\n", Capabilities->SilentInstall);
DPRINT("Capabilities->RawDeviceOK - %x\n", Capabilities->RawDeviceOK);
DPRINT("Capabilities->SurpriseRemovalOK - %x\n", Capabilities->SurpriseRemovalOK);
DPRINT("Capabilities->Address - %x\n", Capabilities->Address);
DPRINT("Capabilities->UINumber - %x\n", Capabilities->UINumber);
DPRINT("Capabilities->DeviceState[0] - %x\n", Capabilities->DeviceState[0]);
DPRINT("Capabilities->DeviceState[1] - %x\n", Capabilities->DeviceState[1]);
DPRINT("Capabilities->DeviceState[2] - %x\n", Capabilities->DeviceState[2]);
DPRINT("Capabilities->DeviceState[3] - %x\n", Capabilities->DeviceState[3]);
DPRINT("Capabilities->DeviceState[4] - %x\n", Capabilities->DeviceState[4]);
DPRINT("Capabilities->DeviceState[5] - %x\n", Capabilities->DeviceState[5]);
DPRINT("Capabilities->DeviceState[6] - %x\n", Capabilities->DeviceState[6]);
DPRINT("Capabilities->SystemWake - %x\n", Capabilities->SystemWake);
DPRINT("Capabilities->DeviceWake - %x\n", Capabilities->DeviceWake);
DPRINT("Capabilities->D1Latency - %x\n", Capabilities->D1Latency);
DPRINT("Capabilities->D2Latency - %x\n", Capabilities->D2Latency);
DPRINT("Capabilities->D3Latency - %x\n", Capabilities->D3Latency);
}
VOID
NTAPI
USBPORT_DumpingSetupPacket(IN PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket)
{
DPRINT("SetupPacket->bmRequestType.B - %x\n", SetupPacket->bmRequestType.B);
DPRINT("SetupPacket->bRequest - %x\n", SetupPacket->bRequest);
DPRINT("SetupPacket->wValue.LowByte - %x\n", SetupPacket->wValue.LowByte);
DPRINT("SetupPacket->wValue.HiByte - %x\n", SetupPacket->wValue.HiByte);
DPRINT("SetupPacket->wIndex.W - %x\n", SetupPacket->wIndex.W);
DPRINT("SetupPacket->wLength - %x\n", SetupPacket->wLength);
}
VOID
NTAPI
USBPORT_DumpingURB(IN PURB Urb)
{
PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket;
DPRINT_URB("UrbHeader.Length - %x\n", Urb->UrbHeader.Length);
DPRINT_URB("UrbHeader.Function - %x\n", Urb->UrbHeader.Function);
DPRINT_URB("UrbHeader.Status - %x\n", Urb->UrbHeader.Status);
DPRINT_URB("UrbHeader.UsbdDeviceHandle - %p\n", Urb->UrbHeader.UsbdDeviceHandle);
DPRINT_URB("UrbHeader.UsbdFlags - %x\n", Urb->UrbHeader.UsbdFlags);
if (Urb->UrbHeader.Length < 0x48)
{
return;
}
DPRINT_URB("PipeHandle - %p\n", Urb->UrbControlTransfer.PipeHandle);
DPRINT_URB("TransferFlags - %x\n", Urb->UrbControlTransfer.TransferFlags);
DPRINT_URB("TransferBufferLength - %x\n", Urb->UrbControlTransfer.TransferBufferLength);
DPRINT_URB("TransferBuffer - %p\n", Urb->UrbControlTransfer.TransferBuffer);
DPRINT_URB("TransferBufferMDL - %p\n", Urb->UrbControlTransfer.TransferBufferMDL);
DPRINT_URB("UrbLink - %p\n", Urb->UrbControlTransfer.UrbLink);
if (Urb->UrbHeader.Length < 0x50)
{
return;
}
SetupPacket = (PUSB_DEFAULT_PIPE_SETUP_PACKET)&Urb->UrbControlTransfer.SetupPacket;
USBPORT_DumpingSetupPacket(SetupPacket);
}
VOID
NTAPI
USBPORT_DumpingIDs(IN PVOID Buffer)
{
PWSTR Ptr;
ULONG Length;
ULONG TotalLength = 0;
Ptr = (PWSTR)Buffer;
while (*Ptr)
{
DPRINT(" %S\n", Ptr);
Length = (ULONG)wcslen(Ptr) + 1;
Ptr += Length;
TotalLength += Length;
}
DPRINT("TotalLength: %hu\n", TotalLength);
DPRINT("\n");
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,9 @@
/* DO NOT USE THE PRECOMPILED HEADER FOR THIS FILE! */
#include <wdm.h>
#include <initguid.h>
#include <wdmguid.h>
#include <hubbusif.h>
#include <usbbusif.h>
/* NO CODE HERE, THIS IS JUST REQUIRED FOR THE GUID DEFINITIONS */

View file

@ -0,0 +1,901 @@
#include "usbport.h"
#define NDEBUG
#include <debug.h>
VOID
USB_BUSIFFN
USBI_InterfaceReference(IN PVOID BusContext)
{
DPRINT("USBI_InterfaceReference \n");
}
VOID
USB_BUSIFFN
USBI_InterfaceDereference(IN PVOID BusContext)
{
DPRINT("USBI_InterfaceDereference \n");
}
/* USB port driver Interface functions */
NTSTATUS
USB_BUSIFFN
USBHI_CreateUsbDevice(IN PVOID BusContext,
IN OUT PUSB_DEVICE_HANDLE *UsbdDeviceHandle,
IN PUSB_DEVICE_HANDLE UsbdHubDeviceHandle,
IN USHORT PortStatus,
IN USHORT PortNumber)
{
PDEVICE_OBJECT PdoDevice;
PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
PUSB_DEVICE_HANDLE deviceHandle = NULL;
NTSTATUS Status;
DPRINT("USBHI_CreateUsbDevice: ... \n");
PdoDevice = BusContext;
PdoExtension = PdoDevice->DeviceExtension;
Status = USBPORT_CreateDevice(&deviceHandle,
PdoExtension->FdoDevice,
(PUSBPORT_DEVICE_HANDLE)UsbdHubDeviceHandle,
PortStatus,
PortNumber);
*UsbdDeviceHandle = deviceHandle;
return Status;
}
NTSTATUS
USB_BUSIFFN
USBHI_InitializeUsbDevice(IN PVOID BusContext,
OUT PUSB_DEVICE_HANDLE UsbdDeviceHandle)
{
PDEVICE_OBJECT PdoDevice;
PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
DPRINT("USBHI_InitializeUsbDevice \n");
PdoDevice = BusContext;
PdoExtension = PdoDevice->DeviceExtension;
return USBPORT_InitializeDevice((PUSBPORT_DEVICE_HANDLE)UsbdDeviceHandle,
PdoExtension->FdoDevice);
}
NTSTATUS
USB_BUSIFFN
USBHI_GetUsbDescriptors(IN PVOID BusContext,
IN PUSB_DEVICE_HANDLE UsbdDeviceHandle,
IN PUCHAR DeviceDescBuffer,
IN PULONG DeviceDescBufferLen,
IN PUCHAR ConfigDescBuffer,
IN PULONG ConfigDescBufferLen)
{
PDEVICE_OBJECT PdoDevice;
PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
PUSBPORT_DEVICE_HANDLE DeviceHandle;
NTSTATUS Status;
DPRINT("USBHI_GetUsbDescriptors ...\n");
PdoDevice = BusContext;
PdoExtension = PdoDevice->DeviceExtension;
DeviceHandle = (PUSBPORT_DEVICE_HANDLE)UsbdDeviceHandle;
if (DeviceDescBuffer && *DeviceDescBufferLen)
{
if (*DeviceDescBufferLen > sizeof(USB_DEVICE_DESCRIPTOR))
*DeviceDescBufferLen = sizeof(USB_DEVICE_DESCRIPTOR);
RtlCopyMemory(DeviceDescBuffer,
&DeviceHandle->DeviceDescriptor,
*DeviceDescBufferLen);
}
Status = USBPORT_GetUsbDescriptor(DeviceHandle,
PdoExtension->FdoDevice,
USB_CONFIGURATION_DESCRIPTOR_TYPE,
ConfigDescBuffer,
ConfigDescBufferLen);
USBPORT_DumpingDeviceDescriptor((PUSB_DEVICE_DESCRIPTOR)DeviceDescBuffer);
return Status;
}
NTSTATUS
USB_BUSIFFN
USBHI_RemoveUsbDevice(IN PVOID BusContext,
IN OUT PUSB_DEVICE_HANDLE UsbdDeviceHandle,
IN ULONG Flags)
{
PDEVICE_OBJECT PdoDevice;
PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
DPRINT("USBHI_RemoveUsbDevice: UsbdDeviceHandle - %p, Flags - %x\n",
UsbdDeviceHandle,
Flags);
PdoDevice = BusContext;
PdoExtension = PdoDevice->DeviceExtension;
return USBPORT_RemoveDevice(PdoExtension->FdoDevice,
(PUSBPORT_DEVICE_HANDLE)UsbdDeviceHandle,
Flags);
}
NTSTATUS
USB_BUSIFFN
USBHI_RestoreUsbDevice(IN PVOID BusContext,
OUT PUSB_DEVICE_HANDLE OldUsbdDeviceHandle,
OUT PUSB_DEVICE_HANDLE NewUsbdDeviceHandle)
{
PDEVICE_OBJECT PdoDevice;
PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
DPRINT("USBHI_RestoreUsbDevice: OldUsbdDeviceHandle - %p, NewUsbdDeviceHandle - %x\n",
OldUsbdDeviceHandle,
NewUsbdDeviceHandle);
PdoDevice = BusContext;
PdoExtension = PdoDevice->DeviceExtension;
return USBPORT_RestoreDevice(PdoExtension->FdoDevice,
(PUSBPORT_DEVICE_HANDLE)OldUsbdDeviceHandle,
(PUSBPORT_DEVICE_HANDLE)NewUsbdDeviceHandle);
}
NTSTATUS
USB_BUSIFFN
USBHI_QueryDeviceInformation(IN PVOID BusContext,
IN PUSB_DEVICE_HANDLE UsbdDeviceHandle,
OUT PVOID DeviceInfoBuffer,
IN ULONG DeviceInfoBufferLen,
OUT PULONG LenDataReturned)
{
PUSB_DEVICE_INFORMATION_0 DeviceInfo;
PUSBPORT_CONFIGURATION_HANDLE ConfigHandle;
PLIST_ENTRY InterfaceEntry;
PUSBPORT_DEVICE_HANDLE DeviceHandle;
ULONG NumberOfOpenPipes = 0;
PUSB_PIPE_INFORMATION_0 PipeInfo;
PUSBPORT_PIPE_HANDLE PipeHandle;
PUSBPORT_INTERFACE_HANDLE InterfaceHandle;
ULONG ActualLength;
ULONG ix;
DPRINT("USBHI_QueryDeviceInformation: ... \n");
*LenDataReturned = 0;
if (DeviceInfoBufferLen < sizeof(USB_LEVEL_INFORMATION))
{
return STATUS_BUFFER_TOO_SMALL;
}
DeviceInfo = DeviceInfoBuffer;
if (DeviceInfo->InformationLevel > 0)
{
return STATUS_NOT_SUPPORTED;
}
DeviceHandle = UsbdDeviceHandle;
ConfigHandle = DeviceHandle->ConfigHandle;
if (ConfigHandle)
{
InterfaceEntry = ConfigHandle->InterfaceHandleList.Flink;
while (InterfaceEntry &&
InterfaceEntry != &ConfigHandle->InterfaceHandleList)
{
InterfaceHandle = CONTAINING_RECORD(InterfaceEntry,
USBPORT_INTERFACE_HANDLE,
InterfaceLink);
NumberOfOpenPipes += InterfaceHandle->InterfaceDescriptor.bNumEndpoints;
InterfaceEntry = InterfaceEntry->Flink;
}
}
ActualLength = sizeof(USB_DEVICE_INFORMATION_0) +
(NumberOfOpenPipes - 1) * sizeof(USB_PIPE_INFORMATION_0);
if (DeviceInfoBufferLen < ActualLength)
{
DeviceInfo->ActualLength = ActualLength;
*LenDataReturned = sizeof(USB_LEVEL_INFORMATION);
return STATUS_BUFFER_TOO_SMALL;
}
RtlZeroMemory(DeviceInfo, ActualLength);
DeviceInfo->InformationLevel = 0;
DeviceInfo->ActualLength = ActualLength;
DeviceInfo->DeviceAddress = DeviceHandle->DeviceAddress;
DeviceInfo->NumberOfOpenPipes = NumberOfOpenPipes;
DeviceInfo->DeviceSpeed = DeviceHandle->DeviceSpeed;
RtlCopyMemory(&DeviceInfo->DeviceDescriptor,
&DeviceHandle->DeviceDescriptor,
sizeof(USB_DEVICE_DESCRIPTOR));
USBPORT_DumpingDeviceDescriptor(&DeviceInfo->DeviceDescriptor);
if (DeviceHandle->DeviceSpeed == UsbFullSpeed ||
DeviceHandle->DeviceSpeed == UsbLowSpeed)
{
DeviceInfo->DeviceType = Usb11Device;
}
else if (DeviceHandle->DeviceSpeed == UsbHighSpeed)
{
DeviceInfo->DeviceType = Usb20Device;
}
DeviceInfo->CurrentConfigurationValue = 0;
if (!ConfigHandle)
{
*LenDataReturned = ActualLength;
return STATUS_SUCCESS;
}
DeviceInfo->CurrentConfigurationValue =
ConfigHandle->ConfigurationDescriptor->bConfigurationValue;
InterfaceEntry = ConfigHandle->InterfaceHandleList.Flink;
while (InterfaceEntry &&
InterfaceEntry != &ConfigHandle->InterfaceHandleList)
{
InterfaceHandle = CONTAINING_RECORD(InterfaceEntry,
USBPORT_INTERFACE_HANDLE,
InterfaceLink);
if (InterfaceHandle->InterfaceDescriptor.bNumEndpoints > 0)
{
PipeInfo = &DeviceInfo->PipeList[0];
PipeHandle = &InterfaceHandle->PipeHandle[0];
for (ix = 0;
ix < InterfaceHandle->InterfaceDescriptor.bNumEndpoints;
ix++)
{
if (PipeHandle->Flags & PIPE_HANDLE_FLAG_NULL_PACKET_SIZE)
{
PipeInfo->ScheduleOffset = 1;
}
else
{
PipeInfo->ScheduleOffset =
PipeHandle->Endpoint->EndpointProperties.ScheduleOffset;
}
RtlCopyMemory(&PipeInfo->EndpointDescriptor,
&PipeHandle->EndpointDescriptor,
sizeof(USB_ENDPOINT_DESCRIPTOR));
PipeInfo += 1;
PipeHandle += 1;
}
}
InterfaceEntry = InterfaceEntry->Flink;
}
*LenDataReturned = ActualLength;
return STATUS_SUCCESS;
}
NTSTATUS
USB_BUSIFFN
USBHI_GetControllerInformation(IN PVOID BusContext,
OUT PVOID ControllerInfoBuffer,
IN ULONG ControllerInfoBufferLen,
OUT PULONG LenDataReturned)
{
PDEVICE_OBJECT PdoDevice;
PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
PDEVICE_OBJECT FdoDevice;
PUSBPORT_DEVICE_EXTENSION FdoExtension;
PUSB_CONTROLLER_INFORMATION_0 InfoBuffer;
NTSTATUS Status;
DPRINT("USBHI_GetControllerInformation: ControllerInfoBufferLen - %x\n",
ControllerInfoBufferLen);
PdoDevice = BusContext;
PdoExtension = PdoDevice->DeviceExtension;
FdoDevice = PdoExtension->FdoDevice;
FdoExtension = FdoDevice->DeviceExtension;
InfoBuffer = ControllerInfoBuffer;
*LenDataReturned = 0;
if (ControllerInfoBufferLen < sizeof(USB_LEVEL_INFORMATION))
{
Status = STATUS_BUFFER_TOO_SMALL;
return Status;
}
*LenDataReturned = sizeof(USB_LEVEL_INFORMATION);
if (InfoBuffer->InformationLevel > 0)
{
Status = STATUS_NOT_SUPPORTED;
return Status;
}
InfoBuffer->ActualLength = sizeof(USB_CONTROLLER_INFORMATION_0);
if (ControllerInfoBufferLen >= sizeof(USB_CONTROLLER_INFORMATION_0))
{
InfoBuffer->SelectiveSuspendEnabled =
(FdoExtension->Flags & USBPORT_FLAG_SELECTIVE_SUSPEND) ==
USBPORT_FLAG_SELECTIVE_SUSPEND;
}
*LenDataReturned = sizeof(USB_CONTROLLER_INFORMATION_0);
return STATUS_SUCCESS;
}
NTSTATUS
USB_BUSIFFN
USBHI_ControllerSelectiveSuspend(IN PVOID BusContext,
IN BOOLEAN Enable)
{
PDEVICE_OBJECT PdoDevice;
PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
PDEVICE_OBJECT FdoDevice;
PUSBPORT_DEVICE_EXTENSION FdoExtension;
ULONG Flags;
ULONG HcDisable;
NTSTATUS Status;
DPRINT("USBHI_ControllerSelectiveSuspend: Enable - %x\n", Enable);
PdoDevice = BusContext;
PdoExtension = PdoDevice->DeviceExtension;
FdoDevice = PdoExtension->FdoDevice;
FdoExtension = FdoDevice->DeviceExtension;
Flags = FdoExtension->Flags;
if (Flags & USBPORT_FLAG_BIOS_DISABLE_SS)
{
return STATUS_SUCCESS;
}
if (Enable)
{
FdoExtension->Flags |= USBPORT_FLAG_SELECTIVE_SUSPEND;
HcDisable = 0;
}
else
{
FdoExtension->Flags &= ~USBPORT_FLAG_SELECTIVE_SUSPEND;
HcDisable = 1;
}
Status = USBPORT_SetRegistryKeyValue(FdoExtension->CommonExtension.LowerPdoDevice,
TRUE,
REG_DWORD,
L"HcDisableSelectiveSuspend",
&HcDisable,
sizeof(HcDisable));
if (NT_SUCCESS(Status))
{
if (Enable)
FdoExtension->Flags |= USBPORT_FLAG_SELECTIVE_SUSPEND;
else
FdoExtension->Flags &= ~USBPORT_FLAG_SELECTIVE_SUSPEND;
}
return Status;
}
NTSTATUS
USB_BUSIFFN
USBHI_GetExtendedHubInformation(IN PVOID BusContext,
IN PDEVICE_OBJECT HubPhysicalDeviceObject,
IN OUT PVOID HubInformationBuffer,
IN ULONG HubInfoLen,
IN OUT PULONG LenDataReturned)
{
PDEVICE_OBJECT PdoDevice;
PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
PDEVICE_OBJECT FdoDevice;
PUSBPORT_DEVICE_EXTENSION FdoExtension;
PUSBPORT_REGISTRATION_PACKET Packet;
ULONG NumPorts;
ULONG ix;
PUSB_EXTHUB_INFORMATION_0 HubInfoBuffer;
USBHUB_PORT_STATUS PortStatus;
ULONG PortAttrX;
DPRINT("USBHI_GetExtendedHubInformation: ... \n");
PdoDevice = BusContext;
PdoExtension = PdoDevice->DeviceExtension;
FdoDevice = PdoExtension->FdoDevice;
FdoExtension = FdoDevice->DeviceExtension;
Packet = &FdoExtension->MiniPortInterface->Packet;
HubInfoBuffer = HubInformationBuffer;
PortStatus.AsULONG = 0;
if (HubPhysicalDeviceObject != PdoDevice)
{
*LenDataReturned = 0;
return STATUS_NOT_SUPPORTED;
}
if (HubInfoLen < sizeof(USB_EXTHUB_INFORMATION_0))
{
*LenDataReturned = 0;
return STATUS_BUFFER_TOO_SMALL;
}
NumPorts = PdoExtension->RootHubDescriptors->Descriptor.bNumberOfPorts;
HubInfoBuffer->NumberOfPorts = NumPorts;
if (NumPorts == 0)
{
*LenDataReturned = sizeof(USB_EXTHUB_INFORMATION_0);
return STATUS_SUCCESS;
}
for (ix = 0; ix < HubInfoBuffer->NumberOfPorts; ++ix)
{
HubInfoBuffer->Port[ix].PhysicalPortNumber = ix + 1;
HubInfoBuffer->Port[ix].PortLabelNumber = ix;
HubInfoBuffer->Port[ix].VidOverride = 0;
HubInfoBuffer->Port[ix].PidOverride = 0;
HubInfoBuffer->Port[ix].PortAttributes = 0;
if (Packet->MiniPortFlags & USB_MINIPORT_FLAGS_USB2)
{
HubInfoBuffer->Port[ix].PortAttributes = USB_PORTATTR_SHARED_USB2;
Packet->RH_GetPortStatus(FdoExtension->MiniPortExt,
ix,
&PortStatus);
if (PortStatus.UsbPortStatus.Usb20PortStatus.AsUshort16 & 0x8000)
{
HubInfoBuffer->Port[ix].PortAttributes |= USB_PORTATTR_OWNED_BY_CC;
}
}
else
{
if (!(FdoExtension->Flags & USBPORT_FLAG_COMPANION_HC))
{
continue;
}
if (USBPORT_FindUSB2Controller(FdoDevice))
{
HubInfoBuffer->Port[ix].PortAttributes |= USB_PORTATTR_NO_OVERCURRENT_UI;
}
}
}
for (ix = 0; ix < HubInfoBuffer->NumberOfPorts; ++ix)
{
PortAttrX = 0;
USBPORT_GetRegistryKeyValueFullInfo(FdoDevice,
FdoExtension->CommonExtension.LowerPdoDevice,
FALSE,
L"PortAttrX",
sizeof(L"PortAttrX"),
&PortAttrX,
sizeof(PortAttrX));
HubInfoBuffer->Port[ix].PortAttributes |= PortAttrX;
}
*LenDataReturned = sizeof(USB_EXTHUB_INFORMATION_0);
return STATUS_SUCCESS;
}
NTSTATUS
USB_BUSIFFN
USBHI_GetRootHubSymbolicName(IN PVOID BusContext,
IN OUT PVOID HubInfoBuffer,
IN ULONG HubInfoBufferLen,
OUT PULONG HubNameActualLen)
{
PDEVICE_OBJECT PdoDevice;
UNICODE_STRING HubName;
PUNICODE_STRING InfoBuffer;
NTSTATUS Status;
DPRINT("USBHI_GetRootHubSymbolicName: ... \n");
PdoDevice = BusContext;
Status = USBPORT_GetSymbolicName(PdoDevice, &HubName);
if (HubInfoBufferLen < HubName.Length)
{
InfoBuffer = HubInfoBuffer;
InfoBuffer->Length = 0;
}
else
{
RtlCopyMemory(HubInfoBuffer, HubName.Buffer, HubName.Length);
}
*HubNameActualLen = HubName.Length;
if (NT_SUCCESS(Status))
RtlFreeUnicodeString(&HubName);
return Status;
}
PVOID
USB_BUSIFFN
USBHI_GetDeviceBusContext(IN PVOID BusContext,
IN PVOID DeviceHandle)
{
DPRINT1("USBHI_GetDeviceBusContext: UNIMPLEMENTED. FIXME. \n");
return NULL;
}
NTSTATUS
USB_BUSIFFN
USBHI_Initialize20Hub(IN PVOID BusContext,
IN PUSB_DEVICE_HANDLE UsbdHubDeviceHandle,
IN ULONG TtCount)
{
PDEVICE_OBJECT PdoDevice;
PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
DPRINT("USBHI_Initialize20Hub: UsbdHubDeviceHandle - %p, TtCount - %x\n",
UsbdHubDeviceHandle,
TtCount);
PdoDevice = BusContext;
PdoExtension = PdoDevice->DeviceExtension;
return USBPORT_Initialize20Hub(PdoExtension->FdoDevice,
(PUSBPORT_DEVICE_HANDLE)UsbdHubDeviceHandle,
TtCount);
}
NTSTATUS
USB_BUSIFFN
USBHI_RootHubInitNotification(IN PVOID BusContext,
IN PVOID CallbackContext,
IN PRH_INIT_CALLBACK CallbackFunction)
{
PDEVICE_OBJECT PdoDevice;
PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
PDEVICE_OBJECT FdoDevice;
PUSBPORT_DEVICE_EXTENSION FdoExtension;
KIRQL OldIrql;
DPRINT("USBHI_RootHubInitNotification \n");
PdoDevice = BusContext;
PdoExtension = PdoDevice->DeviceExtension;
FdoDevice = PdoExtension->FdoDevice;
FdoExtension = FdoDevice->DeviceExtension;
KeAcquireSpinLock(&FdoExtension->RootHubCallbackSpinLock, &OldIrql);
PdoExtension->RootHubInitContext = CallbackContext;
PdoExtension->RootHubInitCallback = CallbackFunction;
KeReleaseSpinLock(&FdoExtension->RootHubCallbackSpinLock, OldIrql);
return STATUS_SUCCESS;
}
VOID
USB_BUSIFFN
USBHI_FlushTransfers(IN PVOID BusContext,
OUT PUSB_DEVICE_HANDLE UsbdDeviceHandle)
{
PDEVICE_OBJECT PdoDevice;
PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
DPRINT("USBHI_FlushTransfers: ... \n");
PdoDevice = BusContext;
PdoExtension = PdoDevice->DeviceExtension;
USBPORT_BadRequestFlush(PdoExtension->FdoDevice);
}
VOID
USB_BUSIFFN
USBHI_SetDeviceHandleData(IN PVOID BusContext,
IN PVOID DeviceHandle,
IN PDEVICE_OBJECT UsbDevicePdo)
{
DPRINT1("USBHI_SetDeviceHandleData: UNIMPLEMENTED. FIXME. \n");
}
/* USB bus driver Interface functions */
VOID
USB_BUSIFFN
USBDI_GetUSBDIVersion(IN PVOID BusContext,
OUT PUSBD_VERSION_INFORMATION VersionInfo,
OUT PULONG HcdCapabilities)
{
DPRINT1("USBDI_GetUSBDIVersion: UNIMPLEMENTED. FIXME. \n");
}
NTSTATUS
USB_BUSIFFN
USBDI_QueryBusTime(IN PVOID BusContext,
OUT PULONG CurrentFrame)
{
DPRINT1("USBDI_QueryBusTime: UNIMPLEMENTED. FIXME. \n");
return STATUS_SUCCESS;
}
NTSTATUS
USB_BUSIFFN
USBDI_SubmitIsoOutUrb(IN PVOID BusContext,
IN PURB Urb)
{
DPRINT1("USBDI_SubmitIsoOutUrb: UNIMPLEMENTED. FIXME. \n");
return STATUS_SUCCESS;
}
NTSTATUS
USB_BUSIFFN
USBDI_QueryBusInformation(IN PVOID BusContext,
IN ULONG Level,
OUT PVOID BusInfoBuffer,
OUT PULONG BusInfoBufferLen,
OUT PULONG BusInfoActualLen)
{
PDEVICE_OBJECT PdoDevice;
PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
PDEVICE_OBJECT FdoDevice;
PUSBPORT_DEVICE_EXTENSION FdoExtension;
SIZE_T Length;
PUSB_BUS_INFORMATION_LEVEL_1 Buffer1;
DPRINT("USBDI_QueryBusInformation: Level - %p\n", Level);
if ((Level != 0) || (Level != 1))
{
DPRINT1("USBDI_QueryBusInformation: Level should be 0 or 1\n");
return STATUS_NOT_SUPPORTED;
}
PdoDevice = BusContext;
PdoExtension = PdoDevice->DeviceExtension;
FdoDevice = PdoExtension->FdoDevice;
FdoExtension = FdoDevice->DeviceExtension;
if (Level == 0)
{
if (BusInfoActualLen)
*BusInfoActualLen = sizeof(USB_BUS_INFORMATION_LEVEL_0);
if (*BusInfoBufferLen < sizeof(USB_BUS_INFORMATION_LEVEL_0))
{
return STATUS_BUFFER_TOO_SMALL;
}
*BusInfoBufferLen = sizeof(USB_BUS_INFORMATION_LEVEL_0);
//Buffer0 = BusInfoBuffer;
DPRINT1("USBDI_QueryBusInformation: LEVEL_0 UNIMPLEMENTED. FIXME\n");
//Buffer0->TotalBandwidth = USBPORT_GetTotalBandwidth();
//Buffer0->ConsumedBandwidth = USBPORT_GetAllocatedBandwidth();
return STATUS_SUCCESS;
}
if (Level == 1)
{
Length = sizeof(USB_BUS_INFORMATION_LEVEL_1) +
FdoExtension->CommonExtension.SymbolicLinkName.Length;
if (BusInfoActualLen)
*BusInfoActualLen = Length;
if (*BusInfoBufferLen < Length)
{
return STATUS_BUFFER_TOO_SMALL;
}
*BusInfoBufferLen = Length;
Buffer1 = BusInfoBuffer;
DPRINT1("USBDI_QueryBusInformation: LEVEL_1 UNIMPLEMENTED. FIXME\n");
//Buffer1->TotalBandwidth = USBPORT_GetTotalBandwidth();
//Buffer1->ConsumedBandwidth = USBPORT_GetAllocatedBandwidth();
Buffer1->ControllerNameLength = FdoExtension->CommonExtension.SymbolicLinkName.Length;
RtlCopyMemory(&Buffer1->ControllerNameUnicodeString,
FdoExtension->CommonExtension.SymbolicLinkName.Buffer,
FdoExtension->CommonExtension.SymbolicLinkName.Length);
return STATUS_SUCCESS;
}
return STATUS_SUCCESS;
}
BOOLEAN
USB_BUSIFFN
USBDI_IsDeviceHighSpeed(IN PVOID BusContext)
{
PDEVICE_OBJECT PdoDevice;
PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
PDEVICE_OBJECT FdoDevice;
PUSBPORT_DEVICE_EXTENSION FdoExtension;
PUSBPORT_REGISTRATION_PACKET Packet;
DPRINT("USBDI_IsDeviceHighSpeed: ... \n");
PdoDevice = BusContext;
PdoExtension = PdoDevice->DeviceExtension;
FdoDevice = PdoExtension->FdoDevice;
FdoExtension = FdoDevice->DeviceExtension;
Packet = &FdoExtension->MiniPortInterface->Packet;
return (Packet->MiniPortFlags & USB_MINIPORT_FLAGS_USB2) != 0;
}
NTSTATUS
USB_BUSIFFN
USBDI_EnumLogEntry(IN PVOID BusContext,
IN ULONG DriverTag,
IN ULONG EnumTag,
IN ULONG P1,
IN ULONG P2)
{
DPRINT1("USBDI_EnumLogEntry: UNIMPLEMENTED. FIXME. \n");
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
USBPORT_PdoQueryInterface(IN PDEVICE_OBJECT FdoDevice,
IN PDEVICE_OBJECT PdoDevice,
IN PIRP Irp)
{
PIO_STACK_LOCATION IoStack = IoGetCurrentIrpStackLocation(Irp);
PUSB_BUS_INTERFACE_HUB_V5 InterfaceHub;
PUSB_BUS_INTERFACE_USBDI_V2 InterfaceDI;
UNICODE_STRING GuidBuffer;
NTSTATUS Status;
DPRINT("USBPORT_PdoQueryInterface: ... \n");
if (IsEqualGUIDAligned(IoStack->Parameters.QueryInterface.InterfaceType,
&USB_BUS_INTERFACE_HUB_GUID))
{
/* Get request parameters */
InterfaceHub = (PUSB_BUS_INTERFACE_HUB_V5)IoStack->Parameters.QueryInterface.Interface;
InterfaceHub->Version = IoStack->Parameters.QueryInterface.Version;
/* Check version */
if (IoStack->Parameters.QueryInterface.Version >= 6)
{
DPRINT1("USB_BUS_INTERFACE_HUB_GUID version %x not supported!\n",
IoStack->Parameters.QueryInterface.Version);
return STATUS_NOT_SUPPORTED; // Version not supported
}
/* Interface version 0 */
InterfaceHub->Size = IoStack->Parameters.QueryInterface.Size;
InterfaceHub->BusContext = PdoDevice;
InterfaceHub->InterfaceReference = USBI_InterfaceReference;
InterfaceHub->InterfaceDereference = USBI_InterfaceDereference;
/* Interface version 1 */
if (IoStack->Parameters.QueryInterface.Version >= 1)
{
InterfaceHub->CreateUsbDevice = USBHI_CreateUsbDevice;
InterfaceHub->InitializeUsbDevice = USBHI_InitializeUsbDevice;
InterfaceHub->GetUsbDescriptors = USBHI_GetUsbDescriptors;
InterfaceHub->RemoveUsbDevice = USBHI_RemoveUsbDevice;
InterfaceHub->RestoreUsbDevice = USBHI_RestoreUsbDevice;
InterfaceHub->QueryDeviceInformation = USBHI_QueryDeviceInformation;
}
/* Interface version 2 */
if (IoStack->Parameters.QueryInterface.Version >= 2)
{
InterfaceHub->GetControllerInformation = USBHI_GetControllerInformation;
InterfaceHub->ControllerSelectiveSuspend = USBHI_ControllerSelectiveSuspend;
InterfaceHub->GetExtendedHubInformation = USBHI_GetExtendedHubInformation;
InterfaceHub->GetRootHubSymbolicName = USBHI_GetRootHubSymbolicName;
InterfaceHub->GetDeviceBusContext = USBHI_GetDeviceBusContext;
InterfaceHub->Initialize20Hub = USBHI_Initialize20Hub;
}
/* Interface version 3 */
if (IoStack->Parameters.QueryInterface.Version >= 3)
InterfaceHub->RootHubInitNotification = USBHI_RootHubInitNotification;
/* Interface version 4 */
if (IoStack->Parameters.QueryInterface.Version >= 4)
InterfaceHub->FlushTransfers = USBHI_FlushTransfers;
/* Interface version 5 */
if (IoStack->Parameters.QueryInterface.Version >= 5)
InterfaceHub->SetDeviceHandleData = USBHI_SetDeviceHandleData;
/* Request completed */
return STATUS_SUCCESS;
}
else if (IsEqualGUIDAligned(IoStack->Parameters.QueryInterface.InterfaceType,
&USB_BUS_INTERFACE_USBDI_GUID))
{
/* Get request parameters */
InterfaceDI = (PUSB_BUS_INTERFACE_USBDI_V2)IoStack->Parameters.QueryInterface.Interface;
InterfaceDI->Version = IoStack->Parameters.QueryInterface.Version;
/* Check version */
if (IoStack->Parameters.QueryInterface.Version >= 3)
{
DPRINT1("USB_BUS_INTERFACE_USBDI_GUID version %x not supported!\n",
IoStack->Parameters.QueryInterface.Version);
return STATUS_NOT_SUPPORTED; // Version not supported
}
/* Interface version 0 */
InterfaceDI->Size = IoStack->Parameters.QueryInterface.Size;
InterfaceDI->BusContext = PdoDevice;
InterfaceDI->InterfaceReference = USBI_InterfaceReference;
InterfaceDI->InterfaceDereference = USBI_InterfaceDereference;
InterfaceDI->GetUSBDIVersion = USBDI_GetUSBDIVersion;
InterfaceDI->QueryBusTime = USBDI_QueryBusTime;
InterfaceDI->SubmitIsoOutUrb = USBDI_SubmitIsoOutUrb;
InterfaceDI->QueryBusInformation = USBDI_QueryBusInformation;
/* Interface version 1 */
if (IoStack->Parameters.QueryInterface.Version >= 1)
InterfaceDI->IsDeviceHighSpeed = USBDI_IsDeviceHighSpeed;
/* Interface version 2 */
if (IoStack->Parameters.QueryInterface.Version >= 2)
InterfaceDI->EnumLogEntry = USBDI_EnumLogEntry;
return STATUS_SUCCESS;
}
else
{
/* Convert GUID to string */
Status = RtlStringFromGUID(IoStack->Parameters.QueryInterface.InterfaceType,
&GuidBuffer);
if (NT_SUCCESS(Status))
{
/* Print interface */
DPRINT1("HandleQueryInterface UNKNOWN INTERFACE GUID: %wZ Version %x\n",
&GuidBuffer,
IoStack->Parameters.QueryInterface.Version);
RtlFreeUnicodeString(&GuidBuffer); // Free GUID buffer
}
}
return STATUS_NOT_SUPPORTED;
}

View file

@ -0,0 +1,451 @@
#include "usbport.h"
//#define NDEBUG
#include <debug.h>
VOID
NTAPI
USBPORT_UserGetHcName(IN PDEVICE_OBJECT FdoDevice,
IN PUSBUSER_CONTROLLER_UNICODE_NAME ControllerName,
IN PUSB_UNICODE_NAME UnicodeName)
{
PUSBPORT_DEVICE_EXTENSION FdoExtension;
ULONG Length;
NTSTATUS Status;
ULONG ResultLength;
DPRINT("USBPORT_UserGetHcName: ... \n");
FdoExtension = FdoDevice->DeviceExtension;
Length = ControllerName->Header.RequestBufferLength -
sizeof(USBUSER_CONTROLLER_UNICODE_NAME);
RtlZeroMemory(UnicodeName, Length);
Status = IoGetDeviceProperty(FdoExtension->CommonExtension.LowerPdoDevice,
DevicePropertyDriverKeyName,
Length,
UnicodeName->String,
&ResultLength);
if (!NT_SUCCESS(Status))
{
if (Status == STATUS_BUFFER_TOO_SMALL)
{
ControllerName->Header.UsbUserStatusCode = UsbUserBufferTooSmall;
}
else
{
ControllerName->Header.UsbUserStatusCode = UsbUserInvalidParameter;
}
}
else
{
ControllerName->Header.UsbUserStatusCode = UsbUserSuccess;
UnicodeName->Length = ResultLength + sizeof(UNICODE_NULL);
}
ControllerName->Header.ActualBufferLength = sizeof(USBUSER_CONTROLLER_UNICODE_NAME) +
ResultLength;
}
NTSTATUS
NTAPI
USBPORT_GetSymbolicName(IN PDEVICE_OBJECT RootHubPdo,
IN PUNICODE_STRING DestinationString)
{
PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
PUNICODE_STRING RootHubName;
PWCHAR Buffer;
SIZE_T LengthName;
SIZE_T Length;
PWSTR SourceString;
WCHAR Character;
DPRINT("USBPORT_GetSymbolicName: ... \n");
PdoExtension = RootHubPdo->DeviceExtension;
RootHubName = &PdoExtension->CommonExtension.SymbolicLinkName;
Buffer = RootHubName->Buffer;
if (!Buffer)
{
return STATUS_UNSUCCESSFUL;
}
LengthName = RootHubName->Length;
SourceString = ExAllocatePoolWithTag(PagedPool, LengthName, USB_PORT_TAG);
if (!SourceString)
{
RtlInitUnicodeString(DestinationString, NULL);
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlZeroMemory(SourceString, LengthName);
if (*Buffer == L'\\')
{
Buffer += 1;
if (*Buffer == L'\\')
{
Buffer += 1;
goto Exit;
}
Character = *Buffer;
do
{
if (Character == UNICODE_NULL)
{
break;
}
Buffer += 1;
Character = *Buffer;
}
while (*Buffer != L'\\');
if (*Buffer == L'\\')
{
Buffer += 1;
}
Exit:
Length = (ULONG_PTR)Buffer - (ULONG_PTR)RootHubName->Buffer;
}
else
{
Length = 0;
}
RtlCopyMemory(SourceString,
(PVOID)((ULONG_PTR)RootHubName->Buffer + Length),
RootHubName->Length - Length);
RtlInitUnicodeString(DestinationString, SourceString);
DPRINT("USBPORT_RegisterDeviceInterface: DestinationString - %wZ\n",
DestinationString);
return STATUS_SUCCESS;
}
VOID
NTAPI
USBPORT_UserGetRootHubName(IN PDEVICE_OBJECT FdoDevice,
IN PUSBUSER_CONTROLLER_UNICODE_NAME RootHubName,
IN PUSB_UNICODE_NAME UnicodeName)
{
PUSBPORT_DEVICE_EXTENSION FdoExtension;
UNICODE_STRING UnicodeString;
ULONG Length;
ULONG ResultLength = 0;
NTSTATUS Status;
DPRINT("USBPORT_UserGetRootHubName: ... \n");
FdoExtension = FdoDevice->DeviceExtension;
Length = RootHubName->Header.RequestBufferLength -
sizeof(USBUSER_CONTROLLER_UNICODE_NAME);
RtlZeroMemory(UnicodeName, Length);
Status = USBPORT_GetSymbolicName(FdoExtension->RootHubPdo, &UnicodeString);
if (NT_SUCCESS(Status))
{
ResultLength = UnicodeString.Length;
if (UnicodeString.Length > Length)
{
UnicodeString.Length = Length;
Status = STATUS_BUFFER_TOO_SMALL;
}
if (UnicodeString.Length)
{
RtlCopyMemory(UnicodeName->String,
UnicodeString.Buffer,
UnicodeString.Length);
}
RtlFreeUnicodeString(&UnicodeString);
}
if (!NT_SUCCESS(Status))
{
if (Status == STATUS_BUFFER_TOO_SMALL)
{
RootHubName->Header.UsbUserStatusCode = UsbUserBufferTooSmall;
}
else
{
RootHubName->Header.UsbUserStatusCode = UsbUserInvalidParameter;
}
}
else
{
RootHubName->Header.UsbUserStatusCode = UsbUserSuccess;
UnicodeName->Length = ResultLength + sizeof(UNICODE_NULL);
}
RootHubName->Header.ActualBufferLength = sizeof(USBUSER_CONTROLLER_UNICODE_NAME) +
ResultLength;
}
NTSTATUS
NTAPI
USBPORT_GetUnicodeName(IN PDEVICE_OBJECT FdoDevice,
IN PIRP Irp,
IN PULONG Information)
{
PUSB_HCD_DRIVERKEY_NAME DriverKey;
PIO_STACK_LOCATION IoStack;
ULONG OutputBufferLength;
ULONG IoControlCode;
ULONG Length;
PUSBUSER_CONTROLLER_UNICODE_NAME ControllerName;
PUSB_UNICODE_NAME UnicodeName;
ULONG ActualLength;
DPRINT("USBPORT_GetUnicodeName: ... \n");
*Information = 0;
DriverKey = Irp->AssociatedIrp.SystemBuffer;
IoStack = IoGetCurrentIrpStackLocation(Irp);
OutputBufferLength = IoStack->Parameters.DeviceIoControl.OutputBufferLength;
IoControlCode = IoStack->Parameters.DeviceIoControl.IoControlCode;
if (OutputBufferLength < sizeof(USB_UNICODE_NAME))
{
return STATUS_BUFFER_TOO_SMALL;
}
Length = sizeof(USBUSER_CONTROLLER_UNICODE_NAME);
while (TRUE)
{
ControllerName = ExAllocatePoolWithTag(PagedPool,
Length,
USB_PORT_TAG);
if (!ControllerName)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlZeroMemory(ControllerName, Length);
ControllerName->Header.RequestBufferLength = Length;
UnicodeName = &ControllerName->UnicodeName;
if (IoControlCode == IOCTL_GET_HCD_DRIVERKEY_NAME)
{
ControllerName->Header.UsbUserRequest = USBUSER_GET_CONTROLLER_DRIVER_KEY;
USBPORT_UserGetHcName(FdoDevice, ControllerName, UnicodeName);
}
else
{
ControllerName->Header.UsbUserRequest = USBUSER_GET_ROOTHUB_SYMBOLIC_NAME;
USBPORT_UserGetRootHubName(FdoDevice, ControllerName, UnicodeName);
}
if (ControllerName->Header.UsbUserStatusCode != UsbUserBufferTooSmall)
{
break;
}
Length = ControllerName->Header.ActualBufferLength;
ExFreePoolWithTag(ControllerName, USB_PORT_TAG);
}
if (ControllerName->Header.UsbUserStatusCode != UsbUserSuccess)
{
return STATUS_UNSUCCESSFUL;
}
ActualLength = sizeof(ULONG) + ControllerName->UnicodeName.Length;
DriverKey->ActualLength = ActualLength;
if (OutputBufferLength < ActualLength)
{
DriverKey->DriverKeyName[0] = UNICODE_NULL;
*Information = sizeof(USB_UNICODE_NAME);
}
else
{
RtlCopyMemory(DriverKey->DriverKeyName,
ControllerName->UnicodeName.String,
ControllerName->UnicodeName.Length);
*Information = DriverKey->ActualLength;
}
ExFreePoolWithTag(ControllerName, USB_PORT_TAG);
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
USBPORT_PdoDeviceControl(IN PDEVICE_OBJECT PdoDevice,
IN PIRP Irp)
{
DPRINT1("USBPORT_PdoDeviceControl: UNIMPLEMENTED. FIXME. \n");
return 0;
}
NTSTATUS
NTAPI
USBPORT_PdoInternalDeviceControl(IN PDEVICE_OBJECT PdoDevice,
IN PIRP Irp)
{
PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
PIO_STACK_LOCATION IoStack;
ULONG IoCtl;
NTSTATUS Status;
PdoExtension = PdoDevice->DeviceExtension;
IoStack = IoGetCurrentIrpStackLocation(Irp);
IoCtl = IoStack->Parameters.DeviceIoControl.IoControlCode;
DPRINT("USBPORT_PdoInternalDeviceControl: PdoDevice - %p, Irp - %p, IoCtl - %x\n",
PdoDevice,
Irp,
IoCtl);
if (IoCtl == IOCTL_INTERNAL_USB_SUBMIT_URB)
{
return USBPORT_HandleSubmitURB(PdoDevice, Irp, URB_FROM_IRP(Irp));
}
if (IoCtl == IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO)
{
DPRINT("USBPORT_PdoInternalDeviceControl: IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO\n");
if (IoStack->Parameters.Others.Argument1)
*(PVOID *)IoStack->Parameters.Others.Argument1 = PdoDevice;
if (IoStack->Parameters.Others.Argument2)
*(PVOID *)IoStack->Parameters.Others.Argument2 = PdoDevice;
Status = STATUS_SUCCESS;
goto Exit;
}
if (IoCtl == IOCTL_INTERNAL_USB_GET_HUB_COUNT)
{
DPRINT("USBPORT_PdoInternalDeviceControl: IOCTL_INTERNAL_USB_GET_HUB_COUNT\n");
if (IoStack->Parameters.Others.Argument1)
{
++*(PULONG)IoStack->Parameters.Others.Argument1;
}
Status = STATUS_SUCCESS;
goto Exit;
}
if (IoCtl == IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE)
{
DPRINT("USBPORT_PdoInternalDeviceControl: IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE\n");
if (IoStack->Parameters.Others.Argument1)
{
*(PVOID *)IoStack->Parameters.Others.Argument1 = &PdoExtension->DeviceHandle;
}
Status = STATUS_SUCCESS;
goto Exit;
}
if (IoCtl == IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION)
{
DPRINT("USBPORT_PdoInternalDeviceControl: IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION\n");
return USBPORT_IdleNotification(PdoDevice, Irp);
}
DPRINT("USBPORT_PdoInternalDeviceControl: INVALID INTERNAL DEVICE CONTROL\n");
Status = STATUS_INVALID_DEVICE_REQUEST;
Exit:
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
NTSTATUS
NTAPI
USBPORT_FdoDeviceControl(IN PDEVICE_OBJECT FdoDevice,
IN PIRP Irp)
{
PUSBPORT_DEVICE_EXTENSION FdoExtension;
PIO_STACK_LOCATION IoStack;
ULONG ControlCode;
NTSTATUS Status = STATUS_INVALID_DEVICE_REQUEST;
ULONG_PTR Information = 0;
DPRINT("USBPORT_FdoDeviceControl: Irp - %p\n", Irp);
FdoExtension = FdoDevice->DeviceExtension;
IoStack = IoGetCurrentIrpStackLocation(Irp);
ControlCode = IoStack->Parameters.DeviceIoControl.IoControlCode;
switch (ControlCode)
{
case IOCTL_USB_DIAGNOSTIC_MODE_ON:
DPRINT("USBPORT_FdoDeviceControl: IOCTL_USB_DIAGNOSTIC_MODE_ON\n");
FdoExtension->Flags |= USBPORT_FLAG_DIAGNOSTIC_MODE;
break;
case IOCTL_USB_DIAGNOSTIC_MODE_OFF:
DPRINT("USBPORT_FdoDeviceControl: IOCTL_USB_DIAGNOSTIC_MODE_OFF\n");
FdoExtension->Flags &= ~USBPORT_FLAG_DIAGNOSTIC_MODE;
break;
case IOCTL_USB_GET_NODE_INFORMATION:
DPRINT1("USBPORT_FdoDeviceControl: IOCTL_USB_GET_NODE_INFORMATION\n");
Status = USBPORT_GetUnicodeName(FdoDevice, Irp, &Information);
break;
case IOCTL_GET_HCD_DRIVERKEY_NAME:
DPRINT1("USBPORT_FdoDeviceControl: IOCTL_GET_HCD_DRIVERKEY_NAME\n");
Status = USBPORT_GetUnicodeName(FdoDevice, Irp, &Information);
break;
case IOCTL_USB_USER_REQUEST:
DPRINT1("USBPORT_FdoDeviceControl: IOCTL_USB_USER_REQUEST UNIMPLEMENTED. FIXME\n");
break;
default:
DPRINT1("USBPORT_FdoDeviceControl: Not supported IoControlCode - %x\n",
ControlCode);
Status = STATUS_INVALID_DEVICE_REQUEST;
break;
}
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = Information;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
NTSTATUS
NTAPI
USBPORT_FdoInternalDeviceControl(IN PDEVICE_OBJECT FdoDevice,
IN PIRP Irp)
{
DPRINT1("USBPORT_FdoInternalDeviceControl: UNIMPLEMENTED. FIXME. \n");
return 0;
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,703 @@
#include "usbport.h"
#define NDEBUG
#include <debug.h>
VOID
NTAPI
USBPORT_CompletePdoWaitWake(IN PDEVICE_OBJECT FdoDevice)
{
PUSBPORT_DEVICE_EXTENSION FdoExtension;
PDEVICE_OBJECT PdoDevice;
PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
PIRP Irp;
KIRQL OldIrql;
DPRINT("USBPORT_CompletePdoWaitWake: ... \n");
FdoExtension = FdoDevice->DeviceExtension;
PdoDevice = FdoExtension->RootHubPdo;
PdoExtension = PdoDevice->DeviceExtension;
KeAcquireSpinLock(&FdoExtension->PowerWakeSpinLock, &OldIrql);
Irp = PdoExtension->WakeIrp;
if (Irp && IoSetCancelRoutine(Irp, NULL))
{
PdoExtension->WakeIrp = NULL;
KeReleaseSpinLock(&FdoExtension->PowerWakeSpinLock, OldIrql);
DPRINT("USBPORT_CompletePdoWaitWake: Complete Irp - %p\n", Irp);
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return;
}
KeReleaseSpinLock(&FdoExtension->PowerWakeSpinLock, OldIrql);
}
VOID
NTAPI
USBPORT_HcWakeDpc(IN PRKDPC Dpc,
IN PVOID DeferredContext,
IN PVOID SystemArgument1,
IN PVOID SystemArgument2)
{
DPRINT("USBPORT_HcWakeDpc: ... \n");
USBPORT_CompletePdoWaitWake((PDEVICE_OBJECT)DeferredContext);
}
VOID
NTAPI
USBPORT_HcQueueWakeDpc(IN PDEVICE_OBJECT FdoDevice)
{
PUSBPORT_DEVICE_EXTENSION FdoExtension;
DPRINT("USBPORT_HcQueueWakeDpc: ... \n");
FdoExtension = FdoDevice->DeviceExtension;
KeInsertQueueDpc(&FdoExtension->HcWakeDpc, NULL, NULL);
}
VOID
NTAPI
USBPORT_CompletePendingIdleIrp(IN PDEVICE_OBJECT PdoDevice)
{
PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
PDEVICE_OBJECT FdoDevice;
PUSBPORT_DEVICE_EXTENSION FdoExtension;
PIRP Irp;
DPRINT("USBPORT_CompletePendingIdleIrp: ... \n");
PdoExtension = PdoDevice->DeviceExtension;
FdoDevice = PdoExtension->FdoDevice;
FdoExtension = FdoDevice->DeviceExtension;
Irp = IoCsqRemoveNextIrp(&FdoExtension->IdleIoCsq, 0);
if (Irp)
{
InterlockedDecrement(&FdoExtension->IdleLockCounter);
DPRINT("USBPORT_CompletePendingIdleIrp: Complete Irp - %p\n", Irp);
Irp->IoStatus.Status = STATUS_CANCELLED;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
}
VOID
NTAPI
USBPORT_DoSetPowerD0(IN PDEVICE_OBJECT FdoDevice)
{
DPRINT("USBPORT_DoSetPowerD0: FIXME!\n");
return;
DbgBreakPoint();
//ASSERT(FALSE);
}
VOID
NTAPI
USBPORT_SuspendController(IN PDEVICE_OBJECT FdoDevice)
{
PUSBPORT_DEVICE_EXTENSION FdoExtension;
PUSBPORT_REGISTRATION_PACKET Packet;
DPRINT1("USBPORT_SuspendController \n");
FdoExtension = FdoDevice->DeviceExtension;
Packet = &FdoExtension->MiniPortInterface->Packet;
FdoExtension->TimerFlags |= USBPORT_TMFLAG_RH_SUSPENDED;
USBPORT_FlushController(FdoDevice);
if (FdoExtension->Flags & USBPORT_FLAG_HC_SUSPEND)
{
return;
}
FdoExtension->TimerFlags |= USBPORT_TMFLAG_HC_SUSPENDED;
if (FdoExtension->MiniPortFlags & USBPORT_MPFLAG_INTERRUPTS_ENABLED)
{
FdoExtension->MiniPortFlags |= USBPORT_MPFLAG_SUSPENDED;
USBPORT_Wait(FdoDevice, 10);
Packet->SuspendController(FdoExtension->MiniPortExt);
}
FdoExtension->Flags |= USBPORT_FLAG_HC_SUSPEND;
}
NTSTATUS
NTAPI
USBPORT_ResumeController(IN PDEVICE_OBJECT FdoDevice)
{
NTSTATUS Status = STATUS_UNSUCCESSFUL;
PUSBPORT_DEVICE_EXTENSION FdoExtension;
PUSBPORT_REGISTRATION_PACKET Packet;
KIRQL OldIrql;
MPSTATUS MpStatus;
DPRINT1("USBPORT_ResumeController: ... \n");
FdoExtension = FdoDevice->DeviceExtension;
Packet = &FdoExtension->MiniPortInterface->Packet;
if (!(FdoExtension->Flags & USBPORT_FLAG_HC_SUSPEND))
{
return Status;
}
KeAcquireSpinLock(&FdoExtension->TimerFlagsSpinLock, &OldIrql);
FdoExtension->TimerFlags &= ~(USBPORT_TMFLAG_HC_SUSPENDED |
USBPORT_TMFLAG_RH_SUSPENDED);
KeReleaseSpinLock(&FdoExtension->TimerFlagsSpinLock, OldIrql);
if (!(FdoExtension->MiniPortFlags & USBPORT_MPFLAG_SUSPENDED))
{
FdoExtension->Flags &= ~USBPORT_FLAG_HC_SUSPEND;
return Status;
}
FdoExtension->MiniPortFlags &= ~USBPORT_MPFLAG_SUSPENDED;
if (!Packet->ResumeController(FdoExtension->MiniPortExt))
{
Status = USBPORT_Wait(FdoDevice, 100);
FdoExtension->Flags &= ~USBPORT_FLAG_HC_SUSPEND;
return Status;
}
KeAcquireSpinLock(&FdoExtension->TimerFlagsSpinLock, &OldIrql);
FdoExtension->TimerFlags |= (USBPORT_TMFLAG_HC_SUSPENDED |
USBPORT_TMFLAG_HC_RESUME);
KeReleaseSpinLock(&FdoExtension->TimerFlagsSpinLock, OldIrql);
USBPORT_MiniportInterrupts(FdoDevice, FALSE);
Packet->StopController(FdoExtension->MiniPortExt, 1);
USBPORT_NukeAllEndpoints(FdoDevice);
RtlZeroMemory(FdoExtension->MiniPortExt, Packet->MiniPortExtensionSize);
RtlZeroMemory(FdoExtension->UsbPortResources.StartVA,
Packet->MiniPortResourcesSize);
FdoExtension->UsbPortResources.IsChirpHandled = TRUE;
MpStatus = Packet->StartController(FdoExtension->MiniPortExt,
&FdoExtension->UsbPortResources);
FdoExtension->UsbPortResources.IsChirpHandled = FALSE;
if (!MpStatus)
{
USBPORT_MiniportInterrupts(FdoDevice, TRUE);
}
KeAcquireSpinLock(&FdoExtension->TimerFlagsSpinLock, &OldIrql);
FdoExtension->TimerFlags &= ~(USBPORT_TMFLAG_HC_SUSPENDED |
USBPORT_TMFLAG_HC_RESUME |
USBPORT_TMFLAG_RH_SUSPENDED);
KeReleaseSpinLock(&FdoExtension->TimerFlagsSpinLock, OldIrql);
Status = USBPORT_Wait(FdoDevice, 100);
FdoExtension->Flags &= ~USBPORT_FLAG_HC_SUSPEND;
return Status;
}
NTSTATUS
NTAPI
USBPORT_PdoDevicePowerState(IN PDEVICE_OBJECT PdoDevice,
IN PIRP Irp)
{
PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
PDEVICE_OBJECT FdoDevice;
PUSBPORT_DEVICE_EXTENSION FdoExtension;
PIO_STACK_LOCATION IoStack;
NTSTATUS Status = STATUS_SUCCESS;
POWER_STATE State;
PdoExtension = PdoDevice->DeviceExtension;
FdoDevice = PdoExtension->FdoDevice;
FdoExtension = FdoDevice->DeviceExtension;
IoStack = IoGetCurrentIrpStackLocation(Irp);
State = IoStack->Parameters.Power.State;
DPRINT1("USBPORT_PdoDevicePowerState: Irp - %p, State - %x\n",
Irp,
State.DeviceState);
if (State.DeviceState == PowerDeviceD0)
{
if (FdoExtension->CommonExtension.DevicePowerState == PowerDeviceD0)
{
// FIXME FdoExtension->Flags
while (FdoExtension->SetPowerLockCounter)
{
USBPORT_Wait(FdoDevice, 10);
}
USBPORT_ResumeController(FdoDevice);
PdoExtension->CommonExtension.DevicePowerState = PowerDeviceD0;
USBPORT_CompletePdoWaitWake(FdoDevice);
USBPORT_CompletePendingIdleIrp(PdoDevice);
}
else
{
DPRINT1("USBPORT_PdoDevicePowerState: FdoExtension->Flags - %lx\n",
FdoExtension->Flags);
DbgBreakPoint();
Status = STATUS_UNSUCCESSFUL;
}
}
else if (State.DeviceState == PowerDeviceD1 ||
State.DeviceState == PowerDeviceD2 ||
State.DeviceState == PowerDeviceD3)
{
FdoExtension->TimerFlags |= USBPORT_TMFLAG_WAKE;
USBPORT_SuspendController(FdoDevice);
PdoExtension->CommonExtension.DevicePowerState = State.DeviceState;
}
return Status;
}
VOID
NTAPI
USBPORT_CancelPendingWakeIrp(IN PDEVICE_OBJECT PdoDevice,
IN PIRP Irp)
{
PUSBPORT_DEVICE_EXTENSION FdoExtension;
KIRQL OldIrql;
PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
DPRINT("USBPORT_CancelPendingWakeIrp: ... \n");
IoReleaseCancelSpinLock(Irp->CancelIrql);
PdoExtension = PdoDevice->DeviceExtension;
FdoExtension = PdoExtension->FdoDevice->DeviceExtension;
KeAcquireSpinLock(&FdoExtension->PowerWakeSpinLock, &OldIrql);
if (PdoExtension->WakeIrp == Irp)
{
PdoExtension->WakeIrp = NULL;
}
KeReleaseSpinLock(&FdoExtension->PowerWakeSpinLock, OldIrql);
Irp->IoStatus.Status = STATUS_CANCELLED;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
NTSTATUS
NTAPI
USBPORT_PdoPower(IN PDEVICE_OBJECT PdoDevice,
IN PIRP Irp)
{
PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
PDEVICE_OBJECT FdoDevice;
PIO_STACK_LOCATION IoStack;
PUSBPORT_DEVICE_EXTENSION FdoExtension;
NTSTATUS Status;
KIRQL OldIrql;
DPRINT("USBPORT_PdoPower: Irp - %p\n", Irp);
PdoExtension = PdoDevice->DeviceExtension;
FdoDevice = PdoExtension->FdoDevice;
FdoExtension = FdoDevice->DeviceExtension;
IoStack = IoGetCurrentIrpStackLocation(Irp);
Status = Irp->IoStatus.Status;
switch (IoStack->MinorFunction)
{
case IRP_MN_WAIT_WAKE:
DPRINT("USBPORT_PdoPower: IRP_MN_WAIT_WAKE\n");
if (!(FdoExtension->Flags & USBPORT_FLAG_HC_STARTED))
{
/* The device does not support wake-up */
Status = STATUS_NOT_SUPPORTED;
break;
}
KeAcquireSpinLock(&FdoExtension->PowerWakeSpinLock, &OldIrql);
IoSetCancelRoutine(Irp, USBPORT_CancelPendingWakeIrp);
/* Check if the IRP has been cancelled */
if (Irp->Cancel)
{
if (IoSetCancelRoutine(Irp, NULL))
{
/* IRP has been cancelled, release cancel spinlock */
KeReleaseSpinLock(&FdoExtension->PowerWakeSpinLock, OldIrql);
DPRINT("USBPORT_PdoPower: IRP_MN_WAIT_WAKE - STATUS_CANCELLED\n");
/* IRP is cancelled */
Status = STATUS_CANCELLED;
break;
}
}
if (!PdoExtension->WakeIrp)
{
/* The driver received the IRP
and is waiting for the device to signal wake-up. */
DPRINT("USBPORT_PdoPower: IRP_MN_WAIT_WAKE - No WakeIrp\n");
IoMarkIrpPending(Irp);
PdoExtension->WakeIrp = Irp;
KeReleaseSpinLock(&FdoExtension->PowerWakeSpinLock, OldIrql);
return STATUS_PENDING;
}
else
{
/* An IRP_MN_WAIT_WAKE request is already pending and must be
completed or canceled before another IRP_MN_WAIT_WAKE request
can be issued. */
if (IoSetCancelRoutine(Irp, NULL))
{
DPRINT("USBPORT_PdoPower: IRP_MN_WAIT_WAKE - STATUS_DEVICE_BUSY\n");
KeReleaseSpinLock(&FdoExtension->PowerWakeSpinLock, OldIrql);
PoStartNextPowerIrp(Irp);
Status = STATUS_DEVICE_BUSY;
break;
}
else
{
ASSERT(FALSE);
KeReleaseSpinLock(&FdoExtension->PowerWakeSpinLock, OldIrql);
return Status;
}
}
case IRP_MN_POWER_SEQUENCE:
DPRINT("USBPORT_PdoPower: IRP_MN_POWER_SEQUENCE\n");
PoStartNextPowerIrp(Irp);
break;
case IRP_MN_SET_POWER:
DPRINT("USBPORT_PdoPower: IRP_MN_SET_POWER\n");
if (IoStack->Parameters.Power.Type == DevicePowerState)
{
DPRINT("USBPORT_PdoPower: IRP_MN_SET_POWER/DevicePowerState\n");
Status = USBPORT_PdoDevicePowerState(PdoDevice, Irp);
PoStartNextPowerIrp(Irp);
break;
}
DPRINT("USBPORT_PdoPower: IRP_MN_SET_POWER/SystemPowerState \n");
if (IoStack->Parameters.Power.State.SystemState == PowerSystemWorking)
{
FdoExtension->TimerFlags |= USBPORT_TMFLAG_WAKE;
}
else
{
FdoExtension->TimerFlags &= ~USBPORT_TMFLAG_WAKE;
}
Status = STATUS_SUCCESS;
PoStartNextPowerIrp(Irp);
break;
case IRP_MN_QUERY_POWER:
DPRINT("USBPORT_PdoPower: IRP_MN_QUERY_POWER\n");
Status = STATUS_SUCCESS;
PoStartNextPowerIrp(Irp);
break;
default:
DPRINT1("USBPORT_PdoPower: unknown IRP_MN_POWER!\n");
PoStartNextPowerIrp(Irp);
break;
}
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
NTSTATUS
NTAPI
USBPORT_HcWake(IN PDEVICE_OBJECT FdoDevice,
IN PIRP Irp)
{
DPRINT1("USBPORT_HcWake: UNIMPLEMENTED. FIXME. \n");
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
USBPORT_DevicePowerState(IN PDEVICE_OBJECT FdoDevice,
IN PIRP Irp)
{
DPRINT1("USBPORT_DevicePowerState: UNIMPLEMENTED. FIXME. \n");
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
USBPORT_SystemPowerState(IN PDEVICE_OBJECT FdoDevice,
IN PIRP Irp)
{
DPRINT1("USBPORT_SystemPowerState: UNIMPLEMENTED. FIXME. \n");
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
USBPORT_FdoPower(IN PDEVICE_OBJECT FdoDevice,
IN PIRP Irp)
{
PUSBPORT_DEVICE_EXTENSION FdoExtension;
PIO_STACK_LOCATION IoStack;
NTSTATUS Status;
DPRINT("USBPORT_FdoPower: ... \n");
FdoExtension = FdoDevice->DeviceExtension;
IoStack = IoGetCurrentIrpStackLocation(Irp);
switch (IoStack->MinorFunction)
{
case IRP_MN_WAIT_WAKE:
DPRINT("USBPORT_FdoPower: IRP_MN_WAIT_WAKE\n");
Status = USBPORT_HcWake(FdoDevice, Irp);
return Status;
case IRP_MN_POWER_SEQUENCE:
DPRINT("USBPORT_FdoPower: IRP_MN_POWER_SEQUENCE\n");
break;
case IRP_MN_SET_POWER:
DPRINT("USBPORT_FdoPower: IRP_MN_SET_POWER\n");
if (IoStack->Parameters.Power.Type == DevicePowerState)
{
Status = USBPORT_DevicePowerState(FdoDevice, Irp);
}
else
{
Status = USBPORT_SystemPowerState(FdoDevice, Irp);
}
if (Status != STATUS_PENDING)
break;
return Status;
case IRP_MN_QUERY_POWER:
DPRINT("USBPORT_FdoPower: IRP_MN_QUERY_POWER\n");
Irp->IoStatus.Status = STATUS_SUCCESS;
break;
default:
DPRINT1("USBPORT_FdoPower: unknown IRP_MN_POWER!\n");
break;
}
IoCopyCurrentIrpStackLocationToNext(Irp);
PoStartNextPowerIrp(Irp);
return PoCallDriver(FdoExtension->CommonExtension.LowerDevice, Irp);
}
VOID
NTAPI
USBPORT_DoIdleNotificationCallback(IN PVOID Context)
{
PIO_STACK_LOCATION IoStack;
PDEVICE_OBJECT FdoDevice;
PUSBPORT_DEVICE_EXTENSION FdoExtension;
PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
PIRP NextIrp;
LARGE_INTEGER CurrentTime = {{0, 0}};
PTIMER_WORK_QUEUE_ITEM IdleQueueItem;
PDEVICE_OBJECT PdoDevice;
PUSB_IDLE_CALLBACK_INFO IdleCallbackInfo;
KIRQL OldIrql;
DPRINT("USBPORT_DoIdleNotificationCallback \n");
IdleQueueItem = Context;
FdoDevice = IdleQueueItem->FdoDevice;
FdoExtension = FdoDevice->DeviceExtension;
PdoDevice = FdoExtension->RootHubPdo;
PdoExtension = PdoDevice->DeviceExtension;
KeQuerySystemTime(&CurrentTime);
if ((FdoExtension->IdleTime.QuadPart == 0) ||
(((CurrentTime.QuadPart - FdoExtension->IdleTime.QuadPart) / 10000) >= 500))
{
if (PdoExtension->CommonExtension.DevicePowerState == PowerDeviceD0 &&
FdoExtension->CommonExtension.DevicePowerState == PowerDeviceD0)
{
NextIrp = IoCsqRemoveNextIrp(&FdoExtension->IdleIoCsq, NULL);
if (NextIrp)
{
IoStack = IoGetCurrentIrpStackLocation(NextIrp);
IdleCallbackInfo = IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
if (IdleCallbackInfo && IdleCallbackInfo->IdleCallback)
{
IdleCallbackInfo->IdleCallback(IdleCallbackInfo->IdleContext);
}
if (NextIrp->Cancel)
{
InterlockedDecrement(&FdoExtension->IdleLockCounter);
NextIrp->IoStatus.Status = STATUS_CANCELLED;
NextIrp->IoStatus.Information = 0;
IoCompleteRequest(NextIrp, IO_NO_INCREMENT);
}
else
{
IoCsqInsertIrp(&FdoExtension->IdleIoCsq, NextIrp, NULL);
}
}
}
}
KeAcquireSpinLock(&FdoExtension->TimerFlagsSpinLock, &OldIrql);
FdoExtension->TimerFlags &= ~USBPORT_TMFLAG_IDLE_QUEUEITEM_ON;
KeReleaseSpinLock(&FdoExtension->TimerFlagsSpinLock, OldIrql);
ExFreePoolWithTag(IdleQueueItem, USB_PORT_TAG);
}
NTSTATUS
NTAPI
USBPORT_IdleNotification(IN PDEVICE_OBJECT PdoDevice,
IN PIRP Irp)
{
PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
PDEVICE_OBJECT FdoDevice;
PUSBPORT_DEVICE_EXTENSION FdoExtension;
LONG LockCounter;
NTSTATUS Status = STATUS_PENDING;
DPRINT("USBPORT_IdleNotification: Irp - %p\n", Irp);
PdoExtension = PdoDevice->DeviceExtension;
FdoDevice = PdoExtension->FdoDevice;
FdoExtension = FdoDevice->DeviceExtension;
LockCounter = InterlockedIncrement(&FdoExtension->IdleLockCounter);
if (LockCounter != 0)
{
if (Status != STATUS_PENDING)
{
InterlockedDecrement(&FdoExtension->IdleLockCounter);
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
Status = STATUS_DEVICE_BUSY;
}
if (Status != STATUS_PENDING)
{
InterlockedDecrement(&FdoExtension->IdleLockCounter);
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
Irp->IoStatus.Status = STATUS_PENDING;
IoMarkIrpPending(Irp);
KeQuerySystemTime(&FdoExtension->IdleTime);
IoCsqInsertIrp(&FdoExtension->IdleIoCsq, Irp, 0);
return Status;
}
VOID
NTAPI
USBPORT_AdjustDeviceCapabilities(IN PDEVICE_OBJECT FdoDevice,
IN PDEVICE_OBJECT PdoDevice)
{
PUSBPORT_DEVICE_EXTENSION FdoExtension;
PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
PDEVICE_CAPABILITIES Capabilities;
DPRINT("USBPORT_AdjustDeviceCapabilities: ... \n");
FdoExtension = FdoDevice->DeviceExtension;
PdoExtension = PdoDevice->DeviceExtension;
Capabilities = &PdoExtension->Capabilities;
RtlCopyMemory(Capabilities,
&FdoExtension->Capabilities,
sizeof(DEVICE_CAPABILITIES));
Capabilities->DeviceD1 = FALSE;
Capabilities->DeviceD2 = TRUE;
Capabilities->Removable = FALSE;
Capabilities->UniqueID = FALSE;
Capabilities->WakeFromD0 = TRUE;
Capabilities->WakeFromD1 = FALSE;
Capabilities->WakeFromD2 = TRUE;
Capabilities->WakeFromD3 = FALSE;
Capabilities->Address = 0;
Capabilities->UINumber = 0;
if (Capabilities->SystemWake == PowerSystemUnspecified)
Capabilities->SystemWake = PowerSystemWorking;
Capabilities->DeviceWake = PowerDeviceD2;
Capabilities->DeviceState[PowerSystemSleeping1] = PowerDeviceD3;
Capabilities->DeviceState[PowerSystemSleeping2] = PowerDeviceD3;
Capabilities->DeviceState[PowerSystemSleeping3] = PowerDeviceD3;
Capabilities->DeviceState[PowerSystemHibernate] = PowerDeviceD3;
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,21 @@
#include "usbport.h"
//#define NDEBUG
#include <debug.h>
BOOLEAN
NTAPI
USBPORT_AllocateBandwidthUSB2(IN PDEVICE_OBJECT FdoDevice,
IN PUSBPORT_ENDPOINT Endpoint)
{
DPRINT1("USBPORT_AllocateBandwidthUSB2: UNIMPLEMENTED. FIXME. \n");
return TRUE;
}
VOID
NTAPI
USBPORT_FreeBandwidthUSB2(IN PDEVICE_OBJECT FdoDevice,
IN PUSBPORT_ENDPOINT Endpoint)
{
DPRINT1("USBPORT_FreeBandwidthUSB2: UNIMPLEMENTED. FIXME. \n");
}

View file

@ -0,0 +1,128 @@
#ifndef USBDEBUG_H__
#define USBDEBUG_H__
#if DBG
#ifndef NDEBUG_USBPORT_MINIPORT
#define DPRINT_MINIPORT(fmt, ...) do { \
if (DbgPrint("(%s:%d) " fmt, __RELFILE__, __LINE__, ##__VA_ARGS__)) \
DbgPrint("(%s:%d) DbgPrint() failed!\n", __RELFILE__, __LINE__); \
} while (0)
#else
#if defined(_MSC_VER)
#define DPRINT_MINIPORT __noop
#else
#define DPRINT_MINIPORT(...) do { if(0) { DbgPrint(__VA_ARGS__); } } while(0)
#endif
#endif
#ifndef NDEBUG_USBPORT_CORE
#define DPRINT_CORE(fmt, ...) do { \
if (DbgPrint("(%s:%d) " fmt, __RELFILE__, __LINE__, ##__VA_ARGS__)) \
DbgPrint("(%s:%d) DbgPrint() failed!\n", __RELFILE__, __LINE__); \
} while (0)
#else
#if defined(_MSC_VER)
#define DPRINT_CORE __noop
#else
#define DPRINT_CORE(...) do { if(0) { DbgPrint(__VA_ARGS__); } } while(0)
#endif
#endif
#ifndef NDEBUG_USBPORT_URB
#define DPRINT_URB(fmt, ...) do { \
if (DbgPrint("(%s:%d) " fmt, __RELFILE__, __LINE__, ##__VA_ARGS__)) \
DbgPrint("(%s:%d) DbgPrint() failed!\n", __RELFILE__, __LINE__); \
} while (0)
#else
#if defined(_MSC_VER)
#define DPRINT_URB __noop
#else
#define DPRINT_URB(...) do { if(0) { DbgPrint(__VA_ARGS__); } } while(0)
#endif
#endif
#ifndef NDEBUG_USBPORT_INTERRUPT
#define DPRINT_INT(fmt, ...) do { \
if (DbgPrint("(%s:%d) " fmt, __RELFILE__, __LINE__, ##__VA_ARGS__)) \
DbgPrint("(%s:%d) DbgPrint() failed!\n", __RELFILE__, __LINE__); \
} while (0)
#else
#if defined(_MSC_VER)
#define DPRINT_INT __noop
#else
#define DPRINT_INT(...) do { if(0) { DbgPrint(__VA_ARGS__); } } while(0)
#endif
#endif
#ifndef NDEBUG_USBPORT_TIMER
#define DPRINT_TIMER(fmt, ...) do { \
if (DbgPrint("(%s:%d) " fmt, __RELFILE__, __LINE__, ##__VA_ARGS__)) \
DbgPrint("(%s:%d) DbgPrint() failed!\n", __RELFILE__, __LINE__); \
} while (0)
#else
#if defined(_MSC_VER)
#define DPRINT_TIMER __noop
#else
#define DPRINT_TIMER(...) do { if(0) { DbgPrint(__VA_ARGS__); } } while(0)
#endif
#endif
#ifndef NDEBUG_USBPORT_QUEUE
#define DPRINT_QUEUE(fmt, ...) do { \
if (DbgPrint("(%s:%d) " fmt, __RELFILE__, __LINE__, ##__VA_ARGS__)) \
DbgPrint("(%s:%d) DbgPrint() failed!\n", __RELFILE__, __LINE__); \
} while (0)
#else
#if defined(_MSC_VER)
#define DPRINT_QUEUE __noop
#else
#define DPRINT_QUEUE(...) do { if(0) { DbgPrint(__VA_ARGS__); } } while(0)
#endif
#endif
#else /* not DBG */
#if defined(_MSC_VER)
#define DPRINT_MINIPORT __noop
#define DPRINT_CORE __noop
#define DPRINT_URB __noop
#define DPRINT_INT __noop
#define DPRINT_TIMER __noop
#define DPRINT_QUEUE __noop
#else
#define DPRINT_MINIPORT(...) do { if(0) { DbgPrint(__VA_ARGS__); } } while(0)
#define DPRINT_CORE(...) do { if(0) { DbgPrint(__VA_ARGS__); } } while(0)
#define DPRINT_URB(...) do { if(0) { DbgPrint(__VA_ARGS__); } } while(0)
#define DPRINT_INT(...) do { if(0) { DbgPrint(__VA_ARGS__); } } while(0)
#define DPRINT_TIMER(...) do { if(0) { DbgPrint(__VA_ARGS__); } } while(0)
#define DPRINT_QUEUE(...) do { if(0) { DbgPrint(__VA_ARGS__); } } while(0)
#endif /* _MSC_VER */
#endif /* not DBG */
#endif /* USBDEBUG_H__ */

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,5 @@
#define REACTOS_VERSION_DLL
#define REACTOS_STR_FILE_DESCRIPTION "USB bus driver extension"
#define REACTOS_STR_INTERNAL_NAME "usbport"
#define REACTOS_STR_ORIGINAL_FILENAME "usbport.sys"
#include <reactos/version.rc>

View file

@ -0,0 +1,2 @@
@ stdcall USBPORT_GetHciMn()
@ stdcall USBPORT_RegisterUSBPortDriver(ptr long ptr)

View file

@ -0,0 +1,653 @@
#ifndef USBMPORT_H__
#define USBMPORT_H__
#define USBPORT_HCI_MN 0x10000001
/* Tranfer types */
#define USBPORT_TRANSFER_TYPE_ISOCHRONOUS 0
#define USBPORT_TRANSFER_TYPE_CONTROL 1
#define USBPORT_TRANSFER_TYPE_BULK 2
#define USBPORT_TRANSFER_TYPE_INTERRUPT 3
/* Endpoint states */
#define USBPORT_ENDPOINT_UNKNOWN 0
#define USBPORT_ENDPOINT_PAUSED 2
#define USBPORT_ENDPOINT_ACTIVE 3
#define USBPORT_ENDPOINT_REMOVE 4
#define USBPORT_ENDPOINT_CLOSED 5
/* Endpoint status */
#define USBPORT_ENDPOINT_RUN 0
#define USBPORT_ENDPOINT_HALT 1
#define USBPORT_ENDPOINT_CONTROL 4
/* Types of resources. For USBPORT_RESOURCES::ResourcesTypes */
#define USBPORT_RESOURCES_PORT 1
#define USBPORT_RESOURCES_INTERRUPT 2
#define USBPORT_RESOURCES_MEMORY 4
typedef struct _USBPORT_RESOURCES {
ULONG ResourcesTypes;
ULONG HcFlavor;
ULONG InterruptVector;
KIRQL InterruptLevel;
UCHAR Padded1[3];
KAFFINITY InterruptAffinity;
BOOLEAN ShareVector;
UCHAR Padded2[3];
KINTERRUPT_MODE InterruptMode;
ULONG Reserved;
PVOID ResourceBase;
SIZE_T IoSpaceLength;
PVOID StartVA;
PVOID StartPA;
UCHAR LegacySupport;
BOOLEAN IsChirpHandled;
UCHAR Reserved2;
UCHAR Reserved3;
} USBPORT_RESOURCES, *PUSBPORT_RESOURCES;
C_ASSERT(sizeof(USBPORT_RESOURCES) == 52);
typedef ULONG MPSTATUS; // Miniport status
typedef ULONG RHSTATUS; // Roothub status
#define MP_STATUS_SUCCESS 0
#define MP_STATUS_FAILURE 1
#define MP_STATUS_NO_RESOURCES 2
#define MP_STATUS_NO_BANDWIDTH 3
#define MP_STATUS_ERROR 4
#define MP_STATUS_RESERVED1 5
#define MP_STATUS_NOT_SUPPORTED 6
#define MP_STATUS_HW_ERROR 7
#define MP_STATUS_UNSUCCESSFUL 8
#define RH_STATUS_SUCCESS 0
#define RH_STATUS_NO_CHANGES 1
#define RH_STATUS_UNSUCCESSFUL 2
typedef USB_20_PORT_CHANGE USB_PORT_STATUS_CHANGE;
typedef union _USBHUB_PORT_STATUS {
struct {
USB_PORT_STATUS UsbPortStatus;
USB_PORT_STATUS_CHANGE UsbPortStatusChange;
};
ULONG AsULONG;
} USBHUB_PORT_STATUS, *PUSBHUB_PORT_STATUS;
/* Hub status & hub status change bits.
See USB 2.0 spec Table 11-19 and Table 11-20. */
#define HUB_STATUS_CHANGE_LOCAL_POWER 0x00010000
#define HUB_STATUS_CHANGE_OVERCURRENT 0x00020000
/* Additional USB Class Codes from USB.org */
#define USBC_DEVICE_CLASS_AUDIO_VIDEO 0x10
#define USBC_DEVICE_CLASS_BILLBOARD 0x11
#define USBC_DEVICE_CLASS_TYPE_C_BRIDGE 0x12
/* Miniport functions */
typedef MPSTATUS
(NTAPI *PHCI_OPEN_ENDPOINT)(
PVOID,
PVOID,
PVOID);
typedef MPSTATUS
(NTAPI *PHCI_REOPEN_ENDPOINT)(
PVOID,
PVOID,
PVOID);
typedef VOID
(NTAPI *PHCI_QUERY_ENDPOINT_REQUIREMENTS)(
PVOID,
PVOID,
PULONG);
typedef VOID
(NTAPI *PHCI_CLOSE_ENDPOINT)(
PVOID,
PVOID,
BOOLEAN);
typedef MPSTATUS
(NTAPI *PHCI_START_CONTROLLER)(
PVOID,
PUSBPORT_RESOURCES);
typedef VOID
(NTAPI *PHCI_STOP_CONTROLLER)(
PVOID,
BOOLEAN);
typedef VOID
(NTAPI *PHCI_SUSPEND_CONTROLLER)(PVOID);
typedef MPSTATUS
(NTAPI *PHCI_RESUME_CONTROLLER)(PVOID);
typedef BOOLEAN
(NTAPI *PHCI_INTERRUPT_SERVICE)(PVOID);
typedef VOID
(NTAPI *PHCI_INTERRUPT_DPC)(
PVOID,
BOOLEAN);
typedef MPSTATUS
(NTAPI *PHCI_SUBMIT_TRANSFER)(
PVOID,
PVOID,
PVOID,
PVOID,
PVOID);
typedef MPSTATUS
(NTAPI *PHCI_SUBMIT_ISO_TRANSFER)(
PVOID,
PVOID,
PVOID,
PVOID,
PVOID);
typedef VOID
(NTAPI *PHCI_ABORT_TRANSFER)(
PVOID,
PVOID,
PVOID,
PULONG);
typedef ULONG
(NTAPI *PHCI_GET_ENDPOINT_STATE)(
PVOID,
PVOID);
typedef VOID
(NTAPI *PHCI_SET_ENDPOINT_STATE)(
PVOID,
PVOID,
ULONG);
typedef VOID
(NTAPI *PHCI_POLL_ENDPOINT)(
PVOID,
PVOID);
typedef VOID
(NTAPI *PHCI_CHECK_CONTROLLER)(PVOID);
typedef ULONG
(NTAPI *PHCI_GET_32BIT_FRAME_NUMBER)(PVOID);
typedef VOID
(NTAPI *PHCI_INTERRUPT_NEXT_SOF)(PVOID);
typedef VOID
(NTAPI *PHCI_ENABLE_INTERRUPTS)(PVOID);
typedef VOID
(NTAPI *PHCI_DISABLE_INTERRUPTS)(PVOID);
typedef VOID
(NTAPI *PHCI_POLL_CONTROLLER)(PVOID);
typedef VOID
(NTAPI *PHCI_SET_ENDPOINT_DATA_TOGGLE)(
PVOID,
PVOID,
ULONG);
typedef ULONG
(NTAPI *PHCI_GET_ENDPOINT_STATUS)(
PVOID,
PVOID);
typedef VOID
(NTAPI *PHCI_SET_ENDPOINT_STATUS)(
PVOID,
PVOID,
ULONG);
typedef VOID
(NTAPI *PHCI_RESET_CONTROLLER)(PVOID);
/* Roothub functions */
typedef VOID
(NTAPI *PHCI_RH_GET_ROOT_HUB_DATA)(
PVOID,
PVOID);
typedef MPSTATUS
(NTAPI *PHCI_RH_GET_STATUS)(
PVOID,
PUSHORT);
typedef MPSTATUS
(NTAPI *PHCI_RH_GET_PORT_STATUS)(
PVOID,
USHORT,
PUSBHUB_PORT_STATUS);
typedef MPSTATUS
(NTAPI *PHCI_RH_GET_HUB_STATUS)(
PVOID,
PUSB_HUB_STATUS);
typedef MPSTATUS
(NTAPI *PHCI_RH_SET_FEATURE_PORT_RESET)(
PVOID,
USHORT);
typedef MPSTATUS
(NTAPI *PHCI_RH_SET_FEATURE_PORT_POWER)(
PVOID,
USHORT);
typedef MPSTATUS
(NTAPI *PHCI_RH_SET_FEATURE_PORT_ENABLE)(
PVOID,
USHORT);
typedef MPSTATUS
(NTAPI *PHCI_RH_SET_FEATURE_PORT_SUSPEND)(
PVOID,
USHORT);
typedef MPSTATUS
(NTAPI *PHCI_RH_CLEAR_FEATURE_PORT_ENABLE)(
PVOID,
USHORT);
typedef MPSTATUS
(NTAPI *PHCI_RH_CLEAR_FEATURE_PORT_POWER)(
PVOID,
USHORT);
typedef MPSTATUS
(NTAPI *PHCI_RH_CLEAR_FEATURE_PORT_SUSPEND)(
PVOID,
USHORT);
typedef MPSTATUS
(NTAPI *PHCI_RH_CLEAR_FEATURE_PORT_ENABLE_CHANGE)(
PVOID,
USHORT);
typedef MPSTATUS
(NTAPI *PHCI_RH_CLEAR_FEATURE_PORT_CONNECT_CHANGE)(
PVOID,
USHORT);
typedef MPSTATUS
(NTAPI *PHCI_RH_CLEAR_FEATURE_PORT_RESET_CHANGE)(
PVOID,
USHORT);
typedef MPSTATUS
(NTAPI *PHCI_RH_CLEAR_FEATURE_PORT_SUSPEND_CHANGE)(
PVOID,
USHORT);
typedef MPSTATUS
(NTAPI *PHCI_RH_CLEAR_FEATURE_PORT_OVERCURRENT_CHANGE)(
PVOID,
USHORT);
typedef VOID
(NTAPI *PHCI_RH_DISABLE_IRQ)(PVOID);
typedef VOID
(NTAPI *PHCI_RH_ENABLE_IRQ)(PVOID);
/* Miniport ioctl functions */
typedef MPSTATUS
(NTAPI *PHCI_START_SEND_ONE_PACKET)(
PVOID,
PVOID,
PVOID,
PULONG,
PVOID,
PVOID,
ULONG,
USBD_STATUS *);
typedef MPSTATUS
(NTAPI *PHCI_END_SEND_ONE_PACKET)(
PVOID,
PVOID,
PVOID,
PULONG,
PVOID,
PVOID,
ULONG,
USBD_STATUS *);
typedef MPSTATUS
(NTAPI *PHCI_PASS_THRU)(
PVOID,
PVOID,
ULONG,
PVOID);
/* Port functions */
typedef ULONG
(NTAPI *PUSBPORT_DBG_PRINT)(
PVOID,
ULONG,
PCH,
...);
typedef ULONG
(NTAPI *PUSBPORT_TEST_DEBUG_BREAK)(PVOID);
typedef ULONG
(NTAPI *PUSBPORT_ASSERT_FAILURE)(
PVOID,
PVOID,
PVOID,
ULONG,
PCHAR);
typedef MPSTATUS
(NTAPI *PUSBPORT_GET_MINIPORT_REGISTRY_KEY_VALUE)(
PVOID,
BOOL,
PCWSTR,
SIZE_T,
PVOID,
SIZE_T);
typedef ULONG
(NTAPI *PUSBPORT_INVALIDATE_ROOT_HUB)(PVOID);
typedef ULONG
(NTAPI *PUSBPORT_INVALIDATE_ENDPOINT)(
PVOID,
PVOID);
typedef ULONG
(NTAPI *PUSBPORT_COMPLETE_TRANSFER)(
PVOID,
PVOID,
PVOID,
USBD_STATUS,
SIZE_T);
typedef ULONG
(NTAPI *PUSBPORT_COMPLETE_ISO_TRANSFER)(
PVOID,
PVOID,
PVOID,
ULONG);
typedef ULONG
(NTAPI *PUSBPORT_LOG_ENTRY)(
PVOID,
ULONG,
ULONG,
ULONG,
ULONG,
ULONG);
typedef PVOID
(NTAPI *PUSBPORT_GET_MAPPED_VIRTUAL_ADDRESS)(
PVOID,
PVOID,
PVOID);
typedef VOID
(NTAPI ASYNC_TIMER_CALLBACK)(
IN PVOID MiniportExtension,
IN PVOID CallBackContext);
typedef ULONG
(NTAPI *PUSBPORT_REQUEST_ASYNC_CALLBACK)(
PVOID,
ULONG,
PVOID,
SIZE_T,
ASYNC_TIMER_CALLBACK *);
typedef MPSTATUS
(NTAPI *PUSBPORT_READ_WRITE_CONFIG_SPACE)(
PVOID,
BOOLEAN,
PVOID,
ULONG,
ULONG);
typedef NTSTATUS
(NTAPI *PUSBPORT_WAIT)(
PVOID,
ULONG);
typedef ULONG
(NTAPI *PUSBPORT_INVALIDATE_CONTROLLER)(
PVOID,
ULONG);
typedef VOID
(NTAPI *PUSBPORT_BUG_CHECK)(PVOID);
typedef ULONG
(NTAPI *PUSBPORT_NOTIFY_DOUBLE_BUFFER)(
PVOID,
PVOID,
PVOID,
SIZE_T);
/* Miniport functions */
typedef VOID
(NTAPI *PHCI_REBALANCE_ENDPOINT)(
PVOID,
PVOID,
PVOID);
typedef VOID
(NTAPI *PHCI_FLUSH_INTERRUPTS)(PVOID);
typedef MPSTATUS
(NTAPI *PHCI_RH_CHIRP_ROOT_PORT)(
PVOID,
USHORT);
typedef VOID
(NTAPI *PHCI_TAKE_PORT_CONTROL)(PVOID);
#define USB_MINIPORT_VERSION_OHCI 0x01
#define USB_MINIPORT_VERSION_UHCI 0x02
#define USB_MINIPORT_VERSION_EHCI 0x03
#define USB_MINIPORT_FLAGS_INTERRUPT 0x0001
#define USB_MINIPORT_FLAGS_PORT_IO 0x0002
#define USB_MINIPORT_FLAGS_MEMORY_IO 0x0004
#define USB_MINIPORT_FLAGS_USB2 0x0010
#define USB_MINIPORT_FLAGS_DISABLE_SS 0x0020
#define USB_MINIPORT_FLAGS_NOT_LOCK_INT 0x0040
#define USB_MINIPORT_FLAGS_POLLING 0x0080
#define USB_MINIPORT_FLAGS_NO_DMA 0x0100
#define USB_MINIPORT_FLAGS_WAKE_SUPPORT 0x0200
typedef struct _USBPORT_REGISTRATION_PACKET {
ULONG MiniPortVersion;
ULONG MiniPortFlags;
ULONG MiniPortBusBandwidth;
ULONG Reserved1;
SIZE_T MiniPortExtensionSize;
SIZE_T MiniPortEndpointSize;
SIZE_T MiniPortTransferSize;
ULONG Reserved2;
ULONG Reserved3;
SIZE_T MiniPortResourcesSize;
/* Miniport */
PHCI_OPEN_ENDPOINT OpenEndpoint;
PHCI_REOPEN_ENDPOINT ReopenEndpoint;
PHCI_QUERY_ENDPOINT_REQUIREMENTS QueryEndpointRequirements;
PHCI_CLOSE_ENDPOINT CloseEndpoint;
PHCI_START_CONTROLLER StartController;
PHCI_STOP_CONTROLLER StopController;
PHCI_SUSPEND_CONTROLLER SuspendController;
PHCI_RESUME_CONTROLLER ResumeController;
PHCI_INTERRUPT_SERVICE InterruptService;
PHCI_INTERRUPT_DPC InterruptDpc;
PHCI_SUBMIT_TRANSFER SubmitTransfer;
PHCI_SUBMIT_ISO_TRANSFER SubmitIsoTransfer;
PHCI_ABORT_TRANSFER AbortTransfer;
PHCI_GET_ENDPOINT_STATE GetEndpointState;
PHCI_SET_ENDPOINT_STATE SetEndpointState;
PHCI_POLL_ENDPOINT PollEndpoint;
PHCI_CHECK_CONTROLLER CheckController;
PHCI_GET_32BIT_FRAME_NUMBER Get32BitFrameNumber;
PHCI_INTERRUPT_NEXT_SOF InterruptNextSOF;
PHCI_ENABLE_INTERRUPTS EnableInterrupts;
PHCI_DISABLE_INTERRUPTS DisableInterrupts;
PHCI_POLL_CONTROLLER PollController;
PHCI_SET_ENDPOINT_DATA_TOGGLE SetEndpointDataToggle;
PHCI_GET_ENDPOINT_STATUS GetEndpointStatus;
PHCI_SET_ENDPOINT_STATUS SetEndpointStatus;
PHCI_RESET_CONTROLLER ResetController;
/* Roothub */
PHCI_RH_GET_ROOT_HUB_DATA RH_GetRootHubData;
PHCI_RH_GET_STATUS RH_GetStatus;
PHCI_RH_GET_PORT_STATUS RH_GetPortStatus;
PHCI_RH_GET_HUB_STATUS RH_GetHubStatus;
PHCI_RH_SET_FEATURE_PORT_RESET RH_SetFeaturePortReset;
PHCI_RH_SET_FEATURE_PORT_POWER RH_SetFeaturePortPower;
PHCI_RH_SET_FEATURE_PORT_ENABLE RH_SetFeaturePortEnable;
PHCI_RH_SET_FEATURE_PORT_SUSPEND RH_SetFeaturePortSuspend;
PHCI_RH_CLEAR_FEATURE_PORT_ENABLE RH_ClearFeaturePortEnable;
PHCI_RH_CLEAR_FEATURE_PORT_POWER RH_ClearFeaturePortPower;
PHCI_RH_CLEAR_FEATURE_PORT_SUSPEND RH_ClearFeaturePortSuspend;
PHCI_RH_CLEAR_FEATURE_PORT_ENABLE_CHANGE RH_ClearFeaturePortEnableChange;
PHCI_RH_CLEAR_FEATURE_PORT_CONNECT_CHANGE RH_ClearFeaturePortConnectChange;
PHCI_RH_CLEAR_FEATURE_PORT_RESET_CHANGE RH_ClearFeaturePortResetChange;
PHCI_RH_CLEAR_FEATURE_PORT_SUSPEND_CHANGE RH_ClearFeaturePortSuspendChange;
PHCI_RH_CLEAR_FEATURE_PORT_OVERCURRENT_CHANGE RH_ClearFeaturePortOvercurrentChange;
PHCI_RH_DISABLE_IRQ RH_DisableIrq;
PHCI_RH_ENABLE_IRQ RH_EnableIrq;
/* Miniport ioctl */
PHCI_START_SEND_ONE_PACKET StartSendOnePacket;
PHCI_END_SEND_ONE_PACKET EndSendOnePacket;
PHCI_PASS_THRU PassThru;
/* Port */
PUSBPORT_DBG_PRINT UsbPortDbgPrint;
PUSBPORT_TEST_DEBUG_BREAK UsbPortTestDebugBreak;
PUSBPORT_ASSERT_FAILURE UsbPortAssertFailure;
PUSBPORT_GET_MINIPORT_REGISTRY_KEY_VALUE UsbPortGetMiniportRegistryKeyValue;
PUSBPORT_INVALIDATE_ROOT_HUB UsbPortInvalidateRootHub;
PUSBPORT_INVALIDATE_ENDPOINT UsbPortInvalidateEndpoint;
PUSBPORT_COMPLETE_TRANSFER UsbPortCompleteTransfer;
PUSBPORT_COMPLETE_ISO_TRANSFER UsbPortCompleteIsoTransfer;
PUSBPORT_LOG_ENTRY UsbPortLogEntry;
PUSBPORT_GET_MAPPED_VIRTUAL_ADDRESS UsbPortGetMappedVirtualAddress;
PUSBPORT_REQUEST_ASYNC_CALLBACK UsbPortRequestAsyncCallback;
PUSBPORT_READ_WRITE_CONFIG_SPACE UsbPortReadWriteConfigSpace;
PUSBPORT_WAIT UsbPortWait;
PUSBPORT_INVALIDATE_CONTROLLER UsbPortInvalidateController;
PUSBPORT_BUG_CHECK UsbPortBugCheck;
PUSBPORT_NOTIFY_DOUBLE_BUFFER UsbPortNotifyDoubleBuffer;
/* Miniport */
PHCI_REBALANCE_ENDPOINT RebalanceEndpoint;
PHCI_FLUSH_INTERRUPTS FlushInterrupts;
PHCI_RH_CHIRP_ROOT_PORT RH_ChirpRootPort;
PHCI_TAKE_PORT_CONTROL TakePortControl;
ULONG Reserved4;
ULONG Reserved5;
} USBPORT_REGISTRATION_PACKET, *PUSBPORT_REGISTRATION_PACKET;
typedef struct _USBPORT_MINIPORT_INTERFACE {
PDRIVER_OBJECT DriverObject;
LIST_ENTRY DriverLink;
PDRIVER_UNLOAD DriverUnload;
ULONG Version;
USBPORT_REGISTRATION_PACKET Packet;
} USBPORT_MINIPORT_INTERFACE, *PUSBPORT_MINIPORT_INTERFACE;
C_ASSERT(sizeof(USBPORT_MINIPORT_INTERFACE) == 336);
typedef struct _USBPORT_ENDPOINT_PROPERTIES {
USHORT DeviceAddress;
USHORT EndpointAddress;
USHORT TotalMaxPacketSize; // TransactionPerMicroframe * MaxPacketSize
UCHAR Period;
UCHAR Reserved1;
USB_DEVICE_SPEED DeviceSpeed;
ULONG UsbBandwidth;
ULONG ScheduleOffset;
ULONG TransferType;
ULONG Direction;
ULONG_PTR BufferVA;
ULONG_PTR BufferPA;
ULONG BufferLength;
ULONG Reserved3;
ULONG MaxTransferSize;
USHORT HubAddr;
USHORT PortNumber;
UCHAR InterruptScheduleMask;
UCHAR SplitCompletionMask;
UCHAR TransactionPerMicroframe; // 1 + additional transactions. Total: from 1 to 3)
UCHAR Reserved4;
ULONG MaxPacketSize;
ULONG Reserved6;
} USBPORT_ENDPOINT_PROPERTIES, *PUSBPORT_ENDPOINT_PROPERTIES;
C_ASSERT(sizeof(USBPORT_ENDPOINT_PROPERTIES) == 64);
typedef struct _USBPORT_SCATTER_GATHER_ELEMENT {
PHYSICAL_ADDRESS SgPhysicalAddress;
ULONG Reserved1;
ULONG SgTransferLength;
ULONG SgOffset;
ULONG Reserved2;
} USBPORT_SCATTER_GATHER_ELEMENT, *PUSBPORT_SCATTER_GATHER_ELEMENT;
C_ASSERT(sizeof(USBPORT_SCATTER_GATHER_ELEMENT) == 24);
typedef struct _USBPORT_SCATTER_GATHER_LIST {
ULONG Flags;
ULONG_PTR CurrentVa;
PVOID MappedSystemVa;
ULONG SgElementCount;
USBPORT_SCATTER_GATHER_ELEMENT SgElement[1];
} USBPORT_SCATTER_GATHER_LIST, *PUSBPORT_SCATTER_GATHER_LIST;
C_ASSERT(sizeof(USBPORT_SCATTER_GATHER_LIST) == 40);
typedef struct _USBPORT_TRANSFER_PARAMETERS {
ULONG TransferFlags;
ULONG TransferBufferLength;
ULONG TransferCounter;
ULONG Reserved1;
ULONG Reserved2;
USB_DEFAULT_PIPE_SETUP_PACKET SetupPacket;
} USBPORT_TRANSFER_PARAMETERS, *PUSBPORT_TRANSFER_PARAMETERS;
C_ASSERT(sizeof(USBPORT_TRANSFER_PARAMETERS) == 28);
typedef struct _USBPORT_ROOT_HUB_DATA {
ULONG NumberOfPorts;
ULONG HubCharacteristics;
ULONG PowerOnToPowerGood;
ULONG HubControlCurrent;
} USBPORT_ROOT_HUB_DATA, *PUSBPORT_ROOT_HUB_DATA;
C_ASSERT(sizeof(USBPORT_ROOT_HUB_DATA) == 16);
ULONG
NTAPI
USBPORT_GetHciMn(VOID);
NTSTATUS
NTAPI
USBPORT_RegisterUSBPortDriver(
IN PDRIVER_OBJECT DriverObject,
IN ULONG Version,
IN PUSBPORT_REGISTRATION_PACKET RegistrationPacket);
#endif /* USBMPORT_H__ */