Enabling interrupts and touching hardware registers in Do0Entry

HI,

In my serial port driver i am mapping the hardware resources in PrepareHardware and accessing the device registers in D0Entry. I am enabling the device interrupts by writing to a register in D0Entry.

But when i update my serial driver with a new driver, i occasionally see a crash. Below is the crash dump.

ADDITIONAL_DEBUG_TEXT:
Use '!findthebuild' command to search for the target build information.
If the build information is available, run '!findthebuild -s ; .reload' to set symbol path and load symbols.

FAULTING_MODULE: 83412000 nt

DEBUG_FLR_IMAGE_TIMESTAMP: 51c50c11

READ_ADDRESS: unable to get nt!MmSpecialPoolStart
unable to get nt!MmSpecialPoolEnd
unable to get nt!MmPoolCodeStart
unable to get nt!MmPoolCodeEnd
00000019

CURRENT_IRQL: 0

FAULTING_IP:
nt!READ_REGISTER_UCHAR+4
8344a5b4 8a02 mov al,byte ptr [edx]

DEFAULT_BUCKET_ID: VISTA_DRIVER_FAULT

BUGCHECK_STR: 0xA

LAST_CONTROL_TRANSFER: from 8344a5b4 to 83452b7f

STACK_TEXT:
WARNING: Stack unwind information not available. Following frames may be wrong.
83539abc 8344a5b4 badb0d00 00000019 86e45502 nt!Kei386EoiHelper+0x28b7
83539b5c 8c148637 78d53668 00000000 87683284 nt!READ_REGISTER_UCHAR+0x4
83539b78 8344bbac 87683280 872ac990 83539c20 Wdf01000!FxInterrupt::_InterruptThunk+0xa7
00000000 00000000 00000000 00000000 00000000 nt!KeSynchronizeExecution+0x15c

STACK_COMMAND: kb

FOLLOWUP_IP:
Wdf01000!FxInterrupt::_InterruptThunk+a7
8c148637 8ad8 mov bl,al

SYMBOL_STACK_INDEX: 2

SYMBOL_NAME: Wdf01000!FxInterrupt::_InterruptThunk+a7

FOLLOWUP_NAME: MachineOwner

MODULE_NAME: Wdf01000

IMAGE_NAME: Wdf01000.sys

BUCKET_ID: WRONG_SYMBOLS

Followup: MachineOwner

I am sure that i am not accessing any NULL pointer any where in my driver code.
I am trying to acquire lock to synchronize with service routine and accessing device registers through READ_REGISTER_UCHAR at some point in the driver. Perhaps this c

Is it Ok to enable interrupts in D0Entry? Is it better to move it to some other call back which gets invoked later than D0ENtry?

Just for additional information, things are working fine when i uninstall the driver and install it again. Driver is crashing only during the update operation.

xxxxx@gmail.com wrote:

In my serial port driver i am mapping the hardware resources in PrepareHardware and accessing the device registers in D0Entry. I am enabling the device interrupts by writing to a register in D0Entry.

Why? This is exactly what the EvtInterruptEnable callback is for. The
callback will only be called when the system is ready to handle
interrupts. Then you disable the device interrupts in EvtInterruptDisable.

STACK_TEXT:
WARNING: Stack unwind information not available. Following frames may be wrong.
83539abc 8344a5b4 badb0d00 00000019 86e45502 nt!Kei386EoiHelper+0x28b7
83539b5c 8c148637 78d53668 00000000 87683284 nt!READ_REGISTER_UCHAR+0x4
83539b78 8344bbac 87683280 872ac990 83539c20 Wdf01000!FxInterrupt::_InterruptThunk+0xa7
00000000 00000000 00000000 00000000 00000000 nt!KeSynchronizeExecution+0x15c

Note the garbage address passed to READ_REGISTER_UCHAR – 78D53668.
That’s the root cause of your crash, probably because you have enabled
interrupts before things are really ready for them.

Is it Ok to enable interrupts in D0Entry? Is it better to move it to some other call back which gets invoked later than D0ENtry?

No. Do it in EvtInterruptEnable.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Tim,

I am writing two drivers here actually… One is the function driver for the controller which hosts my ports. THis acts as a bus driver for the ports and does hardware resource allocation and resource arbitration for the ports.

Second is a function driver for the ports which actually maps the hardware resoruces for the ports. The controller driver receives the interrupts and it dispatches these interrupts to these ports.

Hence my controller driver receives EvtInterruptEnable call back but my port driver doesn’t receive it. IN this case, what can i do in my serial port driver to postpone enabling of interrupts from DoEntry?

Can i have the a call back in the serial port driver that could be called from EvtInterruptEnable in the controller driver?

Everything you have said in the past indicates the ports look like standard
16550 UART’s. If this is the case, why are you writing your own port driver
in the first place? Even if this is not, you should have an ability to
enable/disable an interrupt for a given port, and you use that in the port
driver.

Don Burn
Windows Filesystem and Driver Consulting
Website: http://www.windrvr.com

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@gmail.com
Sent: Tuesday, July 15, 2014 1:09 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Enabling interrupts and touching hardware registers in
Do0Entry

Tim,

I am writing two drivers here actually… One is the function driver for the
controller which hosts my ports. THis acts as a bus driver for the ports
and does hardware resource allocation and resource arbitration for the
ports.

Second is a function driver for the ports which actually maps the hardware
resoruces for the ports. The controller driver receives the interrupts and
it dispatches these interrupts to these ports.

Hence my controller driver receives EvtInterruptEnable call back but my port
driver doesn’t receive it. IN this case, what can i do in my serial port
driver to postpone enabling of interrupts from DoEntry?

Can i have the a call back in the serial port driver that could be called
from EvtInterruptEnable in the controller driver?


NTDEV is sponsored by OSR

Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev

OSR is HIRING!! See http://www.osr.com/careers

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

xxxxx@gmail.com wrote:

I am writing two drivers here actually… One is the function driver for the controller which hosts my ports. THis acts as a bus driver for the ports and does hardware resource allocation and resource arbitration for the ports.

Second is a function driver for the ports which actually maps the hardware resoruces for the ports. The controller driver receives the interrupts and it dispatches these interrupts to these ports.

Hence my controller driver receives EvtInterruptEnable call back but my port driver doesn’t receive it. IN this case, what can i do in my serial port driver to postpone enabling of interrupts from DoEntry?

Can i have the a call back in the serial port driver that could be called from EvtInterruptEnable in the controller driver?

Do you have one interrupt per port? Theoretically, what you’d want to
do is have the bus driver divvy up the resources and hand them to the
port function driver using the regular PNP resource mechanism. Then,
each port function driver would own its interrupt. It would get
EvtInterruptEnable calls, and it would get its own ISR calls.

If you can’t do that, then you have to simulate it. If the interrupt is
owned by the bus driver, then the port function drivers can’t do
anything with the interrupts without either checking with or being
called by the bus driver.

So, your description is correct. The EvtInterruptEnable callback in the
bus driver is going to have to call some callback in the port driver.
You must already be thinking about how to do this, since you’ll have to
do the exact same thing for the ISR and DPC.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

you have received numerous replies about using the correct Evt callbacks.
But in reading your message here, two things jump out at me: first, you
don’t have the right symbols, and second, you removed critical information
from the dump. Where is the register display? I couldn’t tell why the
instruction failed until I could see what is in EDX. So why did you think
this was unimportant. Note that the most common cause is a NULL pointer;
the second-most-common cause is an invalid address, characterized as a
stale pointer (a pointer which is no longer valid), a garbage pointer (not
yet initialized), and a not-yet-valid pointer (the value has been
correctly computed, but has not yet been mapped). Using D0Entry is
certainly suspect; I don’t know when the IRP_MJ_POWER comes relative to
the IRP_MJ_PNP, but it is the PNP that establishes the validity of the
address, and the Evt functions will not be called until it is valid to
call them. So redo it as others have already suggested, and in the
future, make sure you include the ENTIRE !analyze -v output. If you don’t
know what the output means, you are most likely going to edit out critical
information, as you did here. And make sure you have the correct symbols;
if you have live Internet connectivity, link your debugger to the
Microsoft Symbol Server.
Joe

HI,

In my serial port driver i am mapping the hardware resources in
PrepareHardware and accessing the device registers in D0Entry. I am
enabling the device interrupts by writing to a register in D0Entry.

But when i update my serial driver with a new driver, i occasionally see a
crash. Below is the crash dump.

ADDITIONAL_DEBUG_TEXT:
Use ‘!findthebuild’ command to search for the target build information.
If the build information is available, run ‘!findthebuild -s ; .reload’ to
set symbol path and load symbols.

FAULTING_MODULE: 83412000 nt

DEBUG_FLR_IMAGE_TIMESTAMP: 51c50c11

READ_ADDRESS: unable to get nt!MmSpecialPoolStart
unable to get nt!MmSpecialPoolEnd
unable to get nt!MmPoolCodeStart
unable to get nt!MmPoolCodeEnd
00000019

CURRENT_IRQL: 0

FAULTING_IP:
nt!READ_REGISTER_UCHAR+4
8344a5b4 8a02 mov al,byte ptr [edx]

DEFAULT_BUCKET_ID: VISTA_DRIVER_FAULT

BUGCHECK_STR: 0xA

LAST_CONTROL_TRANSFER: from 8344a5b4 to 83452b7f

STACK_TEXT:
WARNING: Stack unwind information not available. Following frames may be
wrong.
83539abc 8344a5b4 badb0d00 00000019 86e45502 nt!Kei386EoiHelper+0x28b7
83539b5c 8c148637 78d53668 00000000 87683284 nt!READ_REGISTER_UCHAR+0x4
83539b78 8344bbac 87683280 872ac990 83539c20
Wdf01000!FxInterrupt::_InterruptThunk+0xa7
00000000 00000000 00000000 00000000 00000000
nt!KeSynchronizeExecution+0x15c

STACK_COMMAND: kb

FOLLOWUP_IP:
Wdf01000!FxInterrupt::_InterruptThunk+a7
8c148637 8ad8 mov bl,al

SYMBOL_STACK_INDEX: 2

SYMBOL_NAME: Wdf01000!FxInterrupt::_InterruptThunk+a7

FOLLOWUP_NAME: MachineOwner

MODULE_NAME: Wdf01000

IMAGE_NAME: Wdf01000.sys

BUCKET_ID: WRONG_SYMBOLS

Followup: MachineOwner

I am sure that i am not accessing any NULL pointer any where in my driver
code.
I am trying to acquire lock to synchronize with service routine and
accessing device registers through READ_REGISTER_UCHAR at some point in
the driver. Perhaps this c

Is it Ok to enable interrupts in D0Entry? Is it better to move it to some
other call back which gets invoked later than D0ENtry?


NTDEV is sponsored by OSR

Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev

OSR is HIRING!! See http://www.osr.com/careers

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

But if the “bus driver” owns the interrupt, why do the port function
drivers care at all? They could use completion routines to handle the
completion of the IRP from the lower-level drivers. Otherwise, this turns
into the “How can I get the USB interrupt in my function driver?”
question. So, if the card driver gets one interrupt for all ports, the
“callback” routine is the completion routine.
Joe

xxxxx@gmail.com wrote:
> I am writing two drivers here actually… One is the function driver for
> the controller which hosts my ports. THis acts as a bus driver for the
> ports and does hardware resource allocation and resource arbitration for
> the ports.
>
> Second is a function driver for the ports which actually maps the
> hardware resoruces for the ports. The controller driver receives the
> interrupts and it dispatches these interrupts to these ports.
>
> Hence my controller driver receives EvtInterruptEnable call back but my
> port driver doesn’t receive it. IN this case, what can i do in my serial
> port driver to postpone enabling of interrupts from DoEntry?
>
> Can i have the a call back in the serial port driver that could be
> called from EvtInterruptEnable in the controller driver?

Do you have one interrupt per port? Theoretically, what you’d want to
do is have the bus driver divvy up the resources and hand them to the
port function driver using the regular PNP resource mechanism. Then,
each port function driver would own its interrupt. It would get
EvtInterruptEnable calls, and it would get its own ISR calls.

If you can’t do that, then you have to simulate it. If the interrupt is
owned by the bus driver, then the port function drivers can’t do
anything with the interrupts without either checking with or being
called by the bus driver.

So, your description is correct. The EvtInterruptEnable callback in the
bus driver is going to have to call some callback in the port driver.
You must already be thinking about how to do this, since you’ll have to
do the exact same thing for the ISR and DPC.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.


NTDEV is sponsored by OSR

Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev

OSR is HIRING!! See http://www.osr.com/careers

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer