ReactOS  0.4.14-dev-98-gb0d4763
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 
17 typedef struct
18 {
20  PINTERRUPTSYNCROUTINE SyncRoutine;
23 
24 class CInterruptSync : public IInterruptSync
25 {
26 public:
28 
30  {
32  return m_Ref;
33  }
35  {
37 
38  if (!m_Ref)
39  {
40  delete this;
41  return 0;
42  }
43  return m_Ref;
44  }
46  CInterruptSync(IUnknown *OuterUnknown){}
47  virtual ~CInterruptSync(){}
48 
49 public:
50 
57 
58  PINTERRUPTSYNCROUTINE m_SyncRoutine;
61 
63 
66 };
67 
68 
69 //---------------------------------------------------------------
70 // IUnknown methods
71 //
72 
73 
74 
76 NTAPI
78  IN REFIID refiid,
79  OUT PVOID* Output)
80 {
82 
83  DPRINT("CInterruptSync::QueryInterface: this %p\n", this);
84 
85  if (IsEqualGUIDAligned(refiid, IID_IInterruptSync) ||
87  {
88  *Output = PVOID(PUNKNOWN(this));
89  PUNKNOWN(*Output)->AddRef();
90  return STATUS_SUCCESS;
91  }
92 
93 
95  {
96  DPRINT1("CInterruptSync::QueryInterface: no interface!!! iface %S\n", GuidString.Buffer);
98  }
99 
100  return STATUS_UNSUCCESSFUL;
101 }
102 
103 //---------------------------------------------------------------
104 // CInterruptSync methods
105 //
106 
107 
108 BOOLEAN
109 NTAPI
112 {
114  This->m_Status = This->m_SyncRoutine(This, This->m_DynamicContext);
115 
116  DPRINT("CInterruptSynchronizedRoutine this %p SyncRoutine %p Context %p Status %x\n", This, This->m_SyncRoutine, This->m_DynamicContext, This->m_Status);
117  return TRUE;
118 }
119 
120 NTSTATUS
121 NTAPI
122 CInterruptSync::CallSynchronizedRoutine(
123  IN PINTERRUPTSYNCROUTINE Routine,
125 {
126  KIRQL OldIrql;
127 
128  DPRINT("CInterruptSync::CallSynchronizedRoutine this %p Routine %p DynamicContext %p Irql %x Interrupt %p\n", this, Routine, DynamicContext, KeGetCurrentIrql(), m_Interrupt);
129 
130  if (!m_Interrupt)
131  {
132  DPRINT("CInterruptSync_CallSynchronizedRoutine %p no interrupt connected\n", this);
134  return STATUS_UNSUCCESSFUL;
135 
137  m_SyncRoutine = Routine;
141 
142  return m_Status;
143  }
144 
145  m_SyncRoutine = Routine;
147 
149  return m_Status;
150  else
151  return STATUS_UNSUCCESSFUL;
152 }
153 
155 NTAPI
156 CInterruptSync::GetKInterrupt()
157 {
158  DPRINT("CInterruptSynchronizedRoutine\n");
159 
160  return m_Interrupt;
161 }
162 
163 BOOLEAN
164 NTAPI
166  IN PKINTERRUPT Interrupt,
168 {
169  PLIST_ENTRY CurEntry;
172  BOOL Success, Ret;
173 
175 
176  DPRINT("IInterruptServiceRoutine Mode %u\n", This->m_Mode);
177 
178  Ret = FALSE;
179  if (This->m_Mode == InterruptSyncModeNormal)
180  {
181  CurEntry = This->m_ServiceRoutines.Flink;
182  while (CurEntry != &This->m_ServiceRoutines)
183  {
184  Entry = CONTAINING_RECORD(CurEntry, SYNC_ENTRY, ListEntry);
185  Status = Entry->SyncRoutine((CInterruptSync*)This, Entry->DynamicContext);
186  if (Status == STATUS_SUCCESS)
187  {
188  /* Mark as handled and break on the first success */
189  Ret = TRUE;
190  break;
191  }
192  CurEntry = CurEntry->Flink;
193  }
194  return Ret;
195  }
196  else if (This->m_Mode == InterruptSyncModeAll)
197  {
198  CurEntry = This->m_ServiceRoutines.Flink;
199  while (CurEntry != &This->m_ServiceRoutines)
200  {
201  Entry = CONTAINING_RECORD(CurEntry, SYNC_ENTRY, ListEntry);
202  Status = Entry->SyncRoutine((CInterruptSync*)This, Entry->DynamicContext);
203  if (Status == STATUS_SUCCESS)
204  {
205  /* Mark as handled but don't break */
206  Ret = TRUE;
207  }
208  CurEntry = CurEntry->Flink;
209  }
210  return Ret;
211  }
212  else if (This->m_Mode == InterruptSyncModeRepeat)
213  {
214  do
215  {
216  Success = FALSE;
217  CurEntry = This->m_ServiceRoutines.Flink;
218  while (CurEntry != &This->m_ServiceRoutines)
219  {
220  Entry = CONTAINING_RECORD(CurEntry, SYNC_ENTRY, ListEntry);
221  Status = Entry->SyncRoutine((CInterruptSync*)This, Entry->DynamicContext);
222  if (Status == STATUS_SUCCESS)
223  {
224  /* Mark as handled if it works at least once */
225  Success = TRUE;
226  Ret = TRUE;
227  }
228  CurEntry = CurEntry->Flink;
229  }
230  } while(Success);
231  return Ret;
232  }
233  else
234  {
235  DPRINT("Unknown mode %u\n", This->m_Mode);
236  return Ret;
237  }
238 }
239 
240 
241 NTSTATUS
242 NTAPI
244 {
247 
248  DPRINT("CInterruptSync::Connect\n");
250 
252  if (!Descriptor)
253  return STATUS_UNSUCCESSFUL;
254 
256  return STATUS_UNSUCCESSFUL;
257 
258  DPRINT1("Vector %u Level %u Flags %x Affinity %x\n", Descriptor->u.Interrupt.Vector, Descriptor->u.Interrupt.Level, Descriptor->Flags, Descriptor->u.Interrupt.Affinity);
259 
262  (PVOID)this,
263  NULL, //&m_Lock,
264  Descriptor->u.Interrupt.Vector,
265  (KIRQL)Descriptor->u.Interrupt.Level,
266  (KIRQL)Descriptor->u.Interrupt.Level,
268  (Descriptor->ShareDisposition != CmResourceShareDeviceExclusive),
269  Descriptor->u.Interrupt.Affinity,
270  FALSE);
271 
272  DPRINT1("CInterruptSync::Connect result %x\n", Status);
273  return Status;
274 }
275 
276 
277 VOID
278 NTAPI
279 CInterruptSync::Disconnect()
280 {
281  DPRINT("CInterruptSync::Disconnect\n");
283 
284  if (!m_Interrupt)
285  {
286  DPRINT("CInterruptSync_Disconnect %p no interrupt connected\n", this);
287  return;
288  }
289 
291  m_Interrupt = NULL;
292 }
293 
294 NTSTATUS
295 NTAPI
296 CInterruptSync::RegisterServiceRoutine(
297  IN PINTERRUPTSYNCROUTINE Routine,
299  IN BOOLEAN First)
300 {
301  PSYNC_ENTRY NewEntry;
302 
303  DPRINT("CInterruptSync::RegisterServiceRoutine\n");
305 
307  if (!NewEntry)
309 
310  NewEntry->SyncRoutine = Routine;
311  NewEntry->DynamicContext = DynamicContext;
312 
313  if (First)
315  else
317 
318  return STATUS_SUCCESS;
319 }
320 
321 NTSTATUS
322 NTAPI
324  OUT PINTERRUPTSYNC* OutInterruptSync,
325  IN PUNKNOWN OuterUnknown OPTIONAL,
327  IN ULONG ResourceIndex,
329 {
332 
333  DPRINT("PcNewInterruptSync entered OutInterruptSync %p OuterUnknown %p ResourceList %p ResourceIndex %u Mode %d\n",
334  OutInterruptSync, OuterUnknown, ResourceList, ResourceIndex, Mode);
335 
336  if (!OutInterruptSync || !ResourceList || Mode < InterruptSyncModeNormal || Mode > InterruptSyncModeRepeat)
338 
339  if (ResourceIndex > ResourceList->NumberOfEntriesOfType(CmResourceTypeInterrupt))
341 
342  This = new(NonPagedPool, TAG_PORTCLASS)CInterruptSync(OuterUnknown);
343  if (!This)
345 
346  Status = This->QueryInterface(IID_IInterruptSync, (PVOID*)OutInterruptSync);
347 
348  if (!NT_SUCCESS(Status))
349  {
350  delete This;
351  return Status;
352  }
353 
354  ResourceList->AddRef();
355 
356  //
357  // initialize object
358  //
359  This->m_Mode = Mode;
360  This->m_ResourceIndex = ResourceIndex;
361  This->m_ResourceList = ResourceList;
362  InitializeListHead(&This->m_ServiceRoutines);
363  KeInitializeSpinLock(&This->m_Lock);
364 
365  return Status;
366 }
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
LIST_ENTRY m_ServiceRoutines
Definition: interrupt.cpp:52
static PWSTR GuidString
Definition: apphelp.c:91
#define IN
Definition: typedefs.h:38
#define REFIID
Definition: guiddef.h:118
#define TRUE
Definition: types.h:120
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ PKSPIN_CONNECT Connect
Definition: ks.h:4536
INTERRUPTSYNCMODE m_Mode
Definition: interrupt.cpp:54
struct _Entry Entry
Definition: kefuncs.h:640
_In_ ULONG Mode
Definition: hubbusif.h:303
_In_ BOOLEAN Release
Definition: classpnp.h:929
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
PKINTERRUPT m_Interrupt
Definition: interrupt.cpp:53
IUnknown * PUNKNOWN
Definition: com_apitest.h:45
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
#define TAG_PORTCLASS
Definition: private.hpp:24
PVOID AllocateItem(IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes)
Definition: misc.c:30
LONG NTSTATUS
Definition: precomp.h:26
PVOID DynamicContext
Definition: interrupt.cpp:21
Definition: interrupt.cpp:17
#define InsertTailList(ListHead, Entry)
INTERRUPTSYNCMODE
Definition: portcls.h:828
const MUI_LANGUAGE_RESOURCE ResourceList[]
Definition: muilanguages.h:414
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
CInterruptSync(IUnknown *OuterUnknown)
Definition: interrupt.cpp:46
#define IsEqualGUIDAligned(guid1, guid2)
Definition: wdm.template.h:233
PVOID m_DynamicContext
Definition: interrupt.cpp:59
WCHAR First[]
Definition: FormatMessage.c:11
friend BOOLEAN NTAPI CInterruptSynchronizedRoutine(IN PVOID ServiceContext)
Definition: interrupt.cpp:110
UCHAR KIRQL
Definition: env_spec_w32.h:591
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
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
#define STDMETHODIMP
Definition: basetyps.h:43
FORCEINLINE VOID KeInitializeSpinLock(_Out_ PKSPIN_LOCK SpinLock)
Definition: kefuncs.h:251
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
enum _KINTERRUPT_MODE KINTERRUPT_MODE
VOID NTAPI IoDisconnectInterrupt(PKINTERRUPT InterruptObject)
Definition: irq.c:140
void DPRINT(...)
Definition: polytest.cpp:61
PRESOURCELIST m_ResourceList
Definition: interrupt.cpp:55
void * PVOID
Definition: retypes.h:9
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
BOOLEAN NTAPI IInterruptServiceRoutine(IN PKINTERRUPT Interrupt, IN PVOID ServiceContext)
Definition: interrupt.cpp:165
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
IN PVOID IN PVOID IN USHORT IN USHORT IN PINTERFACE Interface
Definition: pci.h:359
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
const GUID IID_IUnknown
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
struct SYNC_ENTRY * PSYNC_ENTRY
KSPIN_LOCK m_Lock
Definition: interrupt.cpp:51
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
NTSTATUS NTAPI PcNewInterruptSync(OUT PINTERRUPTSYNC *OutInterruptSync, IN PUNKNOWN OuterUnknown OPTIONAL, IN PRESOURCELIST ResourceList, IN ULONG ResourceIndex, IN INTERRUPTSYNCMODE Mode)
Definition: interrupt.cpp:323
#define PC_ASSERT_IRQL_EQUAL(x)
Definition: private.hpp:31
_In_ PKSERVICE_ROUTINE _In_opt_ PVOID ServiceContext
Definition: iofuncs.h:798
ULONG AddRef()
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
ULONG m_ResourceIndex
Definition: interrupt.cpp:56
STDMETHODIMP_(ULONG) Release()
Definition: interrupt.cpp:34
#define InterlockedDecrement
Definition: armddk.h:52
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
Definition: arc.h:85
friend BOOLEAN NTAPI IInterruptServiceRoutine(IN PKINTERRUPT Interrupt, IN PVOID ServiceContext)
Definition: interrupt.cpp:165
Definition: typedefs.h:117
NTSYSAPI NTSTATUS WINAPI RtlStringFromGUID(REFGUID, PUNICODE_STRING)
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
Status
Definition: gdiplustypes.h:24
IResourceList * PRESOURCELIST
Definition: portcls.h:442
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
PINTERRUPTSYNCROUTINE SyncRoutine
Definition: interrupt.cpp:20
#define InterlockedIncrement
Definition: armddk.h:53
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
BOOLEAN NTAPI CInterruptSynchronizedRoutine(IN PVOID ServiceContext)
Definition: interrupt.cpp:110
virtual ~CInterruptSync()
Definition: interrupt.cpp:47
ULONG KSPIN_LOCK
Definition: env_spec_w32.h:72
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
static ULONG WINAPI AddRef(IStream *iface)
Definition: clist.c:90
#define CmResourceTypeInterrupt
Definition: hwresource.cpp:124
IInterruptSync * PINTERRUPTSYNC
Definition: portcls.h:878
#define DPRINT1
Definition: precomp.h:8
#define OUT
Definition: typedefs.h:39
#define CM_RESOURCE_INTERRUPT_LATCHED
Definition: cmtypes.h:144
PINTERRUPTSYNCROUTINE m_SyncRoutine
Definition: interrupt.cpp:58
unsigned int ULONG
Definition: retypes.h:1
BOOLEAN NTAPI KeSynchronizeExecution(IN OUT PKINTERRUPT Interrupt, IN PKSYNCHRONIZE_ROUTINE SynchronizeRoutine, IN PVOID SynchronizeContext OPTIONAL)
Definition: interrupt.c:142
return STATUS_SUCCESS
Definition: btrfs.c:2966
NTSTATUS m_Status
Definition: interrupt.cpp:60
STDMETHODIMP_(ULONG) AddRef()
Definition: interrupt.cpp:29
LIST_ENTRY ListEntry
Definition: interrupt.cpp:19
STDMETHODIMP QueryInterface(REFIID InterfaceId, PVOID *Interface)
Definition: interrupt.cpp:77
base of all file and directory entries
Definition: entries.h:82
IN PVOID DynamicContext
Definition: portcls.h:839
_In_ PSTORAGE_PROPERTY_ID _Outptr_ PSTORAGE_DESCRIPTOR_HEADER * Descriptor
Definition: classpnp.h:966
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68