KMDF DMA ISR not called 2nd time

I am writing a KMDF DMA driver (again based on PLX9x5x sample - aren’t they alll?) and I am seeing the following issue…

1/ In the Request handler (ReadFile, WriteFile, DeviceIoControl) I initialize and execute the transaction (WdfDmaTransactionInitialize, WdfDmaTransactionExecute)

2/ In the EvtProgramDma callback I acquire the interrupt lock and program for DMA xfer:
a. DMA 0 Mode Register (DMAMODE0)
b. Interrupt CSR Register (INTCSR)
c. DMA 0 Descriptor Pointer Register (DMADPR0)
d. DMA 0 CSR Register (DMACSR0)

3/ The ISR gets called, and here I:
a. read Interrupt CSR register (INTCSR)
b. clear interrupt (DMACSR0)
c. queue DPC

4/ In DPC I *think* I am re-enabling interrupts:
a. INTCSR &= ~DMA0_ACTIVE
b. INTCSR |= PCI_IRQ_ENABLE
c. DMACSR0 = 0
d. if transactionComplete, call Request Completion function, where I release DMA transaction object

My test application sends down one request at a time, and this all goes well for 1st invocation.

The issue occurs if I then try to send down another request:
The steps above are repeated, but after programming the hardware for DMA xfer in the EvtProgramDma callback (step 2/ above), the subsequent ISR never gets called?!

If I send down any more requests, BSOD results with invalid operation on DMA transaction object not in correct state, as I am trying to initialize before the previous object was released.

I notice the PLX9x5x sample in its DPC merely clears INTCSR and DMACSR0 in its device extension, but does not perform any actual register I/O, e.g. WRITE_PORT_ULONG.

Does anyone have an insight as to why the ISR is not called again?

Thanks!
MarkH

xxxxx@knowwareinc.com wrote:

I am writing a KMDF DMA driver (again based on PLX9x5x sample - aren’t they alll?) and I am seeing the following issue…

1/ In the Request handler (ReadFile, WriteFile, DeviceIoControl) I initialize and execute the transaction (WdfDmaTransactionInitialize, WdfDmaTransactionExecute)

2/ In the EvtProgramDma callback I acquire the interrupt lock and program for DMA xfer:
a. DMA 0 Mode Register (DMAMODE0)
b. Interrupt CSR Register (INTCSR)
c. DMA 0 Descriptor Pointer Register (DMADPR0)
d. DMA 0 CSR Register (DMACSR0)

You should not need to tweak INTSCR in EvtProgramDma.  The global
interrupt gets enabled in EvtInterruptEnable and remains so until
EvtInterruptDisable is called.

 

3/ The ISR gets called, and here I:
a. read Interrupt CSR register (INTCSR)
b. clear interrupt (DMACSR0)
c. queue DPC

Right.

 

4/ In DPC I *think* I am re-enabling interrupts:
a. INTCSR &= ~DMA0_ACTIVE
b. INTCSR |= PCI_IRQ_ENABLE
c. DMACSR0 = 0
d. if transactionComplete, call Request Completion function, where I release DMA transaction object

You should not need to touch any hardware registers in your DPC. 
DMA0_ACTIVE and DMA1_ACTIVE are read-only status bits.  They only tell
you if an interrupt is pending.  The interrupt itself was cleared in the
ISR when you cleared the bit in DMACSR0.  If you clear it again, you
open up the possibility that you are clearing an interrupt that you have
not handled yet.  Do you have the data book for your chip?

I notice the PLX9x5x sample in its DPC merely clears INTCSR and DMACSR0 in its device extension, but does not perform any actual register I/O, e.g. WRITE_PORT_ULONG.

Right.  It’s recording its internal notion of the register states, but
the physical manipulation was all done in the ISR.


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

Thanks, Tim for your reply.

It makes sense not to alter INTCSR after EvtInterruptEnable. I removed setting any registers in my DPC, and after spending all day on this, I still am not receiving subsequent interrupts.

However, I did discover one thing interesting …

I notice that while in EvtProgramDMA the 2nd time that bit 14 of INTCSR has been set -
this is *PciAbortIntActive*.

Do you (or anyone out here, I guess) know what could be the cause for that being set?
I have not yet been able to figure this out.

Thanks again!
MarkH

xxxxx@knowwareinc.com wrote:

I notice that while in EvtProgramDMA the 2nd time that bit 14 of INTCSR has been set -
this is *PciAbortIntActive*.

Do you (or anyone out here, I guess) know what could be the cause for that being set?
I have not yet been able to figure this out.

I’ll repeat my previous question:  do you have the data book for the
chip you are using, or are you shooting in the dark?  Sixty seconds with
Google led me to a PLX 9656 data book.   It says that bit indicates that
a “PCI Master or Target Abort” occurred, and section 3.4.1.11 discusses
Master/Target Aborts.  It generally means you’re talking to a device
that is non-responsive.

In the meantime, you should triple-check all of your descriptors to make
sure you’re doing what you think you are doing.


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