ReactOS 0.4.17-dev-1281-g065abb3
hubreq.cpp
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS SuperSpeed USB Hub Driver
3 * LICENSE: MIT (https://spdx.org/licenses/MIT)
4 * PURPOSE: Transfers the hub sends to its own hub device
5 * COPYRIGHT: Copyright 2026 Justin Miller <justin.miller@reactos.org>
6 */
7
8#include "usbhub3.h"
9
10#define NDEBUG
11#include <debug.h>
12
13/* Public in newer usb.h: the transfer must not wait on paging */
14#ifndef USB3_URB_RESERVED_RESOURCES
15#define USB3_URB_RESERVED_RESOURCES 0x00000010
16#endif
17
18/* Control request blocks */
19
24 _In_ WDFIOTARGET SizingTarget)
25{
28
30 Attributes.ParentObject = Parent;
31
32 Status = WdfRequestCreate(&Attributes, SizingTarget, &Request);
33 if (!NT_SUCCESS(Status))
34 {
35 DPRINT1("Control request create for %p failed 0x%lx\n", Parent, Status);
36 return Status;
37 }
38
39 Irp = WdfRequestWdmGetIrp(Request);
40 UsbdFlags = 0;
41 return STATUS_SUCCESS;
42}
43
44VOID
46{
49
51
52 Status = WdfRequestReuse(Request, &Params);
53 if (!NT_SUCCESS(Status))
54 DPRINT1("Reusing request %p failed 0x%lx\n", Request, Status);
55}
56
57/*
58 * The setup packet is already filled. A refused send is reported through the
59 * request's status, and the request is made ready for the next use.
60 */
63 _In_ WDFIOTARGET Target,
64 _In_opt_ UCXUSBDEVICE Device,
69 _In_ BOOLEAN ShortTransferOk,
70 _In_ BOOLEAN ForwardProgress)
71{
74
75 Urb.Hdr.Length = sizeof(Urb);
76 Urb.Hdr.Function = URB_FUNCTION_CONTROL_TRANSFER_EX;
77 Urb.Hdr.UsbdDeviceHandle = Device;
78 Urb.Hdr.UsbdFlags = UsbdFlags;
79
80 Urb.TransferFlags = USBD_DEFAULT_PIPE_TRANSFER;
81 if (ShortTransferOk)
82 Urb.TransferFlags |= USBD_SHORT_TRANSFER_OK;
83 if (Urb.SetupPacket[0] & 0x80)
84 Urb.TransferFlags |= USBD_TRANSFER_DIRECTION_IN;
85 if (ForwardProgress)
86 Urb.TransferFlags |= USB3_URB_RESERVED_RESOURCES;
87
88 Urb.TransferBufferLength = Length;
89 Urb.TransferBuffer = Buffer;
90 Urb.TransferBufferMDL = NULL;
92
93 RtlZeroMemory(&Stack, sizeof(Stack));
95 Stack.Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB;
96 Stack.Parameters.Others.Argument1 = &Urb;
97 WdfRequestWdmFormatUsingStackLocation(Request, &Stack);
98
99 WdfRequestSetCompletionRoutine(Request, Completion, Context);
100
102 return STATUS_SUCCESS;
103
104 Status = WdfRequestGetStatus(Request);
105 if (!NT_SUCCESS(Status))
106 {
107 DPRINT1("Control request 0x%x to device %p not sent 0x%lx\n", Urb.SetupPacket[1], Device, Status);
108 Reuse();
109 }
110
111 return Status;
112}
113
114/* TT clear on behalf of ucx01000 */
115
116static const char HubTagClearTt[] = "hub TT clear";
117
118/* One TT clear in flight; several can be outstanding at once */
120{
123 UCXENDPOINT Endpoint;
124};
125
126/* CLEAR_TT_BUFFER wValue; only control and bulk endpoints of low and full speed devices qualify */
127static
129NTAPI
132 _In_ UCXENDPOINT Endpoint,
133 _In_ ULONG EndpointAddress,
135{
136 HubConfiguration* Config = Child->m_CurrentConfig;
139 HubPipe* Pipe;
140 ULONG Index;
141 USHORT Type;
142
143 *Value = 0;
144
145 if (Child->Speed() != UsbLowSpeed && Child->Speed() != UsbFullSpeed)
146 return STATUS_UNSUCCESSFUL;
147
148 if (Endpoint == Child->m_DefaultEndpoint)
149 {
150 *Value = (USHORT)((EndpointAddress & 0x0F) | ((Child->m_Address & 0x7F) << 4));
151 return STATUS_SUCCESS;
152 }
153
154 if (Config == NULL)
155 return STATUS_UNSUCCESSFUL;
156
157 for (Entry = Config->Interfaces.Flink; Entry != &Config->Interfaces; Entry = Entry->Flink)
158 {
160
161 for (Index = 0; Index < Interface->PipeCount; Index++)
162 {
163 Pipe = &Interface->Pipes[Index];
164 if (Pipe->Endpoint != Endpoint)
165 continue;
166
167 switch (Pipe->Descriptor->bmAttributes & USB_ENDPOINT_TYPE_MASK)
168 {
170 Type = 2;
171 break;
172
174 Type = 0;
175 break;
176
177 default:
178 return STATUS_UNSUCCESSFUL;
179 }
180
181 *Value = (USHORT)((EndpointAddress & 0x0F) | ((Child->m_Address & 0x7F) << 4) | (Type << 11));
182 if (EndpointAddress & USB_ENDPOINT_DIRECTION_MASK)
183 *Value |= 0x8000;
184 return STATUS_SUCCESS;
185 }
186 }
187
188 return STATUS_UNSUCCESSFUL;
189}
190
191static
192VOID
193NTAPI
195 _In_ WDFREQUEST Request,
196 _In_ WDFIOTARGET Target,
199{
201 HubFdo* Hub = Clear->Hub;
202
204
205 if (!NT_SUCCESS(Params->IoStatus.Status))
206 {
207 DPRINT1("Hub %p TT clear for endpoint %p failed 0x%lx, URB status 0x%lx\n",
208 Hub, Clear->Endpoint, Params->IoStatus.Status, Clear->Control.Urb.Hdr.Status);
209 }
210
212
215}
216
217/* Every path tells UCX the clear is over exactly once; until then the transfer cannot be canceled */
218VOID
219NTAPI
221 _In_ UCXHUB_HUB_CONTEXT HubContext,
222 _In_ UCXHUB_DEVICE_CONTEXT DeviceContext,
223 _In_ UCXENDPOINT Endpoint,
226{
230 WDFREQUEST Request = NULL;
234
236 goto Done;
237
238 /* Computed even for RESET_TT, which does not use it */
242 if (!NT_SUCCESS(Status))
243 goto Done;
244
246 if (Clear == NULL)
247 {
248 DPRINT1("Hub %p no memory for a TT clear\n", Hub);
249 goto Done;
250 }
251
252 Clear->Hub = Hub;
253 Clear->Endpoint = Endpoint;
254
255 if (!NT_SUCCESS(Clear->Control.Create(Hub->m_Device, WdfDeviceGetIoTarget(Hub->m_Device))))
256 goto Done;
257 Request = Clear->Control.Request;
258
259 Clear->Control.SetSetup(0x23,
261 ResetTt ? 0 : Value,
263 0);
264
265 Status = Clear->Control.Send(Hub->m_RootHubTarget,
266 Hub->UsbDevice(),
268 Clear,
269 NULL,
270 0,
271 FALSE,
273 if (NT_SUCCESS(Status))
274 return;
275
276Done:
277 if (Request != NULL)
279 if (Clear != NULL)
281
283}
284
285/* Output of IOCTL_USB_GET_PORT_STATUS */
286#define HUB_USER_PORT_STATUS_OFFSET 4
287#define HUB_USER_PORT_STATUS_SIZE 8
288
289static EVT_WDF_REQUEST_COMPLETION_ROUTINE HubControlComplete;
290static EVT_WDF_REQUEST_COMPLETION_ROUTINE HubInterruptComplete;
291
292/* Hub level transfers */
293
294static
295VOID
296NTAPI
298 _In_ WDFREQUEST Request,
299 _In_ WDFIOTARGET Target,
302{
304 NTSTATUS Status = Params->IoStatus.Status;
305
308
310
311 if (!NT_SUCCESS(Status))
312 {
313 DPRINT1("Hub %p control request 0x%x failed 0x%lx, URB status 0x%lx\n",
314 Hub, Hub->m_Control.Urb.SetupPacket[1], Status, Hub->m_Control.Urb.Hdr.Status);
317 return;
318 }
319
321}
322
323/* A refused send is reported to the machine right away */
324static
325VOID
326NTAPI
328 _In_ HubFdo* Hub,
331 _In_ BOOLEAN ShortOk)
332{
334
336 Hub->UsbDevice(),
338 Hub,
339 Buffer,
340 Length,
341 ShortOk,
343 if (!NT_SUCCESS(Status))
345}
346
347VOID
349{
351 DPRINT("Hub %p acking hub change %u\n", m_Hub, m_Hub->m_SelectedFeature);
353}
354
355/* Only full, high and SuperSpeed hubs have a hub descriptor */
356VOID
358{
359 switch (m_Hub->m_Parent.HubSpeed)
360 {
361 case UsbFullSpeed:
362 case UsbHighSpeed:
366 0,
367 sizeof(m_Hub->m_HubDescriptor.Usb20));
369 break;
370
371 case UsbSuperSpeed:
375 0,
376 sizeof(m_Hub->m_HubDescriptor.Usb30));
378 break;
379
380 default:
381 DPRINT1("Hub %p of speed %lu has no hub descriptor\n", m_Hub, (ULONG)m_Hub->m_Parent.HubSpeed);
382 m_Hub->Post(HubEvent::TransferFailed);
383 break;
384 }
385}
386
387VOID
389{
391 DPRINT("Hub %p reading device status\n", m_Hub);
393}
394
395/* The previous copy is kept even when the send then fails */
396VOID
398{
400
402 DPRINT("Hub %p reading hub status\n", m_Hub);
404}
405
406/* The parent reports a 1 based depth; the hub wants it 0 based */
407VOID
409{
411 DPRINT("Hub %p setting hub depth %lu\n", m_Hub, (ULONG)m_Hub->m_Parent.HubDepth - 1);
413}
414
415/* The first read takes 255 bytes, a second one the full length; the buffer is zeroed so a short read leaves no stale wTotalLength */
416VOID
418 _In_ BOOLEAN FullLength)
419{
424
425 if (!FullLength)
426 {
427 if (Previous != NULL)
429 Previous = NULL;
431 }
432 else
433 {
434 Length = Previous->wTotalLength;
435 }
436
438
440 if (Buffer == NULL)
441 {
442 DPRINT1("Hub %p no memory for a %lu byte configuration descriptor\n", m_Hub, Length);
444 }
445 else
446 {
447 DPRINT("Hub %p reading %lu bytes of configuration descriptor\n", m_Hub, Length);
449
452 m_Hub->UsbDevice(),
454 m_Hub,
455 Buffer,
456 Length,
457 TRUE,
459 }
460
461 if (Previous != NULL)
463
464 if (NT_SUCCESS(Status))
465 return;
466
468 {
471 }
472
473 m_Hub->Post(HubEvent::TransferFailed);
474}
475
476/* Despite the name, only wTotalLength is looked at */
479{
482}
483
484/*
485 * The length check runs after the validator so both get logged. A read
486 * shorter than a configuration descriptor is refused before any copy.
487 */
490{
495
496 if (m_Hub->m_Control.Urb.TransferBufferLength < sizeof(*Held) || TotalLength < sizeof(*Held))
497 {
498 DPRINT1("Hub %p configuration descriptor too short, %lu bytes, wTotalLength %u\n",
499 m_Hub, m_Hub->m_Control.Urb.TransferBufferLength, TotalLength);
500 goto Exit;
501 }
502
503 /* The buffer was sized from the first read, so a larger second wTotalLength is rejected */
505 {
507 goto Exit;
508 }
509
510 if (TotalLength < MAXUCHAR)
511 {
513 if (Copy == NULL)
514 {
515 DPRINT1("Hub %p no memory to cache the configuration descriptor\n", m_Hub);
516 goto Exit;
517 }
518
521 }
522
524 goto Exit;
525
527 {
529 goto Exit;
530 }
531
532 Valid = TRUE;
533
534Exit:
535 if (Copy != NULL)
537
539 {
542 }
543
544 return Valid;
545}
546
547/*
548 * Flags are only ever set, so a re-read after a hub reset cannot clear one.
549 * The validator gets the full buffer size, not the returned length.
550 */
553{
554 USHORT Characteristics;
555 ULONG OverCurrentMode;
556
557 switch (m_Hub->m_Parent.HubSpeed)
558 {
559 case UsbFullSpeed:
560 case UsbHighSpeed:
562 return FALSE;
563
566
567 if (Characteristics & 0x0001)
568 m_Hub->SetFlag(HubFlag::PerPortPower);
569 if (Characteristics & 0x0008)
570 m_Hub->SetFlag(HubFlag::PerPortOverCurrent);
571 return TRUE;
572
573 case UsbSuperSpeed:
575 return FALSE;
576
579 OverCurrentMode = (Characteristics >> 3) & 0x3;
580
581 if (Characteristics & 0x0001)
582 m_Hub->SetFlag(HubFlag::PerPortPower);
583 if (OverCurrentMode == 1)
584 m_Hub->SetFlag(HubFlag::PerPortOverCurrent);
585 else if (OverCurrentMode >= 2)
586 m_Hub->SetFlag(HubFlag::NoOverCurrentProtection);
587 return TRUE;
588
589 default:
590 DPRINT1("Hub %p of speed %lu has no hub descriptor to parse\n", m_Hub, (ULONG)m_Hub->m_Parent.HubSpeed);
591 return FALSE;
592 }
593}
594
597{
599 return TRUE;
600}
601
604{
607
609 {
610 DPRINT1("Hub %p over current change, hub status 0x%x\n", m_Hub, Status);
611 HubNoteHubOverCurrent(m_Hub);
612 m_Hub->m_SelectedChange = (Status & HS_OVER_CURRENT) ? HubChange::OverCurrent : HubChange::OverCurrentCleared;
614 return HubCheck::Yes;
615 }
616
618 {
619 DPRINT("Hub %p local power change, hub status 0x%x\n", m_Hub, Status);
620 m_Hub->m_SelectedChange = (Status & HS_LOCAL_POWER_LOST) ? HubChange::PowerLost : HubChange::PowerGood;
622 return HubCheck::Yes;
623 }
624
625 if (Change != 0)
626 DPRINT1("Hub %p reports unknown hub change 0x%x\n", m_Hub, Change);
627
628 return (Change != 0) ? HubCheck::Error : HubCheck::No;
629}
630
633{
634 return m_Hub->m_SelectedChange;
635}
636
637/* A lost change is never reported */
640{
641 return HubChange::None;
642}
643
646{
648}
649
652{
653 return TRUE;
654}
655
656/* Status change interrupt transfer */
657
658static
659VOID
660NTAPI
662 _In_ WDFREQUEST Request,
663 _In_ WDFIOTARGET Target,
666{
669 NTSTATUS Status = Params->IoStatus.Status;
670
673
674 /* Built by hand; the bitmap helper that initializes it is pageable */
675 Interrupt->BitmapBytes = (USHORT)Interrupt->Urb.TransferBufferLength;
676 Interrupt->Bitmap.SizeOfBitMap = Interrupt->BitmapBytes * 8;
677 Interrupt->Bitmap.Buffer = (PULONG)Interrupt->BitmapBuffer;
678
679 if (!NT_SUCCESS(Status))
680 {
681 /* The hub cancels its own read when it powers down */
683 {
684 DPRINT("Hub %p status change read canceled\n", Hub);
685 }
686 else
687 {
688 DPRINT1("Hub %p status change read failed 0x%lx, URB status 0x%lx\n",
689 Hub, Status, Interrupt->Urb.Hdr.Status);
691 }
692
694 return;
695 }
696
698}
699
700/*
701 * After a transfer with no change bits, the root hub is asked to hold the
702 * next one in UCX instead of polling the controller driver.
703 */
704VOID
706{
711
713 WdfRequestReuse(Interrupt->Request, &Reuse);
714
715 RtlZeroMemory(&Interrupt->Urb, sizeof(Interrupt->Urb));
716 Interrupt->Urb.Hdr.Length = sizeof(Interrupt->Urb);
718 Interrupt->Urb.Hdr.UsbdDeviceHandle = m_Hub->UsbDevice();
719 Interrupt->Urb.TransferFlags = USBD_SHORT_TRANSFER_OK;
721 Interrupt->Urb.TransferFlags |= USB3_URB_RESERVED_RESOURCES;
722
723 Interrupt->Urb.TransferBuffer = Interrupt->BitmapBuffer;
724 Interrupt->Urb.TransferBufferLength = m_Hub->IsRootHub() ? Interrupt->BitmapMaxBytes : m_Hub->m_InterruptMaxPacket;
725 Interrupt->Urb.PipeHandle = Interrupt->Pipe;
726
727 if (Interrupt->LastInterruptWasEmpty)
728 {
729 Interrupt->Urb.Hdr.UsbdFlags |= UCXHUB_URB_FLAG_PEND_INTERRUPT_TX;
730 Interrupt->LastInterruptWasEmpty = FALSE;
731 }
732
733 RtlZeroMemory(&Stack, sizeof(Stack));
735 Stack.Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB;
736 Stack.Parameters.Others.Argument1 = &Interrupt->Urb;
737 WdfRequestWdmFormatUsingStackLocation(Interrupt->Request, &Stack);
738
739 WdfRequestSetCompletionRoutine(Interrupt->Request, HubInterruptComplete, m_Hub);
740
741 if (WdfRequestSend(Interrupt->Request, WdfDeviceGetIoTarget(m_Hub->m_Device), WDF_NO_SEND_OPTIONS))
742 return;
743
744 /* A refused send with a success status posts nothing */
745 Status = WdfRequestGetStatus(Interrupt->Request);
746 WdfRequestReuse(Interrupt->Request, &Reuse);
747
748 if (!NT_SUCCESS(Status))
749 {
750 DPRINT1("Hub %p status change read not sent 0x%lx\n", m_Hub, Status);
751 m_Hub->Post(HubEvent::InterruptFailed);
752 }
753}
754
755/* The completion still posts exactly one event */
756VOID
758{
759 if (!WdfRequestCancelSentRequest(m_Hub->m_Interrupt.Request))
760 DPRINT1("Hub %p status change read not canceled\n", m_Hub);
761}
762
763/* Bit 0 is read even after a zero length completion */
766{
768 HubCheck Result = (Interrupt->BitmapBuffer[0] & 1) ? HubCheck::Yes : HubCheck::No;
769 ULONG Bit;
770
771 for (Bit = 1; Bit < (ULONG)Interrupt->BitmapBytes * 8; Bit++)
772 {
773 if (!(Interrupt->BitmapBuffer[Bit / 8] & (1 << (Bit % 8))))
774 continue;
775
776 if (m_Hub->FindPort(Bit) == NULL)
777 {
778 DPRINT1("Hub %p reports a change on missing port %lu\n", m_Hub, Bit);
779 return HubCheck::Error;
780 }
781 }
782
783 return Result;
784}
785
786/* Client and user mode port status */
787
788/* Reads into the target port's own status buffer */
789VOID
791{
793 BOOLEAN Extended = Port->HasProperty(PortProperty::EnhancedSuperSpeed);
794 USHORT Length = Extended ? sizeof(Port->m_Current) : sizeof(Port->m_Current.StatusChange);
795
796 m_Hub->m_Control.SetSetup(0xA3, HUB_REQUEST_GET_STATUS, Extended ? 2 : 0, Port->Number(), Length);
797 HubSendControl(m_Hub, &Port->m_Current, Length, FALSE);
798}
799
800static
801WDFREQUEST
802NTAPI
804 _In_ HubFdo* Hub,
806{
807 WDFREQUEST Request = Hub->m_PortStatusRequest;
808
810
812 WdfRequestGetParameters(Request, Params);
813 return Request;
814}
815
816/* A child sees a port that lost power as disabled once, so its driver resets it */
817VOID
819{
821 USHORT Status = Port->m_Current.StatusChange.PortStatus.AsUshort16;
822 USHORT Change = Port->m_Current.StatusChange.PortChange.AsUshort16;
825 WDFMEMORY Memory;
827 PULONG Bits;
828 HubPdo* Pdo;
829
830 switch (Params.Parameters.DeviceIoControl.IoControlCode)
831 {
833 Result = WdfRequestRetrieveOutputMemory(Request, &Memory);
834 if (!NT_SUCCESS(Result))
835 {
836 DPRINT1("Hub %p port %u status output buffer missing 0x%lx\n", m_Hub, Port->Number(), Result);
837 WdfRequestComplete(Request, Result);
838 return;
839 }
840
841 *(PUSHORT)((PUCHAR)WdfMemoryGetBuffer(Memory, NULL) + HUB_USER_PORT_STATUS_OFFSET) = Status;
843 return;
844
846 Bits = (PULONG)Params.Parameters.Others.Arg1;
847 Pdo = (HubPdo*)Params.Parameters.Others.Arg2;
849
850 if (Status & PS_CONNECTED)
851 *Bits |= USBD_PORT_CONNECTED;
852 else
854
855 if (Status & PS_ENABLED)
856 {
857 if (Pdo->m_Flags & (LONG)PdoFlag::ReportPortDisabled)
858 InterlockedAnd(&Pdo->m_Flags, ~(LONG)PdoFlag::ReportPortDisabled);
859 else
860 *Bits |= USBD_PORT_ENABLED;
861 }
862
863 if (Change & PC_CONNECT)
865
866 if (!NT_SUCCESS(Result))
867 {
868 DPRINT1("Hub %p port %u status 0x%x change 0x%x reported as no device\n",
869 m_Hub, Port->Number(), Status, Change);
870 }
871
872 WdfRequestComplete(Request, Result);
873 return;
874
875 default:
876 DPRINT1("Hub %p port status request with IOCTL 0x%lx\n",
877 m_Hub, Params.Parameters.DeviceIoControl.IoControlCode);
878 WdfRequestComplete(Request, STATUS_ADAPTER_HARDWARE_ERROR);
879 return;
880 }
881}
882
883VOID
885 _In_ BOOLEAN HardwareError)
886{
889
890 if (Params.Parameters.DeviceIoControl.IoControlCode == IOCTL_INTERNAL_USB_GET_PORT_STATUS)
891 *(PULONG)Params.Parameters.Others.Arg1 = 0;
892
893 DPRINT1("Hub %p port %u status request failed, hardware error %u\n",
894 m_Hub, m_Hub->m_PortStatusTarget->Number(), HardwareError);
895
896 WdfRequestComplete(Request, HardwareError ? STATUS_ADAPTER_HARDWARE_ERROR : STATUS_NO_SUCH_DEVICE);
897}
Type
Definition: Type.h:7
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
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
HubFdo * Hub
Definition: bootdev.cpp:261
Definition: bufpool.h:45
Definition: fdo.h:132
PUSB_CONFIGURATION_DESCRIPTOR m_ConfigDescriptor
Definition: fdo.h:425
USHORT m_SelectedFeature
Definition: fdo.h:427
WDFDEVICE m_Device
Definition: fdo.h:349
USB_HUB_DESCRIPTOR Usb20
Definition: fdo.h:419
VOID SetFlag(_In_ HubFlag Flag)
Definition: fdo.h:160
static HubFdo * FromContext(_In_ UCXHUB_HUB_CONTEXT Context)
Definition: fdo.h:144
WDFIOTARGET m_RootHubTarget
Definition: fdo.h:368
WDFREQUEST m_PortStatusRequest
Definition: fdo.h:392
ULONG m_PortCount
Definition: fdo.h:379
USHORT m_ConfigTotalLength
Definition: fdo.h:426
VOID Post(_In_ HubEvent Event)
Definition: fdo.h:194
HubControlRequest m_Control
Definition: fdo.h:413
USB_HUB_STATUS_AND_CHANGE m_PreviousHubStatus
Definition: fdo.h:424
HubInterruptRequest m_Interrupt
Definition: fdo.h:414
UCXHUB_STACK_INTERFACE m_Stack
Definition: fdo.h:356
BOOLEAN HasFlag(_In_ HubFlag Flag) const
Definition: fdo.h:153
ULONG m_FailureMessageId
Definition: fdo.h:402
USB_DEVICE_STATUS m_DeviceStatus
Definition: fdo.h:422
UCXUSBDEVICE UsbDevice() const
Definition: fdo.h:180
USHORT m_InterruptMaxPacket
Definition: fdo.h:429
HubPort * m_PortStatusTarget
Definition: fdo.h:393
HubChange m_SelectedChange
Definition: fdo.h:428
USB_30_HUB_DESCRIPTOR Usb30
Definition: fdo.h:420
ULONG m_MaxPortPower
Definition: fdo.h:384
BOOLEAN NeedsForwardProgress() const
Definition: fdo.h:208
UCXHUB_PARENT_INTERFACE m_Parent
Definition: fdo.h:355
BOOLEAN IsRootHub() const
Definition: fdo.h:174
union HubFdo::@1628 m_HubDescriptor
HubPort * FindPort(_In_ ULONG PortNumber)
Definition: fanout.cpp:42
USB_HUB_STATUS_AND_CHANGE m_HubStatus
Definition: fdo.h:423
HubChange LostHubChange()
Definition: hubreq.cpp:639
VOID GetHubDescriptor()
Definition: hubreq.cpp:357
BOOLEAN CacheConfigDescriptor()
Definition: hubreq.cpp:489
VOID StartStatusChangeRead()
Definition: hubreq.cpp:705
VOID AckHubChange()
Definition: hubreq.cpp:348
BOOLEAN IsErrorFatal()
Definition: hubreq.cpp:651
HubFdo * m_Hub
Definition: hubsm.h:574
VOID GetStandardStatus()
Definition: hubreq.cpp:388
VOID GetHubStatus()
Definition: hubreq.cpp:397
VOID GetConfigDescriptor(_In_ BOOLEAN FullLength)
Definition: hubreq.cpp:417
BOOLEAN ConfigDescriptorTruncated()
Definition: hubreq.cpp:478
HubCheck CheckHubChangeBit()
Definition: hubreq.cpp:765
VOID CancelStatusChangeRead()
Definition: hubreq.cpp:757
HubCheck SelectHubChange()
Definition: hubreq.cpp:603
BOOLEAN OverCurrentCleared()
Definition: hubreq.cpp:645
BOOLEAN ParseHubDescriptor()
Definition: hubreq.cpp:552
VOID FailPortStatus(_In_ BOOLEAN HardwareError)
Definition: hubreq.cpp:884
VOID ReplyPortStatus()
Definition: hubreq.cpp:818
BOOLEAN ParsePowerStatus()
Definition: hubreq.cpp:596
VOID SetHubDepth()
Definition: hubreq.cpp:408
VOID GetPortStatus()
Definition: hubreq.cpp:790
HubChange PendingHubChange()
Definition: hubreq.cpp:632
USHORT Number() const
Definition: hubport.h:213
BOOLEAN Valid
Definition: desccheck.cpp:2227
PLIST_ENTRY Entry
Definition: devhcd.cpp:1262
ULONG Copy
Definition: devhcd.cpp:1449
KEVENT Done
Definition: devreq.cpp:1162
_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
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define NonPagedPool
Definition: env_spec_w32.h:307
return pRequest Reuse(ReuseParams)
Status
Definition: gdiplustypes.h:24
CPPORT Port[4]
Definition: headless.c:38
BOOLEAN NTAPI HubValidateHubConfiguration(_In_ HubFdo *Hub, _In_reads_bytes_(Length) PUSB_CONFIGURATION_DESCRIPTOR Descriptor, _In_ ULONG Length)
Definition: hubdescval.cpp:46
BOOLEAN NTAPI HubCheckUsb2HubDescriptor(_In_ HubFdo *Hub, _In_reads_bytes_(Length) PUSB_HUB_DESCRIPTOR Descriptor, _In_ ULONG Length)
Definition: hubdescval.cpp:59
VOID NTAPI HubLogConfigTotalLengthMismatch(_In_ HubFdo *Hub)
Definition: hubdescval.cpp:85
BOOLEAN NTAPI HubCheckUsb3HubDescriptor(_In_ HubFdo *Hub, _In_reads_bytes_(Length) PUSB_30_HUB_DESCRIPTOR Descriptor, _In_ ULONG Length)
Definition: hubdescval.cpp:72
Previous
static EVT_WDF_REQUEST_COMPLETION_ROUTINE HubInterruptComplete
Definition: hubreq.cpp:290
static EVT_WDF_REQUEST_COMPLETION_ROUTINE HubControlComplete
Definition: hubreq.cpp:289
#define USB3_URB_RESERVED_RESOURCES
Definition: hubreq.cpp:15
static NTSTATUS NTAPI HubTtClearValue(_In_ HubChild *Child, _In_ UCXENDPOINT Endpoint, _In_ ULONG EndpointAddress, _Out_ PUSHORT Value)
Definition: hubreq.cpp:130
static WDFREQUEST NTAPI HubTakePortStatusRequest(_In_ HubFdo *Hub, _Out_ PWDF_REQUEST_PARAMETERS Params)
Definition: hubreq.cpp:803
static const char HubTagClearTt[]
Definition: hubreq.cpp:116
VOID NTAPI HubClearTtBuffer(_In_ UCXHUB_HUB_CONTEXT HubContext, _In_ UCXHUB_DEVICE_CONTEXT DeviceContext, _In_ UCXENDPOINT Endpoint, _In_ ULONG EndpointNumber, _In_ ULONG TtPortNumber)
Definition: hubreq.cpp:220
#define HUB_USER_PORT_STATUS_SIZE
Definition: hubreq.cpp:287
#define HUB_USER_PORT_STATUS_OFFSET
Definition: hubreq.cpp:286
static VOID NTAPI HubSendControl(_In_ HubFdo *Hub, _In_reads_bytes_opt_(Length) PVOID Buffer, _In_ ULONG Length, _In_ BOOLEAN ShortOk)
Definition: hubreq.cpp:327
static VOID NTAPI HubTtClearComplete(_In_ WDFREQUEST Request, _In_ WDFIOTARGET Target, _In_ PWDF_REQUEST_COMPLETION_PARAMS Params, _In_ WDFCONTEXT Context)
Definition: hubreq.cpp:194
#define HUB_REQUEST_CLEAR_FEATURE
Definition: hubreq.h:86
#define HUB_SETUP_REQUEST_TIMEOUT_MS
Definition: hubreq.h:11
#define HUB_MSG_CONTROL_TRANSFER_FAILED
Definition: hubreq.h:151
#define HUB_REQUEST_CLEAR_TT_BUFFER
Definition: hubreq.h:89
#define HUB_REQUEST_RESET_TT
Definition: hubreq.h:90
#define HUB_MSG_INTERRUPT_FAILED
Definition: hubreq.h:152
#define PC_CONNECT
Definition: hubreq.h:136
#define HUB_REQUEST_GET_STATUS
Definition: hubreq.h:85
#define PS_CONNECTED
Definition: hubreq.h:126
#define HUB_C_LOCAL_POWER
Definition: hubreq.h:94
#define HUB_REQUEST_GET_DESCRIPTOR
Definition: hubreq.h:88
#define HS_OVER_CURRENT
Definition: hubreq.h:147
#define HUB_C_OVER_CURRENT
Definition: hubreq.h:95
#define HUB_REQUEST_SET_HUB_DEPTH
Definition: hubreq.h:91
#define PS_ENABLED
Definition: hubreq.h:127
#define HS_LOCAL_POWER_LOST
Definition: hubreq.h:146
HubCheck
Definition: hubsm.h:72
@ TransferFailed
@ InterruptFailed
HubChange
Definition: hubsm.h:80
_In_ UCXHUB_DEVICE_CONTEXT _In_ UCXENDPOINT _In_ ULONG _In_ ULONG TtPortNumber
Definition: hubucx.h:240
_Must_inspect_result_ _In_ PUCXHUB_DEVICE_CREATE_INFO _Out_ UCXUSBDEVICE * Device
Definition: hubucx.h:258
_In_ UCXHUB_DEVICE_CONTEXT DeviceContext
Definition: hubucx.h:237
_In_ UCXHUB_DEVICE_CONTEXT _In_ UCXENDPOINT Endpoint
Definition: hubucx.h:238
_In_ UCXHUB_DEVICE_CONTEXT _In_ UCXENDPOINT _In_ ULONG EndpointNumber
Definition: hubucx.h:239
_In_ UCXUSBDEVICE _In_ PDEVICE_OBJECT Pdo
Definition: hubucx.h:280
#define UCXHUB_URB_FLAG_PEND_INTERRUPT_TX
Definition: hubucx.h:100
#define HUB_TAG_HUB
Definition: hubutil.h:12
#define InterlockedAnd
Definition: interlocked.h:77
_In_ PIRP Irp
Definition: kse.h:79
_In_ PIRP _In_ PIO_COMPLETION_ROUTINE _In_ PVOID Context
Definition: kse.h:81
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
static PVOID ExAllocatePoolZero(ULONG PoolType, SIZE_T NumberOfBytes, ULONG Tag)
Definition: precomp.h:45
static void Clear(void)
Definition: treeview.c:388
#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 _In_reads_bytes_opt_(s)
Definition: no_sal2.h:224
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:329
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define STATUS_ADAPTER_HARDWARE_ERROR
Definition: ntstatus.h:524
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:73
static void Exit(void)
Definition: sock.c:1330
ULONG UsbdFlags
Definition: hubreq.h:24
_Must_inspect_result_ NTSTATUS Create(_In_ WDFOBJECT Parent, _In_ WDFIOTARGET SizingTarget)
Definition: hubreq.cpp:22
NTSTATUS Send(_In_ WDFIOTARGET Target, _In_opt_ UCXUSBDEVICE Device, _In_ PFN_WDF_REQUEST_COMPLETION_ROUTINE Completion, _In_ WDFCONTEXT Context, _In_reads_bytes_opt_(Length) PVOID Buffer, _In_ ULONG Length, _In_ BOOLEAN ShortTransferOk, _In_ BOOLEAN ForwardProgress)
Definition: hubreq.cpp:62
VOID SetSetup(_In_ UCHAR RequestType, _In_ UCHAR RequestCode, _In_ USHORT Value, _In_ USHORT Index, _In_ USHORT Length)
Definition: hubreq.h:34
struct _URB_CONTROL_TRANSFER_EX Urb
Definition: hubreq.h:21
WDFREQUEST Request
Definition: hubreq.h:70
HubControlRequest Control
Definition: hubreq.cpp:121
HubFdo * Hub
Definition: hubreq.cpp:122
UCXENDPOINT Endpoint
Definition: hubreq.cpp:123
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
USB_DEVICE_SPEED HubSpeed
Definition: hubucx.h:504
UCXUSBDEVICE Hub
Definition: hubucx.h:430
PFN_UCXHUB_CLEAR_TT_BUFFER_COMPLETE ClearTtBufferComplete
Definition: hubucx.h:450
USHORT wHubCharacteristics
Definition: usb300.h:288
USHORT wHubCharacteristics
Definition: usb100.h:174
UCHAR bNumberOfPorts
Definition: usb100.h:173
uint32_t * PULONG
Definition: typedefs.h:59
#define NTAPI
Definition: typedefs.h:36
uint16_t * PUSHORT
Definition: typedefs.h:56
#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 Config
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFREQUEST Request
_In_ UCXUSBDEVICE _In_ ULONG Interface
Definition: ucxusbdevice.h:428
#define STATUS_NO_SUCH_DEVICE
Definition: udferr_usr.h:136
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
#define MAXUCHAR
Definition: umtypes.h:117
USHORT SelfPowered
Definition: usb300.h:82
USHORT AsUshort16
Definition: usb200.h:260
USB_HUB_STATUS HubStatus
Definition: usb200.h:273
USB_HUB_CHANGE HubChange
Definition: usb200.h:274
USHORT AsUshort16
Definition: usb200.h:249
#define USB_REQUEST_GET_STATUS
Definition: usb100.h:78
struct _USB_CONFIGURATION_DESCRIPTOR * PUSB_CONFIGURATION_DESCRIPTOR
#define USB_REQUEST_GET_DESCRIPTOR
Definition: usb100.h:82
#define USB_CONFIGURATION_DESCRIPTOR_TYPE
Definition: usb100.h:50
#define USB_ENDPOINT_TYPE_CONTROL
Definition: usb100.h:62
#define USB_ENDPOINT_DIRECTION_MASK
Definition: usb100.h:73
#define USB_ENDPOINT_TYPE_MASK
Definition: usb100.h:61
#define USB_ENDPOINT_TYPE_BULK
Definition: usb100.h:64
@ UsbSuperSpeed
Definition: usb200.h:45
@ UsbHighSpeed
Definition: usb200.h:44
@ UsbLowSpeed
Definition: usb200.h:42
@ UsbFullSpeed
Definition: usb200.h:43
#define USB_20_HUB_DESCRIPTOR_TYPE
Definition: usb200.h:280
#define USB_30_HUB_DESCRIPTOR_TYPE
Definition: usb200.h:281
@ ResetTtOnCancel
@ NoClearTtOnCancel
#define USBD_TRANSFER_DIRECTION_IN
Definition: usb.h:167
#define USBD_SHORT_TRANSFER_OK
Definition: usb.h:161
#define URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER
Definition: usb.h:95
#define USBD_DEFAULT_PIPE_TRANSFER
Definition: usb.h:163
_In_opt_ PVOID HubContext
Definition: usbdhub.h:41
_In_ ULONG TotalLength
Definition: usbdlib.h:185
#define IOCTL_INTERNAL_USB_SUBMIT_URB
Definition: usbioctl.h:32
#define IOCTL_USB_GET_PORT_STATUS
Definition: usbioctl.h:672
#define USBD_PORT_ENABLED
Definition: usbioctl.h:41
#define USBD_PORT_CONNECTED
Definition: usbioctl.h:42
#define IOCTL_INTERNAL_USB_GET_PORT_STATUS
Definition: usbioctl.h:44
WdfObjectDelete(String)
WdfRequestCompleteWithInformation(Request, STATUS_SUCCESS, ActualLength)
_In_ WDFCOLLECTION _In_ ULONG Index
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFDEVICE Child
Definition: wdffdo.h:536
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_INTERRUPT_CONFIG _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFINTERRUPT * Interrupt
Definition: wdfinterrupt.h:379
_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
#define WdfObjectDereferenceWithTag(Handle, Tag)
Definition: wdfobject.h:829
FORCEINLINE VOID WDF_OBJECT_ATTRIBUTES_INIT(_Out_ PWDF_OBJECT_ATTRIBUTES Attributes)
Definition: wdfobject.h:147
#define WdfObjectReferenceWithTag(Handle, Tag)
Definition: wdfobject.h:806
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413
_Must_inspect_result_ FORCEINLINE BOOLEAN WdfRequestSend(_In_ WDFREQUEST Request, _In_ WDFIOTARGET Target, _In_opt_ PWDF_REQUEST_SEND_OPTIONS Options)
Definition: wdfrequest.h:677
_In_ WDFIOTARGET Target
Definition: wdfrequest.h:306
_In_ WDFIOTARGET _In_ PWDF_REQUEST_COMPLETION_PARAMS Params
Definition: wdfrequest.h:308
@ WDF_REQUEST_REUSE_NO_FLAGS
Definition: wdfrequest.h:92
FORCEINLINE VOID WDF_REQUEST_PARAMETERS_INIT(_Out_ PWDF_REQUEST_PARAMETERS Parameters)
Definition: wdfrequest.h:211
EVT_WDF_REQUEST_COMPLETION_ROUTINE * PFN_WDF_REQUEST_COMPLETION_ROUTINE
Definition: wdfrequest.h:313
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:639
FORCEINLINE VOID WDF_REQUEST_REUSE_PARAMS_INIT(_Out_ PWDF_REQUEST_REUSE_PARAMS Params, _In_ ULONG Flags, _In_ NTSTATUS Status)
Definition: wdfrequest.h:364
#define WDF_NO_SEND_OPTIONS
Definition: wdftypes.h:109
_In_ WDFUSBPIPE Pipe
Definition: wdfusb.h:1741
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409
#define IRP_MJ_INTERNAL_DEVICE_CONTROL