Port driver interrupt is invalid when info is passed in from bus


I'm practice the kmdf driver for serial but encountered a big difficulty.

I hope to know why my legacy interrupt does not work properly on the port driver with the bus.

My architecture is a bus which static generated serial port.

I've tried to implement port driver directly without the bus.

And the interrupt is worked fine.

Then I tried to write a bus driver and changed the SerialMapHWResources part of the original port driver by pass the value through the bus.

Interrupt Info get error and don't enter the SerialEvtInterruptEnable & SerialEvtInterruptDisable since I add the port driver into the architecture

Btw, I get the memory by SerialMapHWResources at bus driver and pass the irql, vector, affinity to the port driver's hardware prepare callback.

I'd tried to assign the parameter to the irq when WdfInterruptCreate, but I can't find the method to do this.

Can somebody tell me how to make the interrupt work in my port driver?

Many thanks.

Best Regards,
Luke Chen

I think I may not have explained the problem clearly.
Let me explain it again~


Serial Driver with legacy Interrupt

A bus static creates 4 ports

Refer to Windows-driver-samples\general\toaster\toastDrv\kmdf\bus\static, and add pnpPowerCallbacks.EvtDevicePrepareHardware = BusEvtPrepareHardware callback to obtain the Controller, TrIrql, Affinity, TrVector and other values ​​through WdfCmResourceListGetDescriptor

The port driver refers to Windows-driver-samples\serial\serial, puts the InterruptCreate in SerialEvtDeviceAdd, uses pnpPowerCallbacks.EvtDevicePrepareHardware in the same way and replaces the SerialMapHWResources action with the value obtained from the bus.

interruptConfig.EvtInterruptDisable = SerialEvtInterruptDisable
interruptConfig.EvtInterruptEnable = SerialEvtInterruptEnable

Neither of these two callbacks can be entered. Using WdfInterruptGetInfo, I found that except Size, which is 64, the rest have no value.

I would like to ask what should be done if this architecture wants to establish an Interrupt on each port driver? Maybe which sample can I refer to?
(If SerialMapHWResources is moved directly from bus driver to the port driver, both PResList and PTresList will be 0 and cannot operate normally)

Many thanks.

I'm confused. What is the hardware here? If this is a PCI device, then the interrupt should have been allocated to your bus driver amd discovered in EvtDeviceAdd. If this is a legacy serial port that doesn't use standard I/O port and IRQ numbers, then you need to modify your ACPI DSDT to advertise the device and its capabilities, and again the operating system will assign the interrupt to your bus driver.

There's only one interrupt, so you need to come up with your own scheme to "sublet" the interrupt to your upper-level drivers.

If this is a virtual bus, then you can't use the interrupt mechanism.

Right. And to be clear, there is no public mechanism to do what's called "second level dispatching" for interrupts in Windows (Windows HAS one, just nobody's exposed it for use by 3rd party drivers). So, there's no public Windows-provided way for your bus driver which, when it gets an interrupt, then passes that interrupt along to one of his child devices.

As Mr. @Tim_Roberts said, if you want to do this, you'll need to implement it yourself. Sadly.

Hi Tim, Peter,

Very thanks for information.

Sorry for the uncompleted information. The hardware is PCI device.

As you said.
The interrupt have been allocated to bus driver and discovered in EvtDeviceAdd.

So when I got only port driver without bus. I can generate my interrupt successfully and use it.

But when the bus came into the architecture, my port driver can't get the resource by WdfCmResourceListGetCount and WdfCmResourceListGetDescriptor even I delete this part from bus.
So that the interrupt I generated through wdfInterruptCreate has no effect.

If all I expect is the interrupt can be used by the child port driver even if it is not create on the port driver.
Is there have any suggestions or methods that I can have a try?

Many thanks~

Best Regards,
Luke Chen

What's happening is the PCI bus driver is assigning the device's resources to your bus driver, because PCI.sys considers your bus driver to be the FUNCTION driver for the enumerated device. Because the resources are assigned to your bus driver they cannot be claimed by any other driver in the system, whether your bus driver claims them or not. This is how Windows works.

I'm not sure WHY you want/need a bus driver in your case. I assume you have a good reason. In the case, you're only option is to create a private interface between your port and bus driver where the port driver registers his ISR with your bus driver, and the bus driver calls that ISR when it gets an interrupt from the device.

This is what Mr. Roberts was alluding to in his initial reply.

Hi Peter,

Thank you for your information again.

I am a newbie in WDF, so I tried it for a few days with no results.
I tried some of the APIs I found from MSDN but I still can't get the interrupt object of the bus driver on the port driver side.

Could you give me more hints or some reference APIs that might be useful for "create a private interface between your port and bus driver" ?

Thank you so much.

Well, one possible alternative is here described here:
Using Bus Interfaces for Driver to Driver Communication – OSR

1 Like