Driver starts only once

Hello,

I’m working on updating an old WDM bus-driver for some serially connected hardware, where on a newer system this hardware is connected via UART instead of a legacy COM port.
I’ve come so far that I can install the driver when Windows is running, and everything is working just fine.

Although, if I reboot Windows, the driver doesn’t work any longer. The driver gets loaded and sends some stuff on the UART, but very soon a surprise removal happens and the driver is not loaded again after that.
It is not a general issue during boot though. If I uninstall the driver, then the UART device is also uninstalled and requires a reboot to get back. If I then reinstall my driver (before rebooting), the driver doesn’t start immediately (obviously). But when rebooting then, the driver loads just fine.
The driver enumerates two child devices, but none of them have a driver installed during these tests (and installing their drivers makes no difference). And after the surprise removal, none of the child nor parent drivers are present in device manager.

I don’t really know where to look anymore. Does anyone have any ideas what might cause surprise removal of a UART device during boot?

As an experiment, I’ve also made a small dummy driver using WDF, that uses the same UART. That driver loads just fine, every time. So the UART in itself seems fine. But I really don’t want to rewrite the entire driver.

I would do the driver rewrite, and actually do the rewrite using KMDF instead of WDF. Why? Simply, you’re going to spend hours/ days/ months trying to fix something that at the end of the day is still old legacy potentially buggy code. It’s already misbehaving once, who is to say it won’t do something else in a few weeks?

Figure out the business logic of the legacy driver, spend a day whipping out a KMDF framework (there are lot’s of good samples to start from), drop in the business logic and after spending a few weeks you’re done and can focus on other things …

So you are porting some device from a serial port to a UART? What? UARTs control COM ports, so I must be missing something

based on your description, you have some kind of reference counting problem. Possibly involving power management. This is the part that KMDF handles automatically for you as well as the most technically challenging part - the state machine has hundreds of states. As you have observed, that code is solid and I recommend that unless you have a compelling reason not to use it, you will spend less time porting the device specific logic to KMDF, than you would trying to re-implement KMDF

Yeah, maybe you´re right about porting to KMDF.

Actually, I began working on a KMDF driver (the “small dummy driver”), and got a fair bit on the way.
But then I got stuck doing that as well. But, maybe I should start another thread to try solving that issue instead.

It’s just so annoying that this old driver, which has been working flawlessly for many, many years, seems to be so close to working. I’m sure it’s just a tiny detail causing the issue.

My main job these days is reviewing the code of others. I can’t tell you how many times people have come to me saying something to the effect ‘my code works perfectly except for one tiny flaw that I can’t quite find’. It is almost never one small thing. Most often the one observable problem is the tip of an iceberg of other problems that just haven’t come up yet

I have no knowledge in your specific case, but in general given the choice between a well tested and vendor supported framework, versus rolling my own, versus using someone else’s home brew solution from a decade ago the choice seems clear

2 Likes

on a newer system this hardware is connected via UART instead of a legacy COM port.

UART instead of COM port? How it is connected to the PC? Is your driver a bus or a function driver?

@Pavel_A said:

on a newer system this hardware is connected via UART instead of a legacy COM port.

UART instead of COM port? How it is connected to the PC? Is your driver a bus or a function driver?

My best guess would be, since it is a common strategy for specialized hardware vendors: This external hardware has an RS232 interface and was slightly modernized by integrating a USB/serial adapter chip into the housing. So now physically it looks like a USB device, but it is still addressed through a COM port.

And, still going on with my guesswork, whatever problems the “old WDM bus driver” is facing, their most likely root cause are subtle differences in the way the serial API is implemented in the driver supplied by the adapter chip vendor, when compared to the orginal Serial.sys in Windows.

@Pavel_A said:

on a newer system this hardware is connected via UART instead of a legacy COM port.

UART instead of COM port? How it is connected to the PC? Is your driver a bus or a function driver?

All of this is run on a custom PC, in a somewhat isolated environment.
So the device which this driver is for, is hard wired to a UART/COM port on a Q7 module.

Previously, the hw has been connected to a standard Intel 16550 COM port, enumerated by windows as COMx using built in drivers.
Our driver was made as a autostarting legacy driver, which used IoRegisterPlugPlayNotification to get notified when a Comport is enumerated, and used that to get and open the right port (this is probably a pretty bad way of doing it all, but that’s how it was originally done some 20 odd years ago and has been working ever since).

Now, on a new model PC, there is no 16550 COM port. Instead it has a Intel Serial IO UART (integrated into the Apollo Lake SoC).
There really isn’t much difference, except from that the Serial IO UART doesn’t automatically enumerate as a COM port. Thus, the old way doesn’t work.
The only things I’ve had to change, is going from legacy driver into PnP driver, and then how the IO device handler is obtained in the driver. Otherwise it’s pretty much the same.

I’d guess that the fact that it is now a PnP driver instead of legacy, is the main reason for why it doesn’t work.

Whether it is a bus or function driver; I don’t understand the question.
From what I’ve understood, a bus driver is simply a function driver which enumerates child devices. Which our driver does, so I guess it’s a bus driver.

Anyways, I’ve taken your advice and gone back to port the driver to KMDF.
More on that in another thread.