Some confusing NDIS-related questions

Considering a NDIS-Wdm drvier for a USB Device , acting as NIC .

1 . When the USB Device is removed/surprised remove , who notifies NDIS of the message of Device Removal ? PNP manager or the lower miniport driver ?

In my case ,when a device is removed , PNP message can really generate a removal message to the miniport driver and unbinding of miniport driver with the bound protocol occurs accordingly. But I find my queryinformation is still invoked perodically in response to the request of NDIS, ndicating NDIS seems not to know the removal is happening. So I think that NDIS doesn’t know/care any PNP message except the related messages from
miniport driver. Please correct me if something is wrong .

2 . Regarding the scenarios mentioned in item 1 , If NDIS is notified of the removal message from the lower miniport driver , then how does the miniport driver get this message ?

NDIS5.1 or later provides PnPEventNotifyHandler callback . But for NDIS5.0 , how ??

Currently , I get this message from the the completRoutine and check if the error is NDIS_STATUS_DEVICE_DISCONNECTED.(0xC000009D)

Please correct me and enhance me if any faults improper .

3 . How to notify NDIS of removal message ?

In MSDN , NdisMIndicateStatus is mentioned . Besides , is there any other way to achieve this goal ?

I ever saw some miniport driver , it notifies upper driver by returing some speicifed value , NDIS_STATUS_CLOSING , NDIS_STATUS_NOT_ACCEPTD etc.

I suppose these value can change code path of NDIS internally and therefore , stops the more sending to miniport.
But I made a trial ,and found that returning these doesn’t prevent NDIS from sending more requests.
So , my question is if these magic values can be used formally to notify NDIS ?

Forget to say thanks . Hehe .

Thanks a lot in advance.

For NDIS-WDM the NDIS Miniport is the FDO (and IIRC the Power Policy Owner).
The surprise removal is delivered to the FDO just like any other PnP stack
and because NDIS has grabbed all of the Dispatch routines, NDIS learns of
the removal and notifies the Miniport - not the other way around.

NDIS handles the details of synchronizing the binding teardown with the
miniport halt process. The NDIS 5.1 Miniport PnP handler is how your
Miniport can coordinate with this activity a bit more proactively.

RE: NDIS 5.0 - Are you targeting Win2K?

As a Miniport remember, you *react* to what the Port driver (in this case
NDIS) tells you. The only ‘indication’ that a LAN miniport makes to NDIS is
in regards to media state (typically).

Good Luck,
Dave Cattley

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of xiedong_sl@126.com
Sent: Thursday, October 15, 2009 9:52 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] Some confusing NDIS-related questions

Considering a NDIS-Wdm drvier for a USB Device , acting as NIC .

1 . When the USB Device is removed/surprised remove , who notifies NDIS of
the message of Device Removal ? PNP manager or the lower miniport driver ?

In my case ,when a device is removed , PNP message can really generate a
removal message to the miniport driver and unbinding of miniport driver
with the bound protocol occurs accordingly. But I find my queryinformation
is still invoked perodically in response to the request of NDIS, ndicating
NDIS seems not to know the removal is happening. So I think that NDIS
doesn’t know/care any PNP message except the related messages from
miniport driver. Please correct me if something is wrong .

2 . Regarding the scenarios mentioned in item 1 , If NDIS is notified of the
removal message from the lower miniport driver , then how does the miniport
driver get this message ?

NDIS5.1 or later provides PnPEventNotifyHandler callback . But for
NDIS5.0 , how ??

Currently , I get this message from the the completRoutine and check if
the error is NDIS_STATUS_DEVICE_DISCONNECTED.(0xC000009D)

Please correct me and enhance me if any faults improper .

3 . How to notify NDIS of removal message ?

In MSDN , NdisMIndicateStatus is mentioned . Besides , is there any
other way to achieve this goal ?

I ever saw some miniport driver , it notifies upper driver by returing
some speicifed value , NDIS_STATUS_CLOSING , NDIS_STATUS_NOT_ACCEPTD etc.

I suppose these value can change code path of NDIS internally and
therefore , stops the more sending to miniport.
But I made a trial ,and found that returning these doesn’t prevent NDIS
from sending more requests.
So , my question is if these magic values can be used formally to
notify NDIS ?


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

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

>1 . When the USB Device is removed/surprised remove , who notifies NDIS of >the message of Device Removal ? PNP manager or the lower miniport driver ?
Your driver should be attached to USB stack. Because of this your virtual miniport driver gets surprise remove and later remove IRPs from USB stack. After getting such Irps you could call NdisMRemoveMiniport notifying NDIS that your hardware does not work now.

Igor Sharovar

Thanks to David ,

"For NDIS-WDM the NDIS Miniport is the FDO (and IIRC the Power Policy Owner). The surprise removal is delivered to the FDO just like any other PnP stack and because NDIS has grabbed all of the Dispatch routines, NDIS learns of the removal and notifies the Miniport - not the other way around.
"

If so , Why NDIS does not hook and handle all requests/Packets to Miniport , which are sent in the course of unbinding of Miniport driver with protocol ? Actually, I still can receive requests in QueryInformation callback.

"

"RE: NDIS 5.0 - Are you targeting Win2K? "

Yes , my driver need to support this Platform .

"
As a Miniport remember, you *react* to what the Port driver (in this case NDIS) tells you. The only ‘indication’ that a LAN miniport makes to NDIS is in regards to media state (typically).
"
I see . I am confused the device removal and media state . That’s two stories.

NDIS handles the details of synchronizing the binding teardown with the miniport halt process. The NDIS 5.1 Miniport PnP handler is how your Miniport can coordinate with this activity a bit more proactively.
"
So , I can say that Miniport PnP handler is invoked prior to Unbound , Right ?

<mr. sharovar>
Because of this your virtual miniport driver gets surprise remove and later
remove IRPs from USB stack. After getting such Irps you could call
NdisMRemoveMiniport notifying NDIS that your hardware does not work now.
</mr.>

Hmm, I don’t think that an NDIS Miniport Driver is supposed to be processing
IRPs of any kind from its device stack in the ‘normal’ case. NDIS handles
all of those IRPs and translates them into Miniport handler calls. As
such, NDIS gets the surprise remove and in the process of handling it
(coordinating the state transitions of the miniport, bindings, and overall
device stack) it (NDIS) calls the Miniport handlers to tell it what is going
on.

It is my understanding that calling NdisMRemoveMiniport() is an
‘extrodinary’ action (or one used in conjunction with LBFO) to command NDIS
to remove the device *not* to inform NDIS that the device has been removed.

I could be wrong… (heck, I probably am wrong!)

Dave Cattley
Consulting Engineer
Systems Software Development

To Igor , Thanks

in NDIS5.0 , no surprise removal handler callback is provided , I have no chance to handle it and call NdisMRemoveMiniport accordingly .

I think NDIS has taken over it and call it to unbound it with procotol driver .


If so , Why NDIS does not hook and handle all requests/Packets to Miniport ,
which are sent in the course of unbinding of Miniport driver with protocol ?
Actually, I still can receive requests in QueryInformation callback.

A miniport is not concerned (and should not be concerned) with whether or
not a protocol is bound to it. The miniport has a fixed set of rules to
obey irrespective of how many protocols (if any) are bound to it. Forget
about bindings in a miniport. They might as well not exist.

You get Miniport{Query|Set}Information() callbacks and you process them. It
does not matter if the miniport is bound or not. The miniport processes the
information request. That might mean it is ‘failed’ but that is still
processing it. Only the state of your NIC (device and possibly device
stack) effect how you process an NDIS_REQUEST. Where the request comes from
(NDIS or a Protocol) is irrelevant.


So , I can say that Miniport PnP handler is invoked prior to Unbound ,
Right ?

No, not particularly. Again I refer you to the above - in a Miniport,
bindings are irrelevant. Don’t worry about them.

If you care about a PnP notification and the state change of the Device
Stack implied by the callback causes some difference in the processing of
packets, requests, and status indications, then, your driver should best do
what it needs to change state based on the PnP notification. This might,
for instance, mean you have to stop sending packets ‘down’ the stack as IRPs
(or URBs or whatever).

I think the WDK (or at least the older 3790.1830 DDK) sample NDISWDM had
some hints on how to interface to USB. I also think that the NDIS-WDF(USB)
approach to building such a driver is a good idea (may be required now by
WHQL). The WDK sample USBNWIFI shows in great detail how this is put
together.

Good Luck,
Dave Cattley

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of xiedong_sl@126.com
Sent: Thursday, October 15, 2009 10:32 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Some confusing NDIS-related questions

Thanks to David ,

"For NDIS-WDM the NDIS Miniport is the FDO (and IIRC the Power Policy
Owner). The surprise removal is delivered to the FDO just like any other PnP
stack and because NDIS has grabbed all of the Dispatch routines, NDIS learns
of the removal and notifies the Miniport - not the other way around.
"

If so , Why NDIS does not hook and handle all requests/Packets to Miniport ,
which are sent in the course of unbinding of Miniport driver with protocol ?
Actually, I still can receive requests in QueryInformation callback.

"

"RE: NDIS 5.0 - Are you targeting Win2K? "

Yes , my driver need to support this Platform .

"
As a Miniport remember, you *react* to what the Port driver (in this case
NDIS) tells you. The only ‘indication’ that a LAN miniport makes to NDIS is
in regards to media state (typically).
"
I see . I am confused the device removal and media state . That’s two
stories.

NDIS handles the details of synchronizing the binding teardown with the
miniport halt process. The NDIS 5.1 Miniport PnP handler is how your
Miniport can coordinate with this activity a bit more proactively.
"
So , I can say that Miniport PnP handler is invoked prior to Unbound ,
Right ?


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

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

If the device is enumerated by USB, this is not necessary. NDIS_WDM is not
different from regular ndis from the PNP’s pov. NDIS.sys handles state
change PNP/po and wmi irps directed to its FDO.

On the other hand, if the virtual nic is not enumerated by USB but somehow
gets a ptr to the USB target device, then he would need to either register
PNP notification of play with the QDR/RemovalRelation IRP in the USB stack.
But I don’t think this is OP’s situation.

A PNP device gets SR irp because its parent excluded its PDO in response to
QDR/BusRelation. These IRPs are from pnp manager, not from the USB stack.
Only pnp manager can send such IRPs. This also holds even if we are talking
about the 2nd scenario mentioned above.

Calvin Guan
Broadcom Corp.
Connecting Everything(r)


A miniport is not concerned (and should not be concerned) with whether or not a protocol is bound to it. The miniport has a fixed set of rules to obey irrespective of how many protocols (if any) are bound to it. Forget about bindings in a miniport.

Understand , but , Does it cause anther issue ?

Consider such a scenario :

Unbinding of Miniport to upper protocol is in progress and the miniport frequently receives NDIS_Request.

My question is the frequent NDIS_Requests from other components makes it impossible for miniport to decrease its reference count to one . Then the preformance of miniport driver unloading is affected adversely, Right ?


Unbinding of Miniport to upper protocol is in progress and the miniport
frequently receives NDIS_Request.

This not the concern of the miniport. The protocol should have stopped
issuing requests (and sends) to the binding if NDIS has indicated an unbind.
Again, the miniport should just process the requests.


My question is the frequent NDIS_Requests from other components makes it
impossible for miniport to decrease its reference count to one . Then the
preformance of miniport driver unloading is affected adversely, Right ?

In a word, No. If your miniport (instance) continues to get NDIS_REQUESTs
then it is not unloading (or halting). NDIS ensures that requests and sends
stop before halting the instance.

And what reference count are you referring to? The miniport does not
control any NDIS reference count that affects unloading *directly*. The
only thing a miniport can do is ‘wait’ during MiniportHalt or
MiniportUnload. In an NDIS-WDM (or NDIS-WDF) miniport, the only thing that
should delay MiniportHalt is waiting for outstanding resources passed to the
lower-edge to be returned. In other words, IRPs need to be canceled and
resources ‘recovered’ from the lower edge before allowing the MiniportHalt
to complete.

The *performance* of unloading a Miniport Driver is not something I would be
concerned with. The *correctness* of doing so is far more important. BTW,
you may be confusing ‘halting the device’ with unloading the driver.
However, in both cases ‘correctness’ is the most important thing. Resources
must be recovered and returned before halting or unloading.

Regards,
Dave Cattley


And what reference count are you referring to? …

This reference count is the one obtained from realtime debugging . For example :

kd> !miniport fb113ad0

Miniport fb113ad0 : Motorola USB Networking Driver #2, v0.0

AdapterContext : fb13db78
Flags : 28452400
PROCESSING_REQUEST, IGNORE_TOKEN_RING_ERRORS, DESERIALIZED
RESOURCES_AVAILABLE, DOES_NOT_DO_LOOPBACK, MEDIA_CONNECTED
NOT_BUS_MASTER, NOT_SUPPORTS_MEDIA_SENSE,
PnPFlags : 40400031
PM_SUPPORTED, REMOVE_IN_PROGRESS, DEVICE_POWER_ENABLED
NDIS_WDM_DRIVER,
MiniportState : STATE_UNDEFINED
IfIndex : 0
Ndis5MiniportInNdis6Mode : 0
InternalResetCount : 0000
MiniportResetCount : 0000
References : 3
UserModeOpenReferences: 0
PnPDeviceState : CurrentDevicePowerState : PowerDeviceD0

Here , References is 3.

Thanks very much , David

Appreciate for your great reply.

Daniel Xie wrote:

Miniport fb113ad0 : Motorola USB Networking Driver #2, v0.0

David, allow me to shed some light on the situation. Apparently, Daniel Xie has taken over the NDIS-USB driver (and others, I’ve since realized) that I wrote for Motorola many years ago. This is an NDIS-KMDF driver based solely on NDISEDGE. The device is (or at least was) a cell phone running Linux with a pair of bulk endpoints to do CDC Ethernet.

These phones were commonly hooked up, 15 to 30 or more at a time, to a shoddy machine in a dusty factory in China, with a bunch of cheap, flaky third-party OHCI controller cards, and had their firmware reflashed, which involves power-cycling the device repeatedly (and thus it going on and off the bus frequently).

After doing this for not too long, with any given CATC analyzer trace of this type of activity showing blood red with bus errors, the host-side USB stack would become totally scrambled, and the driver would refuse to unload because its “reference count” that you see above is non-zero. Another symptom that we would see is the count of outstanding packets indicated to NDIS would also stay non-zero. I believe MPHalt() would just spin forever, waiting for these counts to zero out, but they never would. So you would just see many instances of the device in Device Manager, even though the phones had all been unplugged. I would then be summoned to the factory to explain these “aberrations”. So, I think Daniel is trying to figure out why his driver won’t unload.

Same story with his post from a few weeks ago about some race inside usbport or whatever … just trying to power-cycle 30 cell phones all connected to the same machine, at the same time…

<mr. aseltine>
Apparently, Daniel Xie has taken over the NDIS-USB driver (and others, I’ve
since realized) that I wrote for Motorola many years ago.
</mr.>

Ah, so you are just the right source to help him out!

I can only do harm at this point :slight_smile:

Cheers,
Dave Cattley

David R. Cattley wrote:

Ah, so you are just the right source to help him out!

Apparently you didn’t deduce what I think the solution is from the tone of my post :slight_smile:

To David

Any suggestion is really appreciated .

To Chris ,

Another symptom that we would see is the count of outstanding packets indicated to NDIS would also stay non-zero.

How do you get to know it ? I check all packets sent and indicated and it indicates all packets are handled and then successfully return to their owners . what output in windbg implies this fact ? ? Please help to figure it out .

I believe MPHalt() would just spin forever, waiting for these counts to zero out, but they never would.

From the investigation , I think that this issue happens at the point when unbind of miniport to protocol driver. and at this time , MPhalt is not involved yet . Please correct me if something wrong .

Here is the stack :

4.000034 86fc13c8 001c747 Blocked nt!KiSwapContext+0x2e
nt!KiSwapThread+0x46
nt!KeWaitForSingleObject+0x1c2
NDIS!ndisUnbindProtocol+0x196
NDIS!ndisCloseMiniportBindings+0x1f7
NDIS!ndisPnPRemoveDevice+0x142
NDIS!NdisIMDeInitializeDeviceInstance+0x44
eacfilt_f7bc3000+0xc4b
NDIS!ndisUnbindProtocol+0x157
NDIS!ndisCloseMiniportBindings+0x1f7
NDIS!ndisPnPRemoveDevice+0x142
NDIS!ndisPnPDispatch+0x446
nt!IopfCallDriver+0x31
myswch_f7b93000+0xe20
myswch_f7b93000+0x4ef
nt!IopfCallDriver+0x31
nt!IopSynchronousCall+0xb7
nt!IopRemoveDevice+0x93
nt!IopSurpriseRemoveLockedDeviceNode+0x90
nt!IopDeleteLockedDeviceNode+0x24
nt!IopDeleteLockedDeviceNodes+0x3f
nt!PiProcessQueryRemoveAndEject+0x4d2
nt!PiProcessTargetDeviceEvent+0x2a
nt!PiWalkDeviceList+0x122
nt!ExpWorkerThread+0x100
nt!PspSystemThreadStartup+0x34
nt!KiThreadStartup+0x16

Daniel Xie wrote:

How do you get to know it ? I check all packets sent and indicated
and it indicates all packets are handled and then successfully return
to their owners . what output in windbg implies this fact ? ? Please
help to figure it out .

I believe I (and the NDISEDGE sample) called these variables “nBusyRecv” and “nBusySend”. But these values aren’t checked until you’re inside MPHalt, which you say you’re not reaching.

I’m talking about this code:

while ((Adapter->nBusyRecv) || (Adapter->nBusySend))
{
DEBUGP(MP_ERROR, ("outstanding packets detected – nBusyRecv %d, "
“nBusySend %d.”, Adapter->nBusyRecv, Adapter->nBusySend));

NdisMSleep(1000000);
}

From the investigation , I think that this issue happens at the point
when unbind of miniport to protocol driver. and at this time , MPhalt
is not involved yet

Entirely possible. Based on the backtraces you provided, that seems like the case. Maybe Mr. Cattley can shed a little more light on this one.

<chris.aseltine>
Maybe Mr. Cattley can shed a little more light on this one.
</chris.aseltine>

Gee, do you know my dad too? Hey is a civil so when you talk bridges to him
he thinks “Tacoma Narrows” and not “Ethernet”. Dave, David, or “Hey you”
works for me but I digress…

To the OP:

I noted in the stack back-trace that it appears you have the Nortel VPN
client installed (EACFILT) along with a driver that I do not recognize named
MYSWCH.

My first suggestion is that you reduce the complexity of your test
environment to the bare minimum - in particular, ditch all the IM drivers
you can from the adapter bindings. That is a set of headaches you don’t
need when trying to figure out if you *NIC* driver and the system are
getting along. This may come as a surprise but there are plenty of IM
drivers out there with problems around suspend/resume/power transitions.

The stack back-trace seems to imply that the binding to the EACFILT
‘protocol’ edge has been signaled to close and is waiting on something.
What it is waiting on is anybody’s guess.

Using the command

!stacks 3 ndis!

Should show other stacks in the system that have ndis! ‘active’ in them.

It might be useful to know what other threads in the system are
‘participants’ in this problem and in particular which ones might be
continuing to ‘send’ packet or make ‘requests’ on the binding. When you
get into this state of being ‘stuck’, it would be helpful to have
break-points set on your MiniportSendXxx, MiniportReturnPackets, and
MiniportXXXInformation entrypoints to get some idea of what protocol might
be continuing to make requests that keep the binding reference from
draining.

But the first step should be to ditch every other bit of network software
that is not necessary. I assume you do not need to have a VPN connection
going to have this occur so why in the world the EACFILT would be installed
on your test target is beyond me.

Good Luck,
Dave Cattley

To all .

Thanks very much . I will uninstall useless drivers and then check this issue .