From: chris.aseltine on
I am about to develop (using the KMDF) an NDIS miniport driver which
will be communicating with a USB device which will send and receive
Ethernet frames over bulk endpoints. I am basing the approach on the
NDISEDGE sample in the KMDF distribution.

There is a small blurb at the end of the HTML handout given with the
driver that addresses how one might adapt the driver for use with a USB
device. However, it is a little light on details (at least for someone
of my experience level) and seems to have not been updated for the KMDF
(for example, it references "BULKUSB" and not "OSRFXUSB" as a source of
info on how to talk USB).

I've been studying past posts on this group as well as the KMDF help
topics, MSDN library, etc. I have a few general questions about this
approach:

1) In the KMDF help page for WdfDeviceMiniportCreate, there is (what
seems to be) a fairly extensive set of restrictions on what WDF APIs
may not be called from within the context of a miniport driver. This
includes WdfIoQueueCreate(), which is used extensively in the OSRFXUSB
sample and seems to greatly simplify handling of reads and writes.

What implications do these restrictions have for the portion of my
driver that talks to USBD? Will I have to manage the reading and
writing of packets "manually", that is, in a more verbose manner than
is seen in the OSRFX sample?

2) The driver will need to have a "management" interface that can be
accessed from user mode, i.e. DeviceIoControl(). I saw some (albeit
dated) lengthy posts / flames (especially one guy going off for several
pages..) about how it's not possible to hook into most kernel APIs from
NDIS, so this precluded using IOCTLs or doing such things as preventing
the unsafe removal box when IRP_MN_SURPRISE_REMOVAL comes along.

Then I saw at http://www.ndis.com/faq/QA10290101.htm about how to
create a "management" interface to the miniport with
NdisMRegisterDevice(). This seems to be just what I need. Can someone
confirm this will work for talking to the driver directly? Also, if I
were to look for this device with SetupDiEnumDeviceInterfaces(), which
GUID would I use? I don't see a GUID argument to that call.

3) This may not make any sense, but how much more difficult would it
be to separate the USB and NDIS functions of the driver into two
separate .sys drivers, with the NDIS driver communicating to the USB as
a lower filter? Someone said this might cause confusion over power
policies and so on.

Thanks for any help.

-Chris

From: Eliyas Yakub [MSFT] on
inline

> device. However, it is a little light on details (at least for someone
> of my experience level) and seems to have not been updated for the KMDF
> (for example, it references "BULKUSB" and not "OSRFXUSB" as a source of
> info on how to talk USB).
>

I will fix that. We recently included the WDF equivalent of BULKUSB in the
WDK. This sample is called USBSAMP. You can look at that sample also.


>
> 1) In the KMDF help page for WdfDeviceMiniportCreate, there is (what
> seems to be) a fairly extensive set of restrictions on what WDF APIs
> may not be called from within the context of a miniport driver. This
> includes WdfIoQueueCreate(), which is used extensively in the OSRFXUSB
> sample and seems to greatly simplify handling of reads and writes.
>
> What implications do these restrictions have for the portion of my
> driver that talks to USBD? Will I have to manage the reading and
> writing of packets "manually", that is, in a more verbose manner than
> is seen in the OSRFX sample?

This restriction doesn't affect you. In a NDIS miniport driver, you get data
through NDIS callbacks - not thru read, write IRPs.

>
> 2) The driver will need to have a "management" interface that can be
> accessed from user mode, i.e. DeviceIoControl(). I saw some (albeit
> dated) lengthy posts / flames (especially one guy going off for several
> pages..) about how it's not possible to hook into most kernel APIs from
> NDIS, so this precluded using IOCTLs or doing such things as preventing
> the unsafe removal box when IRP_MN_SURPRISE_REMOVAL comes along.
>
> Then I saw at http://www.ndis.com/faq/QA10290101.htm about how to
> create a "management" interface to the miniport with
> NdisMRegisterDevice(). This seems to be just what I need. Can someone
> confirm this will work for talking to the driver directly? Also, if I
> were to look for this device with SetupDiEnumDeviceInterfaces(), which
> GUID would I use? I don't see a GUID argument to that call.

You can continue to use NdisMRegisterDevice for your sideband ioctl
communication. Framework will not interfere on that. You should follow the
NETVMINI sample in the DDK/WDK on how to use NdisMRegisterDevice and deal
with all the PNP issues in your app. The driver sample also contains an app
to demonstrate that.

>
> 3) This may not make any sense, but how much more difficult would it
> be to separate the USB and NDIS functions of the driver into two
> separate .sys drivers, with the NDIS driver communicating to the USB as
> a lower filter? Someone said this might cause confusion over power
> policies and so on.
>

It's not difficult but you should avoid if possible. Folks do something like
that if they have different types of hardware (PCI, USB, Serial) and
different platforms such as NT and 9x platforms to support. In that case you
can keep the modules that interact with NDIS separate from the one that
interacts with hardware. Remember, this will also affect the performance of
your driver.

-Eliyas


From: chris.aseltine on
Eliyas,

Thanks for the help. Just a few brief followup questions:

> > 1) In the KMDF help page for WdfDeviceMiniportCreate, there is (what
> > seems to be) a fairly extensive set of restrictions on what WDF APIs
> > may not be called from within the context of a miniport driver. This
> > includes WdfIoQueueCreate(), which is used extensively in the OSRFXUSB
> > sample and seems to greatly simplify handling of reads and writes.
> >
> > What implications do these restrictions have for the portion of my
> > driver that talks to USBD? Will I have to manage the reading and
> > writing of packets "manually", that is, in a more verbose manner than
> > is seen in the OSRFX sample?
>
> This restriction doesn't affect you. In a NDIS miniport driver, you get data
> through NDIS callbacks - not thru read, write IRPs.

Hmm.. ok. I've been studying the NDISEDGE code. It looks like upon
initialization, the driver creates a series of receive blocks (in
NICAllocRecvResources) and then has a work item that (continually) is
posting these blocks down (as reads) to the target device as they are
exhausted.

So, to adapt this for USB, it looks like (in addition to initializing
my USB device earlier on in the process) I'll need to modify
NICPost(Read|Write)Request to use (say)
WdfUsbTargetPipeFormatRequestForRead instead, and use that to read
ethernet frames from the bulk endpoint. (Can I have more than one
outstanding async read posted to the USB driver?)

Since an ethernet frame is ~1500 bytes maximum, can I safely just issue
USB reads of say, 2K, and then (assuming the device is behaving
properly) treat each completed read request as a full frame?

In other words, I don't have to reassemble / disassemble any packets
after/before I talk to USB, right? Back in BULKUSB I saw lots of code
for "recycling" IRPs for the purpose of completing read/write requests,
but it looks like WDF simplifies this (a lot).

> > Then I saw at http://www.ndis.com/faq/QA10290101.htm about how to
> > create a "management" interface to the miniport with
> > NdisMRegisterDevice(). This seems to be just what I need. Can someone
> > confirm this will work for talking to the driver directly? Also, if I
> > were to look for this device with SetupDiEnumDeviceInterfaces(), which
> > GUID would I use? I don't see a GUID argument to that call.
>
> You can continue to use NdisMRegisterDevice for your sideband ioctl
> communication. Framework will not interfere on that. You should follow the
> NETVMINI sample in the DDK/WDK on how to use NdisMRegisterDevice and deal
> with all the PNP issues in your app. The driver sample also contains an app
> to demonstrate that.

Thanks for the pointer -- I'll look in there for tips.

> > 3) This may not make any sense, but how much more difficult would it
> > be to separate the USB and NDIS functions of the driver into two
> > separate .sys drivers
>
> It's not difficult but you should avoid if possible. Folks do something like
> that if they have different types of hardware (PCI, USB, Serial) and
> different platforms such as NT and 9x platforms to support.

Ok. In that case, I don't qualify -- thanks for talking me out of it.

One more overall question: is there anything in this approach (that
I've mentioned so far) that would disqualify me from getting WHQL
certification, all other challenges aside?

I ask because of the ranting guy from several years ago talking about
disallowed API calls / methods that won't pass the WHQL test -- just
want to make sure what I'm doing is both stable and "blessed".

-Chris

From: Doron Holan [MS] on
I would assume you have to continuously read from the BULK IN endpoint to
receive data from the wire. If so, look at
WdfUsbTargetPipeConfigContinuousReader and let KMDF to the reading for you.

d

--
Please do not send e-mail directly to this alias. this alias is for
newsgroup purposes only.
This posting is provided "AS IS" with no warranties, and confers no rights.


<chris.aseltine(a)gmail.com> wrote in message
news:1153516079.192630.302410(a)m79g2000cwm.googlegroups.com...
> Eliyas,
>
> Thanks for the help. Just a few brief followup questions:
>
>> > 1) In the KMDF help page for WdfDeviceMiniportCreate, there is (what
>> > seems to be) a fairly extensive set of restrictions on what WDF APIs
>> > may not be called from within the context of a miniport driver. This
>> > includes WdfIoQueueCreate(), which is used extensively in the OSRFXUSB
>> > sample and seems to greatly simplify handling of reads and writes.
>> >
>> > What implications do these restrictions have for the portion of my
>> > driver that talks to USBD? Will I have to manage the reading and
>> > writing of packets "manually", that is, in a more verbose manner than
>> > is seen in the OSRFX sample?
>>
>> This restriction doesn't affect you. In a NDIS miniport driver, you get
>> data
>> through NDIS callbacks - not thru read, write IRPs.
>
> Hmm.. ok. I've been studying the NDISEDGE code. It looks like upon
> initialization, the driver creates a series of receive blocks (in
> NICAllocRecvResources) and then has a work item that (continually) is
> posting these blocks down (as reads) to the target device as they are
> exhausted.
>
> So, to adapt this for USB, it looks like (in addition to initializing
> my USB device earlier on in the process) I'll need to modify
> NICPost(Read|Write)Request to use (say)
> WdfUsbTargetPipeFormatRequestForRead instead, and use that to read
> ethernet frames from the bulk endpoint. (Can I have more than one
> outstanding async read posted to the USB driver?)
>
> Since an ethernet frame is ~1500 bytes maximum, can I safely just issue
> USB reads of say, 2K, and then (assuming the device is behaving
> properly) treat each completed read request as a full frame?
>
> In other words, I don't have to reassemble / disassemble any packets
> after/before I talk to USB, right? Back in BULKUSB I saw lots of code
> for "recycling" IRPs for the purpose of completing read/write requests,
> but it looks like WDF simplifies this (a lot).
>
>> > Then I saw at http://www.ndis.com/faq/QA10290101.htm about how to
>> > create a "management" interface to the miniport with
>> > NdisMRegisterDevice(). This seems to be just what I need. Can someone
>> > confirm this will work for talking to the driver directly? Also, if I
>> > were to look for this device with SetupDiEnumDeviceInterfaces(), which
>> > GUID would I use? I don't see a GUID argument to that call.
>>
>> You can continue to use NdisMRegisterDevice for your sideband ioctl
>> communication. Framework will not interfere on that. You should follow
>> the
>> NETVMINI sample in the DDK/WDK on how to use NdisMRegisterDevice and
>> deal
>> with all the PNP issues in your app. The driver sample also contains an
>> app
>> to demonstrate that.
>
> Thanks for the pointer -- I'll look in there for tips.
>
>> > 3) This may not make any sense, but how much more difficult would it
>> > be to separate the USB and NDIS functions of the driver into two
>> > separate .sys drivers
>>
>> It's not difficult but you should avoid if possible. Folks do something
>> like
>> that if they have different types of hardware (PCI, USB, Serial) and
>> different platforms such as NT and 9x platforms to support.
>
> Ok. In that case, I don't qualify -- thanks for talking me out of it.
>
> One more overall question: is there anything in this approach (that
> I've mentioned so far) that would disqualify me from getting WHQL
> certification, all other challenges aside?
>
> I ask because of the ranting guy from several years ago talking about
> disallowed API calls / methods that won't pass the WHQL test -- just
> want to make sure what I'm doing is both stable and "blessed".
>
> -Chris
>


From: Eliyas Yakub [MSFT] on
For reading data from an USB endpoint on a continuous basis, you should use
the KMDF continuous reader interface -
WdfUsbTargetPipeConfigContinuousReader. It will do lot of heavy lifting
interms of formatting, reusing, and reposting the request for every read.

The OSRUSB sample (enumswitches) demonstrates how to use this continuous
reader interfaces.

We are currently working on a native WWAN sample driver for an USB device
that uses this interface to read packets. So I know you can make of this.
The sample is not complete yet so I can't share with you.

>
> One more overall question: is there anything in this approach (that
> I've mentioned so far) that would disqualify me from getting WHQL
> certification, all other challenges aside?
>

As long as you use the right NDIS interfaces at the top, you don't have to
worry about getting disqualified. In fact we are encouraging people to use
KMDF with NDIS for interfacing with USB and other WDM stacks.

--
-Eliyas
This posting is provided "AS IS" with no warranties, and confers no rights.
http://www.microsoft.com/whdc/driver/tips/default.mspx