ReactOS 0.4.17-dev-1281-g065abb3
devsm_hub.cpp
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS USB Hub Driver
3 * LICENSE: MIT (https://spdx.org/licenses/MIT)
4 * PURPOSE: Device state machine, the hub suspended sub machine
5 * COPYRIGHT: Copyright 2026 Justin Miller <justin.miller@reactos.org>
6 */
7
8/* INCLUDES *******************************************************************/
9
10#include "usbhub3.h"
11
12/* GLOBALS ********************************************************************/
13
14/* The hub is suspended with the device's power reference dropped */
16 { NULL, "HubSuspended", SM_STATE_YIELDS_TO_CALLER,
18
19/* Same, but the port was found disabled or failed while the hub suspended */
21 { NULL, "HubSuspendedPortOff", SM_STATE_YIELDS_TO_CALLER,
23
24/* FUNCTIONS ******************************************************************/
25
29{
30 switch (Event)
31 {
32 case DsmEvent::HubResumed:
35
36 case DsmEvent::HubResumedWithReset:
39
40 case DsmEvent::HubResumedInS0:
42 return EndWith(DsmEvent::SuspendedAfterHubResume);
43
44 case DsmEvent::PortNowDisabled:
45 case DsmEvent::PortNowEnabledOnReconnect:
47
48 case DsmEvent::PortNowSuspended:
50
51 case DsmEvent::PortNowEnabled:
53
54 case DsmEvent::PdoPowerDown:
57
58 default:
59 return SmUnhandled();
60 }
61}
62
66{
67 switch (Event)
68 {
69 case DsmEvent::HubResumed:
70 case DsmEvent::HubResumedWithReset:
73
74 case DsmEvent::HubResumedInS0:
76 return EndWith(DsmEvent::NeedsReenumeration);
77
78 case DsmEvent::PortNowEnabled:
79 case DsmEvent::PortNowDisabled:
80 case DsmEvent::PortNowSuspended:
81 case DsmEvent::PortNowEnabledOnReconnect:
83
84 default:
85 return SmUnhandled();
86 }
87}
88
89/* The port changed while the hub was suspended, the device needs enumerating again */
93{
94 switch (Event)
95 {
96 case DsmEvent::HubResumed:
97 case DsmEvent::HubResumedWithReset:
99 return EndWith(DsmEvent::NeedsReenumeration);
100
101 case DsmEvent::PortDetached:
102 return EndWith(DsmEvent::PortDetached);
103
104 default:
105 return SmUnhandled();
106 }
107}
108
112{
113 switch (Event)
114 {
115 case DsmEvent::HubResumed:
119
120 return EndWith(DsmEvent::SuspendedAfterHubResume);
121
122 case DsmEvent::PortResumeDone:
125
126 case DsmEvent::PortDetached:
127 return EndWith(DsmEvent::PortDetached);
128
129 case DsmEvent::HubResumedWithReset:
132
133 default:
134 return SmUnhandled();
135 }
136}
137
141{
142 switch (Event)
143 {
144 case DsmEvent::HubResumed:
147
148 case DsmEvent::PortDetached:
149 return EndWith(DsmEvent::PortDetached);
150
151 case DsmEvent::HubResumedWithReset:
153 return EndWith(DsmEvent::NeedsReenumeration);
154
155 default:
156 return SmUnhandled();
157 }
158}
159
162{
164 return EndWith(DsmEvent::NeedsReenumeration);
165
166 return EndWith(DsmEvent::ResumedWithHub);
167}
168
169/* Hub resumed; the port machine reports where the port ended up */
173{
174 switch (Event)
175 {
176 case DsmEvent::PortNowDisabled:
177 case DsmEvent::PortNowEnabledOnReconnect:
178 return EndWith(DsmEvent::NeedsReenumeration);
179
180 case DsmEvent::PortNowEnabled:
182
183 case DsmEvent::PortNowSuspended:
184 return EndWith(DsmEvent::SuspendedAfterHubResume);
185
186 case DsmEvent::PortDetached:
187 return EndWith(DsmEvent::PortDetached);
188
189 case DsmEvent::HubSuspending:
191
192 case DsmEvent::HubStopping:
194
195 default:
196 return SmUnhandled();
197 }
198}
199
200/* Hub resumed with a reset; the device is enumerated again unless the port is suspended */
204{
205 switch (Event)
206 {
207 case DsmEvent::PortNowEnabled:
208 case DsmEvent::PortNowDisabled:
209 case DsmEvent::PortNowEnabledOnReconnect:
210 return EndWith(DsmEvent::NeedsReenumeration);
211
212 case DsmEvent::PortNowSuspended:
214
215 case DsmEvent::HubSuspending:
217
218 case DsmEvent::HubStopping:
220
221 case DsmEvent::PortDetached:
222 return EndWith(DsmEvent::PortDetached);
223
224 default:
225 return SmUnhandled();
226 }
227}
228
229/* The hub suspends again before the port machine caught up */
233{
234 switch (Event)
235 {
236 case DsmEvent::PortNowSuspended:
238 return SmTransition(&HubSuspended);
239
240 case DsmEvent::PortNowDisabled:
243
244 case DsmEvent::PortNowEnabled:
245 case DsmEvent::PortNowEnabledOnReconnect:
247
248 case DsmEvent::PortDetached:
250 return EndWith(DsmEvent::PortDetached);
251
252 default:
253 return SmUnhandled();
254 }
255}
256
260{
261 switch (Event)
262 {
263 case DsmEvent::PortSuspendDone:
265 return SmTransition(&HubSuspended);
266
267 case DsmEvent::PortDetached:
268 return EndWith(DsmEvent::PortDetached);
269
270 case DsmEvent::PortFault:
273
274 default:
275 return SmUnhandled();
276 }
277}
278
279/* The hub stops before the port machine caught up; the power reference stays */
283{
284 switch (Event)
285 {
286 case DsmEvent::PortNowEnabled:
287 case DsmEvent::PortNowEnabledOnReconnect:
289
290 case DsmEvent::PortDetached:
291 return EndWith(DsmEvent::PortDetached);
292
293 case DsmEvent::PortNowSuspended:
294 case DsmEvent::PortNowDisabled:
295 return EndWith(DsmEvent::HubStoppedHoldingReference);
296
297 default:
298 return SmUnhandled();
299 }
300}
301
305{
306 switch (Event)
307 {
308 case DsmEvent::PortDetached:
309 return EndWith(DsmEvent::PortDetached);
310
311 case DsmEvent::PortFault:
312 case DsmEvent::PortDisableDone:
313 return EndWith(DsmEvent::HubStoppedHoldingReference);
314
315 default:
316 return SmUnhandled();
317 }
318}
319
320/* Resuming the port only so the device can be reset and enumerated again */
324{
325 switch (Event)
326 {
327 case DsmEvent::PortResumeDone:
328 case DsmEvent::PortNowEnabledOnReconnect:
329 case DsmEvent::PortResumeTimeout:
330 case DsmEvent::PortFault:
331 case DsmEvent::PortNowDisabled:
332 return EndWith(DsmEvent::NeedsReenumeration);
333
334 case DsmEvent::PortDetached:
335 return EndWith(DsmEvent::PortDetached);
336
337 case DsmEvent::HubStopping:
339
340 case DsmEvent::HubSuspending:
342
343 default:
344 return SmUnhandled();
345 }
346}
347
351{
352 switch (Event)
353 {
354 case DsmEvent::PortResumeDone:
356
357 case DsmEvent::PortNowEnabledOnReconnect:
358 case DsmEvent::PortResumeTimeout:
359 case DsmEvent::PortNowDisabled:
360 case DsmEvent::PortFault:
361 return EndWith(DsmEvent::HubStoppedHoldingReference);
362
363 case DsmEvent::PortDetached:
364 return EndWith(DsmEvent::PortDetached);
365
366 default:
367 return SmUnhandled();
368 }
369}
370
374{
375 switch (Event)
376 {
377 case DsmEvent::PortResumeDone:
378 case DsmEvent::PortNowEnabledOnReconnect:
380
381 case DsmEvent::PortFault:
382 case DsmEvent::PortNowDisabled:
383 case DsmEvent::PortResumeTimeout:
386
387 case DsmEvent::PortDetached:
388 return EndWith(DsmEvent::PortDetached);
389
390 default:
391 return SmUnhandled();
392 }
393}
SM_RESULT HubResumeWithPortSuspended(_In_ DsmEvent Event)
Definition: devsm_hub.cpp:110
SM_RESULT HubPortResumedForReset(_In_ DsmEvent Event)
Definition: devsm_hub.cpp:322
static const State AwaitingPort
Definition: devsm.h:222
SM_RESULT HubResumeEndedForSuspend(_In_ DsmEvent Event)
Definition: devsm_hub.cpp:372
static const State ResumingPort
Definition: devsm.h:236
SM_RESULT HubPortSyncedForReset(_In_ DsmEvent Event)
Definition: devsm_hub.cpp:202
SM_RESULT HubPortSyncedForStop(_In_ DsmEvent Event)
Definition: devsm_hub.cpp:281
BOOLEAN ResetOnResumeFromSx()
Definition: devmisc.cpp:345
static const State HubSuspendedPortOff
Definition: devsm.h:423
static const State SuspendingPort
Definition: devsm.h:235
SM_RESULT HubResumeEndedForStop(_In_ DsmEvent Event)
Definition: devsm_hub.cpp:349
SM_RESULT EndWith(_In_ DsmEvent Result)
Definition: devsm.cpp:186
SM_RESULT HubResumeWithPortEnabled(_In_ DsmEvent Event)
Definition: devsm_hub.cpp:139
SM_RESULT HubPortSuspendedAgain(_In_ DsmEvent Event)
Definition: devsm_hub.cpp:258
VOID RequestPortResume()
Definition: hubport.cpp:650
VOID ReferenceDevicePower()
Definition: fanout.cpp:1038
SM_RESULT HubEndResumedOrReenumerate()
Definition: devsm_hub.cpp:161
static const State DisablingPort
Definition: devsm.h:221
SM_RESULT HubPortSyncedForSuspend(_In_ DsmEvent Event)
Definition: devsm_hub.cpp:231
VOID DereferenceDevicePower()
Definition: fanout.cpp:1044
SM_RESULT HubPortOffForStop(_In_ DsmEvent Event)
Definition: devsm_hub.cpp:303
SM_RESULT HubResumeForReenumeration(_In_ DsmEvent Event)
Definition: devsm_hub.cpp:91
VOID SignalPnpWaiter()
Definition: childpdo.cpp:4023
SM_RESULT OnHubSuspended(_In_ DsmEvent Event)
Definition: devsm_hub.cpp:27
static const State HubSuspended
Definition: devsm.h:422
SM_RESULT HubPortSynced(_In_ DsmEvent Event)
Definition: devsm_hub.cpp:171
SM_RESULT OnHubSuspendedPortOff(_In_ DsmEvent Event)
Definition: devsm_hub.cpp:64
static SM_RESULT SmTransition(_In_ const State *Target)
Definition: smengine.h:194
static SM_RESULT SmUnhandled()
Definition: smengine.h:188
DsmEvent
Definition: devsm.h:15
_Check_return_ _In_ DXGK_EVENT_TYPE _In_ ULONG Event
Definition: dispmprt.h:1287
#define NULL
Definition: types.h:112
#define _In_
Definition: no_sal2.h:158
#define SM_STATE_YIELDS_TO_CALLER
Definition: smengine.h:42
One state. Handler gets every event the state sees.
Definition: smengine.h:93
_In_ WDFDPC _In_ BOOLEAN Wait
Definition: wdfdpc.h:170