ReactOS 0.4.17-dev-1281-g065abb3
suspend.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: Idle notification IRP of a child PDO and the idle machine actions
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/* FUNCTIONS ******************************************************************/
14
15/* The machine lock serializes everything, so the cancel spin lock is let go at once */
16static
17VOID
22{
23 HubPdo* Pdo = HubGetPdoContext(WdfWdmDeviceGetWdfDeviceHandle(DeviceObject));
24
25 IoReleaseCancelSpinLock(Irp->CancelIrql);
26 DPRINT("Idle IRP %p on port %u canceled\n", Irp, Pdo->m_PortNumber);
27 Pdo->m_Idle.Post(IdleEvent::RequestCanceled, NULL);
28}
29
30/* The client callback runs on this thread, at passive level */
31static
32VOID
35 _In_ WDFWORKITEM WorkItem)
36{
37 HubPdo* Pdo = HubGetPdoContext(WdfWorkItemGetParentObject(WorkItem));
38
39 Pdo->m_Idle.Post(IdleEvent::WorkItemRan, NULL);
40}
41
45HubPdoCreateIdleWorkItem(
47{
50
51 PAGED_CODE();
52
54 Config.AutomaticSerialization = FALSE;
55
57 Attributes.ParentObject = Pdo->m_Device;
58
59 return WdfWorkItemCreate(&Config, &Attributes, &Pdo->m_IdleWorkItem);
60}
61
62/* After a post the IRP may already be completed; only the returned status is valid */
66HubPdoSubmitIdleRequest(
69{
71 PUSB_IDLE_CALLBACK_INFO Info = (PUSB_IDLE_CALLBACK_INFO)Stack->Parameters.DeviceIoControl.Type3InputBuffer;
72
73 if (Info == NULL || Info->IdleCallback == NULL)
74 {
75 DPRINT1("Idle IRP %p on port %u has no callback\n", Irp, Pdo->m_PortNumber);
76 Irp->IoStatus.Status = STATUS_NO_CALLBACK_ACTIVE;
79 }
80
81 DPRINT("Idle IRP %p submitted on port %u\n", Irp, Pdo->m_PortNumber);
82 return Pdo->m_Idle.Post(IdleEvent::RequestSubmitted, Irp);
83}
84
85/* Idle machine actions */
86
89{
90 if (m_Pdo->m_Hub->HasFlag(HubFlag::ParentNoSelectiveSuspend))
91 {
92 DPRINT("Port %u: parent stack has no selective suspend\n", m_Pdo->m_PortNumber);
93 return FALSE;
94 }
95
96 return TRUE;
97}
98
99VOID
101 _In_ PIRP Irp)
102{
104}
105
106/* FALSE when the IRP was canceled before and the hub took it back */
109 _In_ PIRP Irp)
110{
112
113 if (!Irp->Cancel)
114 return TRUE;
115
116 /* NULL here means the cancel routine already owns it and will post */
118 return TRUE;
119
120 DPRINT("Idle IRP %p was canceled before it was held\n", Irp);
121 return FALSE;
122}
123
124/* FALSE when the cancel routine is running or about to */
127 _In_ PIRP Irp)
128{
129 return IoSetCancelRoutine(Irp, NULL) != NULL;
130}
131
132/* Enqueuing an already queued work item does nothing */
133VOID
135{
137}
138
139VOID
141 _In_ PIRP Irp)
142{
144 PUSB_IDLE_CALLBACK_INFO Info = (PUSB_IDLE_CALLBACK_INFO)Stack->Parameters.DeviceIoControl.Type3InputBuffer;
145
146 DPRINT("Calling idle callback of port %u\n", m_Pdo->m_PortNumber);
147 Info->IdleCallback(Info->IdleContext);
148}
149
150/* Cancel and power state completions are the normal ends of an idle IRP */
151VOID
153 _In_ PIRP Irp,
155{
157 DPRINT("Idle IRP %p on port %u completed 0x%lx\n", Irp, m_Pdo->m_PortNumber, Status);
158 else
159 DPRINT1("Idle IRP %p on port %u failed 0x%lx\n", Irp, m_Pdo->m_PortNumber, Status);
160
161 Irp->IoStatus.Status = Status;
163}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
#define PAGED_CODE()
unsigned char BOOLEAN
Definition: actypes.h:127
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
BOOLEAN HasFlag(_In_ HubFlag Flag) const
Definition: fdo.h:153
HubFdo * m_Hub
Definition: childpdo.h:56
USHORT m_PortNumber
Definition: childpdo.h:58
WDFWORKITEM m_IdleWorkItem
Definition: childpdo.h:107
BOOLEAN DisarmCancel(_In_ PIRP Irp)
Definition: suspend.cpp:126
VOID QueueIdleWorkItem()
Definition: suspend.cpp:134
BOOLEAN SelectiveSuspendSupported()
Definition: suspend.cpp:88
VOID CompleteIdleRequest(_In_ PIRP Irp, _In_ NTSTATUS Status)
Definition: suspend.cpp:152
VOID MarkRequestPending(_In_ PIRP Irp)
Definition: suspend.cpp:100
BOOLEAN ArmCancel(_In_ PIRP Irp)
Definition: suspend.cpp:108
VOID InvokeIdleCallback(_In_ PIRP Irp)
Definition: suspend.cpp:140
HubPdo * m_Pdo
Definition: idlesm.h:194
_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 _IRQL_uses_cancel_
Definition: driverspecs.h:237
#define _IRQL_requires_max_(irql)
Definition: driverspecs.h:230
#define _IRQL_requires_(irql)
Definition: driverspecs.h:229
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
Status
Definition: gdiplustypes.h:24
WdfWorkItemEnqueue(WorkItem)
_In_opt_ PVOID _In_ PUCXHUB_WORKITEM WorkItem
Definition: hubucx.h:227
_In_ UCXUSBDEVICE _In_ PDEVICE_OBJECT Pdo
Definition: hubucx.h:280
@ RequestSubmitted
IoMarkIrpPending(Irp)
IoSetCancelRoutine(Irp, CancelRoutine)
_In_ PIRP Irp
Definition: kse.h:79
if(dx< 0)
Definition: linetemp.h:194
#define _Inout_
Definition: no_sal2.h:162
#define _In_
Definition: no_sal2.h:158
#define IoCompleteRequest
Definition: irp.c:1272
VOID NTAPI IoReleaseCancelSpinLock(IN KIRQL Irql)
Definition: util.c:150
#define STATUS_NO_CALLBACK_ACTIVE
Definition: ntstatus.h:848
#define STATUS_POWER_STATE_INVALID
Definition: ntstatus.h:957
#define DPRINT
Definition: sndvol32.h:73
static VOID NTAPI HubIdleCancel(_Inout_ PDEVICE_OBJECT DeviceObject, _Inout_ _IRQL_uses_cancel_ PIRP Irp)
Definition: suspend.cpp:19
static VOID NTAPI HubIdleWorkItem(_In_ WDFWORKITEM WorkItem)
Definition: suspend.cpp:34
#define NTAPI
Definition: typedefs.h:36
_Must_inspect_result_ _In_ WDFDEVICE _In_ PUCX_CONTROLLER_CONFIG Config
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:690
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2061
FORCEINLINE VOID WDF_OBJECT_ATTRIBUTES_INIT(_Out_ PWDF_OBJECT_ATTRIBUTES Attributes)
Definition: wdfobject.h:147
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:639
FORCEINLINE VOID WDF_WORKITEM_CONFIG_INIT(_Out_ PWDF_WORKITEM_CONFIG Config, _In_ PFN_WDF_WORKITEM EvtWorkItemFunc)
Definition: wdfworkitem.h:85
#define IO_NO_INCREMENT
Definition: iotypes.h:598