ReactOS  0.4.15-dev-2704-gd5265b0
interruptobjectum.cpp
Go to the documentation of this file.
1 /*++
2 
3 Copyright (c) Microsoft Corporation
4 
5 Module Name:
6 
7  InterruptObjectUm.cpp
8 
9 Abstract:
10 
11  This module implements a frameworks managed interrupt object
12 
13 Author:
14 
15 Environment:
16 
17  User mode only
18 
19 Revision History:
20 
21 
22 
23 --*/
24 
25 #include "fxmin.hpp"
26 #include "FxInterruptThreadpoolUm.hpp"
27 
28 extern "C" {
29 #include "InterruptObjectUm.tmh"
30 }
31 
32 #define STRSAFE_LIB
33 #include <strsafe.h>
34 
40  )
41 {
42  IWudfDeviceStack *deviceStack;
43  HRESULT hr;
46  CM_SHARE_DISPOSITION shareVector;
47 
49 
51 
52  switch (m_ShareVector) {
53  case WdfTrue:
54  //
55  // Override the bus driver's value, explicitly sharing this interrupt.
56  //
57  shareVector = CmResourceShareShared;
58  break;
59 
60  case WdfFalse:
61  //
62  // Override the bus driver's value, explicitly claiming this interrupt
63  // as non-shared.
64  //
65  shareVector = CmResourceShareDeviceExclusive;
66  break;
67 
68  case WdfUseDefault:
69  default:
70  //
71  // Leave the bus driver's value alone.
72  //
73  shareVector = CmResourceShareUndetermined;
74  break;
75  }
76 
77  //
78  // Create a thread pool if not already created. An interrupt is created in
79  // one of the pnp callbacks (OnAddDevice, OnPrepareHarwdare etc) so there is
80  // no race in getting and setting the theradpool pointer.
81  //
83  if (pool == NULL) {
85  &pool);
86  if (FAILED(hr))
87  {
88  goto exit;
89  }
90 
92  }
93 
94  //
95  // create an instance of interruypt wait block
96  //
98  this,
101  if (FAILED(hr)) {
104  "Waitblock creation failed for CWdfInterrupt object"
105  " %!hresult!", hr);
106  goto exit;
107  }
108 
109  //
110  // Send an IOCTL to redirector to create and initialize an interrupt object
111  //
113 
114  hr = deviceStack->InitializeInterrupt((WUDF_INTERRUPT_CONTEXT) this,
116  shareVector,
118  );
119 
120  if (SUCCEEDED(hr))
121  {
123  }
124  else
125  {
126  PUMDF_VERSION_DATA driverVersion = deviceStack->GetMinDriverVersion();
127 
128  BOOL preserveCompat =
129  deviceStack->ShouldPreserveIrpCompletionStatusCompatibility();
130 
131  status = CHostFxUtil::NtStatusFromHr(
132  hr,
133  driverVersion->MajorNumber,
134  driverVersion->MinorNumber,
135  preserveCompat
136  );
137  }
138 
139  if (!NT_SUCCESS(status)) {
142  "failed to initialize interrupt "
143  "%!STATUS!", status);
144 
145  goto exit;
146  }
147 
148 exit:
149 
150  //
151  // Dispose will do cleanup. No need to cleanup here.
152  //
153 
154  return status;
155 }
156 
157 NTSTATUS
159  VOID
160  )
161 {
162  HRESULT hr;
164  IWudfDeviceStack2 *deviceStack;
166  BOOLEAN isRdConnectingOrConnected = FALSE;
167 
170 
171  //
172  // reset the interrupt event to non-signaled state to start with a
173  // clean slate.
174  //
176 
177  //
178  // Open the queue and enqueue an interrupt event wait to the threadpool
179  // before connecting the interrupt in the reflector. This minimizes the
180  // processing delay for interrupts that fire as soon as they are connected,
181  // like GPIO button devices that have no means to explicitly enable and
182  // disable interrupts at the hardware level.
183  //
184  StartThreadpoolWaitQueue();
185 
186  //
187  // Tell the PnP Manager to connect the interrupt. Send a message to
188  // redirector to do so. When ConnectInterrupt returns a failure code,
189  // we use isRdConnectingOrConnected to check if the failure was due
190  // to an already connected or currently connecting interrupt.
191  //
192  hr = deviceStack->ConnectInterrupt(m_RdInterruptContext,
193  &isRdConnectingOrConnected);
194  if (FAILED(hr))
195  {
196  if (isRdConnectingOrConnected) {
197  //
198  // The connect call failed because we asked the Reflector to connect
199  // an already connected or currently connecting interrupt. Perhaps the
200  // client made a redundant call to WdfInterruptEnable. In this case,
201  // we want to keep the threadpool active so that we continue to receive
202  // and acknowledge interrupts - otherwise RdIsrPassiveLevel may time out.
203  //
206  "Multiple connection attempts for !WDFINTERRUPT 0x%p",
207  GetHandle());
208 
210  FX_VERIFY_WITH_NAME(DRIVER(BadArgument, TODO),
211  CHECK("Multiple interrupt connection attempts", FALSE),
212  pFxDriverGlobals->Public.DriverName);
213  }
214  }
215  else {
216  //
217  // Connecting the interrupt in the reflector failed, which means
218  // that IoConnectInterruptEx either failed or was not called at all.
219  // All we need to do in this case is revert the actions done by
220  // StartThreadpoolWaitQueue above, which are closing the queue
221  // and removing the enqueued interrupt event wait.
222  //
223  StopAndFlushThreadpoolWaitQueue();
224  }
225 
226  PUMDF_VERSION_DATA driverVersion = deviceStack->GetMinDriverVersion();
227  BOOL preserveCompat =
228  deviceStack->ShouldPreserveIrpCompletionStatusCompatibility();
229 
230  status = CHostFxUtil::NtStatusFromHr(
231  hr,
232  driverVersion->MajorNumber,
233  driverVersion->MinorNumber,
234  preserveCompat
235  );
236 
239  "Connect message to reflector returned failure "
240  "%!hresult!", hr);
241 
242  return status;
243  }
244 
246 
247  return status;
248 }
249 
250 VOID
252  VOID
253  )
254 {
255  IWudfDeviceStack *deviceStack;
256  HRESULT hr;
257  InterruptControlType controlType;
258 
259  //
260  // Tell the PnP Manager to disconnect the interrupt.
261  // Send a message to redirector to do so.
262  //
264 
265  controlType = InterruptControlTypeDisconnect;
266  hr = deviceStack->ControlInterrupt(m_RdInterruptContext, controlType);
267  if (FAILED(hr))
268  {
271  "Disconnect message to reflector returned failure "
272  "%!hresult!", hr);
273 
274  FX_VERIFY_WITH_NAME(INTERNAL, TRAPMSG("Disconnect message to reflector returned failure. "),
275  GetDriverGlobals()->Public.DriverName);
276  }
277 
278  //
279  // Now that interrupt has been disconnected, flush the threadpool. Note that
280  // we need to do this after disconnect because if we did it before disconnect,
281  // we might drop any spurious interrupts that were generated after
282  // the driver disabled interrupt generation in its Disable callback,
283  // and after the DPCs were flushed. Fx can't drop spurious interrupt
284  // because if the interrupt is level-triggered then refelctor would be waiting
285  // for acknowledgement. The fact that disconnect command to reflector has
286  // returned to fx guarantees that there are no more interrupts pending in
287  // reflector.
288  //
289  StopAndFlushThreadpoolWaitQueue();
290 
291  //
292  // There might still be WorkItemForIsr running as a result of
293  // the handling of spurious interrupt by driver, so we need to flush the
294  // workitem as well.
295  //
297 
298  return;
299 }
300 
301 VOID
306  )
307 {
308  IWudfDeviceStack *deviceStack;
309  HRESULT hr;
310 
312 
313  //
314  // Tell reflector to set the policy of interrupt.
315  //
316  hr = deviceStack->SetInterruptPolicy(m_RdInterruptContext,
317  Policy,
318  Priority,
320  if (FAILED(hr))
321  {
324  "SetPolicy message to reflector returned failure "
325  "%!hresult!", hr);
326  }
327 
328  FX_VERIFY_WITH_NAME(INTERNAL, CHECK_HR(hr), GetDriverGlobals()->Public.DriverName);
329 
330  return;
331 }
332 
333 VOID
335  __inout PIO_RESOURCE_DESCRIPTOR IoResourceDescriptor
336  )
337 /*++
338 
339 Routine Description:
340 
341  This function allows an interrupt object to change the
342  IoResourceRequirementsList that the PnP Manager sends during
343  IRP_MN_FILTER_RESOURCE_REQUIREMENTS. This function takes a single
344  IoResourceDescriptor and applies default or user specified policy.
345 
346 Arguments:
347 
348  IoResourceDescriptor - Pointer to descriptor that matches this interrupt object
349 
350 Return Value:
351 
352  VOID
353 
354 --*/
355 {
356  UNREFERENCED_PARAMETER(IoResourceDescriptor);
357 
358  ASSERTMSG("Not implemented for UMDF\n", FALSE);
359 }
360 
361 VOID
363  VOID
364  )
365 {
366  IWudfDeviceStack *deviceStack;
367  InterruptControlType controlType;
368  HRESULT hr;
369 
370  if (m_RdInterruptContext == NULL) {
371  //
372  // Reflector hasn't yet created a partner interrupt object so nothing
373  // to do.
374  //
375  return;
376  }
377 
378  //
379  // Send a message to redirector to reset interrupt info.
380  //
382 
383  controlType = InterruptControlTypeResetInterruptInfo;
384  hr = deviceStack->ControlInterrupt(m_RdInterruptContext, controlType);
385  if (FAILED(hr))
386  {
389  "ResetInterruptInfo message to reflector returned failure "
390  "%!hresult!", hr);
391  }
392 
393  FX_VERIFY_WITH_NAME(INTERNAL, CHECK_HR(hr), GetDriverGlobals()->Public.DriverName);
394 
395  return;
396 }
397 
398 VOID
400  VOID
401  )
402 {
403  IWudfDeviceStack *deviceStack;
404  InterruptControlType controlType;
405  HRESULT hr;
406 
407  if (m_RdInterruptContext == NULL) {
408  //
409  // Reflector hasn't yet created a partner interrupt object so nothing
410  // to do.
411  //
412  return;
413  }
414 
415  //
416  // Send a message to redirector to revoke interrupt resources.
417  //
419 
420  controlType = InterruptControlTypeRevokeResources;
421  hr = deviceStack->ControlInterrupt(m_RdInterruptContext, controlType);
422  if (FAILED(hr))
423  {
426  "RevokeResources message to reflector returned failure "
427  "%!hresult!", hr);
428  }
429 
430  FX_VERIFY_WITH_NAME(INTERNAL, CHECK_HR(hr), GetDriverGlobals()->Public.DriverName);
431 
432  return;
433 }
434 
435 VOID
437  VOID
438  )
439 {
440  IWudfDeviceStack *deviceStack;
441  HRESULT hr;
442 
443  //
444  // Send a message to redirector to flush DPCs.
445  //
447  hr = deviceStack->ControlInterrupt(m_RdInterruptContext,
448  InterruptControlTypeFlushQueuedDpcs);
449  if (FAILED(hr))
450  {
453  "FlushQueuedDpcs message to reflector returned failure "
454  "%!hresult!", hr);
455 
456  FX_VERIFY_WITH_NAME(INTERNAL,
457  TRAPMSG("FlushQueuedDpcs message to reflector returned failure"),
458  GetDriverGlobals()->Public.DriverName);
459  }
460 
461  return;
462 }
463 
464 VOID
468  __in PWDF_INTERRUPT_INFO InterruptInfo
469  )
470 {
471  IWudfDeviceStack *deviceStack;
472  HRESULT hr;
473 
474  //
475  // level-triggered interrupt handling is supported only on win8 and newer.
476  //
477  if (IsLevelTriggered(CmDescTrans->Flags) &&
479  hr = E_INVALIDARG;
482  "Failed to assign interrupt resource to interrupt object"
483  "because interrupt resource is for level-triggered interrupt"
484  "which is not supported on this platform. See the docs for info on"
485  "supported platforms. %!hresult!\n", hr);
486 
487  FX_VERIFY_WITH_NAME(DRIVER(BadArgument, TODO), TRAPMSG(
488  "Failed to assign interrupt resource to interrupt object"
489  "because interrupt resource is for level-triggered interrupt"
490  "which is not supported on this platform. See the docs for info on"
491  "supported platforms."),
492  GetDriverGlobals()->Public.DriverName);
493  }
494 
495  //
496  // Sharing is only supported for level-triggered interrupts. We allow
497  // shared latched interrupts in order to accomodate incorrect device
498  // firmwares that mistakenly declare their exclusive resources as shared.
499  // Genuinely shared edge-triggered interrupts will cause a deadlock
500  // because of how the OS handles non-passive latched interrupts with
501  // multiple registered handlers. See RdInterrupt::AssignResources
502  // for details.
503  //
504  if (IsLevelTriggered(CmDescTrans->Flags) == FALSE &&
505  CmDescTrans->ShareDisposition != CmResourceShareDeviceExclusive) {
506 
509  "The resource descriptor indicates that this is a shared "
510  "edge-triggered interrupt. UMDF only supports sharing of "
511  "level-triggered interrupts. Please check if your device "
512  "firmware mistakenly declares this resource as shared "
513  "instead of device exclusive. If the resource is in fact "
514  "shared, then UMDF does not support this device.\n");
515  }
516 
517  //
518  // Tell the PnP Manager to assign resources to the interrupt.
519  // Send a message to redirector to do so.
520  //
522 
523  hr = deviceStack->AssignInterruptResources(m_RdInterruptContext,
524  CmDescRaw,
525  CmDescTrans,
526  InterruptInfo,
528  if (FAILED(hr))
529  {
532  "AssignResources message to reflector returned failure "
533  "%!hresult!\n", hr);
534  }
535 
536  FX_VERIFY_WITH_NAME(INTERNAL, CHECK_HR(hr),
537  GetDriverGlobals()->Public.DriverName);
538 
539 }
540 
541 VOID
542 FxInterrupt::ThreadpoolWaitCallback(
543  VOID
544  )
545 {
547 
548  //
549  // ETW event for performance measurement
550  //
551  EventWriteEVENT_UMDF_FX_INTERRUPT_NOTIFICATION_RECEIVED(
553  );
554 
555  //
556  // Invoke the ISR callback under interrupt lock.
557  //
558  if (IsWakeCapable()) {
559  //
560  // if it is a wake capable interrupt, we will hand it off
561  // to the state machine so that it can power up the device
562  // if required and then invoke the ISR callback
563  //
565  } else {
566  AcquireLock();
569  );
570  ReleaseLock();
571  }
572 
573  //
574  // Queue another wait. MSDN: You must re-register the event with the
575  // wait object before signaling it each time to trigger the wait callback.
576  //
577  if (m_CanQueue) {
578  QueueSingleWaitOnInterruptEvent();
579  }
580 
581  //
582  // Return acknowledgement to reflector if it's handled at passive level
583  // by reflector.
584  //
586  IWudfDeviceStack *deviceStack;
587  HRESULT hr;
588 
590 
591  hr = deviceStack->AcknowledgeInterrupt(m_RdInterruptContext, claimed);
592 
593  if (FAILED(hr)) {
596  "AcknowledgeInterrupt message to reflector returned "
597  "failure. Check UMDF log for failure reason. %!hresult!", hr);
598 
599  FX_VERIFY_WITH_NAME(INTERNAL, TRAPMSG("AcknowledgeInterrupt message to "
600  "reflector returned failure. Check UMDF log for failure reason. "),
601  GetDriverGlobals()->Public.DriverName);
602  }
603  }
604 
605  return;
606 }
607 
608 VOID
609 FxInterrupt::QueueSingleWaitOnInterruptEvent(
610  VOID
611  )
612 {
614 }
615 
616 VOID
617 FxInterrupt::StartThreadpoolWaitQueue(
618  VOID
619  )
620 {
621  m_CanQueue = TRUE;
622 
623  QueueSingleWaitOnInterruptEvent();
624 }
625 
626 VOID
627 FxInterrupt::StopAndFlushThreadpoolWaitQueue(
628  VOID
629  )
630 {
631  //
632  // We need to stop the threadpool wait queue and accomplish the following:
633  // 1) Prevent any new waits from being queued.
634  // 2) Removed any waits already queued.
635  // 3) Wait for interrupt isr callback to complete.
636  //
637 
638  //
639  // Prevent any more enquing now that interrupt has been disconnected.
640  //
641  m_CanQueue = FALSE;
642 
643  //
644  // wait for isr callback
645  //
647 
648  //
649  // remove any waits already queued
650  //
652 
653  //
654  // wait for callback. This additional wait for callback is needed to
655  // handle the follwoing race:
656  // - CanQueue is set to false in this thread
657  // - Callback is executing at statement after CanQueue check so it did not
658  // see false.
659  // - this thread waits for callback
660  // - callback thread queues a wait and returns
661  // - the wait earlier queued is satisfied and callback runs
662  // - this thread clears the queue (there is nothing to clear) but there is
663  // still a callback runnning and this thread needs to wait.
664  //
666 }
667 
668 VOID
669 CALLBACK
673  PTP_WAIT Wait,
674  TP_WAIT_RESULT WaitResult
675  )
676 {
677  FxInterrupt* fxInterrupt = (FxInterrupt*) Parameter;
678 
681  UNREFERENCED_PARAMETER(WaitResult);
682 
683  fxInterrupt->ThreadpoolWaitCallback();
684 
685  return;
686 }
687 
688 VOID
690  VOID
691  )
692 {
693  //
694  // flush the threadpool callbacks
695  //
696  StopAndFlushThreadpoolWaitQueue();
697 
698  //
699  // Rundown the workitem.
700  //
701  if (m_SystemWorkItem != NULL) {
704  }
705 
706  //
707  // If present, delete the default passive-lock.
708  //
709  if (m_DisposeWaitLock) {
710  ASSERT(m_WaitLock != NULL);
712  m_WaitLock = NULL;
714  }
715 
716  //
717  // waitblock destructor will ensure event and waitblock cleanup.
718  //
719  if (m_InterruptWaitblock != NULL) {
720  delete m_InterruptWaitblock;
722  }
723 
724  //
725  // No need to explicitly delete the COM wrapper (CWdfInterrupt).
726  // The COM wrapper will get deleted in fxInterrupt's destroy callback when
727  // the object tree reference taken during creation will be released.
728  //
729 }
730 
731 BOOLEAN
733  VOID
734  )
735 {
736  FX_VERIFY_WITH_NAME(INTERNAL, TRAPMSG("Not implemented"),
737  GetDriverGlobals()->Public.DriverName);
738  return FALSE;
739 }
740 
741 VOID
743  VOID
744  )
745 {
746  //
747  // For UMDF, we allow drivers to call WdfInterruptQueueDpcdForIsr, and
748  // internally we queue a workitem and invoke EvtInterruptDpc. Only
749  // one of the callbacks EvtInterruptDpc or EvtInterruptWorkitem is
750  // allowed.
751  //
754 
756 
757  //
758  // Call the drivers registered WorkItemForIsr event callback
759  //
760  if (m_CallbackLock != NULL) {
761  KIRQL irql = 0;
762 
764  if (m_EvtInterruptWorkItem != NULL) {
766  }
767  else {
769  }
771  }
772  else {
773  if (m_EvtInterruptWorkItem != NULL) {
775  }
776  else {
778  }
779  }
780 
781  return;
782 }
783 
784 BOOLEAN
789  )
790 {
792  BOOLEAN isPassive;
793 
795 
797  isPassive = pParams->Interrupt->IsPassiveHandling();
798  FX_VERIFY(INTERNAL, CHECK("Must be Passive Interrupt", isPassive));
799 
800  //
801  // The internal synchronize routine will call the routine under lock
802  //
804 }
FxWaitLock * m_WaitLock
Definition: fxinterrupt.hpp:77
CfxDevice * m_Device
Definition: fxobject.hpp:329
virtual VOID DeleteObject(VOID)
KSYNCHRONIZE_ROUTINE * MdInterruptSynchronizeRoutine
Definition: mxgeneralkm.h:38
#define _Must_inspect_result_
Definition: no_sal2.h:62
static MdInterruptServiceRoutineType _InterruptThunk
_Must_inspect_result_ NTSTATUS ConnectInternal(VOID)
BOOLEAN _SynchronizeExecution(__in MdInterrupt Interrupt, __in MdInterruptSynchronizeRoutine SynchronizeRoutine, __in PVOID SynchronizeContext)
HRESULT hr
Definition: shlfolder.c:183
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_INTERRUPT_CONFIG Configuration
Definition: wdfinterrupt.h:372
VOID RevokeResourcesInternal(VOID)
#define TRUE
Definition: types.h:120
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
WDFDEVICE __inline GetHandle(VOID)
Definition: fxdevice.hpp:237
_In_ WDFDPC _In_ BOOLEAN Wait
Definition: wdfdpc.h:167
VOID FlushQueuedWorkitem(VOID)
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_INTERRUPT_CONFIG _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFINTERRUPT * Interrupt
Definition: wdfinterrupt.h:372
LONG NTSTATUS
Definition: precomp.h:26
#define CALLBACK
Definition: compat.h:35
static HRESULT _CreateAndInit(_In_ PFX_DRIVER_GLOBALS DriverGlobals, _Out_ FxInterruptThreadpool **ppThreadpool)
BOOLEAN m_DisposeWaitLock
Definition: fxinterrupt.hpp:98
RD_INTERRUPT_CONTEXT m_RdInterruptContext
BOOLEAN m_CanQueue
static HRESULT _CreateAndInit(_In_ FxInterruptThreadpool *Threadpool, _In_ FxInterrupt *Interrupt, _In_ PTP_WAIT_CALLBACK WaitCallback, _Out_ FxInterruptWaitblock **Waitblock)
WDF_TRI_STATE m_ShareVector
Definition: fxinterrupt.hpp:54
KIRQL irql
Definition: wave.h:1
IWudfDeviceStack * deviceStack
FxSystemWorkItem * m_SystemWorkItem
Definition: fxinterrupt.hpp:87
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn BOOLEAN Physical UINT32 ACPI_TABLE_HEADER *OutTableHeader ACPI_TABLE_HEADER **OutTable ACPI_HANDLE UINT32 ACPI_WALK_CALLBACK ACPI_WALK_CALLBACK void void **ReturnValue UINT32 ACPI_BUFFER *RetPathPtr ACPI_OBJECT_HANDLER void *Data ACPI_OBJECT_HANDLER void **Data ACPI_STRING ACPI_OBJECT_LIST ACPI_BUFFER *ReturnObjectBuffer ACPI_DEVICE_INFO **ReturnBuffer ACPI_HANDLE Parent
Definition: acpixf.h:728
_In_ PVOID Parameter
Definition: ldrtypes.h:241
#define CHECK(type, val, base, expected)
BOOLEAN QueueDpcForIsr(VOID)
VOID AssignResourcesInternal(__in PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDescRaw, __in PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDescTrans, __in PWDF_INTERRUPT_INFO InterruptConfig)
FX_VERIFY_WITH_NAME(DRIVER(BadArgument, TODO), CHECK(ERROR_STRING_HW_ACCESS_NOT_ALLOWED,(pDevice->IsDirectHardwareAccessAllowed()==TRUE)), DriverGlobals->DriverName)
VOID FlushAndRundownInternal(VOID)
UCHAR KIRQL
Definition: env_spec_w32.h:591
VOID SetInterruptThreadpool(_In_ FxInterruptThreadpool *Pool)
Definition: fxdevice.hpp:1049
#define TODO
Definition: SAX2.c:49
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
IWudfDeviceStack2 * GetDeviceStack2(VOID)
Definition: fxdeviceum.hpp:444
#define ASSERTMSG(msg, exp)
Definition: nt_native.h:431
if SUCCEEDED(hr)
virtual void Lock(__out PKIRQL PreviousIrql)=0
VOID DisconnectInternal(VOID)
#define E_INVALIDARG
Definition: ddrawi.h:101
enum _WDF_INTERRUPT_POLICY WDF_INTERRUPT_POLICY
unsigned char BOOLEAN
_Must_inspect_result_ BOOLEAN IsVersionGreaterThanOrEqualTo(__in ULONG Major, __in ULONG Minor)
Definition: globalskm.cpp:92
struct _TP_CALLBACK_INSTANCE * PTP_CALLBACK_INSTANCE
Definition: winnt_old.h:4304
BOOLEAN IsLevelTriggered(__in ULONG Flags)
IWudfDeviceStack * GetDeviceStack(VOID)
Definition: fxdeviceum.hpp:435
VOID FlushQueuedDpcs(VOID)
PFX_DRIVER_GLOBALS pFxDriverGlobals
BOOLEAN m_PassiveHandlingByRedirector
FX_VERIFY(INTERNAL, CHECK_NOT_NULL(LoaderInterface->pIWudfHost))
_In_ PKSYNCHRONIZE_ROUTINE SynchronizeRoutine
Definition: kefuncs.h:536
#define ASSERT(a)
Definition: mode.c:44
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
LONG HRESULT
Definition: typedefs.h:79
enum _WDF_INTERRUPT_PRIORITY WDF_INTERRUPT_PRIORITY
_In_ WDFINTERRUPT _In_ WDF_INTERRUPT_POLICY _In_ WDF_INTERRUPT_PRIORITY _In_ KAFFINITY TargetProcessorSet
Definition: wdfinterrupt.h:651
VOID SetPolicyInternal(__in WDF_INTERRUPT_POLICY Policy, __in WDF_INTERRUPT_PRIORITY Priority, __in PGROUP_AFFINITY TargetProcessorSet)
PFN_WDF_INTERRUPT_WORKITEM m_EvtInterruptWorkItem
VOID FilterResourceRequirements(__inout PIO_RESOURCE_DESCRIPTOR IoResourceDescriptor)
_In_ WDFINTERRUPT _In_ WDF_INTERRUPT_POLICY _In_ WDF_INTERRUPT_PRIORITY Priority
Definition: wdfinterrupt.h:651
VOID ReleaseLock(VOID)
VOID WorkItemHandler(VOID)
FxCallbackLock * m_CallbackLock
Definition: fxinterrupt.hpp:93
#define __inout
Definition: dbghelp.h:50
__inline BOOLEAN IsWakeCapable(VOID)
PFN_WDF_INTERRUPT_ISR m_EvtInterruptIsr
virtual void Unlock(__in KIRQL PreviousIrql)=0
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
#define TRACE_LEVEL_WARNING
Definition: storswtr.h:28
_In_ PKSYNCHRONIZE_ROUTINE _In_opt_ __drv_aliasesMem PVOID SynchronizeContext
Definition: kefuncs.h:536
#define TRACINGPNP
Definition: dbgtrace.h:67
__inline BOOLEAN IsPassiveHandling(VOID)
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
enum _CM_SHARE_DISPOSITION CM_SHARE_DISPOSITION
VOID ResetInternal(VOID)
#define NULL
Definition: types.h:112
FxInterruptThreadpool * GetInterruptThreadpool(VOID)
Definition: fxdevice.hpp:1057
_Must_inspect_result_ NTSTATUS InitializeInternal(__in FxObject *Parent, __in PWDF_INTERRUPT_CONFIG Configuration)
WDFINTERRUPT GetHandle(VOID)
FxInterruptWaitblock * m_InterruptWaitblock
FX_TRACK_DRIVER(fxDriverGlobals)
_Must_inspect_result_ __inline BOOLEAN FxIsPassiveLevelInterruptSupported(VOID)
Definition: fxglobals.h:1081
BOOLEAN WakeInterruptIsr(VOID)
PFN_WDF_INTERRUPT_DPC m_EvtInterruptDpc
#define STATUS_SUCCESS
Definition: shellext.h:65
void exit(int exitcode)
Definition: _exit.c:33
_In_ WDFINTERRUPT _In_ WDF_INTERRUPT_POLICY Policy
Definition: wdfinterrupt.h:651
VOID AcquireLock(VOID)
#define __in
Definition: dbghelp.h:35
static SERVICE_STATUS status
Definition: service.c:31
IN PVOID Instance
Definition: pci.h:361
WDF_INTERRUPT_INFO m_InterruptInfo
Definition: ps.c:97
int claimed[4]
Definition: mach.c:32