Re[2]: Updating a Driver (1394)

> OK, good point, I think indeed this might be the problem. Just to be

sure: DriverEntry is called each time I connect the first of my 1394
device. And the driver will be unloaded not before I disconnected my
last 1394 device, is that correct?
If yes, I have that “unload” problem, but I don’t know why. It even
happens if I didn’t access the device from an application.

Driver Entry is called when the driver is loaded. This generally occurs
when you plug in the first device.

The DriverUnload routine will be called when the driver is unloaded.
If this routine has not been declared the driver will not be unloaded
(I think). It will generally be called when the last device is removed
but not if some process still has a handle open.

I use dbgview from sysinternals.com to see debug messages. I haven’t
used SoftIce (but I would like to) but I’m sure it will give you
something equivalent (or better). I place a debug message in the load
and unload routine to directly observe loading and unloading. I do not
trust to any other method or logical argument (usually based on
observations of AddDevice and IRP_MN_REMOVE_DEVICE) period.
There are just too many
things that can interfere and it is very annoying when you update the
driver and can’t figure out why your changes haven’t accomplished
anything, only to discover after much work that the driver isn’t being
updated (this can also be dealt with by religiously updating the
version number).

I too used 1394diag as a starting point for my driver (I would do
things differently know that I know a little more). If you use the
SubmitIrpSynch routine for communication with the 1394 driver than
fixing the UserMode issue can be as simple as the following code:

if (Irb) {
if (!Irp || Irp->RequestorMode == UserMode) {
// allocate an IRP
Irp = IoAllocateIrp(…

Robert Newton

[snip]

I’m doing that. I’m the proud owner of a SoftICE kernel mode debugger
and like using this “instrument”! How can I see where the unloading
procedure actually stuck? I’m not using an own driver unload routine.
What is the PNP call sequence for unplugging a 1394-er device? (I guess
surprise removal).
thanks and regards
Daniel

Sorry, I just remembered, an Unload routine is mandatory as per WDM rules.
If I interpret your statement above correctly, you are not using an Unload
routine. The DDK states:

“Any driver that can be replaced, or unloaded and reloaded, while the system
is running must have an Unload routine. All WDM drivers must have Unload
routines.”

and…

“Although Unload routines are optional for non-WDM drivers, Driver Verifier
will fail any driver that does not provide an Unload routine.”

Since you don’t a warning (or bugcheck) from driver verifier, you must have
not been using driver verifier. If you enable driver verifier, you may find
other errors as well. (be sure to enable I/O verification and Advanced I/O
verification). Since verifier is more advanced on WinXP, testing on WinXP
could be fruitful also. Maybe the comments above concerning verifier
failing any driver without an unload routine apply to verifier under XP
only? I don’t know honestly.

It is quite amazing, but the 1394diag driver in the 3790 Windows server 2003
DDK has its unload routine commented out in DriverEntry. Rumors are that
this sample is fairly buggy. For a good PnP example, see the toaster sample
(for a function driver) in the DDK.

good luck,

Philip Lukidis

excellent, guys!
It’s running now!!! Loading and Unloading works perfectly!!!
But I had to change quite a lot to reach that. For whatever reasons the
routine for IRP_MJ_SYSTEM_CONTROL is commented out in DriverEntry of the
1394diag sample as well as the DriverUnload routine. After activating
the DriverVerifier, I rarely used it before, it told me about the
missing function. I corrected it, but still there were some fatal
errors. In the pnp.c file (from the diag sample) I found some
differences between the Win2k DDK and WinXP DDK sample, mainly the WinXP
diag uses more t1394Diag_SubmitIrpAsync() calls while the Win2k diag
exclusively uses t1394Diag_SubmitIrpSynch(). I guess for this PNP
sequence it doesn’t make a big difference if the functions were called
synchronously or asynchronously, or am I wrong? So I adapted my driver
to the WinXP diag sample and voilà, it worked! Cool. One problem solved.
So, thank you very much for your help!

There is another tiny little problem. As already mentioned the device is
plugged in a 1394-PCI card to a desktop PC on WinXP SP1. I tested now
several times to plug and unplug the device. It worked, but sometimes I
had to force a bus reset from my 1394-device that the system took notice
about the newly plugged in device and ran through my DriverEntry. But
sometimes nothing happened, even after few minutes waiting. As I know a
bus reset should occur after a topology change and therefore show the
system that there is a new device. Why does it just work sometimes?

Thanks very much, I really appreciate your help guys!
Regards
Daniel

Philip Lukidis wrote:

[snip]

>I’m doing that. I’m the proud owner of a SoftICE kernel mode debugger
>and like using this “instrument”! How can I see where the unloading
>procedure actually stuck? I’m not using an own driver unload routine.
>What is the PNP call sequence for unplugging a 1394-er device? (I guess
>surprise removal).
>thanks and regards
>Daniel
>

Sorry, I just remembered, an Unload routine is mandatory as per WDM rules.
If I interpret your statement above correctly, you are not using an Unload
routine. The DDK states:

“Any driver that can be replaced, or unloaded and reloaded, while the system
is running must have an Unload routine. All WDM drivers must have Unload
routines.”

and…

“Although Unload routines are optional for non-WDM drivers, Driver Verifier
will fail any driver that does not provide an Unload routine.”

Since you don’t a warning (or bugcheck) from driver verifier, you must have
not been using driver verifier. If you enable driver verifier, you may find
other errors as well. (be sure to enable I/O verification and Advanced I/O
verification). Since verifier is more advanced on WinXP, testing on WinXP
could be fruitful also. Maybe the comments above concerning verifier
failing any driver without an unload routine apply to verifier under XP
only? I don’t know honestly.

It is quite amazing, but the 1394diag driver in the 3790 Windows server 2003
DDK has its unload routine commented out in DriverEntry. Rumors are that
this sample is fairly buggy. For a good PnP example, see the toaster sample
(for a function driver) in the DDK.

good luck,

Philip Lukidis

[snip]

excellent, guys!
It’s running now!!! Loading and Unloading works perfectly!!!
But I had to change quite a lot to reach that. For whatever reasons the
routine for IRP_MJ_SYSTEM_CONTROL is commented out in DriverEntry of the
1394diag sample as well as the DriverUnload routine. After activating
the DriverVerifier, I rarely used it before, it told me about the
missing function. I corrected it, but still there were some fatal
errors. In the pnp.c file (from the diag sample) I found some
differences between the Win2k DDK and WinXP DDK sample, mainly the WinXP
diag uses more t1394Diag_SubmitIrpAsync() calls while the Win2k diag
exclusively uses t1394Diag_SubmitIrpSynch(). I guess for this PNP
sequence it doesn’t make a big difference if the functions were called
synchronously or asynchronously, or am I wrong? So I adapted my driver
to the WinXP diag sample and voilà, it worked! Cool. One problem solved.
So, thank you very much for your help!

For PnP, using the sync or async version really depends. For example, in
IRP_MN_START_DEVICE, you must forward the IRP down synchronously, wait for
it to come up, and then do your StartDevice processing. This holds for
IRP_MN_CANCEL_REMOVE_DEVICE, IRP_MN_CANCEL_STOP_DEVICE as well (and other
cases too). In these cases, use the sync version. For
IRP_MN_REMOVE_DEVICE, you end up sending the IRP down async and detaching
and deleting after it returns (i.e. this IRP is never pended), so you use
the sync version. I’m leaving out alot of details in how the IRPs are
handled, and just talking about the sync and async functions in a PnP
context.

The latest DKK has a complete listing on how to handle each PnP IRP. IMHO
it is best accompanied by Walter Oney’s *2nd Edition* book, Programming the
Windows Driver Model
. The book is a lifesaver, and it is well worth
acquiring. The toaster function driver example in the latest DDK is also a
good introduction to PnP. If your device will be used on Win2k and higher
only, then use IO_REMOVE_LOCKs also for synchronzing PnP removal with I/O in
your stack (this lock are not present in the toaster, which uses I/O
increments/decrements for 9x/me compatibility).

OTOH, for non PnP situations, you should be careful in using the sync
version. You must be at IRQL < DISPATCH_LEVEL.

There is another tiny little problem. As already mentioned the device is
plugged in a 1394-PCI card to a desktop PC on WinXP SP1. I tested now
several times to plug and unplug the device. It worked, but sometimes I
had to force a bus reset from my 1394-device that the system took notice
about the newly plugged in device and ran through my DriverEntry. But
sometimes nothing happened, even after few minutes waiting. As I know a
bus reset should occur after a topology change and therefore show the
system that there is a new device. Why does it just work sometimes?

Thanks very much, I really appreciate your help guys!
Regards
Daniel

Out of curiosity, are you aware that that IRP for handling bus resets
(IRP_MN_BUS_RESET) is obsolete in WinXP and later OS and should not be used?
Instead, you should register for a bus reset notification in startdevice,
and unregister in removedevice. The 1394diag sample in the latest DDK does
register/unregister for bus reset notification in fact. The Win2k DDK uses
the obsolete IRP_MN_BUS_RESET IIRC.

When your device is not enumerated on plugin, did you actually see a bus
reset on your bus analyzer (I hope you have one, they are invaluable)? Did
you see the host controller trying to read your config ROM after said bus
reset?

[snip]

good luck,

Philip Lukidis

> There is another tiny little problem. As already mentioned the device is

plugged in a 1394-PCI card to a desktop PC on WinXP SP1. I tested now
several times to plug and unplug the device. It worked, but sometimes I
had to force a bus reset from my 1394-device that the system took notice
about the newly plugged in device and ran through my DriverEntry. But
sometimes nothing happened, even after few minutes waiting. As I know a
bus reset should occur after a topology change and therefore show the
system that there is a new device. Why does it just work sometimes?

Following a bus reset the system (Windows) queries the nodes on the
bus to identify the devices. Only nodes that respond with suitable
information will cause the system to attempt to to load a driver. I’ve
only observed what you describe when either my device is not working
correctly or, when I’ve had some communication problem
causing a high error rate. Try pushing the cable in and out of the
connectors a few times.

Robert Newton