ReactOS  0.4.15-dev-2701-g34593d9
fxinterruptapi.cpp
Go to the documentation of this file.
1 /*++
2 
3 Copyright (c) Microsoft Corporation
4 
5 Module Name:
6 
7  FxInterruptApi.cpp
8 
9 Abstract:
10 
11  This implements the WDFINTERRUPT API's
12 
13 Author:
14 
15 
16 
17 
18 Environment:
19 
20  Both kernel and user mode
21 
22 Revision History:
23 
24 
25 --*/
26 
27 #include "pnppriv.hpp"
28 
29 extern "C" {
30 // #include "FxInterruptApi.tmh"
31 }
32 
33 //
34 // At this time we are unable to include wdf19.h in the share code, thus for
35 // now we simply cut and paste the needed structures.
36 //
37 typedef struct _WDF_INTERRUPT_CONFIG_V1_9 {
38  ULONG Size;
39 
40  //
41  // If this interrupt is to be synchronized with other interrupt(s) assigned
42  // to the same WDFDEVICE, create a WDFSPINLOCK and assign it to each of the
43  // WDFINTERRUPTs config.
44  //
45  WDFSPINLOCK SpinLock;
46 
48 
50 
51  //
52  // Automatic Serialization of the DpcForIsr
53  //
55 
56  // Event Callbacks
58 
60 
62 
64 
66 
67 //
68 // The interrupt config structure has changed post win8-Beta. This is a
69 // temporary definition to allow beta drivers to load on post-beta builds.
70 // Note that size of win8-beta and win8-postbeta structure is different only on
71 // non-x64 platforms, but the fact that size is same on amd64 is harmless because
72 // the struture gets zero'out by init macro, and the default value of the new
73 // field is 0 on amd64.
74 //
77 
78  //
79  // If this interrupt is to be synchronized with other interrupt(s) assigned
80  // to the same WDFDEVICE, create a WDFSPINLOCK and assign it to each of the
81  // WDFINTERRUPTs config.
82  //
83  WDFSPINLOCK SpinLock;
84 
86 
88 
89  //
90  // DIRQL handling: automatic serialization of the DpcForIsr/WaitItemForIsr.
91  // Passive-level handling: automatic serialization of all callbacks.
92  //
94 
95  //
96  // Event Callbacks
97  //
103 
104  //
105  // These fields are only used when interrupt is created in
106  // EvtDevicePrepareHardware callback.
107  //
110 
111  //
112  // Optional passive lock for handling interrupts at passive-level.
113  //
114  WDFWAITLOCK WaitLock;
115 
116  //
117  // TRUE: handle interrupt at passive-level.
118  // FALSE: handle interrupt at DIRQL level. This is the default.
119  //
121 
123 
124 //
125 // Interrupt Configuration Structure
126 //
127 typedef struct _WDF_INTERRUPT_CONFIG_V1_11 {
128  ULONG Size;
129 
130  //
131  // If this interrupt is to be synchronized with other interrupt(s) assigned
132  // to the same WDFDEVICE, create a WDFSPINLOCK and assign it to each of the
133  // WDFINTERRUPTs config.
134  //
135  WDFSPINLOCK SpinLock;
136 
138 
140 
141  //
142  // DIRQL handling: automatic serialization of the DpcForIsr/WaitItemForIsr.
143  // Passive-level handling: automatic serialization of all callbacks.
144  //
146 
147  //
148  // Event Callbacks
149  //
155 
156  //
157  // These fields are only used when interrupt is created in
158  // EvtDevicePrepareHardware callback.
159  //
162 
163  //
164  // Optional passive lock for handling interrupts at passive-level.
165  //
166  WDFWAITLOCK WaitLock;
167 
168  //
169  // TRUE: handle interrupt at passive-level.
170  // FALSE: handle interrupt at DIRQL level. This is the default.
171  //
173 
174  //
175  // TRUE: Interrupt is reported inactive on explicit power down
176  // instead of disconnecting it.
177  // FALSE: Interrupt is disconnected instead of reporting inactive
178  // on explicit power down.
179  // DEFAULT: Framework decides the right value.
180  //
182 
184 
185 //
186 // extern "C" the entire file
187 //
188 extern "C" {
189 
192 NTSTATUS
193 STDCALL
194 WDFEXPORT(WdfInterruptCreate)(
195  __in
197  __in
198  WDFDEVICE Device,
199  __in
201  __in_opt
203  __out
204  WDFINTERRUPT* Interrupt
205  )
206 
207 /*++
208 
209 Routine Description:
210 
211  Create an Interrupt object along with its associated DpcForIsr.
212 
213 Arguments:
214 
215  Object - Handle to a WDFDEVICE or WDFQUEUE to associate the interrupt with.
216 
217  pConfiguration - WDF_INTERRUPT_CONFIG structure.
218 
219  pAttributes - Optional WDF_OBJECT_ATTRIBUTES to request a context
220  memory allocation, and a DestroyCallback.
221 
222  pInterrupt - Pointer to location to return the resulting WDFINTERRUPT handle.
223 
224 Returns:
225 
226  STATUS_SUCCESS - A WDFINTERRUPT handle has been created.
227 
228 --*/
229 
230 {
231  DDI_ENTRY();
232 
241 
243  Device,
245  (PVOID*)&pDevice,
247 
250 
255  } else {
257  }
258 
259 
260  //
261  // We could check if Configuration->Size != expectedConfigSize, but
262  // logic below allows me to installing old WDF drivers v1.11 on new WDF.
263  //
264  if (Configuration->Size != sizeof(WDF_INTERRUPT_CONFIG) &&
265  Configuration->Size != sizeof(WDF_INTERRUPT_CONFIG_V1_11) &&
267  Configuration->Size != sizeof(WDF_INTERRUPT_CONFIG_V1_9)) {
268 
271  "WDF_INTERRUPT_CONFIG size 0x%x incorrect, expected 0x%x",
273 
275  }
276 
277  //
278  // Normalize WDF_INTERRUPT_CONFIG structure.
279  //
280  if (Configuration->Size < sizeof(WDF_INTERRUPT_CONFIG)) {
281  //
282  // Init new fields to default values.
283  //
286  Configuration->EvtInterruptDpc);
287  //
288  // Copy over existing fields and readjust the struct size.
289  //
291  intConfig.Size = sizeof(intConfig);
292 
293  //
294  // Use new config structure from now on.
295  //
297  }
298 
299  //
300  // Parameter validation.
301  //
302 
303 #if (FX_CORE_MODE == FX_CORE_USER_MODE)
304  //
305  // Ensure access to interrupts is allowed
306  //
307  FX_VERIFY_WITH_NAME(DRIVER(BadArgument, TODO),
310  DriverGlobals->DriverName);
311 
312  //
313  // PassiveHandling member must be set to TRUE. INIT macro does that for
314  // UMDF. This check ensures the field is not overriden by caller.
315  //
316  FX_VERIFY_WITH_NAME(DRIVER(BadArgument, TODO),
317  CHECK("PassiveHandling not set to TRUE in WDF_INTERRUPT_CONFIG structure",
318  (Configuration->PassiveHandling == TRUE)),
319  DriverGlobals->DriverName);
320 #endif
321 
322  if (Configuration->EvtInterruptIsr == NULL) {
325  "NULL EvtInterruptIsr in WDF_INTERRUPT_CONFIG structure 0x%p"
326  " passed", Configuration);
328  }
329 
330  //
331  // Driver can specify a parent only in the AutomaticSerialization case.
332  //
335  Attributes,
336  Configuration->AutomaticSerialization ?
340  return status;
341  }
342 
343  if (Attributes != NULL && Attributes->ParentObject != NULL) {
345  Attributes->ParentObject,
347  (PVOID*)&pParent);
348  }
349  else {
351  }
352 
354 
356  0x0 == (pDevice->GetCallbackFlags() &
358 
360 
363  "WDFINTERRUPTs can only be created during: "
364  "(1) EvtDriverDeviceAdd when the WDFDEVICE %p is initially created, or "
365  "(2) EvtDevicePrepareHardware, %!STATUS!", Device, status);
366 
367  return status;
368  }
369 
370  //
371  // Interrupts created in EvtDriverDeviceAdd must not specify any
372  // CM resources b/c driver doesn't known them yet.
373  //
375 
376  if (Configuration->InterruptRaw != NULL ||
377  Configuration->InterruptTranslated != NULL) {
378 
380 
383  "Not NULL InterruptRaw or InterruptTranslated in "
384  "WDF_INTERRUPT_CONFIG structure 0x%p passed, %!STATUS!",
386 
387  return status;
388  }
389 
390  //
391  // Wake Interrupts can not be created in AddDevice as it is
392  // not known if they are actually marked as wake capable
393  //
394  if (Configuration->CanWakeDevice) {
396 
399  "CanWakeDevice set in WDF_INTERRUPT_CONFIG structure 0x%p"
400  "during EvtDriverDeviceAdd, %!STATUS!",
402 
403  return status;
404  }
405  }
406 
407  //
408  // Checks for interrupt created in EvtDevicePrepareHardware.
409  //
411  //
412  // CM resources must be specified.
413  //
414  if (Configuration->InterruptRaw == NULL ||
415  Configuration->InterruptTranslated == NULL) {
416 
418 
421  "NULL InterruptRaw or InterruptTranslated in "
422  "WDF_INTERRUPT_CONFIG structure 0x%p passed, %!STATUS!",
424 
425  return status;
426  }
427 
428  //
429  // Share vector must be default.
430  //
431  if (Configuration->ShareVector != WdfUseDefault) {
433 
436  "Driver cannot specify ShareVector different from "
437  "WdfUseDefault in EvtDevicePrepareHardware callback,"
438  "WDF_INTERRUPT_CONFIG structure 0x%p passed, %!STATUS!",
440 
441  return status;
442  }
443 
444  }
445 
446  if (Configuration->CanWakeDevice) {
448  Configuration->InterruptTranslated->Flags) == FALSE) {
449 
453  "Driver cannot specify an interrupt as CanWakeDevice if "
454  "the CM_RESOURCE_INTERRUPT_WAKE_HINT is not present."
455  "WDF_INTERRUPT_CONFIG structure 0x%p passed, %!STATUS!",
457 
458  return status;
459  }
460 
461  //
462  // Driver is allowed to create wake interrupt only if it
463  // is the power policy owner so that the we can wake the
464  // stack when the interrupt fires
465  //
470  "Driver cannot specify an interrupt as CanWakeDevice if "
471  "it is not power policy powner. WDF_INTERRUPT_CONFIG "
472  "structure 0x%p passed, %!STATUS!",
474 
475  return status;
476  }
477 
478  //
479  // Declaring an interrupt as wake capable allows it to
480  // take ownership of interrupt from ACPI. It does not
481  // make sense for a PDO
482  //
483  if (pDevice->IsPdo()) {
487  "Driver cannot specify an interrupt as CanWakeDevice for a PDO "
488  "WDF_INTERRUPT_CONFIG structure 0x%p passed, %!STATUS!",
490 
491  return status;
492  }
493  }
494 
495  if (Configuration->EvtInterruptDpc != NULL &&
496  Configuration->EvtInterruptWorkItem != NULL) {
500  "Driver can provide either EvtInterruptDpc or "
501  "EvtInterruptWorkItem callback but not both. "
502  "WDF_INTERRUPT_CONFIG structure 0x%p passed, %!STATUS!",
504 
505  return status;
506  }
507 
508  if (Configuration->PassiveHandling == FALSE) {
509  //
510  // DIRQL handling validations.
511  //
512  if (Configuration->WaitLock) {
516  "Driver cannot specify WaitLock when handling interrupts at "
517  "DIRQL, WDF_INTERRUPT_CONFIG structure 0x%p passed, %!STATUS!",
519 
520  return status;
521  }
522  //
523  // Wake interrupts should be passive level so that the stack
524  // can be sychronously bring the device back to D0 form within
525  // the ISR
526  //
527  if (Configuration->CanWakeDevice) {
529 
532  "CanWakeDevice set in WDF_INTERRUPT_CONFIG structure for an"
533  "interrupt not marked as passive 0x%p, %!STATUS!",
535 
536  return status;
537  }
538  }
539  else {
540  //
541  // Passive-level handling validations.
542  //
547  "The current version of Windows does not support the handling "
548  "of interrupts at passive-level, WDF_INTERRUPT_CONFIG "
549  "structure 0x%p passed, %!STATUS!", Configuration, status);
550 
551  return status;
552  }
553 
554  if (Configuration->SpinLock) {
558  "Driver cannot specify SpinLock when handling interrupts at "
559  "passive-level, WDF_INTERRUPT_CONFIG structure 0x%p passed, "
560  "%!STATUS!", Configuration, status);
561 
562  return status;
563  }
564 
565 
566  //
567  // For UMDF reflector decides whether to handle the interrupt
568  // at passive or DIRQL. Driver has no choice. Therefore this check
569  // is applicable only for KMDF.
570  //
571 #if (FX_CORE_MODE == FX_CORE_KERNEL_MODE)
572  if (Configuration->InterruptTranslated != NULL &&
574  Configuration->InterruptTranslated->Flags)) {
578  "Driver cannot specify PassiveHandling for MSI interrupts, "
579  "WDF_INTERRUPT_CONFIG structure 0x%p passed, %!STATUS!",
581 
582  return status;
583  }
584 #endif
585  }
586 
587  //
588  // Make sure the specified resources are valid.
589  // Do this check only under verifier b/c if the driver has a lot of
590  // interrupts/resources, this verification can slow down power up.
591  // Note that if InterruptRaw is != NULL, it implies that
592  // InterruptTranslated is != NULL from the checks above.
593  //
595  if (Configuration->InterruptRaw != NULL ) {
597  Configuration->InterruptRaw,
598  Configuration->InterruptTranslated,
599  Configuration);
600  if (!NT_SUCCESS(status)) {
601  return status;
602  }
603  }
604  }
605 
608  pDevice,
609  pParent,
610  Attributes,
612  &pFxInterrupt);
613 
615  *Interrupt = (WDFINTERRUPT) pFxInterrupt->GetObjectHandle();
616  }
617 
618  return status;
619 }
620 
621 BOOLEAN
622 STDCALL
624  __in
626  __in
627  WDFINTERRUPT Interrupt
628  )
629 
630 /*++
631 
632 Routine Description:
633 
634  Queue the DPC for the ISR
635 
636 Arguments:
637 
638  Interrupt - Handle to WDFINTERUPT object created with WdfInterruptCreate.
639 
640 Returns:
641 
642  TRUE - If the DPC has been enqueued.
643 
644  FALSE - If the DPC has already been enqueued.
645 
646 --*/
647 
648 {
649  DDI_ENTRY();
650 
652 
654  Interrupt,
656  (PVOID*)&pFxInterrupt);
657 
659 }
660 
661 BOOLEAN
662 STDCALL
664  __in
666  __in
667  WDFINTERRUPT Interrupt
668  )
669 
670 /*++
671 
672 Routine Description:
673 
674  Queue the interrupt's work-item for the ISR.
675 
676 Arguments:
677 
678  Interrupt - Handle to WDFINTERUPT object created with WdfInterruptCreate.
679 
680 Returns:
681 
682  TRUE - If the work-item has been enqueued.
683 
684  FALSE - If the work-item has already been enqueued.
685 
686 
687 --*/
688 
689 {
690  DDI_ENTRY();
691 
693 
695  Interrupt,
697  (PVOID*)&pFxInterrupt);
698 
700 }
701 
703 BOOLEAN
704 STDCALL
705 WDFEXPORT(WdfInterruptSynchronize)(
706  __in
708  __in
709  WDFINTERRUPT Interrupt,
710  __in
712  __in
714  )
715 
716 /*++
717 
718 Routine Description:
719 
720  Synchronize execution with the interrupt handler
721 
722 Arguments:
723 
724  Interrupt - Handle to WDFINTERUPT object created with WdfInterruptCreate.
725 
726  Callback - PWDF_INTERRUPT_SYNCHRONIZE callback function to invoke
727 
728  Context - Context to pass to the PFN_WDF_INTERRUPT_SYNCHRONIZE callback
729 
730 Returns:
731 
732  BOOLEAN result from user PFN_WDF_INTERRUPT_SYNCHRONIZE callback
733 
734 --*/
735 
736 {
737  DDI_ENTRY();
738 
741 
743  Interrupt,
745  (PVOID*)&pFxInterrupt);
746 
749  PASSIVE_LEVEL);
750  if (!NT_SUCCESS(status)) {
751  return FALSE;
752  }
753  }
754 
756 
758 }
759 
761 VOID
762 STDCALL
763 WDFEXPORT(WdfInterruptAcquireLock)(
764  __in
766  __in
768  _Acquires_lock_(_Curr_)
769  WDFINTERRUPT Interrupt
770  )
771 
772 /*++
773 
774 Routine Description:
775 
776  Begin synchronization to the interrupts IRQL level
777 
778 Arguments:
779 
780  Interrupt - Handle to WDFINTERUPT object created with WdfInterruptCreate.
781 
782 Returns:
783 
784 --*/
785 
786 {
787  DDI_ENTRY();
788 
791 
793  Interrupt,
795  (PVOID*)&pFxInterrupt);
796 
799  PASSIVE_LEVEL);
800  if (!NT_SUCCESS(status)) {
801  return;
802  }
803  }
804 
806 }
807 
809 VOID
810 STDCALL
811 WDFEXPORT(WdfInterruptReleaseLock)(
812  __in
814  __in
816  _Releases_lock_(_Curr_)
817  WDFINTERRUPT Interrupt
818  )
819 
820 /*++
821 
822 Routine Description:
823 
824  End synchronization to the interrupts IRQL level
825 
826 Arguments:
827 
828  Interrupt - Handle to WDFINTERUPT object created with WdfInterruptCreate.
829 
830 Returns:
831 
832 --*/
833 
834 {
835  DDI_ENTRY();
836 
839 
841  Interrupt,
843  (PVOID*)&pFxInterrupt);
844 
847  PASSIVE_LEVEL);
848  if (!NT_SUCCESS(status)) {
849  return;
850  }
851  }
852 
854 }
855 
857 VOID
858 STDCALL
859 WDFEXPORT(WdfInterruptEnable)(
860  __in
862  __in
863  WDFINTERRUPT Interrupt
864  )
865 
866 /*++
867 
868 Routine Description:
869 
870  Request that the interrupt be enabled in the hardware.
871 
872 Arguments:
873 
874  Interrupt - Handle to WDFINTERUPT object created with WdfInterruptCreate.
875 
876 Returns:
877 
878 --*/
879 
880 {
881  DDI_ENTRY();
882 
885 
887  Interrupt,
889  (PVOID*)&pFxInterrupt);
890 
892  PASSIVE_LEVEL);
893  if (!NT_SUCCESS(status)) {
894  return;
895  }
896 
897  //
898  // Okay to ignore error status. Called function prints error messages.
899  //
901 }
902 
904 VOID
905 STDCALL
906 WDFEXPORT(WdfInterruptDisable)(
907  __in
909  __in
910  WDFINTERRUPT Interrupt
911  )
912 
913 /*++
914 
915 Routine Description:
916 
917  Request that the interrupt be disabled in the hardware.
918 
919 Arguments:
920 
921  Interrupt - Handle to WDFINTERUPT object created with WdfInterruptCreate.
922 
923 Returns:
924 
925 --*/
926 
927 {
928  DDI_ENTRY();
929 
932 
934  Interrupt,
936  (PVOID*)&pFxInterrupt);
937 
939  PASSIVE_LEVEL);
940  if (!NT_SUCCESS(status)) {
941  return;
942  }
943 
944  //
945  // Okay to ignore error status. Called function prints error messages.
946  //
948 }
949 
951 struct _KINTERRUPT*
952 STDCALL
954  __in
956  __in
957  WDFINTERRUPT Interrupt
958  )
959 
960 /*++
961 
962 Routine Description:
963 
964  Return the WDM _KINTERRUPT*
965 
966 Arguments:
967 
968  Interrupt - Handle to WDFINTERUPT object created with WdfInterruptCreate.
969 
970 Returns:
971 
972 --*/
973 
974 {
975  DDI_ENTRY();
976 
978 
980  Interrupt,
982  (PVOID*)&pFxInterrupt);
983 
984  return pFxInterrupt->GetInterruptPtr();
985 }
986 
988 VOID
989 STDCALL
990 WDFEXPORT(WdfInterruptGetInfo)(
991  __in
993  __in
994  WDFINTERRUPT Interrupt,
995  __out
997  )
998 
999 /*++
1000 
1001 Routine Description:
1002 
1003  Return the WDF_INTERRUPT_INFO that describes this
1004  particular Message Signaled Interrupt MessageID.
1005 
1006 Arguments:
1007 
1008  Interrupt - Handle to WDFINTERUPT object created with WdfInterruptCreate.
1009 
1010 Returns:
1011  Nothing
1012 
1013 --*/
1015  DDI_ENTRY();
1016 
1020 
1022  Interrupt,
1024  (PVOID*)&pFxInterrupt,
1025  &pFxDriverGlobals);
1026 
1028 
1029  if (sizeof(WDF_INTERRUPT_INFO_V1_7) == Info->Size) {
1030  size = sizeof(WDF_INTERRUPT_INFO_V1_7);
1031  }
1032  else if (sizeof(WDF_INTERRUPT_INFO) == Info->Size) {
1033  size = sizeof(WDF_INTERRUPT_INFO);
1034  }
1035  else {
1038  "WDF_INTERRUPT_INFO %p Size %d invalid, expected %d",
1039  Interrupt, Info->Size, sizeof(WDF_INTERRUPT_INFO));
1041  return;
1042  }
1043 
1045 
1046  Info->Size = size;
1047 }
1048 
1049 WDFDEVICE
1050 STDCALL
1052  __in
1054  __in
1055  WDFINTERRUPT Interrupt
1056  )
1057 
1058 /*++
1059 
1060 Routine Description:
1061 
1062  Get the device that the interrupt is related to.
1063 
1064 Arguments:
1065 
1066  Interrupt - Handle to WDFINTERUPT object created with WdfInterruptCreate.
1067 
1068 Returns:
1069 
1070  WDFDEVICE
1071 
1072 --*/
1073 
1074 {
1075  DDI_ENTRY();
1076 
1078 
1080  Interrupt,
1082  (PVOID*)&pFxInterrupt);
1083 
1084  return pFxInterrupt->GetDevice()->GetHandle();
1085 }
1086 
1088 VOID
1089 STDCALL
1090 WDFEXPORT(WdfInterruptSetPolicy)(
1091  __in
1093  __in
1094  WDFINTERRUPT Interrupt,
1095  __in
1097  __in
1099  __in
1101  )
1102 
1103 /*++
1104 
1105 Routine Description:
1106 
1107  Interrupts have attributes that a driver might want to influence. This
1108  routine tells the Framework to tell the PnP manager what the driver would
1109  prefer.
1110 
1111 Arguments:
1112 
1113  Interrupt - Handle to WDFINTERUPT object created with WdfInterruptCreate.
1114 
1115 Returns:
1116 
1117  NTSTATUS
1118 
1119 --*/
1120 
1122  DDI_ENTRY();
1123 
1127 
1129  Interrupt,
1131  (PVOID*)&pFxInterrupt,
1132  &pFxDriverGlobals);
1133 
1138  "Policy %d is out of range", Policy);
1140  return;
1141  }
1142 
1146  "Priority %d is out of range", Priority);
1148  return;
1149  }
1150 
1153 
1155 }
1156 
1158 VOID
1159 STDCALL
1160 WDFEXPORT(WdfInterruptSetExtendedPolicy)(
1161  __in
1163  __in
1164  WDFINTERRUPT Interrupt,
1165  __in
1167  )
1168 
1169 /*++
1170 
1171 Routine Description:
1172 
1173  Interrupts have attributes that a driver might want to influence. This
1174  routine tells the Framework to tell the PnP manager what the driver would
1175  prefer.
1176 
1177 Arguments:
1178 
1179  Interrupt - Handle to WDFINTERUPT object created with WdfInterruptCreate.
1180 
1181  PolicyAndGroup - Driver preference for policy, priority and group affinity.
1182 
1183 Returns:
1184 
1185  NTSTATUS
1186 
1187 --*/
1188 
1190  DDI_ENTRY();
1191 
1197 
1199  Interrupt,
1201  (PVOID*)&pFxInterrupt,
1202  &pFxDriverGlobals);
1203 
1207  "WDF_INTERRUPT_EXTENDED_POLICY %p Size %d invalid, expected %d",
1209  PolicyAndGroup->Size,
1212  return;
1213  }
1214 
1215  policy = PolicyAndGroup->Policy;
1216  priority = PolicyAndGroup->Priority;
1217  processorSet = &PolicyAndGroup->TargetProcessorSetAndGroup;
1218 
1223  "Policy %d is out of range", policy);
1225  return;
1226  }
1227 
1228  if (priority < WdfIrqPriorityLow || priority > WdfIrqPriorityHigh) {
1231  "Priority %d is out of range", priority);
1233  return;
1234  }
1235 
1236  if (processorSet->Reserved[0] != 0 || processorSet->Reserved[1] != 0 ||
1237  processorSet->Reserved[2] != 0) {
1240  "TargetProcessorSet's reserved fields are not zero");
1242  return;
1243  }
1244 
1246 }
1247 
1250 _Post_satisfies_(return == 1 || return == 0)
1251 BOOLEAN
1252 STDCALL
1253 WDFEXPORT(WdfInterruptTryToAcquireLock)(
1254  __in
1256  __in
1257  _Requires_lock_not_held_(_Curr_)
1258  _When_(return!=0, _Acquires_lock_(_Curr_))
1259  WDFINTERRUPT Interrupt
1260  )
1261 
1262 /*++
1263 
1264 Routine Description:
1265 
1266  Try to acquire the interrupt's passive-lock.
1267 
1268 Arguments:
1269 
1270  Interrupt - Handle to WDFINTERUPT object created with WdfInterruptCreate.
1271 
1272 Returns:
1273 
1274  TRUE: function was able to successfully acquire the lock.
1275 
1276  FALSE: function was unable to acquire the lock.
1277 
1278 --*/
1279 
1280 {
1281  DDI_ENTRY();
1282 
1284  NTSTATUS status;
1285 
1287  Interrupt,
1289  (PVOID*)&pFxInterrupt);
1290 
1292  if (pFxInterrupt->IsPassiveHandling() == FALSE) {
1295  "WDFINTERRUPT %p is handled at DIRQL. This API is not "
1296  "available for DIQRL interrupt handling.",
1297  Interrupt);
1299  return FALSE;
1300  }
1301 
1303  PASSIVE_LEVEL);
1304  if (!NT_SUCCESS(status)) {
1305  return FALSE;
1306  }
1307  }
1308 
1309  return pFxInterrupt->TryToAcquireLock();
1310 }
1311 
1313 VOID
1314 STDCALL
1315 WDFEXPORT(WdfInterruptReportActive)(
1316  _In_
1318  _In_
1319  WDFINTERRUPT Interrupt
1320  )
1321 
1322 /*++
1323 
1324 Routine Description:
1325 
1326  This DDI informs the system that the interrupt is active and expecting
1327  interrupt requests on the associated lines. This is typically called after
1328  having reported the lines as inactive via WdfInterruptReportInactive.
1329  The DDI doesn't do anything if this DDI is called before
1330  WdfInterruptReportInactive while the interrupt is connected.
1331 
1332 Arguments:
1333 
1334  Interrupt - Handle to WDFINTERUPT object created with WdfInterruptCreate.
1335 
1336 Returns:
1337 
1338  VOID
1339 
1340 --*/
1341 {
1342  DDI_ENTRY();
1343 
1346 
1348  Interrupt,
1350  (PVOID*)&pFxInterrupt,
1351  &pFxDriverGlobals);
1352 
1354 
1355  return;
1356 }
1357 
1359 VOID
1360 STDCALL
1361 WDFEXPORT(WdfInterruptReportInactive)(
1362  _In_
1364  _In_
1365  WDFINTERRUPT Interrupt
1366  )
1367 
1368 /*++
1369 
1370 Routine Description:
1371 
1372  This DDI informs the system that the the interrupt is no longer active
1373  and is not expecting interrupt requests on the associated lines.
1374 
1375 Arguments:
1376 
1377  Interrupt - Handle to WDFINTERUPT object created with WdfInterruptCreate.
1378 
1379 Returns:
1380 
1381  VOID
1382 
1383 --*/
1384 {
1385  DDI_ENTRY();
1386 
1389 
1391  Interrupt,
1393  (PVOID*)&pFxInterrupt,
1394  &pFxDriverGlobals);
1395 
1397 
1398  return;
1399 }
1400 
1401 } // extern "C"
PCM_PARTIAL_RESOURCE_DESCRIPTOR InterruptRaw
Definition: wdf111.h:1467
enum _WDF_DEVICE_PNP_STATE WDF_DEVICE_PNP_STATE
#define DDI_ENTRY()
Definition: fxglobalskm.h:56
return STATUS_NOT_SUPPORTED
__in WDFINTERRUPT __in WDF_INTERRUPT_POLICY __in WDF_INTERRUPT_PRIORITY __in KAFFINITY TargetProcessorSet
#define _Must_inspect_result_
Definition: no_sal2.h:62
__in WDFINTERRUPT __in PFN_WDF_INTERRUPT_SYNCHRONIZE __in WDFCONTEXT Context
BOOLEAN FxVerifierOn
Definition: fxglobals.h:420
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
PFN_WDF_INTERRUPT_ISR EvtInterruptIsr
PFN_WDF_INTERRUPT_DISABLE EvtInterruptDisable
Definition: wdf19.h:1195
GLint x0
Definition: linetemp.h:95
WDF_TRI_STATE ShareVector
Definition: wdf19.h:1179
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_INTERRUPT_CONFIG Configuration
Definition: wdfinterrupt.h:372
#define __in_opt
Definition: dbghelp.h:38
#define TRUE
Definition: types.h:120
WDFDEVICE __inline GetHandle(VOID)
Definition: fxdevice.hpp:237
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
enum _WDF_TRI_STATE WDF_TRI_STATE
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_INTERRUPT_CONFIG _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFINTERRUPT * Interrupt
Definition: wdfinterrupt.h:372
__in WDFINTERRUPT __out PWDF_INTERRUPT_INFO Info
RtlCopyMemory(Info, pFxInterrupt->GetInfo(), size)
WDF_TRI_STATE ReportInactiveOnPowerDown
Definition: wdf111.h:1489
LONG NTSTATUS
Definition: precomp.h:26
FxVerifierDbgBreakPoint(pFxDriverGlobals)
WDFSPINLOCK SpinLock
Definition: wdf19.h:1177
struct _WDF_INTERRUPT_CONFIG_V1_11 * PWDF_INTERRUPT_CONFIG_V1_11
__in WDFINTERRUPT __in WDF_INTERRUPT_POLICY Policy
DriverGlobals
__in WDFINTERRUPT __in PWDF_INTERRUPT_EXTENDED_POLICY PolicyAndGroup
#define CHECK(type, val, base, expected)
struct _WDF_INTERRUPT_INFO WDF_INTERRUPT_INFO
PFN_WDF_INTERRUPT_DPC EvtInterruptDpc
Definition: wdf111.h:1455
_Must_inspect_result_ __in WDFDEVICE Device
_Must_inspect_result_ NTSTATUS ForceDisconnect(VOID)
WDF_INTERRUPT_POLICY policy
#define STATUS_INVALID_DEVICE_STATE
Definition: udferr_usr.h:178
struct _WDF_INTERRUPT_INFO_V1_7 WDF_INTERRUPT_INFO_V1_7
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:683
struct _WDF_INTERRUPT_CONFIG WDF_INTERRUPT_CONFIG
PFN_WDF_INTERRUPT_ENABLE EvtInterruptEnable
Definition: wdf111.h:1457
PFN_WDF_INTERRUPT_ENABLE EvtInterruptEnable
Definition: wdf19.h:1193
PFN_WDF_INTERRUPT_ISR EvtInterruptIsr
Definition: wdf111.h:1453
PCM_PARTIAL_RESOURCE_DESCRIPTOR InterruptTranslated
Definition: wdf111.h:1469
PFN_WDF_INTERRUPT_ENABLE EvtInterruptEnable
#define TODO
Definition: SAX2.c:49
#define FALSE
Definition: types.h:117
EVT_WDF_INTERRUPT_SYNCHRONIZE * PFN_WDF_INTERRUPT_SYNCHRONIZE
Definition: wdfinterrupt.h:115
#define WDFEXPORT(a)
Definition: fxmacros.hpp:157
__in WDFINTERRUPT __in WDF_INTERRUPT_POLICY __in WDF_INTERRUPT_PRIORITY Priority
FORCEINLINE VOID WDF_INTERRUPT_CONFIG_INIT(_Out_ PWDF_INTERRUPT_CONFIG Configuration, _In_ PFN_WDF_INTERRUPT_ISR EvtInterruptIsr, _In_opt_ PFN_WDF_INTERRUPT_DPC EvtInterruptDpc)
Definition: wdfinterrupt.h:271
struct _WDF_INTERRUPT_CONFIG_V1_11_BETA WDF_INTERRUPT_CONFIG_V1_11_BETA
#define _Releases_lock_(a)
Definition: btrfs_drv.h:208
VOID ReportActive(_In_ BOOLEAN Internal=FALSE)
PVOID __inline GetObjectHandle(VOID)
Definition: fxobject.hpp:603
#define __out
Definition: dbghelp.h:62
struct _WDF_INTERRUPT_CONFIG_V1_11 WDF_INTERRUPT_CONFIG_V1_11
__inline BOOLEAN QueueDeferredRoutineForIsr(VOID)
#define ERROR_STRING_HW_ACCESS_NOT_ALLOWED
Definition: device_common.h:40
PFN_WDF_INTERRUPT_WORKITEM EvtInterruptWorkItem
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
ULONG size
WDF_INTERRUPT_PRIORITY priority
GROUP_AFFINITY processorSet
BOOLEAN STDCALL WDFEXPORT() WdfInterruptQueueDpcForIsr(__in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFINTERRUPT Interrupt)
PWDF_INTERRUPT_INFO GetInfo(VOID)
FxDevice * pDevice
struct _WDF_INTERRUPT_CONFIG_V1_9 * PWDF_INTERRUPT_CONFIG_V1_9
__in _Requires_lock_not_held_(_Curr_) _Acquires_lock_(_Curr_) WDFINTERRUPT Interrupt)
BOOLEAN STDCALL WDFEXPORT() WdfInterruptQueueWorkItemForIsr(__in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFINTERRUPT Interrupt)
NTSTATUS status
PCM_PARTIAL_RESOURCE_DESCRIPTOR InterruptTranslated
struct _WDF_INTERRUPT_CONFIG_V1_9 WDF_INTERRUPT_CONFIG_V1_9
__inline NTSTATUS FxVerifierCheckIrqlLevel(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in KIRQL Irql)
Definition: fxverifier.h:158
GLsizeiptr size
Definition: glext.h:5919
_Must_inspect_result_ __in WDFDEVICE __in PWDF_INTERRUPT_CONFIG Configuration
#define STDCALL
Definition: wdf.h:45
PFN_WDF_INTERRUPT_DISABLE EvtInterruptDisable
Definition: wdf111.h:1459
CfxDevice * GetDevice(VOID)
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
EVT_WDF_INTERRUPT_WORKITEM * PFN_WDF_INTERRUPT_WORKITEM
Definition: wdfinterrupt.h:153
FxInterrupt * pFxInterrupt
enum _WDF_INTERRUPT_PRIORITY WDF_INTERRUPT_PRIORITY
__inline BYTE GetCallbackFlags(VOID)
Definition: fxdevice.hpp:1501
$USHORT Reserved[3]
Definition: ntbasedef.h:662
KAFFINITY Mask
Definition: ntbasedef.h:660
_Must_inspect_result_ __in WDFDEVICE __in PWDF_INTERRUPT_CONFIG __in_opt PWDF_OBJECT_ATTRIBUTES __out WDFINTERRUPT * Interrupt
__in _Requires_lock_held_(_Curr_) _Releases_lock_(_Curr_) WDFINTERRUPT Interrupt)
ULONG expectedConfigSize
PFN_WDF_INTERRUPT_DISABLE EvtInterruptDisable
EVT_WDF_INTERRUPT_ISR * PFN_WDF_INTERRUPT_ISR
Definition: wdfinterrupt.h:94
PFN_WDF_INTERRUPT_ISR EvtInterruptIsr
Definition: wdf19.h:1189
_Must_inspect_result_ NTSTATUS ValidateInterruptResourceCm(__in PCM_PARTIAL_RESOURCE_DESCRIPTOR CmIntResourceRaw, __in PCM_PARTIAL_RESOURCE_DESCRIPTOR CmIntResource, __in PWDF_INTERRUPT_CONFIG Configuration)
EVT_WDF_INTERRUPT_ENABLE * PFN_WDF_INTERRUPT_ENABLE
Definition: wdfinterrupt.h:175
BOOLEAN IsPowerPolicyOwner(VOID)
Definition: fxpkgpnp.hpp:3612
_In_ WDFINTERRUPT _In_ WDF_INTERRUPT_POLICY _In_ WDF_INTERRUPT_PRIORITY Priority
Definition: wdfinterrupt.h:651
#define _Post_satisfies_(e)
Definition: no_sal2.h:66
PFN_WDF_INTERRUPT_DPC EvtInterruptDpc
Definition: wdf19.h:1191
VOID ReleaseLock(VOID)
VOID SetPolicy(__in WDF_INTERRUPT_POLICY Policy, __in WDF_INTERRUPT_PRIORITY Priority, __in PGROUP_AFFINITY TargetProcessorSet)
__inline WDF_DEVICE_PNP_STATE GetDevicePnpState()
Definition: fxdevice.hpp:1149
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), Device, FX_TYPE_DEVICE,(PVOID *)&pDevice, &pFxDriverGlobals)
BOOLEAN Synchronize(__in PFN_WDF_INTERRUPT_SYNCHRONIZE Callback, __in WDFCONTEXT Context)
_Must_inspect_result_ NTSTATUS FxValidateObjectAttributes(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in PWDF_OBJECT_ATTRIBUTES Attributes, __in ULONG Flags=FX_VALIDATE_OPTION_NONE_SPECIFIED)
_Must_inspect_result_ __drv_maxIRQL(DISPATCH_LEVEL) NTSTATUS STDCALL WDFEXPORT(WdfInterruptCreate)(__in PWDF_DRIVER_GLOBALS DriverGlobals
#define VOID
Definition: acefi.h:82
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
static BOOLEAN _IsWakeHintedInterrupt(__in USHORT ResourceFlags)
_Must_inspect_result_ _In_ WDFDEVICE Device
Definition: wdfchildlist.h:474
WDF_TRI_STATE ShareVector
Definition: wdf111.h:1440
FxPkgPnp * m_PkgPnp
Definition: fxdevice.hpp:670
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
_In_ WDFINTERRUPT _In_ PFN_WDF_INTERRUPT_SYNCHRONIZE Callback
Definition: wdfinterrupt.h:456
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
#define _In_
Definition: no_sal2.h:158
PFX_DRIVER_GLOBALS pFxDriverGlobals
#define TRACINGPNP
Definition: dbgtrace.h:67
__inline BOOLEAN IsPassiveHandling(VOID)
#define _IRQL_requires_max_(irql)
Definition: driverspecs.h:213
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
__in WDFINTERRUPT __in PFN_WDF_INTERRUPT_SYNCHRONIZE Callback
FX_VERIFY_WITH_NAME(DRIVER(BadArgument, TODO), CHECK(ERROR_STRING_HW_ACCESS_NOT_ALLOWED,(pDevice->IsInterruptAccessAllowed()==TRUE)), DriverGlobals->DriverName)
FxObject * pParent
ULONG_PTR KAFFINITY
Definition: compat.h:85
FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), Interrupt, FX_TYPE_INTERRUPT,(PVOID *)&pFxInterrupt)
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
FxPointerNotNull(pFxDriverGlobals, Configuration)
PFN_WDF_INTERRUPT_WORKITEM EvtInterruptWorkItem
Definition: wdf111.h:1461
#define NULL
Definition: types.h:112
_Must_inspect_result_ NTSTATUS ForceReconnect(VOID)
EVT_WDF_INTERRUPT_DISABLE * PFN_WDF_INTERRUPT_DISABLE
Definition: wdfinterrupt.h:197
BOOLEAN TryToAcquireLock(VOID)
_Must_inspect_result_ __in WDFDEVICE __in PWDF_INTERRUPT_CONFIG __in_opt PWDF_OBJECT_ATTRIBUTES Attributes
BOOLEAN QueueWorkItemForIsr(VOID)
_Must_inspect_result_ struct _KINTERRUPT *STDCALL WDFEXPORT() WdfInterruptWdmGetInterrupt(__in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFINTERRUPT Interrupt)
BOOLEAN IsInterruptAccessAllowed(VOID)
Definition: fxdevice.hpp:2079
#define _When_(c, a)
Definition: no_sal2.h:38
_Must_inspect_result_ __inline BOOLEAN FxIsPassiveLevelInterruptSupported(VOID)
Definition: fxglobals.h:1081
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
WDFDEVICE STDCALL WDFEXPORT() WdfInterruptGetDevice(__in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFINTERRUPT Interrupt)
static _Must_inspect_result_ NTSTATUS _CreateAndInit(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in CfxDevice *Device, __in_opt FxObject *Parent, __in PWDF_OBJECT_ATTRIBUTES Attributes, __in PWDF_INTERRUPT_CONFIG Configuration, __out FxInterrupt **Interrupt)
__inline BOOLEAN IsPdo(VOID)
Definition: fxdevice.hpp:1245
PFN_WDF_INTERRUPT_DPC EvtInterruptDpc
__inline PFX_DRIVER_GLOBALS GetFxDriverGlobals(__in PWDF_DRIVER_GLOBALS DriverGlobals)
Definition: fxglobals.h:597
WDF_DEVICE_PNP_STATE devicePnpState
_In_ WDFINTERRUPT _In_ PWDF_INTERRUPT_EXTENDED_POLICY PolicyAndGroup
Definition: wdfinterrupt.h:688
#define _Acquires_lock_(lock)
VOID ReportInactive(_In_ BOOLEAN Internal=FALSE)
_In_ WDFINTERRUPT _In_ WDF_INTERRUPT_POLICY Policy
Definition: wdfinterrupt.h:651
VOID AcquireLock(VOID)
struct _WDF_INTERRUPT_CONFIG_V1_11_BETA * PWDF_INTERRUPT_CONFIG_V1_11_BETA
#define __in
Definition: dbghelp.h:35
static BOOLEAN _IsMessageInterrupt(__in USHORT ResourceFlags)
BOOLEAN AutomaticSerialization
Definition: wdf19.h:1186
PCM_PARTIAL_RESOURCE_DESCRIPTOR InterruptRaw
PFN_WDF_INTERRUPT_ISR EvtInterruptIsr
Definition: wdfinterrupt.h:225
WDF_INTERRUPT_CONFIG intConfig
EVT_WDF_INTERRUPT_DPC * PFN_WDF_INTERRUPT_DPC
Definition: wdfinterrupt.h:134
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ _In_opt_ PWDF_OBJECT_ATTRIBUTES Attributes
struct _KINTERRUPT * GetInterruptPtr(VOID)
Definition: ps.c:97