ReactOS 0.4.17-dev-1281-g065abb3
hostreset.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: Controller reset machine actions and the device fan out around a reset
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
15{
19};
20
21static
22VOID
27{
31
32 /* Root hub endpoints have no machine and the root hub keeps its programming */
33 if (Device->IsRootHub())
34 return;
35
36 if (FanOut->MarkDeprogrammed)
37 Device->m_DeprogrammedByControllerReset = TRUE;
38
39 for (Entry = Device->m_EndpointList.Flink;
40 Entry != &Device->m_EndpointList;
41 Entry = Entry->Flink)
42 {
44
45 NT_ASSERT(!UcxIsListEntryLinked(&Endpoint->m_ControllerResetLink));
47 InsertTailList(&FanOut->Endpoints, &Endpoint->m_ControllerResetLink);
48 FanOut->Count++;
49 }
50}
51
52static
53VOID
56 _Inout_ UcxResetFanOut* FanOut,
58{
61
62 while (!IsListEmpty(&FanOut->Endpoints))
63 {
64 Entry = RemoveHeadList(&FanOut->Endpoints);
65 Endpoint = CONTAINING_RECORD(Entry, UcxEndpoint, m_ControllerResetLink);
67
68 Endpoint->m_Machine.SmPost(Event);
70 }
71}
72
73VOID
77 _In_ BOOLEAN IncludeDisconnected)
78{
80
81 m_RootHub->Device()->WalkSubtree(Visitor, Context, IncludeDisconnected);
82}
83
85VOID
87{
88 UcxResetFanOut FanOut;
89
91 FanOut.Count = 0;
92 FanOut.MarkDeprogrammed = TRUE;
93
95
96 /* Set before the first post so a synchronous ack cannot underflow it */
99
100 DPRINT("Controller %p preparing %lu endpoints for reset\n", this, FanOut.Count);
101
102 UcxPostToCollectedEndpoints(&FanOut, EpEvent::ControllerResetStarting);
103
104 if (FanOut.Count == 0)
105 PostResetEvent(CrEvent::DevicesReady);
106}
107
108/* Notifies whatever endpoints exist now, not only the ones that were prepared */
109VOID
111{
112 UcxResetFanOut FanOut;
113
115 FanOut.Count = 0;
116 FanOut.MarkDeprogrammed = FALSE;
117
119 DPRINT("Controller %p reset done, notifying %lu endpoints\n", this, FanOut.Count);
120 UcxPostToCollectedEndpoints(&FanOut, EpEvent::ControllerResetDone);
121}
122
123VOID
125{
127 PostResetEvent(CrEvent::DevicesReady);
128}
129
130VOID
131NTAPI
136{
139
140 ((UcxController*)Context)->m_ResetMachine.SmContinueOnPassive();
141}
142
143/* Controller reset machine actions */
144
145VOID
147{
149}
150
151VOID
153{
155}
156
157VOID
159{
163}
164
165VOID
167{
168 WdfIoQueueStop(m_Controller->m_PendDuringResetQueue, NULL, NULL);
169}
170
171VOID
173{
174 WdfIoQueueStart(m_Controller->m_PendDuringResetQueue);
175}
176
177VOID
179{
181}
182
183VOID
185{
187}
188
189VOID
191{
193}
194
195VOID
197{
199}
200
201VOID
203{
205}
206
207VOID
209{
211}
212
213VOID
215{
217}
218
219/* The HCD reports back through UcxControllerResetComplete, maybe from inside this call */
220VOID
222{
223 DPRINT1("Controller %p being reset\n", m_Controller);
225}
226
227VOID
230{
231 DPRINT("Controller %p completing hub reset request, success %u\n", m_Controller, Succeeded);
233}
234
235VOID
237{
239}
240
241VOID
243{
246}
247
248VOID
250{
252}
253
254VOID
256{
258}
unsigned char BOOLEAN
Definition: actypes.h:127
#define InterlockedDecrement
Definition: armddk.h:52
#define DPRINT1
Definition: precomp.h:8
VOID CompleteHubReset(_In_ BOOLEAN Succeeded)
Definition: hostreset.cpp:228
UcxController * m_Controller
Definition: crsm.h:152
VOID ReleaseResetCompleteWaiter()
Definition: hostreset.cpp:255
VOID LetResetCompletionProceed()
Definition: hostreset.cpp:249
KEVENT m_ResetCompleteProcessed
Definition: hostctl.h:319
VOID PostResetEvent(_In_ CrEvent Event)
Definition: hostctl.h:200
UcxRootHub * m_RootHub
Definition: hostctl.h:302
BOOLEAN m_WaitOnResetComplete
Definition: hostctl.h:322
VOID WalkDevices(_In_ PFN_UCX_DEVICE_VISITOR Visitor, _In_opt_ PVOID Context, _In_ BOOLEAN IncludeDisconnected)
Definition: hostreset.cpp:74
UCX_CONTROLLER_CONFIG m_Config
Definition: hostctl.h:289
VOID NotifyDevicesResetDone()
Definition: hostreset.cpp:110
static UCXHUB_WORKITEM_ROUTINE ResetMachinePassiveRoutine
Definition: hostctl.h:389
VOID MarkResetFinished()
Definition: hostctl.cpp:551
LONG m_PendingPrepareForReset
Definition: hostctl.h:331
VOID MarkResetInProgress()
Definition: hostctl.cpp:542
KSPIN_LOCK m_TopologyLock
Definition: hostctl.h:310
VOID PrepareForResetOperationDone()
Definition: hostreset.cpp:124
VOID PrepareDevicesForReset()
Definition: hostreset.cpp:86
VOID UnblockReset()
Definition: hostctl.cpp:522
UCXCONTROLLER m_Handle
Definition: hostctl.h:287
WDFQUEUE m_PendDuringResetQueue
Definition: hostctl.h:296
KEVENT m_RootHubMayExitD0
Definition: hostctl.h:318
UcxWorkItem * m_ResetMachineWorkItem
Definition: hostctl.h:316
UcxUsbDevice * Device() const
Definition: rhub.h:71
VOID FailIo()
Definition: rhub.cpp:477
VOID PortChanged()
Definition: rhub.cpp:227
VOID FinishPortResetRequest(_In_ BOOLEAN Succeeded)
Definition: rhub.cpp:500
VOID ResumeIo()
Definition: rhub.cpp:485
VOID WalkSubtree(_In_ PFN_UCX_DEVICE_VISITOR Visitor, _In_opt_ PVOID Context, _In_ BOOLEAN IncludeDisconnected)
Definition: devobj.cpp:396
PLIST_ENTRY Entry
Definition: devhcd.cpp:1262
_Check_return_ _In_ DXGK_EVENT_TYPE _In_ ULONG Event
Definition: dispmprt.h:1287
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define InsertTailList(ListHead, Entry)
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
EpEvent
Definition: epsm.h:15
VOID(NTAPI * PFN_UCX_DEVICE_VISITOR)(_In_ UcxUsbDevice *Device, _In_opt_ PVOID Context)
Definition: hostctl.h:108
static VOID NTAPI UcxPostToCollectedEndpoints(_Inout_ UcxResetFanOut *FanOut, _In_ EpEvent Event)
Definition: hostreset.cpp:55
static VOID NTAPI UcxCollectEndpointsForReset(_In_ UcxUsbDevice *Device, _In_opt_ PVOID Context)
Definition: hostreset.cpp:24
_Must_inspect_result_ _In_ PUCXHUB_DEVICE_CREATE_INFO _Out_ UCXUSBDEVICE * Device
Definition: hubucx.h:258
_In_opt_ PVOID _In_ PUCXHUB_WORKITEM WorkItem
Definition: hubucx.h:227
_In_ UCXHUB_DEVICE_CONTEXT _In_ UCXENDPOINT Endpoint
Definition: hubucx.h:238
@ UcxHubWorkItemDefault
Definition: hubucx.h:216
_In_ PIRP _In_ PIO_COMPLETION_ROUTINE _In_ PVOID Context
Definition: kse.h:81
#define _Inout_
Definition: no_sal2.h:162
#define _In_
Definition: no_sal2.h:158
#define _In_opt_
Definition: no_sal2.h:212
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:329
#define DPRINT
Definition: sndvol32.h:73
LIST_ENTRY Endpoints
Definition: hostreset.cpp:16
BOOLEAN MarkDeprogrammed
Definition: hostreset.cpp:18
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
VOID Enqueue(_In_ PUCXHUB_WORKITEM_ROUTINE NewRoutine, _In_opt_ PVOID NewContext, _In_ UCXHUB_WORKITEM_ENQUEUE_OPTIONS Options)
Definition: workitem.cpp:56
PFN_UCX_CONTROLLER_RESET EvtControllerReset
#define NTAPI
Definition: typedefs.h:36
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
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
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2061
#define WdfObjectReference(Handle)
Definition: wdfobject.h:803
#define WdfObjectDereference(Handle)
Definition: wdfobject.h:826
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define NT_ASSERT
Definition: rtlfuncs.h:3334