13#define UCX_MAX_SELECT_PIPES 32
14#define UCX_MAX_SELECT_INTERFACES 255
17#define UCX_FAKE_TOTAL_BANDWIDTH 4000000
20#define UCX_UHCI_OPTION_FLAGS 0x000002C3
21#define UCX_EHCI_OPTION_FLAGS 0x00080A95
44 if (HcdCapabilities !=
NULL)
47 if (VersionInformation !=
NULL)
50 VersionInformation->Supported_USB_Version = Slow ? 0x0110 : 0x0200;
61 if (CurrentFrame ==
NULL)
63 DPRINT1(
"QueryBusTime called without a frame pointer\n");
79 DPRINT1(
"SubmitIsoOutUrb is not supported, URB %p\n",
Urb);
102 DPRINT1(
"Bus information query with HCD bandwidth tracking is not supported\n");
125 DPRINT1(
"Bus information level %lu is not supported\n",
Level);
192 if (CurrentMicroFrame ==
NULL)
194 DPRINT1(
"QueryBusTimeEx called without a microframe pointer\n");
200 DPRINT(
"QueryBusTimeEx is not supported for low or full speed device %p\n",
Context);
204 *CurrentMicroFrame = 0;
226 if (HcdiOptionFlags !=
NULL)
228 if (PciVendorId !=
NULL)
234 if (PciSubClass !=
NULL)
236 if (PciRevisionId !=
NULL)
239 *PciProgIf = Slow ? 0x00 : 0x20;
266 : (UCXUSBDEVICE)UcxGetRootHubPdoContext(
Device)->RootHub->m_Handle;
325 DPRINT1(
"USBDI interface query size %u version %u failed 0x%lx, served version %u\n",
326 RequestedSize, RequestedVersion,
Status, FilledVersion);
340 _In_ USBD_CLIENT_HANDLE ClientHandle);
346 _In_ USBD_CLIENT_HANDLE ClientHandle,
353 _In_ USBD_CLIENT_HANDLE ClientHandle,
361 _In_ USBD_CLIENT_HANDLE ClientHandle,
370 _In_ USBD_CLIENT_HANDLE ClientHandle,
385 _In_ USBD_CLIENT_HANDLE ClientHandle,
405 _In_ USBD_CLIENT_HANDLE ClientHandle,
434 if (
Handle->m_VerifierEnabled)
440 if (
Interface->Header.Size >=
sizeof(*Extended))
444 if (
Handle->m_VerifierEnabled)
447 Size =
sizeof(*Extended);
477UcxUsbdHandle::CreateFromQuery(
492 DPRINT1(
"USBD client interface size %u, expected at least %u\n",
499 DPRINT1(
"USBD client interface version %u is not supported\n",
Interface->Header.Version);
505 DPRINT1(
"USBD client registration with device object %p, tag 0x%lx\n",
540 Handle->m_VerifierFailRegistration =
Interface->VerifierFailRegistration;
541 Handle->m_VerifierFailChainedMdl =
Interface->VerifierFailChainedMdlSupport;
542 Handle->m_VerifierFailStaticStreamSupport =
Interface->VerifierFailStaticStreamSupport;
543 Handle->m_VerifierStaticStreamCountOverride =
Interface->VerifierStaticStreamCountOverride;
544 Handle->m_VerifierFailEnableStaticStreams =
Interface->VerifierFailEnableStaticStreams;
547 Handle->m_TrackXrbs =
Handle->m_VerifierEnabled ||
Device->m_Controller->m_DriverVerifierEnabled;
550 if (
Handle->m_VerifierEnabled)
551 Device->TrackStaleHandles();
555 DPRINT1(
"Verifier failed USBD client registration for device %p\n",
Device);
618 BOOLEAN Verifying =
Device->m_Controller->m_DriverVerifierEnabled;
630 if (Verifying ||
Handle->m_VerifierEnabled)
682 DPRINT1(
"XRB allocation of %lu bytes for handle %p failed 0x%lx\n",
Size,
this,
Status);
710 WDFMEMORY
Memory = Xrb->Memory;
712 WDFMEMORY HandleMemory =
Handle->m_Memory;
715 if (!
Handle->m_Unregistered)
738 _In_ USBD_CLIENT_HANDLE ClientHandle,
774 _In_ USBD_CLIENT_HANDLE ClientHandle,
808 Info->NumberOfPipes = Pipes;
822 _In_ USBD_CLIENT_HANDLE ClientHandle,
833 ULONG Interfaces = 0;
847 Pipes +=
Entry->InterfaceDescriptor->bNumEndpoints;
850 DPRINT1(
"Select config for handle %p has too many pipes\n",
Handle);
856 DPRINT1(
"Select config entry %p for handle %p already has an interface\n",
Entry,
Handle);
864 DPRINT1(
"Select config for handle %p has too many interfaces\n",
Handle);
881 Info = &
Urb->UrbSelectConfiguration.Interface;
886 ULONG EntryPipes =
Entry->InterfaceDescriptor->bNumEndpoints;
890 DPRINT1(
"Interface descriptor %p grew while building select config\n",
Entry->InterfaceDescriptor);
913 _In_ USBD_CLIENT_HANDLE ClientHandle,
928 if (InterfaceEntry->InterfaceDescriptor ==
NULL || InterfaceEntry->Interface !=
NULL)
930 DPRINT1(
"Select interface entry %p for handle %p is malformed\n", InterfaceEntry,
Handle);
934 Pipes = InterfaceEntry->InterfaceDescriptor->bNumEndpoints;
937 DPRINT1(
"Select interface for handle %p has %lu pipes\n",
Handle, Pipes);
949 Info = &
Urb->UrbSelectInterface.Interface;
951 InterfaceEntry->Interface =
Info;
973 DPRINT1(
"Freeing corrupted XRB for URB %p\n",
Urb);
983 DPRINT1(
"Freeing URB %p while it is still active\n",
Urb);
1012 _In_ USBD_CLIENT_HANDLE ClientHandle)
#define InterlockedIncrement
#define InterlockedDecrement
DECLSPEC_NORETURN VOID NTAPI KeBugCheckEx(IN ULONG BugCheckCode, IN ULONG_PTR BugCheckParameter1, IN ULONG_PTR BugCheckParameter2, IN ULONG_PTR BugCheckParameter3, IN ULONG_PTR BugCheckParameter4)
LONG m_UsbdInterfaceCount
NTSTATUS GetCurrentFrameNumber(_Out_ PULONG FrameNumber)
UcxController * m_Controller
KSPIN_LOCK m_UsbdHandleLock
NTSTATUS AllocateXrb(_In_ ULONG Size, _In_ ULONG Type, _Outptr_ UcxXrbPreamble **Xrb)
UcxController * m_Controller
static UcxUsbdHandle * FromClientHandle(_In_ USBD_CLIENT_HANDLE Handle)
PDEVICE_OBJECT m_ClientDeviceObject
_In_ UcxUsbDevice * Device
VOID TrackXrb(_In_ UcxXrbPreamble *Xrb)
static NTSTATUS USB_BUSIFFN UcxBusEnumLogEntry(_In_ PVOID Context, _In_ ULONG DriverTag, _In_ ULONG EnumTag, _In_ ULONG P1, _In_ ULONG P2)
static NTSTATUS USB_BUSIFFN UcxBusQueryBusInformation(_In_ PVOID Context, _In_ ULONG Level, _Inout_ PVOID Buffer, _Out_ PULONG BufferLength, _Out_opt_ PULONG ActualLength)
static NTSTATUS USB_BUSIFFN UcxBusQueryBusTimeEx(_In_opt_ PVOID Context, _Out_opt_ PULONG CurrentMicroFrame)
static NTSTATUS NTAPI UcxClientOffloadSelectXrbAllocate(_In_ USBD_CLIENT_HANDLE ClientHandle, _In_ USBD_CONFIGURATION_HANDLE ConfigurationHandle, _Inout_ PUSBD_INTERFACE_LIST_ENTRY InterfaceEntry, _In_ ULONG OffloadedEndpoints, _Outptr_ PURB *Urb)
static NTSTATUS NTAPI UcxClientOffloadNotifyXrbAllocate(_In_ USBD_CLIENT_HANDLE ClientHandle, _In_ USBD_PIPE_HANDLE PipeHandle, _In_ ULONG Flags, _Outptr_ PURB *Urb)
BOOLEAN NTAPI UcxAnyUsbdHandleHasVerifier(_In_ UcxUsbDevice *Device)
VOID NTAPI UcxDropLeakedUsbdHandles(_In_ UcxUsbDevice *Device)
static NTSTATUS NTAPI UcxClientSelectConfigXrbBuild(_In_ USBD_CLIENT_HANDLE ClientHandle, _In_ PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, _In_ PUSBD_INTERFACE_LIST_ENTRY InterfaceList, _Outptr_ PURB *UrbOut)
static VOID USB_BUSIFFN UcxBusGetUsbdiVersion(_In_ PVOID Context, _Out_opt_ PUSBD_VERSION_INFORMATION VersionInformation, _Out_opt_ PULONG HcdCapabilities)
#define UCX_MAX_SELECT_INTERFACES
#define UCX_UHCI_OPTION_FLAGS
static NTSTATUS USB_BUSIFFN UcxBusQueryControllerType(_In_opt_ PVOID Context, _Out_opt_ PULONG HcdiOptionFlags, _Out_opt_ PUSHORT PciVendorId, _Out_opt_ PUSHORT PciDeviceId, _Out_opt_ PUCHAR PciClass, _Out_opt_ PUCHAR PciSubClass, _Out_opt_ PUCHAR PciRevisionId, _Out_opt_ PUCHAR PciProgIf)
#define UCX_FAKE_TOTAL_BANDWIDTH
static NTSTATUS NTAPI UcxClientAllocUrb(_In_ USBD_CLIENT_HANDLE ClientHandle, _Outptr_ PURB *Urb)
static VOID NTAPI UcxClientReleaseUrb(_In_ PURB Urb)
static NTSTATUS NTAPI UcxClientAllocIsochUrb(_In_ USBD_CLIENT_HANDLE ClientHandle, _In_ ULONG NumberOfIsochPackets, _Outptr_ PURB *Urb)
static VOID NTAPI UcxClientUnregister(_In_ USBD_CLIENT_HANDLE ClientHandle)
static NTSTATUS USB_BUSIFFN UcxBusSubmitIsoOutUrb(_In_ PVOID Context, _In_ PURB Urb)
static NTSTATUS NTAPI UcxClientSelectInterfaceXrbBuild(_In_ USBD_CLIENT_HANDLE ClientHandle, _In_ USBD_CONFIGURATION_HANDLE ConfigurationHandle, _In_ PUSBD_INTERFACE_LIST_ENTRY InterfaceEntry, _Outptr_ PURB *UrbOut)
static NTSTATUS USB_BUSIFFN UcxBusQueryBusTime(_In_ PVOID Context, _Out_opt_ PULONG CurrentFrame)
#define UCX_MAX_SELECT_PIPES
static VOID NTAPI UcxDeleteXrbMemory(_In_ UcxXrbPreamble *Xrb)
static BOOLEAN USB_BUSIFFN UcxBusIsDeviceHighSpeed(_In_opt_ PVOID Context)
static BOOLEAN NTAPI UcxIsLowOrFullSpeed(_In_ UcxUsbDevice *Device)
#define UCX_EHCI_OPTION_FLAGS
static VOID NTAPI UcxFillClientInterface603(_Inout_ UcxUsbdHandle *Handle, _Inout_ PUSBD_CLIENT_INTERFACE Interface)
static VOID NTAPI UcxFillInterfaceInformation(_Out_ PUSBD_INTERFACE_INFORMATION Info, _In_ PUSB_INTERFACE_DESCRIPTOR Descriptor, _In_ ULONG Pipes)
#define UCX_USBDI_VERSION
FORCEINLINE PURB NTAPI UcxUrbFromXrb(_In_ UcxXrbPreamble *Xrb)
#define UCX_XRB_SIGNATURE
#define UCX_XRB_KIND_PLAIN
FORCEINLINE UcxXrbPreamble *NTAPI UcxXrbFromUrb(_In_ PURB Urb)
#define UCX_XRB_KIND_ISO_PACKETS
#define UCX_USB3_ACTIVE_URB_REUSED
#define UCX_XRB_KIND_CONFIG
#define UCX_USB3_HANDLE_LEAKED
#define UCX_BUGCHECK_USB3
#define UCX_USB3_XRB_CORRUPTED
#define UCX_XRB_KIND_ALT_SETTING
#define STATUS_NOT_SUPPORTED
_In_ ULONG _In_ UCHAR Level
_In_ D3DDDI_VIDEO_PRESENT_TARGET_ID _In_ ULONG _In_ ULONG Flags
#define NT_SUCCESS(StatCode)
#define _IRQL_requires_(irql)
#define RemoveEntryList(Entry)
#define InsertTailList(ListHead, Entry)
#define InitializeListHead(ListHead)
#define KeInitializeSpinLock(sl)
_In_ UCXUSBDEVICE UsbDevice
VOID NTAPI UcxInterfaceNoOp(_In_ PVOID Context)
_Must_inspect_result_ _In_ PUCXHUB_DEVICE_CREATE_INFO _Out_ UCXUSBDEVICE * Device
_In_ PIRP _In_ PIO_COMPLETION_ROUTINE _In_ PVOID Context
_Must_inspect_result_ _Out_ PNDIS_STATUS _Out_ PNDIS_HANDLE ConfigurationHandle
#define UNREFERENCED_PARAMETER(P)
EVT_WDF_DEVICE_PROCESS_QUERY_INTERFACE_REQUEST UcxEvtQueryUsbdClientInterface
EVT_WDF_DEVICE_PROCESS_QUERY_INTERFACE_REQUEST UcxEvtQueryUsbdiInterface
#define STATUS_BUFFER_TOO_SMALL
#define STATUS_BUFFER_OVERFLOW
struct _LIST_ENTRY * Flink
PFN_USBD_CLIENT_OFFLOAD_SELECT_XRB_ALLOCATE OffloadSelectInterfaceXrbAllocate
ULONG VerifierFailEndpointOffload
PFN_USBD_CLIENT_OFFLOAD_NOTIFY_XRB_ALLOCATE OffloadNotificationXrbAllocate
PFN_USBD_CLIENT_ISOCH_XRB_ALLOCATE SecureIsochXrbAllocate
ULONG VerifierFailSecureTransferSupport
PINTERFACE_REFERENCE InterfaceReference
PUSB_BUSIFFN_SUBMIT_ISO_OUT_URB SubmitIsoOutUrb
PUSB_BUSIFFN_QUERY_CONTROLLER_TYPE QueryControllerType
PUSB_BUSIFFN_QUERY_BUS_TIME QueryBusTime
PINTERFACE_DEREFERENCE InterfaceDereference
PUSB_BUSIFFN_GETUSBDI_VERSION GetUSBDIVersion
PUSB_BUSIFFN_IS_DEVICE_HIGH_SPEED IsDeviceHighSpeed
PUSB_BUSIFFN_QUERY_BUS_TIME_EX QueryBusTimeEx
PUSB_BUSIFFN_QUERY_BUS_INFORMATION QueryBusInformation
PUSB_BUSIFFN_ENUM_LOG_ENTRY EnumLogEntry
#define RtlCopyMemory(Destination, Source, Length)
#define RtlZeroMemory(Destination, Length)
#define CONTAINING_RECORD(address, type, field)
_Must_inspect_result_ _In_ WDFDEVICE _In_ PUCX_CONTROLLER_CONFIG _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ UCXCONTROLLER * Controller
_Must_inspect_result_ _In_ UCXCONTROLLER _In_ PUCX_ROOTHUB_CONFIG _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ UCXROOTHUB * RootHub
_In_ UCXUSBDEVICE _In_ ULONG Interface
BOOLEAN NTAPI UcxVerifierWantsFailure(_In_ ULONG Setting)
NTSTATUS NTAPI UcxRandomErrorStatus(VOID)
FORCEINLINE VOID NTAPI UcxClearListEntry(_Out_ PLIST_ENTRY Entry)
#define STATUS_INVALID_PARAMETER
struct _USBD_INTERFACE_INFORMATION * PUSBD_INTERFACE_INFORMATION
#define URB_FUNCTION_SELECT_INTERFACE
#define URB_FUNCTION_SELECT_CONFIGURATION
struct _USB_BUS_INFORMATION_LEVEL_0 * PUSB_BUS_INFORMATION_LEVEL_0
struct _USB_BUS_INTERFACE_USBDI_V3 * PUSB_BUS_INTERFACE_USBDI_V3
#define USB_BUSIF_USBDI_VERSION_1
struct _USB_BUS_INTERFACE_USBDI_V3 USB_BUS_INTERFACE_USBDI_V3
struct _USB_BUS_INTERFACE_USBDI_V1 USB_BUS_INTERFACE_USBDI_V1
#define USB_BUSIF_USBDI_VERSION_0
struct _USB_BUS_INTERFACE_USBDI_V0 USB_BUS_INTERFACE_USBDI_V0
#define USB_BUSIF_USBDI_VERSION_2
struct _USB_BUS_INFORMATION_LEVEL_1 * PUSB_BUS_INFORMATION_LEVEL_1
#define USB_BUSIF_USBDI_VERSION_3
struct _USB_BUS_INFORMATION_LEVEL_0 USB_BUS_INFORMATION_LEVEL_0
struct _USB_BUS_INFORMATION_LEVEL_1 USB_BUS_INFORMATION_LEVEL_1
struct _USB_BUS_INTERFACE_USBDI_V2 USB_BUS_INTERFACE_USBDI_V2
#define USBD_CLIENT_INTERFACE_VERSION
#define USBD_CLIENT_INTERFACE_VERSION_603
struct _USBD_CLIENT_INTERFACE_603 * PUSBD_CLIENT_INTERFACE_603
#define USBD_CLIENT_INTERFACE_603_SIZE_SECURE
_In_opt_ PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor
#define GET_USBD_INTERFACE_SIZE(numEndpoints)
#define GET_SELECT_INTERFACE_REQUEST_SIZE(totalPipes)
#define USBD_CLIENT_CONTRACT_VERSION_602
_In_ PUSBD_INTERFACE_LIST_ENTRY InterfaceList
#define GET_ISO_URB_SIZE(n)
_In_opt_ PUSB_CONFIGURATION_DESCRIPTOR _Inout_ PUSBD_INTERFACE_LIST_ENTRY _Outptr_ PURB * Urb
WdfStringGetUnicodeString(Original, &Name)
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
_In_ WDFCOLLECTION _In_ ULONG Index
_In_ PWDFDEVICE_INIT _In_ PWDF_OBJECT_ATTRIBUTES RequestAttributes
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG BufferLength
_Must_inspect_result_ _In_ WDFDEVICE _In_ LPCGUID InterfaceType
_Must_inspect_result_ _In_ WDFDEVICE _In_ LPCGUID _Out_ PINTERFACE _In_ USHORT _In_ USHORT Version
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _In_ _Strict_type_match_ POOL_TYPE _In_opt_ ULONG _In_ _Out_ WDFMEMORY * Memory
FORCEINLINE VOID WDF_OBJECT_ATTRIBUTES_INIT(_Out_ PWDF_OBJECT_ATTRIBUTES Attributes)
#define WdfObjectReference(Handle)
#define WdfObjectDereference(Handle)
WDF_EXTERN_C_START typedef _In_ LPGUID _Inout_ PINTERFACE ExposedInterface
WDF_EXTERN_C_START typedef _In_ LPGUID _Inout_ PINTERFACE _Inout_opt_ PVOID ExposedInterfaceSpecificData
_Must_inspect_result_ _In_ WDFIORESLIST _In_ PIO_RESOURCE_DESCRIPTOR Descriptor
_Must_inspect_result_ _In_ WDFUSBDEVICE _In_opt_ PWDF_OBJECT_ATTRIBUTES _In_ ULONG NumberOfIsochPackets
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList
#define PCI_SUBCLASS_SB_USB
#define PCI_CLASS_SERIAL_BUS_CTLR
#define ObDereferenceObject
#define ObReferenceObject