ReactOS 0.4.17-dev-1281-g065abb3
pipe.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: UCXENDPOINT and UCXSSTREAMS objects and the endpoint machine actions
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/* Derived values */
14
15#define UCX_KB(x) ((x) * 1024UL)
16#define UCX_MB(x) ((x) * 1024UL * 1024UL)
17
18/* Rows are Low, Full, High, Super; columns are UcxTransferType, isoch is computed instead */
19static const ULONG UcxMaxTransferTable[4][5] =
20{
21 /* Unknown Control Bulk Isoch Interrupt */
22 { 0, UCX_KB(4), UCX_MB(4), 0, UCX_MB(4) },
23 { 0, UCX_KB(4), UCX_MB(4), 0, UCX_MB(4) },
24 { 0, UCX_KB(64), UCX_MB(4), 0, UCX_MB(4) },
25 { 0, UCX_KB(64), UCX_MB(32), 0, UCX_MB(4) }
26};
27
28/* Anything faster than SuperSpeed is sized as SuperSpeed */
29static
34{
35 return ((ULONG)Speed > (ULONG)UsbSuperSpeed) ? (ULONG)UsbSuperSpeed : (ULONG)Speed;
36}
37
38static
43{
44 return Speed == UsbLowSpeed || Speed == UsbFullSpeed;
45}
46
51 _In_ USHORT BcdUsb,
53{
54 ULONG Row = UcxSpeedRow(Speed);
55 USHORT MaxPacket;
56 ULONG PacketBytes;
57
58 if (Init->TransferType != UcxTransferType::Isochronous)
59 {
60 if (Init->TransferType == UcxTransferType::Control &&
61 UcxIsSlowSpeed(Speed) &&
62 UcxDriver.Allow64KLowOrFullSpeedControl)
63 {
64 return UCX_KB(64);
65 }
66
67 return UcxMaxTransferTable[Row][(ULONG)Init->TransferType];
68 }
69
70 if (Row == (ULONG)UsbSuperSpeed)
71 {
72 if (Init->Companion.bmAttributes.Isochronous.SspCompanion)
73 return 1024 * Init->IsochCompanion.dwBytesPerInterval;
74
75 return 1024 * Init->Companion.wBytesPerInterval;
76 }
77
78 /* Before USB 2.5 the top bits carry the additional transactions per microframe */
79 MaxPacket = Init->Descriptor.wMaxPacketSize;
80 if (BcdUsb < 0x0250)
81 PacketBytes = (MaxPacket & 0x7FF) * (((MaxPacket >> 11) & 0x3) + 1);
82 else
83 PacketBytes = MaxPacket;
84
85 return ((Row == (ULONG)UsbHighSpeed) ? 1024 : 256) * PacketBytes;
86}
87
88/* Exports */
89
92 _In_ UCXENDPOINT Handle)
93{
94 return UcxGetEndpointContext(Handle);
95}
96
97VOID
101{
102 UcxEndpointCallbacks* Target = &Init->Callbacks;
103
104 NT_ASSERT(Init->Kind != UcxEndpointKind::Default);
105
106 Target->Purge = Callbacks->EvtEndpointPurge;
107 Target->Start = Callbacks->EvtEndpointStart;
108 Target->Abort = Callbacks->EvtEndpointAbort;
109 Target->Reset = Callbacks->EvtEndpointReset;
110 Target->OkToCancelTransfers = Callbacks->EvtEndpointOkToCancelTransfers;
111 Target->StaticStreamsAdd = Callbacks->EvtEndpointStaticStreamsAdd;
112 Target->StaticStreamsEnable = Callbacks->EvtEndpointStaticStreamsEnable;
113 Target->StaticStreamsDisable = Callbacks->EvtEndpointStaticStreamsDisable;
114 Target->EnableForwardProgress = (PFN_UCX_HCD_ENDPOINT_ENABLE_FORWARD_PROGRESS)Callbacks->Reserved1;
115
116 /* Appended by newer controller drivers, taken only from the full structure */
117 if (Callbacks->Size == sizeof(*Callbacks))
118 {
119 Target->GetIsochTransferPathDelays = Callbacks->EvtEndpointGetIsochTransferPathDelays;
120 Target->SetCharacteristic = Callbacks->EvtEndpointSetCharacteristic;
121 }
122}
123
124VOID
128{
129 UcxEndpointCallbacks* Target = &Init->Callbacks;
130
131 NT_ASSERT(Callbacks->Size == sizeof(*Callbacks));
132 NT_ASSERT(Init->Kind == UcxEndpointKind::Default);
133
134 Target->DefaultEndpointUpdate = Callbacks->EvtDefaultEndpointUpdate;
135 Target->Purge = Callbacks->EvtEndpointPurge;
136 Target->Start = Callbacks->EvtEndpointStart;
137 Target->Abort = Callbacks->EvtEndpointAbort;
138 Target->OkToCancelTransfers = Callbacks->EvtEndpointOkToCancelTransfers;
139 Target->EnableForwardProgress = (PFN_UCX_HCD_ENDPOINT_ENABLE_FORWARD_PROGRESS)Callbacks->Reserved1;
140}
141
142VOID
146{
147 USB_DEVICE_SPEED Speed = Device->Speed();
148
149 m_Controller = Device->m_Controller;
151 m_Callbacks = Init->Callbacks;
152 m_Descriptor = Init->Descriptor;
153
154 m_Pipe.Endpoint = this;
155 m_Pipe.Kind = Init->Kind;
156 m_Pipe.TransferType = Init->TransferType;
157 m_Pipe.Self = &m_Pipe;
159
160 if (Init->TransferType != UcxTransferType::Control)
162
163 if (Init->TransferType == UcxTransferType::Isochronous)
164 {
165 if (UcxIsSlowSpeed(Speed))
166 {
169 }
170 else
171 {
172 /* bInterval 0 wraps to the top bit, as the x86 shift does */
175 }
176 }
177
178 /* Only async transfers of slow devices behind a real TT need the TT cleared */
180 Init->TransferType != UcxTransferType::Interrupt &&
181 Init->TransferType != UcxTransferType::Isochronous &&
182 UcxIsSlowSpeed(Speed) &&
183 Device->m_Info.TtHub != NULL;
184
191}
192
196 _In_ UCXUSBDEVICE UsbDevice,
199 _Out_ UCXENDPOINT* Endpoint)
200{
202 UcxUsbDevice* Device = UcxUsbDevice::FromHandle(UsbDevice);
203 WDF_OBJECT_ATTRIBUTES Primary;
207
208 *Endpoint = NULL;
209
210 /* Parented to the init block's device, referenced through the parameter */
212 Primary.ParentObject = Init->Device;
214
216 if (!NT_SUCCESS(Status))
217 {
218 DPRINT1("Endpoint object create failed for UsbDevice %p 0x%lx\n", UsbDevice, Status);
219 return Status;
220 }
221
223
224 Context = new (UcxGetEndpointContext(Object)) UcxEndpoint();
225 Context->m_Handle = (UCXENDPOINT)Object;
226 Context->Initialize(Device, Init);
227
228 if (Init->CreateMachine)
229 {
230 Context->m_Machine.Initialize(Context);
231 Context->m_HasMachine = TRUE;
232
233 /* Creation reference, dropped by the machine once it deletes the object */
235 }
236
237 /* Recorded before the disconnect check, so a failure leaves them behind */
238 if (Init->Kind == UcxEndpointKind::Default)
239 {
240 NT_ASSERT(Device->m_DefaultEndpoint == NULL);
241 Device->m_DefaultEndpoint = Context;
242 Device->m_DefaultPipe = &Context->m_Pipe;
243 }
244
245 {
246 SpinLockGuard Guard(&Context->m_Controller->m_TopologyLock);
247
248 if (Device->m_Disconnected)
249 {
251 }
252 else
253 {
254 InsertHeadList(&Device->m_EndpointList, &Context->m_DeviceLink);
255 Context->m_Controller->m_ChildEndpointCount++;
256 }
257 }
258
259 if (!NT_SUCCESS(Status))
260 {
261 DPRINT1("Endpoint %p not created, UsbDevice %p is disconnected\n", Object, UsbDevice);
262
263 if (Context->m_HasMachine)
265
267 return Status;
268 }
269
270 /* Tracking may have been turned on after the insert above and taken it already */
271 if (Device->m_StalePipeIoAllowed)
272 {
273 SpinLockGuard Guard(&Device->m_TrackingLock);
274
275 if (!UcxIsListEntryLinked(&Context->m_TrackingLink))
276 InsertTailList(&Device->m_TrackingList, &Context->m_TrackingLink);
277 }
278
279 DPRINT("Endpoint %p address 0x%x created on UsbDevice %p\n",
280 Context->m_Handle, Context->m_Descriptor.bEndpointAddress, UsbDevice);
281
282 *Endpoint = Context->m_Handle;
283 Init->Created = Context->m_Handle;
285
286 return STATUS_SUCCESS;
287}
288
289/* A context that was never filled has a NULL device and no queue */
290VOID
291NTAPI
292UcxEndpoint::EvtDestroy(
294{
295 UcxEndpoint* Context = UcxGetEndpointContext(Object);
296
297 Context->m_HasMachine = FALSE;
298
299 if (Context->m_Pipe.Queue != NULL)
300 {
301 WdfObjectDereference(Context->m_Pipe.Queue);
302 Context->m_Pipe.Queue = NULL;
303 }
304
305 Context->m_Pipe.Self = NULL;
306
307 if (Context->m_Device != NULL)
308 WdfObjectDereference(Context->m_Device->m_Handle);
309}
310
311/* The first queue wins; later calls are a controller driver bug and ignored */
312VOID
314 _In_ WDFQUEUE Queue)
315{
316 if (m_Pipe.Queue != NULL)
317 {
318 DPRINT1("Endpoint %p already has queue %p\n", m_Handle, m_Pipe.Queue);
319 return;
320 }
321
324}
325
327VOID
329{
332
334 {
336 return;
337 }
338
339 /* A second call during a clear never gets its OK */
341 {
342 DPRINT1("Endpoint %p HCD asked to cancel transfers again during a TT clear\n", m_Handle);
344 return;
345 }
346
348
349 TtHub = UcxUsbDevice::FromHandle(m_Device->m_Info.TtHub);
350 TtHub->m_HubClearTtBuffer(TtHub->m_HubContext,
352 m_Handle,
354 Path->PortPath[Path->TTHubDepth]);
355
357}
358
359VOID
361{
363 return;
364
367}
368
369UCXSSTREAMS
371 _In_ PVOID Tag)
372{
373 UCXSSTREAMS Streams = NULL;
374
375 if (m_Streams == NULL)
376 return NULL;
377
379
380 if (m_Streams != NULL)
381 {
382 Streams = m_Streams->m_Handle;
384 }
385
386 return Streams;
387}
388
389/* Hub interface */
390
399 _Out_ UCXENDPOINT* Endpoint)
400{
401 const UCX_USBDEVICE_EVENT_CALLBACKS* Hcd = &Device->m_Callbacks.Public;
402 UCXCONTROLLER Controller = Device->m_Controller->m_Handle;
404
405 PAGED_CODE();
406
407 Init->Device = Device->m_Handle;
408 Init->CreateMachine = TRUE;
409
410 if (Init->Kind == UcxEndpointKind::Default)
411 {
413 }
414 else
415 {
417 Device->m_Handle,
420 Companion,
421 Init);
422 }
423
424 if (!NT_SUCCESS(Status))
425 DPRINT1("UsbDevice %p HCD endpoint add failed 0x%lx\n", Device->m_Handle, Status);
426
427 /* Success without an endpoint or a queue leaves nothing to send transfers to */
428 if (NT_SUCCESS(Status) &&
429 (Init->Created == NULL || FromHandle(Init->Created)->m_Pipe.Queue == NULL))
430 {
431 DPRINT1("UsbDevice %p HCD endpoint add set no endpoint %p or no queue\n", Device->m_Handle, Init->Created);
432 UcxVerifierBreak(Device->m_Controller->m_DriverVerifierEnabled);
434 }
435
436 if (NT_SUCCESS(Status))
437 {
438 *Endpoint = Init->Created;
439 return Status;
440 }
441
442 *Endpoint = NULL;
443 if (Init->Created != NULL)
444 FromHandle(Init->Created)->DeleteFromHub();
445
446 return Status;
447}
448
452 _In_ UCXUSBDEVICE UsbDevice,
454 _Out_ UCXENDPOINT* Endpoint)
455{
457
458 RtlZeroMemory(&Init, sizeof(Init));
459 Init.Kind = UcxEndpointKind::Default;
460 Init.TransferType = UcxTransferType::Control;
461
462 return CreateThroughHcd(UcxUsbDevice::FromHandle(UsbDevice), &Init, MaxPacketSize, NULL, 0, NULL, Endpoint);
463}
464
468 _In_ UCXUSBDEVICE UsbDevice,
472 _Out_ UCXENDPOINT* Endpoint)
473{
474 static const UcxTransferType TypeFromAttributes[4] =
475 {
476 UcxTransferType::Control,
477 UcxTransferType::Isochronous,
478 UcxTransferType::Bulk,
479 UcxTransferType::Interrupt
480 };
482
483 RtlZeroMemory(&Init, sizeof(Init));
484 Init.TransferType = TypeFromAttributes[Descriptor->bmAttributes & USB_ENDPOINT_TYPE_MASK];
485 Init.Kind = (Descriptor->wMaxPacketSize == 0) ? UcxEndpointKind::ZeroBandwidth : UcxEndpointKind::Generic;
486 RtlCopyMemory(&Init.Descriptor, Descriptor, sizeof(Init.Descriptor));
487
488 if (Companion != NULL)
489 {
490 RtlCopyMemory(&Init.Companion, Companion, sizeof(Init.Companion));
491 Init.HasCompanion = TRUE;
492
493 /* The SuperSpeedPlus companion follows right after; the buffer length is not checked */
494 if (Init.TransferType == UcxTransferType::Isochronous &&
495 Companion->bmAttributes.Isochronous.SspCompanion)
496 {
497 RtlCopyMemory(&Init.IsochCompanion,
498 (PUCHAR)Companion + Companion->bLength,
499 sizeof(Init.IsochCompanion));
500 Init.HasIsochCompanion = TRUE;
501 }
502 }
503
504 return CreateThroughHcd(UcxUsbDevice::FromHandle(UsbDevice),
505 &Init,
506 0,
509 Companion,
510 Endpoint);
511}
512
513/* The machine decides whether it goes now or stays around as stale */
514VOID
516{
517 Post(EpEvent::Delete);
518}
519
520/* Static streams */
521
524 _In_ UCXSSTREAMS Handle)
525{
526 return UcxGetStaticStreamsContext(Handle);
527}
528
532 _In_ UCXENDPOINT Endpoint,
535 _Out_ UCXSSTREAMS* StaticStreams)
536{
537 UcxStaticStreamsInit* StreamsInit = *Init;
538 WDF_OBJECT_ATTRIBUTES Primary;
542
544
545 /* The stream entries follow the context in the same allocation */
547 Primary.ContextSizeOverride = sizeof(UcxStaticStreams) + StreamsInit->StreamCount * sizeof(UcxStream);
548 Primary.ParentObject = StreamsInit->Endpoint;
550
552 if (!NT_SUCCESS(Status))
553 {
554 DPRINT1("Streams object create failed for endpoint %p 0x%lx\n", Endpoint, Status);
555 return Status;
556 }
557
558 Context = new (UcxGetStaticStreamsContext(Object)) UcxStaticStreams();
559 Context->m_Handle = (UCXSSTREAMS)Object;
560 Context->m_StreamCount = StreamsInit->StreamCount;
561 Context->m_Endpoint = UcxEndpoint::FromHandle(Endpoint);
562 Context->m_Init = StreamsInit;
563
564 StreamsInit->Created = Context->m_Handle;
565 *StaticStreams = Context->m_Handle;
566 *Init = NULL;
567
568 return STATUS_SUCCESS;
569}
570
572VOID
574 _In_ PSTREAM_INFO StreamInfo)
575{
578 UcxPipe* EndpointPipe = &m_Endpoint->m_Pipe;
580 ULONG Index;
581
582 if (Init == NULL)
583 {
584 DPRINT1("Streams %p stream info set outside the add callback\n", m_Handle);
585 UcxVerifierBreak(Verifying);
586 return;
587 }
588
589 if (StreamInfo->Size != sizeof(*StreamInfo))
590 {
591 DPRINT1("Streams %p stream info has bad size %lu\n", m_Handle, StreamInfo->Size);
592 Init->Failed = TRUE;
593 UcxVerifierBreak(Verifying);
594 return;
595 }
596
597 /* Counted even when this call then fails */
598 Index = Init->SetInfoCalls++;
599
600 if (Index >= m_StreamCount || StreamInfo->StreamId != Index + 1 || StreamInfo->WdfQueue == NULL)
601 {
602 DPRINT1("Streams %p bad stream info at call %lu, stream ID %lu, queue %p\n",
603 m_Handle, Index, StreamInfo->StreamId, StreamInfo->WdfQueue);
604 Init->Failed = TRUE;
605 UcxVerifierBreak(Verifying);
606 return;
607 }
608
609 WdfObjectReference(StreamInfo->WdfQueue);
610
611 Entry = Stream(Index);
612 Entry->Filled = TRUE;
613 Entry->Index = Index;
614 Entry->Streams = this;
615 Entry->StreamId = StreamInfo->StreamId;
616 Entry->Pipe.Queue = StreamInfo->WdfQueue;
617 Entry->Pipe.Endpoint = m_Endpoint;
618 Entry->Pipe.TransferType = UcxTransferType::Bulk;
619 Entry->Pipe.Kind = UcxEndpointKind::Generic;
620 Entry->Pipe.BelongsToStream = TRUE;
621 Entry->Pipe.DirectionIn = EndpointPipe->DirectionIn;
622 Entry->Pipe.MaximumTransferSize = EndpointPipe->MaximumTransferSize;
623 Entry->Pipe.Self = &Entry->Pipe;
624}
625
626VOID
627NTAPI
628UcxStaticStreams::EvtDestroy(
630{
631 UcxStaticStreams* Context = UcxGetStaticStreamsContext(Object);
633 ULONG Index;
634
635 for (Index = 0; Index < Context->m_StreamCount; Index++)
636 {
637 Entry = Context->Stream(Index);
638 Entry->Pipe.Self = NULL;
639
640 if (Entry->Pipe.Queue != NULL)
641 {
642 WdfObjectDereference(Entry->Pipe.Queue);
643 Entry->Pipe.Queue = NULL;
644 }
645 }
646}
647
648/* Endpoint machine actions */
649
650VOID
652{
654}
655
656VOID
658{
660}
661
662VOID
664{
666}
667
668/* PurgeDone may be posted from inside the callback */
669VOID
671{
673}
674
675VOID
677{
679}
680
681VOID
683{
684 WDFREQUEST Request = (WDFREQUEST)m_Endpoint->TakePending();
685
687}
688
689/* The IRP still comes back through the completion routine and EndpointResetDone */
690VOID
692{
693 DPRINT1("Endpoint %p reset failed, device is gone or reset\n", m_Endpoint->m_Handle);
694 WdfRequestComplete((WDFREQUEST)m_Endpoint->TakePending(), STATUS_NO_SUCH_DEVICE);
695}
696
697VOID
699{
701}
702
703VOID
705{
706 WDFREQUEST Request = (WDFREQUEST)m_Endpoint->TakePending();
707
709}
710
711/* The open completion deletes the streams and posts StreamsOpened */
712VOID
714{
715 DPRINT1("Endpoint %p static streams enable rejected in this state\n", m_Endpoint->m_Handle);
716 WdfRequestComplete((WDFREQUEST)m_Endpoint->TakePending(), STATUS_INVALID_DEVICE_STATE);
717}
718
719VOID
721 _In_ BOOLEAN ForceFailure)
722{
724
725 if (ForceFailure)
726 {
727 DPRINT1("Endpoint %p static streams open failed by endpoint state\n", m_Endpoint->m_Handle);
729 Irp->IoStatus.Status = STATUS_INVALID_DEVICE_STATE;
730 Irp->IoStatus.Information = 0;
731 }
732 else if (!NT_SUCCESS(Irp->IoStatus.Status))
733 {
735 }
736
738}
739
740VOID
742{
743 WDFREQUEST Request = (WDFREQUEST)m_Endpoint->TakePending();
744
746}
747
748/* Completed by the reset holding queue once the reset is over; the forward status is not checked */
749VOID
751{
752 WDFREQUEST Request = (WDFREQUEST)m_Endpoint->TakePending();
754
755 Status = WdfRequestForwardToIoQueue(Request, m_Endpoint->m_Controller->m_PendDuringResetQueue);
756 if (!NT_SUCCESS(Status))
757 DPRINT1("Endpoint %p could not park streams close %p 0x%lx\n", m_Endpoint->m_Handle, Request, Status);
758}
759
760/* UCX drops its streams even when the controller driver failed the close */
761VOID
763{
765 UcxStaticStreams* Streams;
766
767 {
769
770 Streams = m_Endpoint->m_Streams;
772 }
773
774 if (Streams != NULL)
775 WdfObjectDelete(Streams->m_Handle);
776
779}
780
781/* NULL from the CSQ means the client canceled it meanwhile */
782VOID
784{
786 PURB Urb;
787
788 if (Irp == NULL)
789 return;
790
793}
794
795VOID
797{
799}
800
801/* The request is completed before it is forgotten, and only then may the next one start */
802VOID
804{
806
807 if (InterlockedDecrement(&Controller->m_PendingTreePurgeEndpoints) != 0)
808 return;
809
810 WdfRequestComplete(Controller->m_PendingTreePurge, STATUS_SUCCESS);
811 Controller->m_PendingTreePurge = NULL;
812 WdfIoQueueStart(Controller->m_TreePurgeQueue);
813}
814
815VOID
817{
819}
820
822static
823VOID
824NTAPI
827{
828 UcxUsbDevice* Device = Endpoint->m_Device;
829
830 if (!Device->m_StalePipeIoAllowed)
831 return;
832
833 SpinLockGuard Guard(&Device->m_TrackingLock);
834
835 if (UcxIsListEntryLinked(&Endpoint->m_TrackingLink))
836 {
837 RemoveEntryList(&Endpoint->m_TrackingLink);
838 UcxClearListEntry(&Endpoint->m_TrackingLink);
839 }
840}
841
842/* Delete first, then the creation reference: the parent may already have deleted it */
843VOID
845{
847 UCXENDPOINT Handle = m_Endpoint->m_Handle;
848
849 DPRINT("Endpoint %p deleted\n", Handle);
850
852
853 {
854 SpinLockGuard Guard(&Controller->m_TopologyLock);
855
856 Controller->m_ChildEndpointCount--;
859 }
860
863}
864
868{
871 UcxEndpoint* Replaced = NULL;
872 UcxEndpoint* Candidate;
874 BOOLEAN Parked;
875
877
878 {
879 SpinLockGuard Guard(&Controller->m_TopologyLock);
880
881 for (Entry = Device->m_StaleEndpointList.Flink; Entry != &Device->m_StaleEndpointList; Entry = Entry->Flink)
882 {
883 Candidate = CONTAINING_RECORD(Entry, UcxEndpoint, m_DeviceLink);
884
886 {
889 Replaced = Candidate;
890 break;
891 }
892 }
893
894 Controller->m_ChildEndpointCount--;
898
899 Parked = !Device->m_PendingDelete;
900 if (Parked)
901 InsertTailList(&Device->m_StaleEndpointList, &m_Endpoint->m_DeviceLink);
902 }
903
904 if (Replaced != NULL)
905 Replaced->Post(EpEvent::StaleReplaced);
906
907 DPRINT("Endpoint %p parked as stale %u, replaced %p\n", m_Endpoint->m_Handle, Parked, Replaced);
908
909 return Parked;
910}
911
912/* Already off every list */
913VOID
915{
916 UCXENDPOINT Handle = m_Endpoint->m_Handle;
917
918 DPRINT("Stale endpoint %p deleted\n", Handle);
919
922}
923
926{
928}
929
932{
934}
935
938{
940}
941
944{
946}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
struct _IRP * PIRP
#define PAGED_CODE()
unsigned char BOOLEAN
Definition: actypes.h:127
#define InterlockedDecrement
Definition: armddk.h:52
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
const struct winhelp_callbacks Callbacks
Definition: callback.c:161
VOID CompleteAbortUrb()
Definition: pipe.cpp:783
VOID FailResetRequest()
Definition: pipe.cpp:691
VOID AckControllerReset()
Definition: pipe.cpp:816
VOID FinishStreamsOpenRequest(_In_ BOOLEAN ForceFailure)
Definition: pipe.cpp:720
VOID FinishStreamsCloseRequest()
Definition: pipe.cpp:762
BOOLEAN DeviceAllowsStart()
Definition: pipe.cpp:925
VOID ForwardResetRequest()
Definition: pipe.cpp:682
VOID StartEndpoint()
Definition: pipe.cpp:663
VOID ParkStreamsDisableRequest()
Definition: pipe.cpp:750
BOOLEAN DeviceDisconnected()
Definition: pipe.cpp:937
VOID AbortEndpoint()
Definition: pipe.cpp:676
VOID ReferenceEndpoint()
Definition: pipe.cpp:651
VOID ForwardStreamsDisableRequest()
Definition: pipe.cpp:741
VOID FinishEndpointResetRequest()
Definition: pipe.cpp:698
VOID RejectStreamsEnableRequest()
Definition: pipe.cpp:713
BOOLEAN DeviceDeprogrammed()
Definition: pipe.cpp:931
VOID DereferenceEndpoint()
Definition: pipe.cpp:657
VOID ForwardStreamsEnableRequest()
Definition: pipe.cpp:704
VOID DeleteEndpoint()
Definition: pipe.cpp:844
UcxEndpoint * m_Endpoint
Definition: epsm.h:212
VOID DeleteStaleEndpoint()
Definition: pipe.cpp:914
BOOLEAN ClientHoldsHandle()
Definition: pipe.cpp:943
VOID CompleteHubOperation()
Definition: pipe.cpp:796
VOID PurgeEndpoint()
Definition: pipe.cpp:670
BOOLEAN ParkAsStale()
Definition: pipe.cpp:867
VOID CompleteTreePurge()
Definition: pipe.cpp:803
BOOLEAN m_ClearTtBufferOnAsyncCancel
Definition: hostctl.h:337
IO_CSQ m_AbortPipeCsq
Definition: hostctl.h:306
KSPIN_LOCK m_TopologyLock
Definition: hostctl.h:310
VOID PrepareForResetOperationDone()
Definition: hostreset.cpp:124
UCXCONTROLLER m_Handle
Definition: hostctl.h:287
BOOLEAN m_DriverVerifierEnabled
Definition: hostctl.h:336
WDFQUEUE m_PendDuringResetQueue
Definition: hostctl.h:296
UcxController * m_Controller
Definition: pipe.h:282
UCXSSTREAMS GetStaticStreamsReferenced(_In_ PVOID Tag)
Definition: pipe.cpp:370
VOID SetWdfIoQueue(_In_ WDFQUEUE Queue)
Definition: pipe.cpp:313
static EVT_WDF_OBJECT_CONTEXT_DESTROY EvtDestroy
Definition: pipe.h:334
USB_ENDPOINT_DESCRIPTOR m_Descriptor
Definition: pipe.h:290
UcxEndpointCallbacks m_Callbacks
Definition: pipe.h:289
LIST_ENTRY m_ControllerResetLink
Definition: pipe.h:298
LONG m_CancelSync
Definition: pipe.h:311
static UcxEndpoint * FromHandle(_In_ UCXENDPOINT Handle)
Definition: pipe.cpp:91
BOOLEAN Post(_In_ EpEvent Event)
Definition: pipe.h:255
static NTSTATUS CreateThroughHcd(_In_ UcxUsbDevice *Device, _Inout_ UcxEndpointInit *Init, _In_ ULONG MaxPacketSize, _In_opt_ PUSB_ENDPOINT_DESCRIPTOR Descriptor, _In_ ULONG DescriptorBufferLength, _In_opt_ PUSB_SUPERSPEED_ENDPOINT_COMPANION_DESCRIPTOR Companion, _Out_ UCXENDPOINT *Endpoint)
Definition: pipe.cpp:392
UcxStaticStreams * m_Streams
Definition: pipe.h:286
LIST_ENTRY m_TreePurgeLink
Definition: pipe.h:299
UcxUsbDevice * m_Device
Definition: pipe.h:283
static _Must_inspect_result_ NTSTATUS Create(_In_ UCXUSBDEVICE UsbDevice, _Inout_ PUCXENDPOINT_INIT *EndpointInit, _In_opt_ PWDF_OBJECT_ATTRIBUTES Attributes, _Out_ UCXENDPOINT *Endpoint)
Definition: pipe.cpp:195
VOID ReleaseCancelSync()
Definition: pipe.cpp:360
IO_CSQ_IRP_CONTEXT m_AbortCsqContext
Definition: pipe.h:308
LIST_ENTRY m_DisconnectLink
Definition: pipe.h:297
LONG m_StreamsOpenCount
Definition: pipe.h:287
VOID Initialize(_In_ UcxUsbDevice *Device, _In_ const UcxEndpointInit *Init)
Definition: pipe.cpp:143
LIST_ENTRY m_TrackingLink
Definition: pipe.h:294
UcxPipe m_Pipe
Definition: pipe.h:284
LIST_ENTRY m_OperationLink
Definition: pipe.h:300
UCXENDPOINT m_Handle
Definition: pipe.h:281
static _Must_inspect_result_ NTSTATUS CreateDefaultFromHub(_In_ UCXUSBDEVICE UsbDevice, _In_ ULONG MaxPacketSize, _Out_ UCXENDPOINT *Endpoint)
Definition: pipe.cpp:451
PVOID TakePending()
Definition: pipe.h:264
VOID DeleteFromHub()
Definition: pipe.cpp:515
static _Must_inspect_result_ NTSTATUS CreateFromHub(_In_ UCXUSBDEVICE UsbDevice, _In_ PUSB_ENDPOINT_DESCRIPTOR Descriptor, _In_ ULONG DescriptorBufferLength, _In_opt_ PUSB_SUPERSPEED_ENDPOINT_COMPANION_DESCRIPTOR Companion, _Out_ UCXENDPOINT *Endpoint)
Definition: pipe.cpp:467
LIST_ENTRY m_DeviceLink
Definition: pipe.h:293
BOOLEAN m_ClientHoldsHandle
Definition: pipe.h:313
VOID NeedToCancelTransfers()
Definition: pipe.cpp:328
BOOLEAN m_ClearTtOnCancel
Definition: pipe.h:314
static VOID InitSetDefaultEventCallbacks(_Inout_ PUCXENDPOINT_INIT Init, _In_ PUCX_DEFAULT_ENDPOINT_EVENT_CALLBACKS Callbacks)
Definition: pipe.cpp:125
static VOID InitSetEventCallbacks(_Inout_ PUCXENDPOINT_INIT Init, _In_ PUCX_ENDPOINT_EVENT_CALLBACKS Callbacks)
Definition: pipe.cpp:98
static UcxStaticStreams * FromHandle(_In_ UCXSSTREAMS Handle)
Definition: pipe.cpp:523
static EVT_WDF_OBJECT_CONTEXT_DESTROY EvtDestroy
Definition: pipe.h:389
ULONG m_StreamCount
Definition: pipe.h:381
UcxEndpoint * m_Endpoint
Definition: pipe.h:382
UcxStaticStreamsInit * m_Init
Definition: pipe.h:385
VOID SetStreamInfo(_In_ PSTREAM_INFO StreamInfo)
Definition: pipe.cpp:573
UCXSSTREAMS m_Handle
Definition: pipe.h:380
static _Must_inspect_result_ NTSTATUS Create(_In_ UCXENDPOINT Endpoint, _Inout_ PUCXSSTREAMS_INIT *Init, _In_opt_ PWDF_OBJECT_ATTRIBUTES Attributes, _Out_ UCXSSTREAMS *StaticStreams)
Definition: pipe.cpp:531
BOOLEAN m_Disconnected
Definition: devobj.h:231
VOID CompleteHubOperation()
Definition: devicemgmt.cpp:358
BOOLEAN m_DeprogrammedByControllerReset
Definition: devobj.h:244
BOOLEAN AllowsEndpointStart() const
Definition: devobj.h:130
UCXUSBDEVICE_INFO m_Info
Definition: devobj.h:221
UCXHUB_DEVICE_CONTEXT m_HubDeviceContext
Definition: devobj.h:218
VOID NTAPI UcxCompleteHeldUrbIrp(_In_ PIRP Irp)
Definition: clientxrb.cpp:61
VOID NTAPI UcxCompleteUrbAtDispatch(_In_ PIRP Irp, _In_ PURB Urb, _In_ NTSTATUS Status, _In_ USBD_STATUS UsbdStatus)
Definition: clientxrb.cpp:42
NTKERNELAPI PIRP NTAPI IoCsqRemoveIrp(_Inout_ PIO_CSQ Csq, _Inout_ PIO_CSQ_IRP_CONTEXT Context)
Remove anb IRP from the queue.
Definition: csq.c:326
PLIST_ENTRY Entry
Definition: devhcd.cpp:1262
_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
InitializeListHead & UcxDriver
Definition: driver.cpp:138
#define UCX_MB(x)
Definition: pipe.cpp:16
ULONG NTAPI UcxComputeMaxTransferSize(_In_ USB_DEVICE_SPEED Speed, _In_ USHORT BcdUsb, _In_ const UcxEndpointInit *Init)
Definition: pipe.cpp:49
#define UCX_KB(x)
Definition: pipe.cpp:15
static const ULONG UcxMaxTransferTable[4][5]
Definition: pipe.cpp:19
static VOID NTAPI UcxUntrackEndpoint(_In_ UcxEndpoint *Endpoint)
Definition: pipe.cpp:825
static ULONG NTAPI UcxSpeedRow(_In_ USB_DEVICE_SPEED Speed)
Definition: pipe.cpp:32
static BOOLEAN NTAPI UcxIsSlowSpeed(_In_ USB_DEVICE_SPEED Speed)
Definition: pipe.cpp:41
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define InsertTailList(ListHead, Entry)
#define InsertHeadList(ListHead, Entry)
ULONG Handle
Definition: gdb_input.c:15
Status
Definition: gdiplustypes.h:24
_In_ UCXUSBDEVICE UsbDevice
Definition: hostctl.h:31
UNICODE_STRING Path
_Must_inspect_result_ _In_ PUCXHUB_DEVICE_CREATE_INFO _Out_ UCXUSBDEVICE * Device
Definition: hubucx.h:258
_Must_inspect_result_ _In_ UCXUSBDEVICE _In_ ULONG MaxPacketSize
Definition: hubucx.h:289
_Must_inspect_result_ _In_ UCXUSBDEVICE _In_ ULONG _In_opt_ PUSB_SUPERSPEED_ENDPOINT_COMPANION_DESCRIPTOR Companion
Definition: hubucx.h:308
_In_ UCXHUB_DEVICE_CONTEXT _In_ UCXENDPOINT Endpoint
Definition: hubucx.h:238
_Must_inspect_result_ _In_ UCXUSBDEVICE _In_ ULONG DescriptorBufferLength
Definition: hubucx.h:307
HRESULT Reset([in] ID3D12CommandAllocator *allocator)
#define InterlockedCompareExchange
Definition: interlocked.h:119
_In_ PIRP Irp
Definition: kse.h:79
_In_ PIRP _In_ PIO_COMPLETION_ROUTINE _In_ PVOID Context
Definition: kse.h:81
if(dx< 0)
Definition: linetemp.h:194
static IStream Stream
Definition: htmldoc.c:1115
#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
#define IoCompleteRequest
Definition: irp.c:1272
#define STATUS_INTERNAL_ERROR
Definition: ntstatus.h:559
unsigned short USHORT
Definition: pedump.c:61
UcxTransferType
Definition: pipe.h:20
ULONG NTAPI UcxComputeMaxTransferSize(_In_ USB_DEVICE_SPEED Speed, _In_ USHORT BcdUsb, _In_ const UcxEndpointInit *Init)
Definition: pipe.cpp:49
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:73
PFN_UCX_ENDPOINT_PURGE Purge
Definition: pipe.h:77
PFN_UCX_ENDPOINT_STATIC_STREAMS_ENABLE StaticStreamsEnable
Definition: pipe.h:83
PFN_UCX_ENDPOINT_ABORT Abort
Definition: pipe.h:79
PFN_UCX_ENDPOINT_OK_TO_CANCEL_TRANSFERS OkToCancelTransfers
Definition: pipe.h:81
PFN_UCX_ENDPOINT_RESET Reset
Definition: pipe.h:80
PFN_UCX_ENDPOINT_STATIC_STREAMS_DISABLE StaticStreamsDisable
Definition: pipe.h:84
PFN_UCX_ENDPOINT_START Start
Definition: pipe.h:78
Definition: pipe.h:30
UcxPipe * Self
Definition: pipe.h:40
WDFQUEUE Queue
Definition: pipe.h:31
UcxEndpoint * Endpoint
Definition: pipe.h:32
ULONG IsochPacketLimit
Definition: pipe.h:38
UcxTransferType TransferType
Definition: pipe.h:33
UcxEndpointKind Kind
Definition: pipe.h:34
ULONG MaximumTransferSize
Definition: pipe.h:37
ULONG IsochPeriodMicroframes
Definition: pipe.h:39
BOOLEAN DirectionIn
Definition: pipe.h:36
struct _IO_STACK_LOCATION::@5100::@5139 Others
union _IO_STACK_LOCATION::@1823 Parameters
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
UCXENDPOINT Endpoint
Definition: pipe.h:112
UCXSSTREAMS Created
Definition: pipe.h:116
ULONG StreamCount
Definition: pipe.h:113
UCXUSBDEVICE TtHub
Definition: ucxusbdevice.h:177
USB_DEVICE_PORT_PATH PortPath
Definition: ucxusbdevice.h:178
PFN_UCX_USBDEVICE_ENDPOINT_ADD EvtUsbDeviceEndpointAdd
Definition: ucxusbdevice.h:354
PFN_UCX_USBDEVICE_DEFAULT_ENDPOINT_ADD EvtUsbDeviceDefaultEndpointAdd
Definition: ucxusbdevice.h:353
Definition: usb.h:565
WDFOBJECT ParentObject
Definition: wdfobject.h:130
PFN_WDF_OBJECT_CONTEXT_DESTROY EvtDestroyCallback
Definition: wdfobject.h:115
#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
unsigned char * PUCHAR
Definition: typedefs.h:53
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
_Must_inspect_result_ _In_ UCXENDPOINT _In_ PVOID Tag
Definition: ucxendpoint.h:325
_Must_inspect_result_ _In_ UCXUSBDEVICE _Inout_ PUCXENDPOINT_INIT * EndpointInit
Definition: ucxendpoint.h:314
WDF_EXTERN_C_START struct _STREAM_INFO * PSTREAM_INFO
_Must_inspect_result_ _In_ UCXENDPOINT _Inout_ PUCXSSTREAMS_INIT _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ UCXSSTREAMS * StaticStreams
Definition: ucxsstreams.h:55
_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 UcxVerifierBreak(_In_ BOOLEAN Verifying)
Definition: ucxutil.h:168
FORCEINLINE VOID NTAPI UcxClearListEntry(_Out_ PLIST_ENTRY Entry)
Definition: ucxutil.h:84
#define STATUS_DEVICE_NOT_CONNECTED
Definition: udferr_usr.h:160
#define STATUS_NO_SUCH_DEVICE
Definition: udferr_usr.h:136
#define STATUS_INVALID_DEVICE_STATE
Definition: udferr_usr.h:178
#define USB_ENDPOINT_TYPE_MASK
Definition: usb100.h:61
#define USB_ENDPOINT_DIRECTION_IN(x)
Definition: usb100.h:76
@ UsbSuperSpeed
Definition: usb200.h:45
@ UsbHighSpeed
Definition: usb200.h:44
@ UsbLowSpeed
Definition: usb200.h:42
@ UsbFullSpeed
Definition: usb200.h:43
enum _USB_DEVICE_SPEED USB_DEVICE_SPEED
struct _URB * PURB
#define USBD_STATUS_SUCCESS
Definition: usb.h:177
_In_opt_ PUSB_CONFIGURATION_DESCRIPTOR _Inout_ PUSBD_INTERFACE_LIST_ENTRY _Outptr_ PURB * Urb
Definition: usbdlib.h:333
WdfObjectDelete(String)
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object
_In_ WDFCOLLECTION _In_ ULONG Index
_Must_inspect_result_ _In_ WDFDEVICE _In_ PIRP _In_ WDFQUEUE Queue
Definition: wdfdevice.h:2231
#define WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(_attributes, _contexttype)
Definition: wdfobject.h:170
#define WdfObjectReference(Handle)
Definition: wdfobject.h:803
#define WdfObjectReferenceWithTag(Handle, Tag)
Definition: wdfobject.h:806
#define WdfObjectDereference(Handle)
Definition: wdfobject.h:826
_In_ WDFIOTARGET Target
Definition: wdfrequest.h:306
_Must_inspect_result_ _In_ WDFIORESLIST _In_ PIO_RESOURCE_DESCRIPTOR Descriptor
Definition: wdfresource.h:342
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define NT_ASSERT
Definition: rtlfuncs.h:3334