ReactOS 0.4.15-dev-6057-gd708c79
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#ifndef YDEBUG
12#define NDEBUG
13#endif
14
15#include <debug.h>
16
17typedef struct
18{
23
24class CInterruptSync : public CUnknownImpl<IInterruptSync>
25{
26public:
28
30 CInterruptSync(IUnknown *OuterUnknown){}
31 virtual ~CInterruptSync(){}
32
33public:
34
41
45
48};
49
50
51//---------------------------------------------------------------
52// IUnknown methods
53//
54
55
56
60 IN REFIID refiid,
62{
64
65 DPRINT("CInterruptSync::QueryInterface: this %p\n", this);
66
67 if (IsEqualGUIDAligned(refiid, IID_IInterruptSync) ||
69 {
70 *Output = PVOID(PUNKNOWN(this));
71 PUNKNOWN(*Output)->AddRef();
72 return STATUS_SUCCESS;
73 }
74
75
77 {
78 DPRINT1("CInterruptSync::QueryInterface: no interface!!! iface %S\n", GuidString.Buffer);
80 }
81
83}
84
85//---------------------------------------------------------------
86// CInterruptSync methods
87//
88
89
94{
96 This->m_Status = This->m_SyncRoutine(This, This->m_DynamicContext);
97
98 DPRINT("CInterruptSynchronizedRoutine this %p SyncRoutine %p Context %p Status %x\n", This, This->m_SyncRoutine, This->m_DynamicContext, This->m_Status);
99 return TRUE;
100}
101
103NTAPI
104CInterruptSync::CallSynchronizedRoutine(
106 IN PVOID DynamicContext)
107{
109
110 DPRINT("CInterruptSync::CallSynchronizedRoutine this %p Routine %p DynamicContext %p Irql %x Interrupt %p\n", this, Routine, DynamicContext, KeGetCurrentIrql(), m_Interrupt);
111
112 if (!m_Interrupt)
113 {
114 DPRINT("CInterruptSync_CallSynchronizedRoutine %p no interrupt connected\n", this);
116 return STATUS_UNSUCCESSFUL;
117
119 m_SyncRoutine = Routine;
120 m_DynamicContext = DynamicContext;
123
124 return m_Status;
125 }
126
127 m_SyncRoutine = Routine;
128 m_DynamicContext = DynamicContext;
129
131 return m_Status;
132 else
133 return STATUS_UNSUCCESSFUL;
134}
135
137NTAPI
138CInterruptSync::GetKInterrupt()
139{
140 DPRINT("CInterruptSynchronizedRoutine\n");
141
142 return m_Interrupt;
143}
144
146NTAPI
150{
151 PLIST_ENTRY CurEntry;
154 BOOL Success, Ret;
155
157
158 DPRINT("IInterruptServiceRoutine Mode %u\n", This->m_Mode);
159
160 Ret = FALSE;
161 if (This->m_Mode == InterruptSyncModeNormal)
162 {
163 CurEntry = This->m_ServiceRoutines.Flink;
164 while (CurEntry != &This->m_ServiceRoutines)
165 {
166 Entry = CONTAINING_RECORD(CurEntry, SYNC_ENTRY, ListEntry);
167 Status = Entry->SyncRoutine((CInterruptSync*)This, Entry->DynamicContext);
168 if (Status == STATUS_SUCCESS)
169 {
170 /* Mark as handled and break on the first success */
171 Ret = TRUE;
172 break;
173 }
174 CurEntry = CurEntry->Flink;
175 }
176 return Ret;
177 }
178 else if (This->m_Mode == InterruptSyncModeAll)
179 {
180 CurEntry = This->m_ServiceRoutines.Flink;
181 while (CurEntry != &This->m_ServiceRoutines)
182 {
183 Entry = CONTAINING_RECORD(CurEntry, SYNC_ENTRY, ListEntry);
184 Status = Entry->SyncRoutine((CInterruptSync*)This, Entry->DynamicContext);
185 if (Status == STATUS_SUCCESS)
186 {
187 /* Mark as handled but don't break */
188 Ret = TRUE;
189 }
190 CurEntry = CurEntry->Flink;
191 }
192 return Ret;
193 }
194 else if (This->m_Mode == InterruptSyncModeRepeat)
195 {
196 do
197 {
198 Success = FALSE;
199 CurEntry = This->m_ServiceRoutines.Flink;
200 while (CurEntry != &This->m_ServiceRoutines)
201 {
202 Entry = CONTAINING_RECORD(CurEntry, SYNC_ENTRY, ListEntry);
203 Status = Entry->SyncRoutine((CInterruptSync*)This, Entry->DynamicContext);
204 if (Status == STATUS_SUCCESS)
205 {
206 /* Mark as handled if it works at least once */
207 Success = TRUE;
208 Ret = TRUE;
209 }
210 CurEntry = CurEntry->Flink;
211 }
212 } while(Success);
213 return Ret;
214 }
215 else
216 {
217 DPRINT("Unknown mode %u\n", This->m_Mode);
218 return Ret;
219 }
220}
221
222
224NTAPI
225CInterruptSync::Connect()
226{
229
230 DPRINT("CInterruptSync::Connect\n");
232
234 if (!Descriptor)
235 return STATUS_UNSUCCESSFUL;
236
238 return STATUS_UNSUCCESSFUL;
239
240 DPRINT1("Vector %u Level %u Flags %x Affinity %x\n", Descriptor->u.Interrupt.Vector, Descriptor->u.Interrupt.Level, Descriptor->Flags, Descriptor->u.Interrupt.Affinity);
241
244 (PVOID)this,
245 NULL, //&m_Lock,
246 Descriptor->u.Interrupt.Vector,
247 (KIRQL)Descriptor->u.Interrupt.Level,
248 (KIRQL)Descriptor->u.Interrupt.Level,
250 (Descriptor->ShareDisposition != CmResourceShareDeviceExclusive),
251 Descriptor->u.Interrupt.Affinity,
252 FALSE);
253
254 DPRINT1("CInterruptSync::Connect result %x\n", Status);
255 return Status;
256}
257
258
259VOID
260NTAPI
261CInterruptSync::Disconnect()
262{
263 DPRINT("CInterruptSync::Disconnect\n");
265
266 if (!m_Interrupt)
267 {
268 DPRINT("CInterruptSync_Disconnect %p no interrupt connected\n", this);
269 return;
270 }
271
274}
275
277NTAPI
278CInterruptSync::RegisterServiceRoutine(
280 IN PVOID DynamicContext,
282{
283 PSYNC_ENTRY NewEntry;
284
285 DPRINT("CInterruptSync::RegisterServiceRoutine\n");
287
289 if (!NewEntry)
291
292 NewEntry->SyncRoutine = Routine;
293 NewEntry->DynamicContext = DynamicContext;
294
295 if (First)
297 else
299
300 return STATUS_SUCCESS;
301}
302
304NTAPI
306 OUT PINTERRUPTSYNC* OutInterruptSync,
307 IN PUNKNOWN OuterUnknown OPTIONAL,
309 IN ULONG ResourceIndex,
311{
314
315 DPRINT("PcNewInterruptSync entered OutInterruptSync %p OuterUnknown %p ResourceList %p ResourceIndex %u Mode %d\n",
316 OutInterruptSync, OuterUnknown, ResourceList, ResourceIndex, Mode);
317
318 if (!OutInterruptSync || !ResourceList || Mode < InterruptSyncModeNormal || Mode > InterruptSyncModeRepeat)
320
321 if (ResourceIndex > ResourceList->NumberOfEntriesOfType(CmResourceTypeInterrupt))
323
324 This = new(NonPagedPool, TAG_PORTCLASS)CInterruptSync(OuterUnknown);
325 if (!This)
327
328 Status = This->QueryInterface(IID_IInterruptSync, (PVOID*)OutInterruptSync);
329
330 if (!NT_SUCCESS(Status))
331 {
332 delete This;
333 return Status;
334 }
335
336 ResourceList->AddRef();
337
338 //
339 // initialize object
340 //
341 This->m_Mode = Mode;
342 This->m_ResourceIndex = ResourceIndex;
343 This->m_ResourceList = ResourceList;
344 InitializeListHead(&This->m_ServiceRoutines);
345 KeInitializeSpinLock(&This->m_Lock);
346
347 return Status;
348}
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:39
PVOID m_DynamicContext
Definition: interrupt.cpp:43
LIST_ENTRY m_ServiceRoutines
Definition: interrupt.cpp:36
INTERRUPTSYNCMODE m_Mode
Definition: interrupt.cpp:38
NTSTATUS m_Status
Definition: interrupt.cpp:44
CInterruptSync(IUnknown *OuterUnknown)
Definition: interrupt.cpp:30
friend BOOLEAN NTAPI CInterruptSynchronizedRoutine(IN PVOID ServiceContext)
Definition: interrupt.cpp:92
PKINTERRUPT m_Interrupt
Definition: interrupt.cpp:37
PINTERRUPTSYNCROUTINE m_SyncRoutine
Definition: interrupt.cpp:42
ULONG m_ResourceIndex
Definition: interrupt.cpp:40
friend BOOLEAN NTAPI IInterruptServiceRoutine(IN PKINTERRUPT Interrupt, IN PVOID ServiceContext)
Definition: interrupt.cpp:147
KSPIN_LOCK m_Lock
Definition: interrupt.cpp:35
virtual ~CInterruptSync()
Definition: interrupt.cpp:31
STDMETHODIMP QueryInterface(REFIID InterfaceId, PVOID *Interface)
Definition: interrupt.cpp:59
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:92
NTSTATUS NTAPI PcNewInterruptSync(OUT PINTERRUPTSYNC *OutInterruptSync, IN PUNKNOWN OuterUnknown OPTIONAL, IN PRESOURCELIST ResourceList, IN ULONG ResourceIndex, IN INTERRUPTSYNCMODE Mode)
Definition: interrupt.cpp:305
BOOLEAN NTAPI IInterruptServiceRoutine(IN PKINTERRUPT Interrupt, IN PVOID ServiceContext)
Definition: interrupt.cpp:147
PVOID AllocateItem(IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes)
Definition: misc.c:30
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:140
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:231
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:18
PINTERRUPTSYNCROUTINE SyncRoutine
Definition: interrupt.cpp:20
LIST_ENTRY ListEntry
Definition: interrupt.cpp:19
PVOID DynamicContext
Definition: interrupt.cpp:21
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:792