ReactOS 0.4.15-dev-7842-g558ab78
interrupt.cpp
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel Streaming
4 * FILE: drivers/wdm/audio/backpln/portcls/interrupt.cpp
5 * PURPOSE: portcls interrupt object
6 * PROGRAMMER: Johannes Anderwald
7 */
8
9#include "private.hpp"
10
11#define NDEBUG
12#include <debug.h>
13
14typedef struct
15{
20
21class CInterruptSync : public CUnknownImpl<IInterruptSync>
22{
23public:
25
27 CInterruptSync(IUnknown *OuterUnknown){}
28 virtual ~CInterruptSync(){}
29
30public:
31
38
42
45};
46
47//---------------------------------------------------------------
48// IUnknown methods
49//
50
54 IN REFIID refiid,
56{
58
59 DPRINT("CInterruptSync::QueryInterface: this %p\n", this);
60
61 if (IsEqualGUIDAligned(refiid, IID_IInterruptSync) ||
63 {
64 *Output = PVOID(PUNKNOWN(this));
65 PUNKNOWN(*Output)->AddRef();
66 return STATUS_SUCCESS;
67 }
68
70 {
71 DPRINT1("CInterruptSync::QueryInterface: no interface!!! iface %S\n", GuidString.Buffer);
73 }
74
76}
77
78//---------------------------------------------------------------
79// CInterruptSync methods
80//
81
86{
88 This->m_Status = This->m_SyncRoutine(This, This->m_DynamicContext);
89
90 DPRINT("CInterruptSynchronizedRoutine this %p SyncRoutine %p Context %p Status %x\n", This, This->m_SyncRoutine, This->m_DynamicContext, This->m_Status);
91 return TRUE;
92}
93
96CInterruptSync::CallSynchronizedRoutine(
98 IN PVOID DynamicContext)
99{
101
102 DPRINT("CInterruptSync::CallSynchronizedRoutine this %p Routine %p DynamicContext %p Irql %x Interrupt %p\n", this, Routine, DynamicContext, KeGetCurrentIrql(), m_Interrupt);
103
104 if (!m_Interrupt)
105 {
106 DPRINT("CInterruptSync_CallSynchronizedRoutine %p no interrupt connected\n", this);
108 return STATUS_UNSUCCESSFUL;
109
111 m_SyncRoutine = Routine;
112 m_DynamicContext = DynamicContext;
115
116 return m_Status;
117 }
118
119 m_SyncRoutine = Routine;
120 m_DynamicContext = DynamicContext;
121
123 return m_Status;
124 else
125 return STATUS_UNSUCCESSFUL;
126}
127
129NTAPI
130CInterruptSync::GetKInterrupt()
131{
132 DPRINT("CInterruptSynchronizedRoutine\n");
133
134 return m_Interrupt;
135}
136
138NTAPI
142{
143 PLIST_ENTRY CurEntry;
146 BOOL Success, Ret;
147
149
150 DPRINT("IInterruptServiceRoutine Mode %u\n", This->m_Mode);
151
152 Ret = FALSE;
153 if (This->m_Mode == InterruptSyncModeNormal)
154 {
155 CurEntry = This->m_ServiceRoutines.Flink;
156 while (CurEntry != &This->m_ServiceRoutines)
157 {
158 Entry = CONTAINING_RECORD(CurEntry, SYNC_ENTRY, ListEntry);
159 Status = Entry->SyncRoutine((CInterruptSync*)This, Entry->DynamicContext);
160 if (Status == STATUS_SUCCESS)
161 {
162 /* Mark as handled and break on the first success */
163 Ret = TRUE;
164 break;
165 }
166 CurEntry = CurEntry->Flink;
167 }
168 return Ret;
169 }
170 else if (This->m_Mode == InterruptSyncModeAll)
171 {
172 CurEntry = This->m_ServiceRoutines.Flink;
173 while (CurEntry != &This->m_ServiceRoutines)
174 {
175 Entry = CONTAINING_RECORD(CurEntry, SYNC_ENTRY, ListEntry);
176 Status = Entry->SyncRoutine((CInterruptSync*)This, Entry->DynamicContext);
177 if (Status == STATUS_SUCCESS)
178 {
179 /* Mark as handled but don't break */
180 Ret = TRUE;
181 }
182 CurEntry = CurEntry->Flink;
183 }
184 return Ret;
185 }
186 else if (This->m_Mode == InterruptSyncModeRepeat)
187 {
188 do
189 {
190 Success = FALSE;
191 CurEntry = This->m_ServiceRoutines.Flink;
192 while (CurEntry != &This->m_ServiceRoutines)
193 {
194 Entry = CONTAINING_RECORD(CurEntry, SYNC_ENTRY, ListEntry);
195 Status = Entry->SyncRoutine((CInterruptSync*)This, Entry->DynamicContext);
196 if (Status == STATUS_SUCCESS)
197 {
198 /* Mark as handled if it works at least once */
199 Success = TRUE;
200 Ret = TRUE;
201 }
202 CurEntry = CurEntry->Flink;
203 }
204 } while(Success);
205 return Ret;
206 }
207 else
208 {
209 DPRINT("Unknown mode %u\n", This->m_Mode);
210 return Ret;
211 }
212}
213
215NTAPI
216CInterruptSync::Connect()
217{
220
221 DPRINT("CInterruptSync::Connect\n");
223
225 if (!Descriptor)
226 return STATUS_UNSUCCESSFUL;
227
229 return STATUS_UNSUCCESSFUL;
230
231 DPRINT1("Vector %u Level %u Flags %x Affinity %x\n", Descriptor->u.Interrupt.Vector, Descriptor->u.Interrupt.Level, Descriptor->Flags, Descriptor->u.Interrupt.Affinity);
232
235 (PVOID)this,
236 NULL, //&m_Lock,
237 Descriptor->u.Interrupt.Vector,
238 (KIRQL)Descriptor->u.Interrupt.Level,
239 (KIRQL)Descriptor->u.Interrupt.Level,
241 (Descriptor->ShareDisposition != CmResourceShareDeviceExclusive),
242 Descriptor->u.Interrupt.Affinity,
243 FALSE);
244
245 DPRINT1("CInterruptSync::Connect result %x\n", Status);
246 return Status;
247}
248
249VOID
250NTAPI
251CInterruptSync::Disconnect()
252{
253 DPRINT("CInterruptSync::Disconnect\n");
255
256 if (!m_Interrupt)
257 {
258 DPRINT("CInterruptSync_Disconnect %p no interrupt connected\n", this);
259 return;
260 }
261
264}
265
267NTAPI
268CInterruptSync::RegisterServiceRoutine(
270 IN PVOID DynamicContext,
272{
273 PSYNC_ENTRY NewEntry;
274
275 DPRINT("CInterruptSync::RegisterServiceRoutine\n");
277
279 if (!NewEntry)
281
282 NewEntry->SyncRoutine = Routine;
283 NewEntry->DynamicContext = DynamicContext;
284
285 if (First)
287 else
289
290 return STATUS_SUCCESS;
291}
292
294NTAPI
296 OUT PINTERRUPTSYNC* OutInterruptSync,
297 IN PUNKNOWN OuterUnknown OPTIONAL,
299 IN ULONG ResourceIndex,
301{
304
305 DPRINT("PcNewInterruptSync entered OutInterruptSync %p OuterUnknown %p ResourceList %p ResourceIndex %u Mode %d\n",
306 OutInterruptSync, OuterUnknown, ResourceList, ResourceIndex, Mode);
307
308 if (!OutInterruptSync || !ResourceList || Mode < InterruptSyncModeNormal || Mode > InterruptSyncModeRepeat)
310
311 if (ResourceIndex > ResourceList->NumberOfEntriesOfType(CmResourceTypeInterrupt))
313
314 This = new(NonPagedPool, TAG_PORTCLASS)CInterruptSync(OuterUnknown);
315 if (!This)
317
318 Status = This->QueryInterface(IID_IInterruptSync, (PVOID*)OutInterruptSync);
319
320 if (!NT_SUCCESS(Status))
321 {
322 delete This;
323 return Status;
324 }
325
326 ResourceList->AddRef();
327
328 //
329 // initialize object
330 //
331 This->m_Mode = Mode;
332 This->m_ResourceIndex = ResourceIndex;
333 This->m_ResourceList = ResourceList;
334 InitializeListHead(&This->m_ServiceRoutines);
335 KeInitializeSpinLock(&This->m_Lock);
336
337 return Status;
338}
WCHAR First[]
Definition: FormatMessage.c:11
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
#define STDMETHODIMP
Definition: basetyps.h:43
const GUID IID_IUnknown
PRESOURCELIST m_ResourceList
Definition: interrupt.cpp:36
PVOID m_DynamicContext
Definition: interrupt.cpp:40
LIST_ENTRY m_ServiceRoutines
Definition: interrupt.cpp:33
INTERRUPTSYNCMODE m_Mode
Definition: interrupt.cpp:35
NTSTATUS m_Status
Definition: interrupt.cpp:41
CInterruptSync(IUnknown *OuterUnknown)
Definition: interrupt.cpp:27
friend BOOLEAN NTAPI CInterruptSynchronizedRoutine(IN PVOID ServiceContext)
Definition: interrupt.cpp:84
PKINTERRUPT m_Interrupt
Definition: interrupt.cpp:34
PINTERRUPTSYNCROUTINE m_SyncRoutine
Definition: interrupt.cpp:39
ULONG m_ResourceIndex
Definition: interrupt.cpp:37
friend BOOLEAN NTAPI IInterruptServiceRoutine(IN PKINTERRUPT Interrupt, IN PVOID ServiceContext)
Definition: interrupt.cpp:139
KSPIN_LOCK m_Lock
Definition: interrupt.cpp:32
virtual ~CInterruptSync()
Definition: interrupt.cpp:28
STDMETHODIMP QueryInterface(REFIID InterfaceId, PVOID *Interface)
Definition: interrupt.cpp:53
IUnknown * PUNKNOWN
Definition: com_apitest.h:45
#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:32
#define InsertTailList(ListHead, Entry)
#define InsertHeadList(ListHead, Entry)
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
UCHAR KIRQL
Definition: env_spec_w32.h:591
ULONG KSPIN_LOCK
Definition: env_spec_w32.h:72
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define NonPagedPool
Definition: env_spec_w32.h:307
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
#define KeInitializeSpinLock(sl)
Definition: env_spec_w32.h:604
@ Success
Definition: eventcreate.c:712
unsigned int BOOL
Definition: ntddk_ex.h:94
Status
Definition: gdiplustypes.h:25
_In_ ULONG Mode
Definition: hubbusif.h:303
#define CmResourceTypeInterrupt
Definition: hwresource.cpp:124
NTSYSAPI NTSTATUS WINAPI RtlStringFromGUID(REFGUID, PUNICODE_STRING)
ULONG AddRef()
struct SYNC_ENTRY * PSYNC_ENTRY
BOOLEAN NTAPI CInterruptSynchronizedRoutine(IN PVOID ServiceContext)
Definition: interrupt.cpp:84
NTSTATUS NTAPI PcNewInterruptSync(OUT PINTERRUPTSYNC *OutInterruptSync, IN PUNKNOWN OuterUnknown OPTIONAL, IN PRESOURCELIST ResourceList, IN ULONG ResourceIndex, IN INTERRUPTSYNCMODE Mode)
Definition: interrupt.cpp:295
BOOLEAN NTAPI IInterruptServiceRoutine(IN PKINTERRUPT Interrupt, IN PVOID ServiceContext)
Definition: interrupt.cpp:139
PVOID AllocateItem(IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes)
Definition: misc.c:29
static PWSTR GuidString
Definition: apphelp.c:93
#define CM_RESOURCE_INTERRUPT_LATCHED
Definition: cmtypes.h:144
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
VOID NTAPI IoDisconnectInterrupt(PKINTERRUPT InterruptObject)
Definition: irq.c:141
NTSTATUS NTAPI IoConnectInterrupt(OUT PKINTERRUPT *InterruptObject, IN PKSERVICE_ROUTINE ServiceRoutine, IN PVOID ServiceContext, IN PKSPIN_LOCK SpinLock, IN ULONG Vector, IN KIRQL Irql, IN KIRQL SynchronizeIrql, IN KINTERRUPT_MODE InterruptMode, IN BOOLEAN ShareVector, IN KAFFINITY ProcessorEnableMask, IN BOOLEAN FloatingSave)
Definition: irq.c:22
BOOLEAN NTAPI KeSynchronizeExecution(IN OUT PKINTERRUPT Interrupt, IN PKSYNCHRONIZE_ROUTINE SynchronizeRoutine, IN PVOID SynchronizeContext OPTIONAL)
Definition: interrupt.c:237
IInterruptSync * PINTERRUPTSYNC
Definition: portcls.h:888
IResourceList * PRESOURCELIST
Definition: portcls.h:442
NTSTATUS(NTAPI * PINTERRUPTSYNCROUTINE)(IN struct IInterruptSync *InterruptSync, IN PVOID DynamicContext)
Definition: portcls.h:847
INTERRUPTSYNCMODE
Definition: portcls.h:839
@ InterruptSyncModeAll
Definition: portcls.h:841
@ InterruptSyncModeNormal
Definition: portcls.h:840
@ InterruptSyncModeRepeat
Definition: portcls.h:842
#define PC_ASSERT_IRQL_EQUAL(x)
Definition: private.hpp:31
#define TAG_PORTCLASS
Definition: private.hpp:24
#define REFIID
Definition: guiddef.h:118
enum _KINTERRUPT_MODE KINTERRUPT_MODE
@ Output
Definition: arc.h:85
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
base of all file and directory entries
Definition: entries.h:83
Definition: interrupt.cpp:15
PINTERRUPTSYNCROUTINE SyncRoutine
Definition: interrupt.cpp:17
LIST_ENTRY ListEntry
Definition: interrupt.cpp:16
PVOID DynamicContext
Definition: interrupt.cpp:18
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define NTAPI
Definition: typedefs.h:36
void * PVOID
Definition: typedefs.h:50
#define IN
Definition: typedefs.h:39
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_Must_inspect_result_ _In_ WDFDEVICE _In_ LPCGUID _Out_ PINTERFACE Interface
Definition: wdffdo.h:465
_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_ WDFIORESREQLIST _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFIORESLIST * ResourceList
Definition: wdfresource.h:309
_Must_inspect_result_ _In_ WDFIORESLIST _In_ PIO_RESOURCE_DESCRIPTOR Descriptor
Definition: wdfresource.h:342
#define IsEqualGUIDAligned(guid1, guid2)
Definition: wdm.template.h:235
@ CmResourceShareDeviceExclusive
Definition: cmtypes.h:241
_In_ PKSERVICE_ROUTINE _In_opt_ PVOID ServiceContext
Definition: iofuncs.h:801
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778