Windows System Software -- Consulting, Training, Development -- Unique Expertise, Guaranteed Results

Before Posting... Please check out the Community Guidelines in the
Announcements and Administration Category, below.

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

Comments

  • Tim_RobertsTim_Roberts Posts: 12,568
    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.

    Tim Roberts, [email protected]
    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
  • Tim_RobertsTim_Roberts Posts: 12,568
    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.

    Tim Roberts, [email protected]
    Providenza & Boekelheide, Inc.

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!