> Hi,
I am writing an NDIS driver, which in turn interact with the wdm
driver. In the SendHandler routine I am allocating and intializing the
IRPs, calling the lower WDM driver and waiting for the lower driver to
finish the processing.
But, after I send few packets I am getting this error (Error=B8
ATTEMPTED_SWITCH_FROM_DPC) when I call KeWaitForSingleObject routine.
Can somebody guide me on how to overcome this problem.
You cannot do this in your MiniportSend or MiniportSendPackets handler as it
is illegal to call anything that will cause the thread to wait while it at
DISPATCH_LEVEL. MiniportSend is documented as ALWAYS being called at
DISPATCH_LEVEL and MiniportSendPackets may be called at any IRQL up to and
including DISPATCH_LEVEL. It is not possible to write an NDIS driver which
waits in its send handler for the packet to be transmitted by the hardware.
In your case you would be much better off setting a completion routine for the
IRP you are sending to the WDM driver and returning NDIS_STATUS_PENDING from
your send handler. In the IRP completion routine you can then signal
back to NDIS that the packet has been sent successfully using
NdisMSendComplete().
As others have suggested develop your driver with Driver Verifier enabled as
it traps this sort of mistake immediately and gives you a much better idea of
how and where you have made your mistake.
Mike
> ----------
From: xxxxx@mpc-data.co.uk[SMTP:xxxxx@mpc-data.co.uk]
Reply To: xxxxx@lists.osr.com
Sent: Wednesday, June 25, 2003 5:32 PM
To: xxxxx@lists.osr.com
Subject: [ntdev] Re: error ATTEMPTED_SWITCH_FROM_DPC (0XB8)
You cannot do this in your MiniportSend or MiniportSendPackets handler as
it
is illegal to call anything that will cause the thread to wait while it at
DISPATCH_LEVEL. MiniportSend is documented as ALWAYS being called at
DISPATCH_LEVEL and MiniportSendPackets may be called at any IRQL up to and
including DISPATCH_LEVEL.
Both can be called at IRQL <= DISPATCH_LEVEL for deserialized miniports. For
serialized miniports both are called with spinlock held which means
DISPATCH_LEVEL.
Anyway, conclusions are right and it is impossible to wait for non-zero
timeout in any send handler. The problem is under some (not rare)
circumstances sends are processed in context of packet receive handler and
packet receives are originated from DPC. Some sends are processed at
PASSIVE_LEVEL probably in context of original calling thread but driver
can’t depend on it.
As others have suggested develop your driver with Driver Verifier enabled
as
it traps this sort of mistake immediately and gives you a much better idea
of
how and where you have made your mistake.
Good idea. In addition, defensive programming helps i.e.
ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL) before every call of
KeWaitOfSingleObject(). Failed assertion will invoke debugger just before
problem becomes fatal and there is a chance to avoid BSOD and reboot. In
addition, it isn’t dependent on human factor when testing on many computers
(where somebody can forget to turn verifier on).
Best regards,
Michal Vodicka
STMicroelectronics Design and Application s.r.o.
[michal.vodicka@st.com, http:://www.st.com]
Hi Mike,
Thanks a for the suggestion.
I followed the method of using Completion routines (I had to break up a
packet and send them sequentialy) and that part is working fine.
But as of now, I am facing a typical problem with my driver. I am layering
NDIS driver over the USB driver. The problem is, if I install the NDIS
driver over USB driver I am getting a ‘Pagefault’ error after some time.
Surprisingly, if I reinstall USB driver on reboot and instal NDIS driver
on it I am not getting any error at all. It is working absolutly fine…
but, mere disabling and enabling the USB driver is of no use… And I
couldn’t track the pagefault error to any driver.
Hope, somebody can help me over this…
thanks in advance,
kantharaj