ReactOS 0.4.17-dev-1281-g065abb3
devobj.cpp
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS USB Host Controller Extension
3 * LICENSE: MIT (https://spdx.org/licenses/MIT)
4 * PURPOSE: UCXUSBDEVICE creation, deletion, the device tree and per device services
5 * COPYRIGHT: Copyright 2026 Justin Miller <justin.miller@reactos.org>
6 */
7
8#include "ucx01000.h"
9
10#define NDEBUG
11#include <debug.h>
12
13#define UCX_COMPOSITE_VERSION 0x100
14#define UCX_MAX_COMPOSITE_FUNCTIONS 255
15#define UCX_MAX_FORWARD_PROGRESS_SIZE (512 * 1024)
16
19 _In_ UCXUSBDEVICE Handle)
20{
21 return UcxGetUsbDeviceContext(Handle);
22}
23
24static
28{
30
32 return (ULONG64)Now.QuadPart;
33}
34
35VOID
37{
47}
48
49VOID
51 _In_ UCXROOTHUB Handle,
53{
54 m_Handle = (UCXUSBDEVICE)Handle;
57
58 /* Reported as SuperSpeed for filters that ask the controller about its speed */
59 m_Info.Size = sizeof(m_Info);
61
65}
66
67/* Exports */
68
69/* Newer HCDs pass one more slot than the 1.6 structure; never copy past what we hold */
70VOID
74{
75 RtlZeroMemory(&Init->Callbacks, sizeof(Init->Callbacks));
76 RtlCopyMemory(&Init->Callbacks, Callbacks, min(Callbacks->Size, (ULONG)sizeof(Init->Callbacks)));
77}
78
82 _In_ UCXCONTROLLER Controller,
85 _Out_ UCXUSBDEVICE* UsbDevice)
86{
88 UcxUsbDevice* Parent = FromHandle(Init->ParentHub);
90 WDF_OBJECT_ATTRIBUTES UcxAttributes;
94
95 PAGED_CODE();
96
97 *UsbDevice = NULL;
98
101
102 /* Devices hang off their parent hub so deleting a hub deletes what is below it */
103 if (Attributes != NULL)
104 Attributes->ParentObject = Init->ParentHub;
105 else
106 UcxAttributes.ParentObject = Init->ParentHub;
107
109 Attributes != NULL ? &UcxAttributes : NULL,
110 &Object);
111 if (!NT_SUCCESS(Status))
112 {
113 DPRINT1("UsbDevice object create failed under hub %p 0x%lx\n", Init->ParentHub, Status);
114 return Status;
115 }
116
117 Device = new (UcxGetUsbDeviceContext(Object)) UcxUsbDevice();
118 Device->m_Handle = (UCXUSBDEVICE)Object;
119 Device->m_Controller = ControllerContext;
120 Device->m_ParentHub = Parent;
121 Device->m_HubDeviceContext = Init->HubDeviceContext;
122 Device->m_Info = Init->Info;
123 Device->m_Callbacks = Init->Callbacks;
124 Device->m_Timestamp = UcxSystemTimeNow();
125 Device->InitializeLists();
126
127 /* Keeps the tree intact past WdfObjectDelete for stale endpoints of deleted devices */
128 WdfObjectReference(Parent->m_Handle);
129
130 {
131 SpinLockGuard Guard(&ControllerContext->m_TopologyLock);
132
133 if (Parent->m_Disconnected)
134 {
136 }
137 else
138 {
139 InsertTailList(&Parent->m_ChildList, &Device->m_ChildLink);
140 ControllerContext->m_ChildDeviceCount++;
141
142 /* A tree purge in progress above covers new devices too */
143 Device->m_ChildrenMayLeavePurge = Parent->m_ChildrenMayLeavePurge;
144 Device->m_EndpointsMayLeavePurge = Parent->m_ChildrenMayLeavePurge;
145 }
146 }
147
148 if (!NT_SUCCESS(Status))
149 {
150 DPRINT1("UsbDevice %p not created, parent hub %p is disconnected\n", Object, Parent->m_Handle);
152 return Status;
153 }
154
155 DPRINT("UsbDevice %p created under hub %p\n", Device->m_Handle, Parent->m_Handle);
156
157 *UsbDevice = Device->m_Handle;
158 Init->Created = Device->m_Handle;
159 *InitPointer = NULL;
160 return STATUS_SUCCESS;
161}
162
163VOID
164UcxUsbDevice::EvtDestroy(
166{
167 UcxUsbDevice* Device = UcxGetUsbDeviceContext(Object);
168
169 /* Creation failed before the context was set up */
170 if (Device->m_Handle == NULL)
171 return;
172
173 {
174 SpinLockGuard Guard(&Device->m_Controller->m_TopologyLock);
175
176 if (UcxIsListEntryLinked(&Device->m_ChildLink))
177 {
178 RemoveEntryList(&Device->m_ChildLink);
179 UcxClearListEntry(&Device->m_ChildLink);
180 Device->m_Controller->m_ChildDeviceCount--;
181 }
182 }
183
184 WdfObjectDereference(Device->m_ParentHub->m_Handle);
185}
186
188VOID
191{
193 WDFREQUEST Request;
195 ULONG Index;
196
198
199 if (m_Functions == NULL)
200 {
203 }
204 else
205 {
206 for (Index = 0; Index < m_FunctionCount; Index++)
207 {
209
210 if (Candidate->Request != NULL && Candidate->Params->Interface == Interface)
211 {
212 Slot = Candidate;
213 break;
214 }
215 }
216 }
217
218 if (Slot == NULL)
219 {
221 DPRINT1("UsbDevice %p remote wake on interface %lu with no armed request\n", m_Handle, Interface);
222 return;
223 }
224
225 /* A failed unmark means the cancel routine owns the request */
226 if (!NT_SUCCESS(WdfRequestUnmarkCancelable(Slot->Request)))
227 {
229 DPRINT("UsbDevice %p remote wake request is being canceled\n", m_Handle);
230 return;
231 }
232
233 Request = Slot->Request;
234 Slot->Request = NULL;
235 Slot->Params = NULL;
236
238
239 DPRINT("UsbDevice %p remote wake on interface %lu\n", m_Handle, Interface);
240 WdfRequestComplete(Request, STATUS_SUCCESS);
241}
242
243/* Hub interface */
244
246static
248NTAPI
253{
254 PUSB_DEVICE_PORT_PATH Path = &Info->PortPath;
255 ULONG ParentDepth;
256
257 if (Hub->IsRootHub())
258 {
259 Path->Size = sizeof(*Path);
260 Path->PortPathDepth = 1;
261 Path->PortPath[0] = PortNumber;
262 Path->TTHubDepth = 0;
263 Info->TtHub = NULL;
264 return STATUS_SUCCESS;
265 }
266
267 ParentDepth = Hub->m_Info.PortPath.PortPathDepth;
268 if (ParentDepth + 1 > MAX_USB_DEVICE_DEPTH)
269 {
270 DPRINT1("Hub %p port %lu is too deep for a device, depth %lu\n", Hub->m_Handle, PortNumber, ParentDepth + 1);
272 }
273
274 *Path = Hub->m_Info.PortPath;
275 Path->PortPathDepth = ParentDepth + 1;
276 Path->PortPath[ParentDepth] = PortNumber;
277
278 if (Info->DeviceSpeed == UsbLowSpeed || Info->DeviceSpeed == UsbFullSpeed)
279 {
280 if (Hub->Speed() == UsbHighSpeed)
281 {
282 Path->TTHubDepth = ParentDepth;
283 Info->TtHub = Hub->m_Handle;
284 }
285 else
286 {
287 Path->TTHubDepth = Hub->m_Info.PortPath.TTHubDepth;
288 Info->TtHub = Hub->m_Info.TtHub;
289 }
290 }
291
292 return STATUS_SUCCESS;
293}
294
298 _In_ UCXUSBDEVICE Hub,
300 _Out_ UCXUSBDEVICE* UsbDevice)
301{
303 UcxController* Controller = HubDevice->m_Controller;
306
307 PAGED_CODE();
308 NT_ASSERT(HubDevice->IsHub());
309
310 RtlZeroMemory(&Init, sizeof(Init));
311 Init.ParentHub = Hub;
312 Init.HubDeviceContext = Info->HubDeviceContext;
313 Init.Info.Size = sizeof(Init.Info);
314 Init.Info.DeviceSpeed = Info->DeviceSpeed;
315
316 Status = UcxBuildPortPath(HubDevice, Info->PortNumber, &Init.Info);
317 if (!NT_SUCCESS(Status))
318 {
319 *UsbDevice = NULL;
320 return Status;
321 }
322
323 if (!Controller->BlockReset())
324 {
326 DPRINT1("Hub %p port %lu device add during controller reset 0x%lx\n", Hub, Info->PortNumber, Status);
327 }
328 else
329 {
330 Status = Controller->m_Config.EvtControllerUsbDeviceAdd(Controller->m_Handle, &Init.Info, &Init);
331 Controller->UnblockReset();
332
333 if (!NT_SUCCESS(Status))
334 DPRINT1("Hub %p port %lu HCD device add failed 0x%lx\n", Hub, Info->PortNumber, Status);
335 }
336
337 if (NT_SUCCESS(Status))
338 {
339 *UsbDevice = Init.Created;
340 return Status;
341 }
342
343 *UsbDevice = NULL;
344 if (Init.Created != NULL)
345 FromHandle(Init.Created)->DeleteFromHub();
346
347 return Status;
348}
349
350VOID
352{
353 LIST_ENTRY Stale;
356
357 PAGED_CODE();
358
359 DPRINT("UsbDevice %p deleted by the hub\n", m_Handle);
360
362
363 /* Endpoints still alive skip the stale stage from here on */
365
366 InitializeListHead(&Stale);
367 {
369
371 {
372 /* Move the whole stale list over in one step */
375 Stale.Flink->Blink = &Stale;
376 Stale.Blink->Flink = &Stale;
378 }
379 }
380
381 while (!IsListEmpty(&Stale))
382 {
383 Entry = RemoveHeadList(&Stale);
385
387 Endpoint->Post(EpEvent::StaleReplaced);
388 }
389
391}
392
393/* Tree walks */
394
395VOID
399 _In_ BOOLEAN IncludeDisconnected)
400{
403
404 if (!IncludeDisconnected && m_Disconnected)
405 return;
406
407 Visitor(this, Context);
408
410 {
412 Child->WalkSubtree(Visitor, Context, IncludeDisconnected);
413 }
414}
415
416/* Children first at the head of the list, so the deepest endpoints purge first */
417static
418VOID
419NTAPI
423{
424 PLIST_ENTRY Endpoints = (PLIST_ENTRY)Context;
427
428 Device->m_Disconnected = TRUE;
429
430 for (Entry = Device->m_EndpointList.Flink; Entry != &Device->m_EndpointList; Entry = Entry->Flink)
431 {
433
434 WdfObjectReference(Endpoint->m_Handle);
435 InsertHeadList(Endpoints, &Endpoint->m_DisconnectLink);
436 }
437}
438
439VOID
442{
443 LIST_ENTRY Endpoints;
447
448 InitializeListHead(&Endpoints);
449
450 DPRINT("Hub %p disconnect on port %lu\n", m_Handle, PortNumber);
451
452 {
454
455 if (PortNumber == 0)
456 {
458 }
459 else
460 {
461 /* A new enumeration may already sit on the port beside the old device */
463 {
465 const USB_DEVICE_PORT_PATH* Path = &Child->m_Info.PortPath;
466
467 if (Path->PortPath[Path->PortPathDepth - 1] == PortNumber)
468 Child->WalkSubtree(UcxDisconnectVisitor, &Endpoints, FALSE);
469 }
470 }
471 }
472
473 while (!IsListEmpty(&Endpoints))
474 {
475 Entry = RemoveHeadList(&Endpoints);
477 Endpoint = CONTAINING_RECORD(Entry, UcxEndpoint, m_DisconnectLink);
478
479 /* Root hub endpoints have no machine */
480 if (Endpoint->HasMachine())
481 Endpoint->Post(EpEvent::HubDisconnect);
482
484 }
485}
486
487/* Diagnostics only, no reference is taken */
488VOID
491{
492 NT_ASSERT(m_Pdo == NULL);
493 m_Pdo = Pdo;
494}
495
496/* Per device services */
497
499VOID
501{
504
506
509 {
511 {
513 InsertTailList(&m_TrackingList, &Endpoint->m_TrackingLink);
514 }
516 }
518}
519
520VOID
522{
524
526 return;
527
528 if (Parent != NULL && Parent->m_HubNoPingResponse != NULL)
529 Parent->m_HubNoPingResponse(Parent->m_HubContext, m_HubDeviceContext);
530}
531
533static
535NTAPI
538{
539 return Size != 0 && Size <= UCX_MAX_FORWARD_PROGRESS_SIZE;
540}
541
542/* Called with the controller's forward progress mutex held */
545UcxUsbDevice::EnableForwardProgress(
547{
548 ULONG ControlSize = Info->ControlPipeMaxTransferSize;
549 UcxPipe* DefaultPipe = m_DefaultPipe;
550 PFN_UCX_HCD_ENDPOINT_ENABLE_FORWARD_PROGRESS Enable;
551 UcxPipe* Pipe;
552 ULONG Index;
554
555 PAGED_CODE();
556
557 if (ControlSize > UCX_MAX_FORWARD_PROGRESS_SIZE)
558 {
559 DPRINT1("UsbDevice %p control forward progress size %lu too large\n", m_Handle, ControlSize);
561 }
562
563 if (ControlSize != 0 && DefaultPipe->ReservedIoActive)
564 {
565 DPRINT1("UsbDevice %p control pipe forward progress already enabled\n", m_Handle);
567 }
568
569 for (Index = 0; Index < Info->NumberOfPipes; Index++)
570 {
571 Pipe = UcxPipe::FromHandle(Info->Pipes[Index].PipeHandle);
572
573 if (!UcxIsValidForwardProgressSize(Info->Pipes[Index].ReservedTransferLimit) ||
574 Pipe->ReservedIoActive)
575 {
576 DPRINT1("UsbDevice %p pipe %lu bad forward progress size %lu or already enabled\n",
577 m_Handle, Index, Info->Pipes[Index].ReservedTransferLimit);
579 }
580 }
581
582 /* The control pipe keeps resources it already got if they are big enough */
583 if (ControlSize != 0 &&
584 !(DefaultPipe->ForwardProgressAllocatedByHcd &&
585 DefaultPipe->ReservedIoMaxBytes >= ControlSize))
586 {
588 if (Enable == NULL)
589 {
590 DPRINT1("UsbDevice %p HCD has no forward progress callback for the control pipe\n", m_Handle);
592 }
593
594 Status = Enable(m_DefaultEndpoint->m_Handle, ControlSize);
595 if (!NT_SUCCESS(Status))
596 {
597 DPRINT1("UsbDevice %p control pipe forward progress failed 0x%lx\n", m_Handle, Status);
598 return Status;
599 }
600
601 DefaultPipe->ForwardProgressAllocatedByHcd = TRUE;
602 DefaultPipe->ReservedIoMaxBytes = ControlSize;
603 }
604
605 for (Index = 0; Index < Info->NumberOfPipes; Index++)
606 {
607 Pipe = UcxPipe::FromHandle(Info->Pipes[Index].PipeHandle);
608
609 Enable = Pipe->Endpoint->m_Callbacks.EnableForwardProgress;
610 if (Enable == NULL)
611 {
612 DPRINT1("Endpoint %p HCD has no forward progress callback\n", Pipe->Endpoint->m_Handle);
614 }
615
616 Status = Enable(Pipe->Endpoint->m_Handle, Info->Pipes[Index].ReservedTransferLimit);
617 if (!NT_SUCCESS(Status))
618 {
619 DPRINT1("Endpoint %p forward progress failed 0x%lx\n", Pipe->Endpoint->m_Handle, Status);
620 return Status;
621 }
622
623 Pipe->ForwardProgressAllocatedByHcd = TRUE;
624 Pipe->ReservedIoMaxBytes = Info->Pipes[Index].ReservedTransferLimit;
625 }
626
627 /* Only marked once every pipe got its resources */
628 if (ControlSize != 0)
629 DefaultPipe->ReservedIoActive = TRUE;
630
631 for (Index = 0; Index < Info->NumberOfPipes; Index++)
632 UcxPipe::FromHandle(Info->Pipes[Index].PipeHandle)->ReservedIoActive = TRUE;
633
634 return STATUS_SUCCESS;
635}
636
637/* Composite devices and remote wake */
638
639VOID
641 _In_ WDFREQUEST Request)
642{
644 PUSBD_FUNCTION_HANDLE Handles;
646 UcxFunctionRecord* Records;
647 WDFMEMORY Memory;
648 ULONG Index;
650
651 Handles = (PUSBD_FUNCTION_HANDLE)WdfRequestWdmGetIrp(Request)->AssociatedIrp.SystemBuffer;
652
653 if (Register == NULL || Handles == NULL ||
654 Register->Size != sizeof(*Register) ||
655 Register->Version != UCX_COMPOSITE_VERSION ||
656 Register->FunctionCount == 0 ||
657 Register->FunctionCount > UCX_MAX_COMPOSITE_FUNCTIONS)
658 {
659 DPRINT1("UsbDevice %p composite register rejected, request %p\n", m_Handle, Request);
660 WdfRequestComplete(Request, STATUS_INVALID_PARAMETER);
661 return;
662 }
663
665 Attributes.ParentObject = m_Handle;
666
667 Status = WdfMemoryCreate(&Attributes,
670 Register->FunctionCount * sizeof(UcxFunctionRecord),
671 &Memory,
672 (PVOID*)&Records);
673 if (!NT_SUCCESS(Status))
674 {
675 DPRINT1("UsbDevice %p function records allocation failed 0x%lx\n", m_Handle, Status);
676 WdfRequestComplete(Request, Status);
677 return;
678 }
679
680 RtlZeroMemory(Records, Register->FunctionCount * sizeof(UcxFunctionRecord));
681
682 {
684
685 if (m_FunctionsMemory != NULL)
686 {
688 }
689 else
690 {
691 m_FunctionCount = Register->FunctionCount;
692 m_Functions = Records;
694 }
695 }
696
697 if (!NT_SUCCESS(Status))
698 {
699 DPRINT1("UsbDevice %p is already registered as composite\n", m_Handle);
701 WdfRequestComplete(Request, Status);
702 return;
703 }
704
705 /* The output length is not checked */
706 for (Index = 0; Index < Register->FunctionCount; Index++)
707 {
708 Records[Index].Index = Index;
709 Records[Index].Device = this;
710 Handles[Index] = (USBD_FUNCTION_HANDLE)&Records[Index];
711 }
712
713 WdfRequestComplete(Request, STATUS_SUCCESS);
714}
715
716/* Remote wake requests still armed on functions are not canceled here */
717VOID
719 _In_ WDFREQUEST Request)
720{
721 WDFMEMORY Memory = NULL;
722
723 {
725
726 if (m_FunctionsMemory != NULL)
727 {
731 m_FunctionCount = 0;
732 }
733 }
734
735 if (Memory == NULL)
736 {
737 DPRINT1("UsbDevice %p composite unregister without a registration\n", m_Handle);
738 WdfRequestComplete(Request, STATUS_INVALID_DEVICE_STATE);
739 return;
740 }
741
743 WdfRequestComplete(Request, STATUS_SUCCESS);
744}
745
746VOID
748 _In_ WDFREQUEST Request)
749{
751
752 Data = (PUCXHUB_FUNCTION_DATA)WdfRequestWdmGetIrp(Request)->AssociatedIrp.SystemBuffer;
753
754 {
756
757 ((UcxFunctionRecord*)Data->FunctionHandle)->ClientPdo = Data->PhysicalDeviceObject;
758 }
759
760 WdfRequestComplete(Request, STATUS_SUCCESS);
761}
762
763VOID
765 _In_ WDFREQUEST Request)
766{
771
773 if (Params == NULL)
774 {
775 DPRINT1("UsbDevice %p remote wake request %p has no parameters\n", m_Handle, Request);
776 WdfRequestComplete(Request, STATUS_INVALID_PARAMETER);
777 return;
778 }
779
781
782 if ((m_Functions == NULL) != (Params->UsbdFunctionHandle == NULL))
783 {
785 }
786 else
787 {
789 : &((UcxFunctionRecord*)Params->UsbdFunctionHandle)->Wake;
790
791 if (Slot->Request != NULL)
792 {
794 }
795 else
796 {
797 Status = WdfRequestMarkCancelableEx(Request, UcxUsbDevice::EvtRemoteWakeCancel);
798 if (NT_SUCCESS(Status))
799 {
800 Slot->Request = Request;
801 Slot->Params = Params;
802 }
803 }
804 }
805
807
808 if (!NT_SUCCESS(Status))
809 {
810 DPRINT1("UsbDevice %p remote wake request %p failed 0x%lx\n", m_Handle, Request, Status);
811 WdfRequestComplete(Request, Status);
812 }
813}
814
815VOID
816UcxUsbDevice::EvtRemoteWakeCancel(
817 _In_ WDFREQUEST Request)
818{
821 UcxUsbDevice* Device = FromHandle((UCXUSBDEVICE)Args.Arg2);
823
824 {
825 SpinLockGuard Guard(&Device->m_RemoteWakeLock);
826
827 if (Params->UsbdFunctionHandle == NULL)
828 {
829 Slot = &Device->m_RemoteWake;
830 }
831 else
832 {
833 /* The client may have unregistered the functions already */
834 Slot = (Device->m_Functions != NULL)
835 ? &((UcxFunctionRecord*)Params->UsbdFunctionHandle)->Wake
836 : NULL;
837 }
838
839 if (Slot != NULL)
840 {
841 Slot->Request = NULL;
842 Slot->Params = NULL;
843 }
844 }
845
846 DPRINT("UsbDevice %p remote wake request %p canceled\n", Device->m_Handle, Request);
847 WdfRequestComplete(Request, STATUS_CANCELLED);
848}
#define PAGED_CODE()
char ** Args
Definition: acdebug.h:353
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn UINT32 *TableIdx UINT32 ACPI_TABLE_HEADER *OutTableHeader ACPI_TABLE_HEADER **OutTable ACPI_HANDLE UINT32 ACPI_WALK_CALLBACK ACPI_WALK_CALLBACK void void **ReturnValue UINT32 ACPI_BUFFER *RetPathPtr ACPI_OBJECT_HANDLER void *Data ACPI_OBJECT_HANDLER void **Data ACPI_STRING ACPI_OBJECT_LIST ACPI_BUFFER *ReturnObjectBuffer ACPI_DEVICE_INFO **ReturnBuffer ACPI_HANDLE Parent
Definition: acpixf.h:732
unsigned char BOOLEAN
Definition: actypes.h:127
#define InterlockedExchange
Definition: armddk.h:54
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
const struct winhelp_callbacks Callbacks
Definition: callback.c:161
HubFdo * Hub
Definition: bootdev.cpp:261
WDFDEVICE HubDevice
Definition: childpdo.cpp:989
BOOLEAN IsRootHub() const
Definition: fdo.h:174
static UcxController * FromHandle(_In_ UCXCONTROLLER Handle)
Definition: hostctl.cpp:14
KSPIN_LOCK m_TopologyLock
Definition: hostctl.h:310
ULONG m_ChildDeviceCount
Definition: hostctl.h:311
UcxEndpointCallbacks m_Callbacks
Definition: pipe.h:289
UCXENDPOINT m_Handle
Definition: pipe.h:281
UcxController * m_Controller
Definition: devobj.h:216
ULONG m_FunctionCount
Definition: devobj.h:269
BOOLEAN m_Disconnected
Definition: devobj.h:231
BOOLEAN m_ChildrenMayLeavePurge
Definition: devobj.h:232
VOID RemoteWakeNotification(_In_ ULONG Interface)
Definition: devobj.cpp:189
static UcxUsbDevice * FromHandle(_In_ UCXUSBDEVICE Handle)
Definition: devobj.cpp:18
LIST_ENTRY m_EndpointList
Definition: devobj.h:229
static EVT_WDF_REQUEST_CANCEL EvtRemoteWakeCancel
Definition: devobj.h:355
UcxEndpoint * m_DefaultEndpoint
Definition: devobj.h:240
VOID WalkSubtree(_In_ PFN_UCX_DEVICE_VISITOR Visitor, _In_opt_ PVOID Context, _In_ BOOLEAN IncludeDisconnected)
Definition: devobj.cpp:396
LIST_ENTRY m_ChildList
Definition: devobj.h:227
VOID RequestRemoteWakeNotification(_In_ WDFREQUEST Request)
Definition: devobj.cpp:764
VOID TrackStaleHandles()
Definition: devobj.cpp:500
LONG m_PendingNoPingResponse
Definition: devobj.h:257
static VOID InitSetEventCallbacks(_Inout_ PUCXUSBDEVICE_INIT Init, _In_ PUCX_USBDEVICE_EVENT_CALLBACKS Callbacks)
Definition: devobj.cpp:71
VOID InitializeAsRootHub(_In_ UCXROOTHUB Handle, _In_ UcxController *Controller)
Definition: devobj.cpp:50
WDFMEMORY m_FunctionsMemory
Definition: devobj.h:271
VOID DisconnectPort(_In_ ULONG PortNumber)
Definition: devobj.cpp:440
VOID SetFunctionData(_In_ WDFREQUEST Request)
Definition: devobj.cpp:747
LIST_ENTRY m_TrackingList
Definition: devobj.h:237
static _Must_inspect_result_ NTSTATUS Create(_In_ UCXCONTROLLER Controller, _Inout_ PUCXUSBDEVICE_INIT *Init, _In_opt_ PWDF_OBJECT_ATTRIBUTES Attributes, _Out_ UCXUSBDEVICE *UsbDevice)
Definition: devobj.cpp:81
UcxPipe * m_DefaultPipe
Definition: devobj.h:241
BOOLEAN m_EndpointsMayLeavePurge
Definition: devobj.h:233
UCXUSBDEVICE m_Handle
Definition: devobj.h:215
KSPIN_LOCK m_TrackingLock
Definition: devobj.h:236
VOID ReportNoPingResponseIfPending()
Definition: devobj.cpp:521
PDEVICE_OBJECT m_Pdo
Definition: devobj.h:223
VOID SetPdo(_In_ PDEVICE_OBJECT Pdo)
Definition: devobj.cpp:489
LIST_ENTRY m_UsbdHandleList
Definition: devobj.h:275
KSPIN_LOCK m_RemoteWakeLock
Definition: devobj.h:267
BOOLEAN m_PendingDelete
Definition: devobj.h:245
UcxFunctionRecord * m_Functions
Definition: devobj.h:270
UCXUSBDEVICE_INFO m_Info
Definition: devobj.h:221
LIST_ENTRY m_ChildLink
Definition: devobj.h:228
static EVT_WDF_OBJECT_CONTEXT_DESTROY EvtDestroy
Definition: devobj.h:352
VOID InitializeLists()
Definition: devobj.cpp:36
UCXHUB_DEVICE_CONTEXT m_HubDeviceContext
Definition: devobj.h:218
VOID RegisterComposite(_In_ WDFREQUEST Request)
Definition: devobj.cpp:640
VOID UnregisterComposite(_In_ WDFREQUEST Request)
Definition: devobj.cpp:718
UcxRemoteWakeSlot m_RemoteWake
Definition: devobj.h:268
KSPIN_LOCK m_UsbdHandleLock
Definition: devobj.h:274
BOOLEAN m_StalePipeIoAllowed
Definition: devobj.h:238
VOID DeleteFromHub()
Definition: devobj.cpp:351
LIST_ENTRY m_StaleEndpointList
Definition: devobj.h:230
ULONG m_Type
Definition: devobj.h:219
UcxUsbDevice * m_ParentHub
Definition: devobj.h:217
static _Must_inspect_result_ NTSTATUS CreateFromHub(_In_ UCXUSBDEVICE Hub, _In_ PUCXHUB_DEVICE_CREATE_INFO Info, _Out_ UCXUSBDEVICE *UsbDevice)
Definition: devobj.cpp:297
VOID NTAPI UcxDropLeakedUsbdHandles(_In_ UcxUsbDevice *Device)
Definition: clientif.cpp:615
#define STATUS_NOT_SUPPORTED
Definition: d3dkmdt.h:48
_Inout_ HubConfiguration ** Slot
Definition: devhcd.cpp:1260
PLIST_ENTRY Entry
Definition: devhcd.cpp:1262
static ULONG64 NTAPI UcxSystemTimeNow(VOID)
Definition: devobj.cpp:27
#define UCX_COMPOSITE_VERSION
Definition: devobj.cpp:13
static VOID NTAPI UcxDisconnectVisitor(_In_ UcxUsbDevice *Device, _In_opt_ PVOID Context)
Definition: devobj.cpp:420
static BOOLEAN NTAPI UcxIsValidForwardProgressSize(_In_ ULONG Size)
Definition: devobj.cpp:536
#define UCX_MAX_FORWARD_PROGRESS_SIZE
Definition: devobj.cpp:15
static NTSTATUS NTAPI UcxBuildPortPath(_In_ UcxUsbDevice *Hub, _In_ ULONG PortNumber, _Inout_ PUCXUSBDEVICE_INFO Info)
Definition: devobj.cpp:249
#define UCX_MAX_COMPOSITE_FUNCTIONS
Definition: devobj.cpp:14
#define UCX_DEVICE_TYPE_ROOT_HUB
Definition: devobj.h:12
#define UCX_DEVICE_TYPE_HUB
Definition: devobj.h:11
_In_ ULONG Attributes
Definition: dispmprt.h:1077
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
static VOID Wake(_In_ UCHAR Csn)
Definition: hardware.c:154
#define _IRQL_requires_(irql)
Definition: driverspecs.h:229
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define InsertTailList(ListHead, Entry)
#define InsertHeadList(ListHead, Entry)
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
#define NonPagedPool
Definition: env_spec_w32.h:307
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define KeInitializeSpinLock(sl)
Definition: env_spec_w32.h:604
ULONG Handle
Definition: gdb_input.c:15
Status
Definition: gdiplustypes.h:24
_In_ UCXUSBDEVICE UsbDevice
Definition: hostctl.h:31
VOID(NTAPI * PFN_UCX_DEVICE_VISITOR)(_In_ UcxUsbDevice *Device, _In_opt_ PVOID Context)
Definition: hostctl.h:108
UNICODE_STRING Path
_Must_inspect_result_ _In_ PUCXHUB_DEVICE_CREATE_INFO _Out_ UCXUSBDEVICE * Device
Definition: hubucx.h:258
_In_ UCXHUB_DEVICE_CONTEXT _In_ UCXENDPOINT Endpoint
Definition: hubucx.h:238
_In_ ULONG PortNumber
Definition: hubucx.h:272
_In_ UCXUSBDEVICE _In_ PDEVICE_OBJECT Pdo
Definition: hubucx.h:280
struct _UCXHUB_FUNCTION_DATA * PUCXHUB_FUNCTION_DATA
Config Register
Definition: hubwmi.cpp:126
_In_ PIRP _In_ PIO_COMPLETION_ROUTINE _In_ PVOID Context
Definition: kse.h:81
unsigned __int64 ULONG64
Definition: imports.h:198
#define min(a, b)
Definition: monoChain.cc:55
#define _Inout_
Definition: no_sal2.h:162
#define _Must_inspect_result_
Definition: no_sal2.h:62
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
#define _In_opt_
Definition: no_sal2.h:212
_In_ ULONGLONG _In_ ULONGLONG _In_ BOOLEAN Enable
Definition: ntddpcm.h:142
#define KeAcquireSpinLockAtDpcLevel(SpinLock)
Definition: ke.h:125
#define KeReleaseSpinLockFromDpcLevel(SpinLock)
Definition: ke.h:135
struct tm * Now
Definition: output.c:19
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:73
PFN_UCX_HCD_ENDPOINT_ENABLE_FORWARD_PROGRESS EnableForwardProgress
Definition: pipe.h:86
UcxUsbDevice * Device
Definition: devobj.h:44
UcxRemoteWakeSlot Wake
Definition: devobj.h:46
Definition: pipe.h:30
static UcxPipe * FromHandle(_In_ USBD_PIPE_HANDLE Handle)
Definition: pipe.h:53
ULONG ReservedIoMaxBytes
Definition: pipe.h:43
BOOLEAN ForwardProgressAllocatedByHcd
Definition: pipe.h:42
BOOLEAN ReservedIoActive
Definition: pipe.h:41
WDFREQUEST Request
Definition: devobj.h:36
PREQUEST_REMOTE_WAKE_NOTIFICATION Params
Definition: devobj.h:37
PVOID Arg1
Definition: ucxutil.h:103
Definition: typedefs.h:120
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
USB_DEVICE_SPEED DeviceSpeed
Definition: ucxusbdevice.h:176
WDFOBJECT ParentObject
Definition: wdfobject.h:130
PFN_WDF_OBJECT_CONTEXT_DESTROY EvtDestroyCallback
Definition: wdfobject.h:115
struct _LIST_ENTRY * PLIST_ENTRY
#define NTAPI
Definition: typedefs.h:36
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
_Must_inspect_result_ _In_ WDFDEVICE _In_ PUCX_CONTROLLER_CONFIG _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ UCXCONTROLLER * Controller
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFREQUEST Request
_In_ UCXUSBDEVICE _In_ ULONG Interface
Definition: ucxusbdevice.h:428
#define MAX_USB_DEVICE_DEPTH
Definition: ucxusbdevice.h:163
_Must_inspect_result_ NTSTATUS NTAPI UcxCreateObjectWithTwoContexts(_In_ PWDF_OBJECT_ATTRIBUTES Primary, _In_opt_ PWDF_OBJECT_ATTRIBUTES Secondary, _Out_ WDFOBJECT *Object)
Definition: ucxutil.cpp:19
FORCEINLINE BOOLEAN NTAPI UcxIsListEntryLinked(_In_ const LIST_ENTRY *Entry)
Definition: ucxutil.h:94
FORCEINLINE VOID NTAPI UcxClearListEntry(_Out_ PLIST_ENTRY Entry)
Definition: ucxutil.h:84
#define UCX_POOL_TAG
Definition: ucxutil.h:11
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_NO_SUCH_DEVICE
Definition: udferr_usr.h:136
#define STATUS_INVALID_DEVICE_STATE
Definition: udferr_usr.h:178
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
@ UsbSuperSpeed
Definition: usb200.h:45
@ UsbHighSpeed
Definition: usb200.h:44
@ UsbLowSpeed
Definition: usb200.h:42
@ UsbFullSpeed
Definition: usb200.h:43
USBD_FUNCTION_HANDLE * PUSBD_FUNCTION_HANDLE
Definition: usbdlib.h:111
struct _REQUEST_REMOTE_WAKE_NOTIFICATION * PREQUEST_REMOTE_WAKE_NOTIFICATION
struct _REGISTER_COMPOSITE_DEVICE * PREGISTER_COMPOSITE_DEVICE
WdfObjectDelete(String)
BOOL InitPointer(PPDEV ppdev)
Definition: pointer.c:143
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:690
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object
_In_ WDFCOLLECTION _In_ ULONG Index
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4539
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFDEVICE Child
Definition: wdffdo.h:536
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _In_ _Strict_type_match_ POOL_TYPE _In_opt_ ULONG _In_ _Out_ WDFMEMORY * Memory
Definition: wdfmemory.h:169
FORCEINLINE VOID WDF_OBJECT_ATTRIBUTES_INIT(_Out_ PWDF_OBJECT_ATTRIBUTES Attributes)
Definition: wdfobject.h:147
#define WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(_attributes, _contexttype)
Definition: wdfobject.h:170
#define WdfObjectReference(Handle)
Definition: wdfobject.h:803
#define WdfObjectDereference(Handle)
Definition: wdfobject.h:826
_In_ WDFIOTARGET _In_ PWDF_REQUEST_COMPLETION_PARAMS Params
Definition: wdfrequest.h:308
_In_ WDFUSBPIPE Pipe
Definition: wdfusb.h:1741
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778
#define NT_ASSERT
Definition: rtlfuncs.h:3334