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.

WdfDmaTransactionInitializeUsingRequest & WDFREQUEST

Muthu_KumarMuthu_Kumar Posts: 11
How a WdfRequest should be formatted for WdfDmaTransactionInitializeUsingRequest? I'm using WdfRequestCreate, WdfMemoryCreatePreallocated (with content of a buffer I want to DMA) and WdfIoTargetFormatRequestForWrite.

WdfDmaTransactionInitializeUsingRequest fails with c0000010 (invalid device request).

Comments

  • Muthu_KumarMuthu_Kumar Posts: 11
    verifier log shows " Couldn't retrieve mdl from WDFREQUEST..." Am I missing any steps above?
  • Don_Burn-2Don_Burn-2 Posts: 1,620
    In your first post you referred to WdfRequestCreate, are you trying to do
    this on a Create? There is no MDL on a create call, you really have to be
    doing this operation on one of the calls referred to in the documentation
    https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/content/wdfdma
    transaction/nf-wdfdmatransaction-wdfdmatransactioninitializeusingrequest


    Don Burn
    Windows 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: Sunday, March 04, 2018 3:45 PM
    To: Windows System Software Devs Interest List <xxxxx@lists.osr.com>
    Subject: RE:[ntdev] WdfDmaTransactionInitializeUsingRequest & WDFREQUEST

    verifier log shows " Couldn't retrieve mdl from WDFREQUEST..." Am I missing
    any steps above?

    ---
    NTDEV is sponsored by OSR

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

    MONTHLY seminars on crash dump analysis, WDF, Windows internals and software
    drivers!
    Details at <http://www.osr.com/seminars>;

    To unsubscribe, visit the List Server section of OSR Online at
    <http://www.osronline.com/page.cfm?name=ListServer>;
  • Doron_HolanDoron_Holan Posts: 10,353
    If you are going to use a request in this context it is needs to have a valid current stack location. This means a request presented to you by a queue. A self created request that is formatted has valid NEXT stack location. Since you have the mdl, just call WdfDmaTransactionInitialize

    d

    Bent from my phone
    ________________________________
    From: xxxxx@lists.osr.com on behalf of xxxxx@gmail.com
    Sent: Sunday, March 4, 2018 12:45:09 PM
    To: Windows System Software Devs Interest List
    Subject: RE:[ntdev] WdfDmaTransactionInitializeUsingRequest & WDFREQUEST

    verifier log shows " Couldn't retrieve mdl from WDFREQUEST..." Am I missing any steps above?

    ---
    NTDEV is sponsored by OSR

    Visit the list online at:

    MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers!
    Details at

    To unsubscribe, visit the List Server section of OSR Online at
  • Muthu_KumarMuthu_Kumar Posts: 11
    Hi Doron, the situation is I've to send a large buffer to the device. This buffer has a content read from a file. So, I've to create a request from scratch. Should I rather create a MDL and use WdfDmaTransactionInitialize?
  • Peter_ViscarolaPeter_Viscarola Posts: 6,649
    >the situation is I've to send a large buffer to the device

    So... you don't REALLY need a WdfRequest? You just need a buffer and a DMA Transaction?

    In that case, don't build the Request. Just allocate the buffer and/or the MDL that describes the buffer, and WdfDmaTransactionInitialize.... No Request required.

    Peter
    OSR
    @OSRDrivers

    Peter Viscarola
    OSR
    @OSRDrivers

  • Muthu_KumarMuthu_Kumar Posts: 11
    Thanks Peter. Basic question. Do I need WdfCommonBuffer if MDL is used?
  • Tim_RobertsTim_Roberts Posts: 12,567
    xxxxx@gmail.com wrote:
    > Thanks Peter. Basic question. Do I need WdfCommonBuffer if MDL is used?

    It's not an either/or.  You always need an MDL with
    WdfDmaTransactionInitialize.  The question is, where did the buffer come
    from?  What does the MDL point to?

    If you have been handed a buffer, or you already allocated a buffer,
    then you can create an MDL for it and pass it to WDTI, assuming you can
    do scatter/gather.

    If you can't do scatter/gather, then you'll need a common buffer.

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

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

  • Muthu_KumarMuthu_Kumar Posts: 11
    Tim,

    The buffer is allocated using ExAllocatePoolWithTag and filled with content read from a file.

    mdl is created using IoAllocateMdl call with the above buffer

    mdl is then passed to WDTI

    A commonbuffer for write was allocated earlier in EvtDeviceAdd

    I can't do scatter/gather.

    Now, my confusion, how is commonbuffer is used or connected with WdfDmaTransaction object? In EvtProgramDma, WdfDmaTransactionGetBytesTransferred returns 0 and the commonbuffer is empty.
  • Tim_RobertsTim_Roberts Posts: 12,567
    xxxxx@gmail.com wrote:
    > The buffer is allocated using ExAllocatePoolWithTag and filled with content read from a file.
    >
    > mdl is created using IoAllocateMdl call with the above buffer
    >
    > mdl is then passed to WDTI
    >
    > A commonbuffer for write was allocated earlier in EvtDeviceAdd
    >
    > I can't do scatter/gather.

    Then you should fire your hardware engineers.   No PCIe design in the
    21st Century should ever be built without scatter/gather.


    > Now, my confusion, how is commonbuffer is used or connected with WdfDmaTransaction object? In EvtProgramDma, WdfDmaTransactionGetBytesTransferred returns 0 and the commonbuffer is empty.

    There's no connection between them.  The common buffer is just another
    way of allocating memory.  It only gets used if you use it, and right
    now you aren't using it.

    Here's what happens now.  You have your ExAllocatePoolWithTag (which, I
    hope, is non-paged pool?) buffer, which is not physically contiguous. 
    When you pass that to WdfDmaTransactionInitialize, it's going to call
    your callback multiple times, once for each page in the transfer.  Your
    callback will set up and trigger the DMAs, one page at a time.  As you
    get the DMA completion interrupts, you call
    WdfDmaTransactionDmaCompleted, and KMDF will call your callback again
    for the next page.  The common buffer is not involved.

    As long as you have the common buffer, why don't you just read the file
    into the common buffer?  Then you can do the entire thing as one
    transfer.  With a common buffer, there is really no need to use a
    WdfDmaTransaction at all.

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

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

  • Muthu_KumarMuthu_Kumar Posts: 11
    >> Then you should fire your hardware engineers
    I wish I could :)

    >>As long as you have the common buffer, why don't you just read the file
    >>into the common buffer?? Then you can do the entire thing as one
    >>transfer.? With a common buffer, there is really no need to use a
    ><WdfDmaTransaction at all.

    Understood. To be clear, in this case, I don't need WDTI and WDTE calls

    Thanks Tim for the clarification
  • Peter_ViscarolaPeter_Viscarola Posts: 6,649
    <quote>
    If you can't do scatter/gather, then you'll need a common buffer
    </quote>

    Well... no, that's not true.

    Even if your hardware doesn't support scatter/gather, you can do packet-based DMA.

    I'm now thoroughly lost with what the OP needs to do.

    OP... instead of asking us one-line questions, can you please explain the overall goal you want to accomplish? Maybe then we can steer you in the right direction.

    Sorry for being confused. But I am. And I want to help...

    Peter
    OSR
    @OSRDrivers

    Peter Viscarola
    OSR
    @OSRDrivers

  • Muthu_KumarMuthu_Kumar Posts: 11
    Hi Peter, Trying to DMA 8K buffer of data read from a file. Needed clarification around on my attempt to use WdfDmaTransactionInitializeUsingRequest by creating WDFREQUEST from scratch. Needed further clarifications on using mdl & common buffer & WdfDmaTransaction and related APIs. Per Tim, I guess I can just read the content into a common buffer and DMA it without doing the WDF framework way at least for this scenario.
  • Peter_ViscarolaPeter_Viscarola Posts: 6,649
    <quote>
    Trying to DMA 8K buffer of data read from a file
    </quote>

    Thank you for that.

    Who's doing the reading? Does an application send you the data to be DMA'ed? That's the normal workflow for a driver. App reads the file, app calls WriteFile on a handle that's been opened to the device, the driver for that device does the DMA operation.

    Peter
    OSR
    @OSRDrivers

    Peter Viscarola
    OSR
    @OSRDrivers

  • Muthu_KumarMuthu_Kumar Posts: 11
    In this case, the driver has to do read (fw config data) and DMA in D0Entry context.
  • Peter_ViscarolaPeter_Viscarola Posts: 6,649
    <quote>
    In this case, the driver has to do read (fw config data) and DMA in D0Entry
    context.
    </quote>

    No. Sorry. That's not the right design. We don't do DMA operations from within the EvtDeviceD0Entry Event Processing Callback. It just won't work the way you expect.

    Do you need interrupts to process your DMA (and know it's done)? If so, you'll need to start a worker thread from within your EvtDeviceD0EntryPostInterruptsEnabled Event Processing Callback.

    But, there's a bigger question. Longer term, how does your device handle I/O Requests? How does it deal with read and write requests? How does it setup its general DMA processing?

    Peter
    OSR
    @OSRDrivers

    Peter Viscarola
    OSR
    @OSRDrivers

  • Muthu_KumarMuthu_Kumar Posts: 11
    Hi Peter, Yes, it is being done in EvtDeviceD0EntryPostInterruptsEnabled. Sorry, I replied quickly. The reads/writes will be handled very similar to how its done in the wdk sample (PLX9x5x)
  • Tim_RobertsTim_Roberts Posts: 12,567
    xxxxx@gmail.com wrote:
    > Trying to DMA 8K buffer of data read from a file
    > In this case, the driver has to do read (fw config data) and DMA in D0Entry context.

    If you're only doing two pages, then this is trivially easy.   Get
    yourself an 8k common buffer.  Read the file data directly into the
    buffer.  Set up your DMA hardware and trigger the DMA.  All the
    interrupt has to do is set a flag saying "DMA engine is now free".

    Does your hardware have a register-based interface to transfer this
    data?  For a one-time transfer that small, you might as well just do
    register pounding.  DMA isn't buying you anything.

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

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

  • Peter_ViscarolaPeter_Viscarola Posts: 6,649
    <quote>
    For a one-time transfer that small, you might as well just do
    register pounding.
    </quote>

    This. Absolutely.

    In fact, do you *really* want to do this each time your hardware enters D0 state? Because, that's what you're effectively doing by targeting EvtDeviceD0EntryPostInterruptsEnabled.

    If you don't need the interrupts OR the DMA, you can do the one time only register pounding directly in EvtDevicePrepareHardware. *I* know it says not to fool with your hardware in this routine, but that guidance is somewhat out of style. You know that you're in D0 on entry to EvtDevicePrepareHardware, and this happens to be a darn convenient place to do your one-time hardware initialization.

    Alternatively, if you really need to do this with DMA and interrupts, I was going to suggest firing-off a worker thread, and just having it work the setup I/O into your "ordinary" DMA I/O path.

    I, personally, would try to avoid using a unique DMA scheme for the configuration phase of your driver's work. If your ordinary I/O path does packet-based DMA, and (again) if I absolutely needed to DMA the config data, I would try to do packet-based DMA in my config path. I would try to avoid allocating a Common Buffer and writing a bunch of DMA code strictly to handle the initialization. I don't like debugging separate code paths when I can help it. And having two unique ways you handle DMA makes maintenance more confusing, as well.

    Peter
    OSR
    @OSRDrivers

    Peter Viscarola
    OSR
    @OSRDrivers

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!