Wait until the device has finished

Hello,
I am porting a KMDF driver to UMDF 2.0.
The device has no interrupt. After settling a command, the driver must wait for the answer of the device. Of course waiting in a driver is not a good idea…

The source code of the existing driver:

NTSTATUS WaitForCommandResponse(PDEVICE_CONTEXT devContext, unsigned long Timeout)
{
NTSTATUS status;

LARGE_INTEGER Start;
LARGE_INTEGER End;
LARGE_INTEGER Wait;

if (Timeout)
{
Wait.QuadPart = (Timeout /*ms*/ * 10 * 1000) + KeQueryTimeIncrement();
KeQueryTickCount(&Start);
}
else
{
Wait.QuadPart = 0;
Start.QuadPart = 0;
}

while ((status = GetCommandStatus(devContext)) == STATUS_DEVICE_NOT_READY)
{
if (Timeout == 0)
continue;
KeQueryTickCount(&End);
if ((End.QuadPart - Start.QuadPart) * KeQueryTimeIncrement() > Wait.QuadPart)
{
status = STATUS_REQUEST_ABORTED;
break;
}
}
return status;
}

The functions KeQueryTickCount and KeQueryTimeIncrement are not available with UMDF 2.0 and waiting in a driver is ugly…

How can I solve this wait function better? Work item and time out timer?

Regards

Manuel

manuel.parfant@br-automation.com wrote:

I am porting a KMDF driver to UMDF 2.0.
The device has no interrupt. After settling a command, the driver must wait for the answer of the device. Of course waiting in a driver is not a good idea…

The source code of the existing driver:

You’re certainly correct that this is a sub-optimal design, even in
kernel mode.  This is a tight CPU loop, which will consume 100% CPU
while it waits.  Is this a PCI device?

KeQueryTickCount is exactly the same as the user-mode GetTickCount API. 
It only bumps during scheduler intervals, which means once every 16ms. 
Thus, your timeout can never be less than 16ms.

If your typical wait is a few hundred microseconds, then maybe this is
not too bad.  But if your typical wait is multiple milliseconds, then
you should at least put the thread to sleep in between, by using
something like “Sleep(10);”


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Hello Tim,

thank you for your answer.

The device is not a PCI device. It uses the LPC bus and is reported to the PnP manager via ACPI.

The waiting time can be between a few nanoseconds (normal commands) and a few seconds (flash commands).