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

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

Confusing return from StorPortGetSystemAddress

Jeff_GlassJeff_Glass Member Posts: 96
I'm trying to use StorPortGetSystemAddress to get a VA I can use to meet the alignment and transfer length requirements for my device. My Storport miniport is setting MapBuffers to STOR_MAP_NON_READ_WRITE_BUFFERS in the HW_INITIALIZATION_DATA.

I thought I would be able to use StorPortGetSystemAddress to retrieve a VA for both Read/Write and non-Read/Write requests. However, the VA I'm getting from StorPortGetSystemAddress has me confused. I expected to either get back the same VA contained in DataBuffer, or to get back a different VA which pointed to the same physical memory.

StorPortGetSystemAddress returns 0xfffffa80`07564560
Srb->Databuffer is 0xfffffa60`06ec5560
SCATTER_GATHER_ELEMENT.PhysicalAddress 0xb30d5560

!pte 0xfffffa80`07564560 (StorPortGetPhysicalAddress)
VA fffffa8007564560
contains 0000000105600863 contains 0000000105601863 contains 00000001DE6009E3 contains 0000000000000000
pfn 105600 ---DA--KWEV pfn 105601 ---DA--KWEV pfn 1de600 -GLDA--KWEV LARGE PAGE pfn 1de764

!pte 0xfffffa60`06ec5560 (DataBuffer)
VA fffffa6006ec5560
contains 0000000105784863 contains 0000000105783863 contains 00000000B335C863 contains 00000000B30D5963
pfn 105784 ---DA--KWEV pfn 105783 ---DA--KWEV pfn b335c ---DA--KWEV pfn b30d5 -G-DA--KWEV

What exactly is StorPortGetPhysicalAddresses VA pointing to? Can I not use this API if the memory is already mapped?


  • Mark_RoddyMark_Roddy Member - All Emails Posts: 4,306
    STOR_MAP_NON_READ_WRITE_BUFFERS means that only Non Read/Write Buffers are
    mapped and thus only those SRBs have valid Databuffer fields. Perhaps you
    meant to use STOR_MAP_ALL_BUFFERS?

    Mark Roddy

    On Wed, Aug 10, 2011 at 5:47 PM, wrote:

  • Jeff_GlassJeff_Glass Member Posts: 96

    The documentation (from 7600.16385.1) states that STOR_MAP_ALL_BUFFERS is not implemented, so I assumed I would have to use StorPortGetSystemAddress to access the buffers of read/write requests.

    Instead of having two different code paths for read/write vs non-read/write requests, I implemented my code to just always use the pointer I received from StorPortGetSystemAddress. I just ran a test with STOR_MAP_NO_BUFFERS set, and I'm still finding that the VA I'm getting from the API does not point to the memory in the SGL.

    If I take the physical address in the first s/g entry, and type
    !eb <addr> 1 2 3 4
    And then db srb->DataBuffer, I see something like
    <va> 1 2 3 4 0 0 0 0 0
    But If I dump the VA given to me by StorPortGetSystemAddress, then I'll get all 0's. This agrees with the !pte output telling me that the two VA's are pointing at different memory. I just can't figure out what StorPortGetSystemAddress is pointing at, and how I would get a VA that points to the SRB's MDL if it's not already in Srb->DataBuffer.

  • Alex_GrigAlex_Grig Member Posts: 3,238
    srb->DataBuffer may or may not be useable to access the buffer. If the buffer is not mapped, DataBuffer is the same as MDL's original virtual address, which could even be zero.

    The return from StorPortGetSystemAddress CAN be used for the buffer access.
  • Jeff_GlassJeff_Glass Member Posts: 96
    I guess based on the replies I'm getting that StorPortGetSystemAddress is supposed to return a VA that points to the same physical memory as the MDL. So maybe I'm not using the function correctly. I'll check again. To be clear...

    If I edit the physical memory in the first entry of the Windows supplied scatter/gather list (using !eb), I see the change (using db) reflected in the memory pointed to srb->DataBuffer when it's mapped, and I see the change (using !db -m) reflected at the physical memory address. However, I do not see a change (again using db) at the memory pointed to by the pointerI get back from StorPortGetSystemAddress.

    If I do the opposite and edit the memory using eb at the pointer returned by StorPortGetSystemAddress and look for the change at the physical address with !db -m, then I do not see the change I made.

    Also, the !pte results seem to confirm that the virtual addresses are pointing to different physical memory regions.
  • Alex_GrigAlex_Grig Member Posts: 3,238
    If you got a SGL, it may point to a bounce buffer. You can either access the buffer directly, or use DMA, but not both at the same time.
  • Jeff_GlassJeff_Glass Member Posts: 96
    So just to put a bow on this thread..

    The documentation for StorPortGetSystemAddress states "The StorPortGetSystemAddress routine returns a virtual address in system space for the data buffer of the specified SCSI request block (SRB)."

    What it actually returns is a virtual address for the user space buffer that was passed into the O/S.

    If the user used IOCTL_SCSI_PASS_THROUGH, then this will not be the same buffer that is pointed to by the scatter/gather list returned by StorPortGetScatterGatherList because of bounce buffering. It is, I believe, the buffer pointed to by StorPortGetOriginalMdl().

    If the user used IOCTL_SCSI_PASS_THROUGH_DIRECT, then the VA *does* point to the SGL because no bounce buffering is being done.

    There doesn't appear to a way (at least with the Storport framework) to get a virtual address for a the scatter/gather list returned by StorPortGetScatterGatherList if the CDB is read or write command when the request is being bounced.
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!

Upcoming OSR Seminars
Developing Minifilters 29 July 2019 OSR Seminar Space
Writing WDF Drivers 23 Sept 2019 OSR Seminar Space
Kernel Debugging 21 Oct 2019 OSR Seminar Space
Internals & Software Drivers 18 Nov 2019 Dulles, VA