Keep the following points in mind when writing a DpcForIsr or CustomDpc routine:
If a DpcForIsr or CustomDpc routine shares the device or state with an ISR, it must call KeSynchronizeExecution, supplying the address of a driver-supplied SynchCritSection routine that programs the device or accesses the shared state. For more information, see Using Critical Sections.
If a DpcForIsr or CustomDpc routine shares state or resources, such as an interlocked queue or a timer object, with routines other than an ISR, it must protect the shared state or resources with a driver-initialized executive spin lock. For more information, see Spin Locks.
For example, DpcForIsr and CustomDpc routines can neither access nor allocate pageable memory, and they cannot wait on kernel dispatcher objects. On the other hand, they can acquire and release a driver’s executive spin lock with KeAcquireSpinLockAtDpcLevel and KeReleaseSpinLockFromDpcLevel, which run faster than KeAcquireSpinLock and KeReleaseSpinLock.
For lowest-level physical device drivers that use direct I/O, this responsibility can include using a SynchCritSection routine to program the device to transfer more data in order to satisfy the current IRP before the driver calls IoStartNextPacket.