Synchronization with "slow" devices

I’ve got a device that has a really slow bus for communicating with a specific piece of hardware. Communication over this bus happens at initialization, on a settings change (initiated through an IOCTL), and when the hardware generates an IRQ. The ISR queues a DPC to handle the IRQ. However, in the rare event that the user was in the middle of a settings change I need to synchronize access to the bus such that the IOCTL completes before the DPC handles the IRQ.

What’s the recommended synchronization strategy for such a scenario? The EvtIoDeviceControl callback is configured as WdfIoQueueDispatchSequential.

That’s ugly, because of the IRQL inversion. The DPC has a higher IRQL, so the passive ioctl handler would be blocked. Your only two choices are to use KeSynchronizeExecution in the ioctl handler, which will block the DPC, or have your DPC queue a work item (which runs at passive) and use another synchronization method, like a mutex. The latter seems like a friendlier plan.

I agree with Mr. Roberts, and have a suggestion with a slight twist: Why not have the ISR queue a (IRQL PASSIVE_LEVEL) WorkItemforIsr (as opposed to a DPC) and then use the mutex.

Simple, clean, clear, and easy.

Peter

1 Like

Thanks for responding gentlemen. In the meantime I went with the DPC enqueuing a work item. Was happy to get confirmation that route was a top choice. I actually completely forgot WorkItemForIsr existed because I’m in such a habit of reading my IRQ event, disabling it, starting a DPC to finish it and reenable. Thanks for the suggestion Peter.

yes - queue a work item