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

📄 commonapi.c

📁 本压缩包为作者截取的PCI9054的WDM官方驱动源码。欢迎下载。
💻 C
📖 第 1 页 / 共 4 页
字号:

        // Remove object
        if (bRemove)
        {
            DebugPrintf((
                "Removing interrupt wait object (%p)...\n",
                pWaitObject
                ));

            // Remove the object from the list
            RemoveEntryList(
                pEntry
                );

            KeReleaseSpinLock(
                &(pdx->Lock_WaitObjectsList),
                IrqL_Original
                );

            // De-reference the kernel event object
            ObDereferenceObject(
                pWaitObject->pKEvent
                );

            // Release the list object
            ExFreePool(
                pWaitObject
                );

            // Return if removing only a specific object
            if (pEvent != NULL)
                return ApiSuccess;

            // Reset to beginning of list
            KeAcquireSpinLock(
                &(pdx->Lock_WaitObjectsList),
                &IrqL_Original
                );

            pEntry = pdx->List_WaitObjects.Flink;
        }
        else
        {
            // Jump to next item in the list
            pEntry = pEntry->Flink;
        }
    }

    KeReleaseSpinLock(
        &(pdx->Lock_WaitObjectsList),
        IrqL_Original
        );

    return ApiFailed;
}




/******************************************************************************
 *
 * Function   :  PlxPciBusMemTransfer
 *
 * Description:  Reads/Writes device memory to/from a buffer
 *
 ******************************************************************************/
RETURN_CODE
PlxPciBusMemTransfer(
    DEVICE_EXTENSION *pdx,
    IOP_SPACE         IopSpace,
    U32               LocalAddress,
    BOOLEAN           bRemap,
    U8               *pBuffer,
    U32               ByteCount,
    ACCESS_TYPE       AccessType,
    BOOLEAN           bReadOperation
    )
{
    U8           BarIndex;
    U16          Offset_RegRemap;
    U32          RegValue;
    U32          SpaceRange;
    U32          SpaceOffset;
    U32          RemapOriginal;
    U32          BytesToTransfer;
    PLX_UINT_PTR SpaceVa;


    // Added to prevent compiler warnings
    RemapOriginal = 0;

    // Verify data alignment
    switch (AccessType)
    {
        case BitSize8:
            break;

        case BitSize16:
            if (LocalAddress & 0x1)
            {
                DebugPrintf(("ERROR - Local address not aligned\n"));
                return ApiInvalidAddress;
            }

            if (ByteCount & 0x1)
            {
                DebugPrintf(("ERROR - Byte count not aligned\n"));
                return ApiInvalidSize;
            }
            break;

        case BitSize32:
            if (LocalAddress & 0x3)
            {
                DebugPrintf(("ERROR - Local address not aligned\n"));
                return ApiInvalidAddress;
            }

            if (ByteCount & 0x3)
            {
                DebugPrintf(("ERROR - Byte count not aligned\n"));
                return ApiInvalidSize;
            }
            break;

        default:
            DebugPrintf(("ERROR - Invalid access type\n"));
            return ApiInvalidAccessType;
    }

    // Get and Verify the Local Space
    PlxChipGetSpace(
        pdx,
        IopSpace,
        &BarIndex,
        &Offset_RegRemap
        );

    if (BarIndex == (U8)-1)
    {
        return ApiInvalidIopSpace;
    }

    // Only memory spaces are supported by this function
    if (pdx->PciBar[BarIndex].bIsIoSpace)
    {
        DebugPrintf(("ERROR - I/O spaces not supported by this function\n"));
        return ApiInvalidIopSpace;
    }

    // Get kernel virtual address for the space
    SpaceVa = (PLX_UINT_PTR)pdx->PciBar[BarIndex].pVa;

    if (SpaceVa == 0)
    {
        DebugPrintf((
            "ERROR - Invalid kernel VA (0x%08lx) for PCI BAR\n",
            SpaceVa
            ));

        return ApiInvalidAddress;
    }

    // Save the remap register
    if (bRemap)
    {
        RemapOriginal =
            PLX_REG_READ(
                pdx,
                Offset_RegRemap
                );
    }
    else
    {
        // Make sure requested area doesn't exceed our local space window boundary
        if ((LocalAddress + ByteCount) > pdx->PciBar[BarIndex].Size)
        {
            DebugPrintf(("ERROR - requested area exceeds space range\n"));
            return ApiInvalidSize;
        }
    }

    // Get the range of the space
    SpaceRange = ~(pdx->PciBar[BarIndex].Size - 1);

    // Transfer data in blocks
    while (ByteCount != 0)
    {
        // Adjust remap if necessary
        if (bRemap)
        {
            // Clear upper bits of remap
            RegValue = RemapOriginal & ~SpaceRange;

            // Adjust window to local address
            RegValue |= LocalAddress & SpaceRange;

            PLX_REG_WRITE(
                pdx,
                Offset_RegRemap,
                RegValue
                );
        }

        // Get current offset into space
        SpaceOffset = LocalAddress & (~SpaceRange);

        // Calculate bytes to transfer for next block
        if (ByteCount <= (((~SpaceRange) + 1) - SpaceOffset))
        {
            BytesToTransfer = ByteCount;
        }
        else
        {
            BytesToTransfer = ((~SpaceRange) + 1) - SpaceOffset;
        }

        if (bReadOperation)
        {
            // Copy block to user buffer
            switch (AccessType)
            {
                case BitSize8:
                    DEV_MEM_TO_USER_8(
                        pBuffer,
                        (SpaceVa + SpaceOffset),
                        BytesToTransfer
                        );
                    break;

                case BitSize16:
                    DEV_MEM_TO_USER_16(
                        pBuffer,
                        (SpaceVa + SpaceOffset),
                        BytesToTransfer
                        );
                    break;

                case BitSize32:
                    DEV_MEM_TO_USER_32(
                        pBuffer,
                        (SpaceVa + SpaceOffset),
                        BytesToTransfer
                        );
                    break;

                case BitSize64:
                    // 64-bit not implemented yet
                    break;
            }
        }
        else
        {
            // Copy user buffer to device memory
            switch (AccessType)
            {
                case BitSize8:
                    USER_TO_DEV_MEM_8(
                        (SpaceVa + SpaceOffset),
                        pBuffer,
                        BytesToTransfer
                        );
                    break;

                case BitSize16:
                    USER_TO_DEV_MEM_16(
                        (SpaceVa + SpaceOffset),
                        pBuffer,
                        BytesToTransfer
                        );
                    break;

                case BitSize32:
                    USER_TO_DEV_MEM_32(
                        (SpaceVa + SpaceOffset),
                        pBuffer,
                        BytesToTransfer
                        );
                    break;

                case BitSize64:
                    // 64-bit not implemented yet
                    break;
            }
        }

        // Adjust for next block access
        pBuffer      += BytesToTransfer;
        LocalAddress += BytesToTransfer;
        ByteCount    -= BytesToTransfer;
    }

    // Restore the remap register
    if (bRemap)
    {
        PLX_REG_WRITE(
            pdx,
            Offset_RegRemap,
            RemapOriginal
            );
    }

    return ApiSuccess;
}




/******************************************************************************
 *
 * Function   :  PlxPciIoPortTransfer
 *
 * Description:  Read or Write from/to an I/O port
 *
 ******************************************************************************/
RETURN_CODE
PlxPciIoPortTransfer(
    U64          IoPort,
    ACCESS_TYPE  AccessType,
    VOID        *pValue,
    BOOLEAN      bReadOperation
    )
{
    if (pValue == NULL)
        return ApiNullParam;

    if (bReadOperation)
    {
        switch (AccessType)
        {
            case BitSize8:
                *(U8*)pValue =
                    IO_PORT_READ_8(
                        IoPort
                        );
                break;

            case BitSize16:
                *(U16*)pValue =
                    IO_PORT_READ_16(
                        IoPort
                        );
                break;

            case BitSize32:
                *(U32*)pValue =
                    IO_PORT_READ_32(
                        IoPort
                        );
                break;

            default:
                return ApiInvalidAccessType;
        }
    }
    else
    {
        switch (AccessType)
        {
            case BitSize8:
                IO_PORT_WRITE_8(
                    IoPort,
                    *(U8*)pValue
                    );
                break;

            case BitSize16:
                IO_PORT_WRITE_16(
                    IoPort,
                    *(U16*)pValue
                    );
                break;

            case BitSize32:
                IO_PORT_WRITE_32(
                    IoPort,
                    *(U32*)pValue
                    );
                break;

            default:
                return ApiInvalidAccessType;
        }
    }

    return ApiSuccess;
}




/******************************************************************************
 *
 * Function   :  PlxPciPhysicalMemoryAllocate
 *
 * Description:  Allocate physically contiguous page-locked memory
 *
 ******************************************************************************/
RETURN_CODE
PlxPciPhysicalMemoryAllocate(
    DEVICE_EXTENSION *pdx,
    PLX_PHYSICAL_MEM *pPciMem,
    BOOLEAN           bSmallerOk,
    VOID             *pOwner
    )
{
    U32                  DecrementAmount;
    PLX_PHYS_MEM_OBJECT *pBufferObj;


    // Initialize buffer information
    pPciMem->UserAddr     = 0;
    pPciMem->PhysicalAddr = 0;
    pPciMem->CpuPhysical  = 0;

    /*******************************************************
     * Verify size
     *
     * A size of 0 is valid because this function may
     * be called to allocate a common buffer of size 0;
     * therefore, the information is reset & return sucess.
     ******************************************************/
    if (pPciMem->Size == 0)
    {
        return ApiSuccess;
    }

    // Allocate memory for new list object
    pBufferObj =
        ExAllocatePool(
            NonPagedPool,
            sizeof(PLX_PHYS_MEM_OBJECT)
            );

    if (pBufferObj == NULL)
    {
        DebugPrintf((
            "ERROR - Memory allocation for list object failed\n"
            ));

        return ApiInsufficientResources;
    }

⌨️ 快捷键说明

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