KMDF architecture question

I am creating a driver for an 8 channel device that can receive events from
its hardware asynchronously. This device also will also be using the read
and the write requests for DMA of audio data. I can easily see how I can
send messages to the driver using the KMDF and it provides a nice mechanism
to serializing the requests. I don’t see a good example of a way for the
driver to provide a queue for the calling application to receive the
asynchronously generated events. I could send a IRP_MJ_DEVICE_CONTROL
message and only complete it when there was an event ready for the calling
application, but because these messages are serialized into the driver I
would not be able to send IRP_MJ_DEVICE_CONTROL messages to the driver
through this method while I was waiting for an asynchronous event which I
need to do from other threads. Any suggestions? I am porting a driver over
from an embedded system and things like this are rather easy when you have
control over the whole system.

Queuing the IRP is generally considered a “good” way to do it. I won’t
say that it is the “right” way, because different problems call for
different solutions, but IRP queuing is generally a good approach, and
in many situations it *is* the right approach.

How are the requests serialized? It sounds like you have control over
both the driver and the application, so you have a lot of control over
how to move data from the driver to the app. Are you performing the
serialization in your app, or are you assuming that the kernel I/O
manager is serializing requests?

A lot of designs use a design pattern like this:

The app allocates a pool of buffers during initialization. Just
arbitrarily, let’s say 16 buffers, each of 1024 bytes. Each buffer also
has an associated OVERLAPPED structure. (The real values would be
derived from experimentation.) The app opens the device, and issues an
asynchronous DeviceIoControl call for each buffer. Then the app waits
for I/O completion messages, processes the data it received in the
buffer, and reissues the DeviceIoControl for that buffer. In other
words, after initialization is complete, all activity is driven by I/O
completions. (Note that there are several different ways to receive I/O
completions.)

The driver has two main code paths: The DispatchControl routine, which
receives a new buffer from the user-mode app, and the path that receives
asynchronous notifications from the hardware when data is ready
(interrupt) or a DMA has completed. The DispatchControl routine is
analogous to the “top half” of a driver in *nix terminology, and
likewise runs in the context of the process that issued the request
(warning: vast oversimplification, not always true). The interrupt /
DMA notification is analogous to the “bottom half”, and runs in an
arbitrary context.

Typically, for the “receive” path of a device, the DispatchControl
routine handles starting I/O (for the first request in a sequence), or
queuing the IRP if another IRP is already active. Later, the “transfer
complete” handler completes the current IRP and starts I/O for the next
IRP. This is all pretty vanilla stuff in the Windows I/O model. “Send”
is pretty similar, too. I’m using WDM terms, but it all maps 1:1 to
KMDF.

Is there a reason you think pending the IRP_MJ_DEVICE_CONTROL requests
is not the right way? You may be right, of course, or you may just be
missing how your existing design maps to WDM I/O concepts and usage.

– arlie

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Osr Device
driver
Sent: Wednesday, June 07, 2006 3:03 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] KMDF architecture question

I am creating a driver for an 8 channel device that can receive events
from its hardware asynchronously. This device also will also be using
the read and the write requests for DMA of audio data. I can easily see
how I can send messages to the driver using the KMDF and it provides a
nice mechanism to serializing the requests. I don’t see a good example
of a way for the driver to provide a queue for the calling application
to receive the asynchronously generated events. I could send a
IRP_MJ_DEVICE_CONTROL message and only complete it when there was an
event ready for the calling application, but because these messages are
serialized into the driver I would not be able to send
IRP_MJ_DEVICE_CONTROL messages to the driver through this method while I
was waiting for an asynchronous event which I need to do from other
threads. Any suggestions? I am porting a driver over from an embedded
system and things like this are rather easy when you have control over
the whole system.


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

> I could send a IRP_MJ_DEVICE_CONTROL
message and only complete it when there was an event ready for the
calling
application, but because these messages are serialized into the driver I

would not be able to send IRP_MJ_DEVICE_CONTROL messages to the driver
through this method while I was waiting for an asynchronous event which
I
need to do from other threads.

Why are they serialized? Because you created a serialized queue? You
can create a separate queue for IOCTLs, configure it so that IOCTLs are
dispatched to it and then the sync setting for your IOCTL queue is
different then your other queues. Typically the setup is to create a
parallet top level queue to handle IOCTLs and then for the specific
“event” IOCTLs you create a manual queue. When you have an event to
report, you attempt to pop a request off the manual queue.

d

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Osr Device
driver
Sent: Wednesday, June 07, 2006 3:03 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] KMDF architecture question

I am creating a driver for an 8 channel device that can receive events
from
its hardware asynchronously. This device also will also be using the
read
and the write requests for DMA of audio data. I can easily see how I
can
send messages to the driver using the KMDF and it provides a nice
mechanism
to serializing the requests. I don’t see a good example of a way for
the
driver to provide a queue for the calling application to receive the
asynchronously generated events. I could send a IRP_MJ_DEVICE_CONTROL
message and only complete it when there was an event ready for the
calling
application, but because these messages are serialized into the driver I

would not be able to send IRP_MJ_DEVICE_CONTROL messages to the driver
through this method while I was waiting for an asynchronous event which
I
need to do from other threads. Any suggestions? I am porting a driver
over
from an embedded system and things like this are rather easy when you
have
control over the whole system.


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

You can create a parallel top-level queue and then two sub-queues …
one sequential queue to hold your serialized I/O controls and a manual
queue or just a collection to hold your pending event reads.

-p

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Osr Device driver
Sent: Wednesday, June 07, 2006 3:03 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] KMDF architecture question

I am creating a driver for an 8 channel device that can receive events
from its hardware asynchronously. This device also will also be using
the read and the write requests for DMA of audio data. I can easily see
how I can send messages to the driver using the KMDF and it provides a
nice mechanism to serializing the requests. I don’t see a good example
of a way for the driver to provide a queue for the calling application
to receive the asynchronously generated events. I could send a
IRP_MJ_DEVICE_CONTROL message and only complete it when there was an
event ready for the calling application, but because these messages are
serialized into the driver I would not be able to send
IRP_MJ_DEVICE_CONTROL messages to the driver through this method while I
was waiting for an asynchronous event which I need to do from other
threads. Any suggestions? I am porting a driver over from an embedded
system and things like this are rather easy when you have control over
the whole system.


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer