IWDFDevice3::MapIoSpace method

The MapIoSpace method maps the given physical address range to system address space and returns a pseudo base address.

Syntax


HRESULT  MapIoSpace(
  [in]   PHYSICAL_ADDRESS PhysicalAddress,
  [in]   SIZE_T NumberOfBytes,
  [in]   MEMORY_CACHING_TYPE CacheType,
  [out]  VOID **pPseudoBaseAddress
);

Parameters

PhysicalAddress [in]

Specifies the starting 64-bit physical address of the I/O range to be mapped.

NumberOfBytes [in]

Specifies a value greater than zero, indicating the number of bytes to be mapped.

CacheType [in]

Specifies a MEMORY_CACHING_TYPE value, which indicates the cache attribute to use to map the physical address range. The MEMORY_CACHING_TYPE enumeration type is defined in Wudfwdm.h.

pPseudoBaseAddress [out]

The address of a location that receives a pointer to the pseudo base address.

Return value

The method returns S_OK if the operation succeeds. Otherwise, this method returns one of the error codes that are defined in Winerror.h.

Remarks

A driver must call this method during device start-up if it receives translated resources of type CmResourceTypeMemory in a CM_PARTIAL_RESOURCE_DESCRIPTOR structure. MapIoSpace maps the physical address returned in the resource list to a framework-managed address referred to as the pseudo base address.

The driver can then use the pseudo base address to access device registers with READ_REGISTER_Xxx and WRITE_REGISTER_Xxx functions. For an example, see Reading and Writing to Device Registers in UMDF 1.x Drivers.

A driver that calls MapIoSpace must set the UmdfDirectHardwareAccess INF directive to AllowDirectHardwareAccess.

If the driver sets the UmdfRegisterAccessMode INF directive to RegisterAccessUsingUserModeMapping, calling MapIoSpace also maps the given physical address range to a user-mode base address range that the driver can subsequently access by calling GetHardwareRegisterMappedAddress.

For more information about INF directives that UMDF drivers can use, see Specifying WDF Directives in INF Files.

The PHYSICAL_ADDRESS type is defined in Wudfwdm.h, as follows:

typedef LARGE_INTEGER PHYSICAL_ADDRESS;

Examples

In the following code example, a UMDF driver uses its IPnpCallbackHardware2::OnPrepareHardware callback function to examine its memory-mapped register resources and map them into user-mode address space. The example then implements a WriteToDevice method that accesses the memory locations. The driver then calls UnmapIoSpace from its IPnpCallbackHardware2::OnReleaseHardware callback. The driver’s INF file must enable UMDF hardware access feature by setting the UmdfDirectHardwareAccess directive to AllowDirectHardwareAccess.



HRESULT
CMyDevice::OnPrepareHardware(
    __in IWDFDevice3 * pWdfDevice,
    __in IWDFCmResourceList * pRaw,
    __in IWDFCmResourceList * pTrans
    ) 
{
    PCM_PARTIAL_RESOURCE_DESCRIPTOR desc = NULL;
    PHYSICAL_ADDRESS regBasePA = {0};
    ULONG regLength = 0;
    BOOLEAN found = FALSE;
    HRESULT hr = S_OK;

    //
    // Scan the list to identify our resource.
    //
    for (i=0; i < pWdfResTranslated->GetCount(); i++) {
        desc = (PCM_PARTIAL_RESOURCE_DESCRIPTOR) pTrans->GetDescriptor(i);

        switch (desc->Type) {
            case CmResourceTypeMemory:
                //
                // See if this is the memory resource we’re looking for.
                // 
                if (desc->u.Memory.Length == 0x200) {
                    regsBasePA = desc->u.Memory.Start;
                    regsLength = desc->u.Memory.Length;
                    found = TRUE;                    
                }
                break;

            default:
                // Ignore all other descriptors.
                break;
        }
    }

    //
    // Map the resource. Store the register base in partner device
    // object for later access.
    //
    if (found) {
            hr = pWdfDevice->MapIoSpace(regBasePA,
                                           regLengthlength, 
                                           MmNonCached,
                                          (void **)&m_RegBase);
            if (SUCCEEDED(hr)) {
            //
            // Store the register range in partner object. This will 
            // be needed for unmapping.
            //
            m_RegLength = regLength;
        }
    }

    …
}

//
// UMDF driver uses one of the register access APIs such as
// WRITE_REGISTER_Xxx or READ_REGISTER_Xxx macros to access device register.
//
VOID
CMyQueue::WriteToDevice(
    __in IWDFDevice3* pWdfDevice,
    __in UCHAR Value
    )
{
    //
    // Write the UCHAR value at offset 2 from register base.
    //
    WRITE_REGISTER_UCHAR(pWdfDevice, 
                      (m_MyDevice->m_RegBase)+2, 
                       Value);
}

HRESULT
CMyDevice::OnReleaseHardware(
    __in IWDFDevice3 * pWdfDevice,
    __in IWDFCmResourceList * pTrans
    )
{
    //
    // Unmap registers memory resource.
    //
    pWdfDevice->UnmapIoSpace(m_RegBase, m_RegLength);

    return S_OK;
}



Requirements

End of support

Unavailable in UMDF 2.0 and later.

Minimum UMDF version

1.11

Header

Wudfddi.h

DLL

WUDFx.dll

See also

IWDFDevice3

 

 

Send comments about this topic to Microsoft

Show:
© 2014 Microsoft. All rights reserved.