hi
This is regard to my virtual serial usb drivers that exposes 4 virtual com ports...I'm having a problem with getting my bus driver to unload after a usb device reset, which corresponds to a surprise remove. The problem only occurs if I run a testapp that accesses one of the virtual com ports. In one scenario (killing the app with control-c) successfully results in an unload but in another scenario (scenario #2) below, it doesn't.
After removing any code tracking how many children the bus driver creates (it always creates 4) when the usb device is plugged in, I got past my crashing bug which I you folks responded with tips in the past, however I'm still having a problem if a simple testapp has the virtual com port open (opened without FILE_FLAG_OVERLAPPED) and is trying to write (sychronously) to a virtual com port when I reset the usb device. After the reset, I hit control-c to kill the app, but the bus driver doesn't unload because it only destroys 3 out of the 4 child PDOs it created. It doesn't delete the child PDO corresponding to the virtual com port that the test app was using.
The wrench thrown in all of this is that if the test app has the com port open during the reset but isn't doing WriteFiles() to the virtual com port at the time (and after) I reset the usb device and then control-c the app to kill it, then the bus driver will unload after it destroys all 4 child PDOs it created.
I do not understand why the drivers unload OK in one case but not in the other, considering that in both cases, the com port is opened by the test app.
The test app is very simple - a little console app that does a CreateFile for a hard-coded com port name.
Also, under normal circumstances, if I reset the board, the drivers will get unloaded and loaded back up and usb works ok.
Scenario #1 (works)
- plug in USB device
- start up app that opens the first virtual com port and does a 8 byte write (sanity check) and then sleeps infinitely (so it's not accessing the port when the reset in step #3 occurs)
- reset the usb device (it has a reset button on it)
- in the surprise remove handler, the function driver for children unexposes the 4 ports -- deletes the external naming for the COM port (similar to what is done in the DDK serial driver in SerialDoExterternalNaming)
- reset kicks in so that the bus driver re-creates 4 child pdos again, and the COM ports get exposed in the start up code for the function driver for the children.
- stop the app (control-c)
At this point, the bus driver destroys all 4 child PDOs as it should and the bus and function driver for the children get unloaded.
Scenario #2 (doesn't work)
Repeat of Scenario #1 expect that the test app is continually trying to Write 8 bytes to the first virtual serial port (it sits in a while looping sleeping for 250 ms and then does a WriteFile call). As shown by my testapp's debug output, before the reset, the write calls succeed. After the reset, they always fail with error 0x16 (the device does not recognize the command), which is what I expect.
However, the problem is that after I stop the app in step 6 above in Scenario #2, the bus driver only destroys 3 of the 4 child PDOs. The one not getting destroyed corresponds to the one that wasn't destroyed is the one that the app was accessing.
Why isn't the child PDO not getting destroyed? I assume this is the root of my problem of the bus driver not getting unloaded and why subsequent resets leave me unable to access the usb device until I reboot my target machine.
Is there a problem because I re-use the same hardware ID and instance IDs in the bus driver?
My app spits out a debug message about the result of the WriteFile() calls - so it doesn't seem like a pending IRP could be a problem.
If there was a problem with re-exposing the same COM port (e.g. COM8) again or re-using the same hardware ID and instance IDs in the bus driver, while the testapp had the com port open during the reset, then how come I don't have a problem for scenario #1 (in which I don't try to do a WriteFile() after the reset).
thanks in advance
----- Original Message -----
From: Doron Holanmailto:xxxxx
To: Windows System Software Devs Interest Listmailto:xxxxx
Sent: Wednesday, November 30, 2005 11:15 PM
Subject: RE: [ntdev] driver unload problem with unplugged USB device
I meant 2 instances of the parent FDO being loaded for the same piece of hardware. One will be in the surprise removed state, the other will be in the running state. As for how many ports you expose, that is not relevant. My point is that if you to already handle the case where there are 2 instances, one running, one surprise removed, handling 2 instances which are both running at the same time b/c 2 of the same piece of hw is attached will work as well.
d
From: xxxxx@lists.osr.commailto:xxxxx [mailto:xxxxx@lists.osr.com] On Behalf Of S. Drasnin
Sent: Wednesday, November 30, 2005 11:10 PM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] driver unload problem with unplugged USB device
oh, I think I misunderstood. When you said 2, you meant 2 virtual com ports, right?
I thought you meant 2 usb devices that got plugged in at the same time....which won't happen. The usb device being plugged in is what causes my bus driver to get loaded.
There won't be 2 of these usb devices.
Yes, I'm currently hosed if I have one or more virtual com ports open by an app/apps when I unplug the device.
-s
----- Original Message -----
From: Doron Holan
To: Windows System Software Devs Interest List
Sent: Wednesday, November 30, 2005 10:46 PM
Subject: RE: [ntdev] driver unload problem with unplugged USB device
But with the way surprise remove works wrt to PDOs, it does have to b/c you can have N instances running where N-1 are in the surprise removed state.
d
From: xxxxx@lists.osr.commailto:xxxxx [mailto:xxxxx@lists.osr.com] On Behalf Of S. Drasnin
Sent: Wednesday, November 30, 2005 10:07 PM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] driver unload problem with unplugged USB device
Thanks for the info - will read up on it in Oney's book as well.
BTW, the design doesn't need to support more than 1 device being plugged in, fortunately.
----- Original Message -----
From: Doron Holan
To: Windows System Software Devs Interest List
Sent: Wednesday, November 30, 2005 9:42 PM
Subject: RE: [ntdev] driver unload problem with unplugged USB device
Your run your surprise remove handling code in IRP_MN_SURPRISE_REMOVE.
My point about separating the counts is that if the device is plugged in, the previous FDO's count should not have any affect on the newly plugged in FDO. If you are a bus driver, your driver must handle the fact that it can have orphaned PDOs and that the parent FDO can reappear. It is a fact of life in WDM and you must properly reenum your PDOs. When the PDOs are reenumerated, you should use the same PortIDs as you did previously. It's OK to reuse the ID as long as the previous ID has been surprise removed.
Based on you current design, what happens if someone plugged 2 of your devices? In your current design, the 2nd instance would not start properly.
You can detect a hung app if you have definitive behavior expected out of that app and you don't get it....BUT, that is still a bad idea b/c the app could be under a UM debugger and then your driver would start failing when the app was being debugged. The serial interface is not such an interface though, you can't detect it. A driver cannot kill a hung app, all it can do is complete all pending io or make all pending io cancelable.
If no application has a handle open to your driver, the stack will be surprise removed and then removed and then your driver will unload if that is the last parent FDO that your driver is assigned to. The whole point of the surprise remove state is that you are in a state where your device is gone, but the device is still hanging around for whatever reason. You should read oney's book, I think he makes most of this pretty clear.
d
From: xxxxx@lists.osr.commailto:xxxxx [mailto:xxxxx@lists.osr.com] On Behalf Of S. Drasnin
Sent: Wednesday, November 30, 2005 8:55 PM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] driver unload problem with unplugged USB device
hi
This might be a question with an obvious answer, but how do know when I need to run the surprise remove handler? If keep the count in the parent FDO and another parent FDO is created on plug in, how do I get access to that count? Or do you think I need to do something else to detect when I need to do the recovery mechanism.
I can also detect a problem in the children driver because the bus driver stores a PortID (really an index starting at 0 for the 1st child) in each of the child PDO. If the number is too big (>= 4) I can tell in the driver for the children objects that I'm hosed. This is the way my code was operating before I changed the bus driver to fail add device when the count was too big (>= 4) today to see what would happen with the repro scenario.
The other question I had (unrelated to your recommendation) is a general one - do drivers ever detect they have an open handle issue due to a hung app and if so, what kind of recovery mechanisms can be implemented, and what/how do they do it? Maybe a driver could force itself to get unloaded after doing some sort of clean up. Then again, maybe it's not worth it - and people just reboot...
The other thing I didn't try was what would happen if I killed the app before I re-plugged in the device. Would the I/O manager try then to clean up and would my driver then get unloaded properly, followed by the unload of the bus driver?
Thanks (again) in advance and very knowledgeable answers.
----- Original Message -----
From: Doron Holan
To: Windows System Software Devs Interest List
Sent: Wednesday, November 30, 2005 5:11 PM
Subject: RE: [ntdev] driver unload problem with unplugged USB device
Your driver will remain loaded until the last handle is closed in a surprise remove scenario. You will remain in memory until the handle is closed. Yes, the I/O manager is enforcing this behavior.
The correct way to handle this is to remove the global count of PDOs. I would keep the count local to the FDO, but I am not sure what good that would do since you have a hardcoded number of children. Remember, when you get plugged in again, this is a new parent FDO being created.
You have additionally things to worry about here. In your surprise remove handler, you need to delete the COM name symbolic link for the PDO (Assuming the PDO itself is creating the symbolic link, if another FDO is being loaded on top of your enumerated PDO, then that FDO must delete the symbolic link in its surprise remove handler) IIF the symbolic was previously created (Since the PDO can get multiple surprise removes since surprise remove is not necessarily due to the PDO being reported missing). You have to delete the sym link before the surprise remove irp gets back to the pnp manager b/c after it returns, a new PDO can be enumerated by the new instance of your new FDO and when the new PDO enumerates, you want it to be able to expose the same COM name as it previously did w/out conflict in the dos device namespace.
d
From: xxxxx@lists.osr.commailto:xxxxx [mailto:xxxxx@lists.osr.com] On Behalf Of S. Drasnin
Sent: Wednesday, November 30, 2005 4:55 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] driver unload problem with unplugged USB device
hi
I'm having a problem I hope you gurus can help me with.
I have a virtual serial over USB driver. My bus driver gets loaded when a USB device gets plugged in and N (N = 4) child PDOs get created, one for each virtual com port I'm trying to expose. I run into a problem with the following scenario:
1) USB device gets plugged in. Bus driver loads, driver for child PDOs loads (things are up and running)
2) App opens one of the ports to do writes/reads
3) Unplug USB device
Debug output shows the cleanup is occurring in the child PDO driver but the driver doesn't unload.
4) Wait 15 seconds or more (the point is that nothing changes)
5) Plug usb device back in
6) My bus driver's add device routine gets called but I fail it because I have a static variable tracking how many child PDOs I have. (I do not create another PDO)
I return false from this add device routine.
At this point, things are hosed. Closing down the app or unplugging and plugging in the device doesn't help. The bus driver has a yellow circle with an exclamation point in it. To recover, you have to reboot.
If I don't have step #2, both drivers unload ok and then load back up fine when I plug the board back in.
(1) What is the correct way to handle this situation?
(2) Also, in general, what happens if you have a usb function driver with a open handle to the device when the device gets unplugged? Does the driver ever get unloaded? If so, what is the mechanism by which the unload happens? Is it the OS doing it? The driver?
much thanks in advance
---
Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256http:
You are currently subscribed to ntdev as: unknown lmsubst tag argument: ''
To unsubscribe send a blank email to xxxxx@listsosr.commailto:xxxxx
---
Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256http:
You are currently subscribed to ntdev as: unknown lmsubst tag argument: ''
To unsubscribe send a blank email to xxxxx@listsosr.commailto:xxxxx
---
Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256http:
You are currently subscribed to ntdev as: unknown lmsubst tag argument: ''
To unsubscribe send a blank email to xxxxx@listsosr.commailto:xxxxx
---
Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256http:
You are currently subscribed to ntdev as: unknown lmsubst tag argument: ''
To unsubscribe send a blank email to xxxxx@listsosr.commailto:xxxxx
---
Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256http:
You are currently subscribed to ntdev as: unknown lmsubst tag argument: ''
To unsubscribe send a blank email to xxxxx@listsosr.commailto:xxxxx
---
Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256http:
You are currently subscribed to ntdev as: unknown lmsubst tag argument: ''
To unsubscribe send a blank email to xxxxx@listsosr.commailto:xxxxx
---
Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256http:
You are currently subscribed to ntdev as: unknown lmsubst tag argument: ''
To unsubscribe send a blank email to xxxxx@lists.osr.commailto:xxxxx
---
Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256http:
You are currently subscribed to ntdev as: unknown lmsubst tag argument: ''
To unsubscribe send a blank email to xxxxx@lists.osr.commailto:xxxxx</mailto:xxxxx></http:></mailto:xxxxx></http:></mailto:xxxxx></http:></mailto:xxxxx></http:></mailto:xxxxx></http:></mailto:xxxxx></http:></mailto:xxxxx></http:></mailto:xxxxx></http:></mailto:xxxxx></mailto:xxxxx></mailto:xxxxx></mailto:xxxxx></mailto:xxxxx></mailto:xxxxx>