⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 supportfunc.c

📁 本压缩包为作者截取的PCI9054的WDM官方驱动源码。欢迎下载。
💻 C
📖 第 1 页 / 共 3 页
字号:
            IoAllocateMdl(
                pVa,
                SizeToMap,
                FALSE,
                FALSE,
                NULL
                );

        // Check if the MDL allocation succeeded
        if (pMdl == NULL)
        {
            DebugPrintf(("ERROR - MDL allocation for space failed\n"));

            // Release any created MDLs
            while (pdx->PciBar[BarIndex].pMdl != NULL)
            {
                pMdl = pdx->PciBar[BarIndex].pMdl;

                pdx->PciBar[BarIndex].pMdl = pMdl->Next;

                IoFreeMdl(
                    pMdl
                    );
            }

            return STATUS_SUCCESS;
        }
        else
        {
            // Build the MDL
            MmBuildMdlForNonPagedPool(
                pMdl
                );
        }

        // Clear next MDL pointer
        pMdl->Next = NULL;

        // Store MDL
        if (pdx->PciBar[BarIndex].pMdl == NULL)
        {
            // Insert first MDL
            pdx->PciBar[BarIndex].pMdl = pMdl;

            pMdl_Previous = pMdl;
        }
        else
        {
            // Add new MDL to list
            pMdl_Previous->Next = pMdl;

            // Update previous pointer
            pMdl_Previous = pMdl;
        }

        // Adjust for next virtual address
        (U8*)pVa += SizeToMap;

        // Adjust remaining count
        SizeRemain -= SizeToMap;
    }

    return STATUS_SUCCESS;
}




/******************************************************************************
 *
 * Function   :  PlxPciBarResourcesUnmap
 *
 * Description:  Unmap all mapped PCI BAR memory for a device
 *
 ******************************************************************************/
VOID
PlxPciBarResourcesUnmap(
    DEVICE_EXTENSION *pdx
    )
{
    U8   i;
    PMDL pMdl;


    // Go through all the BARS
    for (i = 0; i < PCI_NUM_BARS_TYPE_00; i++)
    {
        // Unmap the space from Kernel space if previously mapped
        if ((pdx->PciBar[i].bIsIoSpace == FALSE) &&
            (pdx->PciBar[i].Physical.QuadPart != 0))
        {
            DebugPrintf(("Unmapping BAR %d...\n", i));

            // Release the MDLs describing the BAR space
            while (pdx->PciBar[i].pMdl != NULL)
            {
                pMdl = pdx->PciBar[i].pMdl;

                pdx->PciBar[i].pMdl = pMdl->Next;

                IoFreeMdl(
                    pMdl
                    );
            }

            // Unmap from kernel space
            if (pdx->PciBar[i].pVa != NULL)
            {
                MmUnmapIoSpace(
                    pdx->PciBar[i].pVa,
                    pdx->PciBar[i].Size
                    );
                pdx->PciBar[i].pVa = NULL;
            }
        }
    }
}




/******************************************************************************
 *
 * Function   :  PlxPciBarSpaceUnmapAll_ByOwner
 *
 * Description:  Unmap any PCI BAR spaces assigned to the specified owner
 *
 ******************************************************************************/
VOID
PlxPciBarSpaceUnmapAll_ByOwner(
    DEVICE_EXTENSION *pdx,
    VOID             *pOwner
    )
{
    VOID             *UserVa;
    KIRQL             IrqL_Original;
    PLIST_ENTRY       pEntry;
    PLX_USER_MAPPING *pMapObject;


    KeAcquireSpinLock(
        &(pdx->Lock_BarMappingsList),
        &IrqL_Original
        );

    pEntry = pdx->List_BarMappings.Flink;

    // Traverse list to find the desired list objects
    while (pEntry != &(pdx->List_BarMappings))
    {
        // Get the object
        pMapObject =
            CONTAINING_RECORD(
                pEntry,
                PLX_USER_MAPPING,
                ListEntry
                );

        // Check if owner matches
        if (pMapObject->pOwner == pOwner)
        {
            // Copy address
            UserVa = pMapObject->pUserVa[0];

            // Release list lock
            KeReleaseSpinLock(
                &(pdx->Lock_BarMappingsList),
                IrqL_Original
                );

            // Unmap BAR space
            PlxPciBarUnmap(
                pdx,
                UserVa,
                pOwner
                ); 

            KeAcquireSpinLock(
                &(pdx->Lock_BarMappingsList),
                &IrqL_Original
                );

            // Restart parsing the list from the beginning
            pEntry = pdx->List_BarMappings.Flink;
        }
        else
        {
            // Jump to next item
            pEntry = pEntry->Flink;
        }
    }

    KeReleaseSpinLock(
        &(pdx->Lock_BarMappingsList),
        IrqL_Original
        );
}




/******************************************************************************
 *
 * Function   :  PlxPciPhysicalMemoryFreeAll_ByOwner
 *
 * Description:  Unmap & release all physical memory assigned to the specified owner
 *
 ******************************************************************************/
VOID
PlxPciPhysicalMemoryFreeAll_ByOwner(
    DEVICE_EXTENSION *pdx,
    VOID             *pOwner
    )
{
    KIRQL                IrqL_Original;
    PLIST_ENTRY          pEntry;
    PLX_PHYSICAL_MEM     PciMem;
    PLX_PHYS_MEM_OBJECT *pMemObject;


    KeAcquireSpinLock(
        &(pdx->Lock_PhysicalMemList),
        &IrqL_Original
        );

    pEntry = pdx->List_PhysicalMem.Flink;

    // Traverse list to find the desired list objects
    while (pEntry != &(pdx->List_PhysicalMem))
    {
        // Get the object
        pMemObject =
            CONTAINING_RECORD(
                pEntry,
                PLX_PHYS_MEM_OBJECT,
                ListEntry
                );

        // Check if owner matches
        if (pMemObject->pOwner == pOwner)
        {
            // Copy memory information
            PciMem.PhysicalAddr = pMemObject->BusPhysical;
            PciMem.Size         = pMemObject->Size;

            // Release list lock
            KeReleaseSpinLock(
                &(pdx->Lock_PhysicalMemList),
                IrqL_Original
                );

            // Release the memory & remove from list
            PlxPciPhysicalMemoryFree(
                pdx,
                &PciMem
                ); 

            KeAcquireSpinLock(
                &(pdx->Lock_PhysicalMemList),
                &IrqL_Original
                );

            // Restart parsing the list from the beginning
            pEntry = pdx->List_PhysicalMem.Flink;
        }
        else
        {
            // Jump to next item
            pEntry = pEntry->Flink;
        }
    }

    KeReleaseSpinLock(
        &(pdx->Lock_PhysicalMemList),
        IrqL_Original
        );
}




/******************************************************************************
 *
 * Function   :  PlxPciPhysicalMemoryUnmapAll_ByOwner
 *
 * Description:  Unmap any physical memory assigned to the specified owner
 *
 ******************************************************************************/
VOID
PlxPciPhysicalMemoryUnmapAll_ByOwner(
    DEVICE_EXTENSION    *pdx,
    PLX_PHYS_MEM_OBJECT *pMemObject,
    VOID                *pOwner
    )
{
    VOID             *pUserVa;
    KIRQL             IrqL_Original;
    PLIST_ENTRY       pEntry;
    PLX_PHYSICAL_MEM  PciMem;
    PHYSICAL_ADDRESS  AddrPhysical;
    PLX_USER_MAPPING *pMapObject;


    // Verify Memory Object
    if (pMemObject == NULL)
    {
        return;
    }

    // Verify size
    if (pMemObject->Size == 0)
    {
        return;
    }

    // Setup memory properties
    PciMem.PhysicalAddr = pMemObject->BusPhysical;
    PciMem.Size         = pMemObject->Size;

    // Find the map object to unmap
    KeAcquireSpinLock(
        &(pMemObject->Lock_MappingsList),
        &IrqL_Original
        );

    pEntry = pMemObject->List_Mappings.Flink;

    // Traverse list to find the desired list object
    while (pEntry != &(pMemObject->List_Mappings))
    {
        // Get the object
        pMapObject =
            CONTAINING_RECORD(
                pEntry,
                PLX_USER_MAPPING,
                ListEntry
                );

        // Check if the owner matches
        if ((pOwner == NULL) || (pMapObject->pOwner == pOwner))
        {
            // Copy virtual address
            PciMem.UserAddr = (PLX_UINT_PTR)pMapObject->pUserVa[0];

            // Release list lock
            KeReleaseSpinLock(
                &(pMemObject->Lock_MappingsList),
                IrqL_Original
                );

            // Unmap the memory & remove from list
            PlxPciPhysicalMemoryUnmap(
                pdx,
                &PciMem,
                pMapObject->pOwner
                ); 

            KeAcquireSpinLock(
                &(pMemObject->Lock_MappingsList),
                &IrqL_Original
                );

            // Restart parsing the list from the beginning
            pEntry = pMemObject->List_Mappings.Flink;
        }
        else
        {
            // Jump to next item
            pEntry = pEntry->Flink;
        }
    }

    KeReleaseSpinLock(
        &(pMemObject->Lock_MappingsList),
        IrqL_Original
        );
}




/******************************************************************************
 *
 * Function   :  PlxDmaChannelCleanup
 *
 * Description:  Called by the Cleanup routine to close any open channels
 *
 ******************************************************************************/
VOID
PlxDmaChannelCleanup(
    DEVICE_EXTENSION *pdx,
    VOID             *pOwner
    )
{
#if defined(DMA_SUPPORT)
    U8          i;
    DMA_CHANNEL channel;


    // Added to avoid compiler warning
    channel = PrimaryPciChannel0;

    for (i = 0; i < NUMBER_OF_DMA_CHANNELS; i++)
    {
        // Check if terminating application is the owner
        if (pdx->DmaInfo[i].pOwner == pOwner)
        {
            DebugPrintf(("Closing DMA channel %d\n", i));

            switch (i)
            {
                case 0:
                    channel = PrimaryPciChannel0;
                    break;

                case 1:
                    channel = PrimaryPciChannel1;
                    break;

                case 2:
                    channel = IopChannel2;
                    break;
            }

            switch (pdx->DmaInfo[i].state)
            {
                case DmaStateClosed:
                    // DMA closed already, do nothing
                    break;

                case DmaStateBlock:
                    PlxDmaBlockChannelClose(
                        pdx,
                        channel,
                        FALSE
                        );
                    break;

                case DmaStateSgl:
                    PlxDmaSglChannelClose(
                        pdx,
                        channel,
                        FALSE
                        );
                    break;

                default:
                    // Unknown or unsupported state
                    break;
            }
        }
    }
#endif  // DMA_SUPPORT
}




#if defined(DMA_SUPPORT)
/******************************************************************************
 *
 * Function   :  PlxSglDmaTransferComplete
 *
 * Description:  Perform any necessary cleanup after an SGL DMA transfer
 *
 ******************************************************************************/
VOID
PlxSglDmaTransferComplete(
    DEVICE_EXTENSION *pdx,
    U8                DmaIndex
    )
{
    KIRQL IrqL_Original;


    if (pdx->DmaInfo[DmaIndex].bPending == FALSE)
    {
        DebugPrintf(("No pending SGL DMA to complete\n"));
        return;
    }

    DebugPrintf((
        "Unlocking user-mode buffer used for SGL DMA transfer...\n"
        ));

    KeAcquireSpinLock(
        &(pdx->Lock_DmaChannel),
        &IrqL_Original
        );

    // Unlock the data buffer and free the MDL
    if (pdx->DmaInfo[DmaIndex].pMdl != NULL)
    {
        MmUnlockPages(
            pdx->DmaInfo[DmaIndex].pMdl
            );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -