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

📄 pcifuction_haero.c

📁 一个 PCI 驱动,实现PC 机与 PCI9045 的通信
💻 C
📖 第 1 页 / 共 3 页
字号:
        }
    }

    return ApiInvalidDeviceInfo;
}

DEVICE_NODE * DeviceListAdd(HANDLE hDevice)
{
    DEVICE_NODE  *pCurrentDevice;
    DEVICE_NODE  *pPreviousDevice;


    LockGlobals();

    pPreviousDevice = pDeviceList;

    if (pDeviceList != NULL)
    {
        while (pPreviousDevice->pNext != NULL)
        {
            pPreviousDevice = pPreviousDevice->pNext;
        }
    }

    // Allocate a new node
    pCurrentDevice = (DEVICE_NODE *)malloc(sizeof(DEVICE_NODE));

    if (pCurrentDevice == NULL)
    {
        UnlockGlobals();
        return NULL;
    }

    // Fill in new data
    pCurrentDevice->Handle     = hDevice;
    pCurrentDevice->pEventList = NULL;
    pCurrentDevice->pDmaList   = NULL;
    pCurrentDevice->pNext      = NULL;

    FillMemory(
        &pCurrentDevice->VirtualAddrs,
        sizeof(VIRTUAL_ADDRESSES),
        0xff
        );

    FillMemory(
        &pCurrentDevice->PciMemory,
        sizeof(PCI_MEMORY),
        0xff
        );

    // Adjust the pointers
    if (pDeviceList == NULL)
    {
        pDeviceList = pCurrentDevice;
    }
    else
    {
        pPreviousDevice->pNext = pCurrentDevice;
    }

    // Release access to globals
    UnlockGlobals();

    return pCurrentDevice;
}

/******************************************************************************
 *
 * Function   :  IoPoolGetNode
 *
 * Description:  Returns an I/O Node from a pool.  New structures are
 *               allocated on an as-needed basis.  An event handle is
 *               also allocated and inserted into the overlapped strucure.
 *
 * Returns    :  Pointer    - to an IO_NODE structure
 *               NULL       - if error 
 *
 *****************************************************************************/
IO_NODE *IoPoolGetNode(void)
{
    IO_NODE *pIoNode;
    IO_NODE *pIoNodePrevious;


    LockGlobals();

    pIoNode = pIoPoolList;

    // Search for an unused already allocated node
    while (pIoNode != NULL)
    {
        if (pIoNode->InUse == FALSE)
        {
            pIoNode->InUse = TRUE;

            UnlockGlobals();

            pIoNode->Overlapped.Internal     = 0;
            pIoNode->Overlapped.InternalHigh = 0;
            pIoNode->Overlapped.Offset       = 0;
            pIoNode->Overlapped.OffsetHigh   = 0;

            return pIoNode;
        }

        pIoNodePrevious = pIoNode;
        pIoNode         = pIoNode->pNext;
    }

    // Allocate a new node
    pIoNode = (IO_NODE *)malloc(sizeof(IO_NODE));
    if (pIoNode == NULL)
    {
        UnlockGlobals();
        return NULL;
    }

    // Mark as In Use
    pIoNode->InUse = TRUE;

    // End the list
    pIoNode->pNext = NULL;

    // Add the node to the list
    if (pIoPoolList == NULL)
        pIoPoolList = pIoNode;
    else
        pIoNodePrevious->pNext = pIoNode;

    UnlockGlobals();

    // Allocate the event
    pIoNode->Overlapped.hEvent = 
        CreateEvent(
            NULL,          // Not inheritable to child processes
            TRUE,          // Manual reset?
            FALSE,         // Intial state
            NULL
            );

    pIoNode->Overlapped.Internal     = 0;
    pIoNode->Overlapped.InternalHigh = 0;
    pIoNode->Overlapped.Offset       = 0;
    pIoNode->Overlapped.OffsetHigh   = 0;

    return pIoNode;
}

void IoPoolReleaseNode(IO_NODE *pIoNode)
{
    pIoNode->InUse = FALSE;
}

RETURN_CODE PlxPciDeviceClose(HANDLE hDevice)
{
    BOOLEAN removed;

    removed = DeviceListRemove(hDevice);

    if (removed == FALSE)
    {
        return ApiInvalidDeviceInfo;
    }

    return ApiSuccess;
}

BOOLEAN DeviceListRemove(HANDLE hDevice)
{
    BOOLEAN       DeviceFound;
    IO_NODE      *pIoNode;
    DEVICE_NODE  *pCurrentDevice;
    DEVICE_NODE  *pPreviousDevice;


    if (pDeviceList == NULL)
        return FALSE;

    LockGlobals();
    
    pCurrentDevice = pDeviceList;

    // Search for the node in the Device List
    DeviceFound = FALSE;
    do
    {
        if (pCurrentDevice->Handle == hDevice)
            DeviceFound = TRUE;
        else
        {
            // Check for end of list
            if (pCurrentDevice->pNext == NULL)
            {
                UnlockGlobals();
                return FALSE;
            }

            pPreviousDevice = pCurrentDevice;
            pCurrentDevice  = pCurrentDevice->pNext;
        }
    }
    while (DeviceFound == FALSE);

    // Remove device from the list
    if (pDeviceList == pCurrentDevice)
    {
        pDeviceList = pCurrentDevice->pNext;
    }
    else
    {
        pPreviousDevice->pNext = pCurrentDevice->pNext;
    }

    // Release access to globals
    UnlockGlobals();

    // Clear the Event List
    if (pCurrentDevice->pEventList != NULL)
    {
        IoListDestroy(&(pCurrentDevice->pEventList));
    }

    // Clear the DMA List
    if (pCurrentDevice->pDmaList != NULL)
    {
        IoListDestroy(
            &(pCurrentDevice->pDmaList)
            );
    }

    pIoNode = IoPoolGetNode();

    // Send message to the driver to unmap the virtual addresses
    if ( pCurrentDevice->VirtualAddrs.Va0   != (unsigned long)-1 ||
         pCurrentDevice->VirtualAddrs.Va1   != (unsigned long)-1 ||
         pCurrentDevice->VirtualAddrs.Va2   != (unsigned long)-1 ||
         pCurrentDevice->VirtualAddrs.Va3   != (unsigned long)-1 ||
         pCurrentDevice->VirtualAddrs.Va4   != (unsigned long)-1 ||
         pCurrentDevice->VirtualAddrs.Va5   != (unsigned long)-1 ||
         pCurrentDevice->VirtualAddrs.VaRom != (unsigned long)-1 )
    {
        pIoNode->IoBuffer.MgmtData.VirtAddr = pCurrentDevice->VirtualAddrs;

        DeviceIoControl(
            pCurrentDevice->Handle,
            PLX_IOCTL_BASE_ADDRESSES_FREE,
            &(pIoNode->IoBuffer),
            sizeof(IOCTLDATA),
            NULL,
            0,
            NULL,
            &(pIoNode->Overlapped)
            );
    }

    // Send message to the driver to unmap the common buffer
    if ( pCurrentDevice->PciMemory.UserAddr     != (unsigned long)-1 ||
         pCurrentDevice->PciMemory.PhysicalAddr != (unsigned long)-1 ||
         pCurrentDevice->PciMemory.Size         != (unsigned long)-1 )
    {
        pIoNode->IoBuffer.MgmtData.PciMemory.UserAddr = pCurrentDevice->PciMemory.UserAddr;

        DeviceIoControl(
            pCurrentDevice->Handle,
            PLX_IOCTL_COMMON_BUFFER_FREE,
            &(pIoNode->IoBuffer),
            sizeof(IOCTLDATA),
            NULL,
            0,
            NULL,
            &(pIoNode->Overlapped)
            );
    }

    IoPoolReleaseNode(
        pIoNode
        );

    // Close the handle
    CloseHandle(
        pCurrentDevice->Handle
        );

    // Release memory
    free(
        pCurrentDevice
        );

    return TRUE;
}

void IoListDestroy(IO_NODE **pIoList)
{
    while (*pIoList != NULL)
    {
        IoListRemove(pIoList,*pIoList);
    }
}

BOOLEAN IoListRemove(IO_NODE **pIoList,IO_NODE  *pIoNodeToRemove)
{
    BOOLEAN  bFlag;
    DWORD    BytesTransferred;
    IO_NODE *pCurrentNode;
    IO_NODE *pPreviousNode;


    if (*pIoList == NULL)
        return FALSE;

    LockGlobals();

    pCurrentNode = *pIoList;

    // Search for the node in the Event List
    bFlag = FALSE;
    do
    {
        if (pCurrentNode == pIoNodeToRemove)
            bFlag = TRUE;
        else
        {
            // Check for end of list
            if (pCurrentNode->pNext == NULL)
            {
                UnlockGlobals();
                return FALSE;
            }

            pPreviousNode = pCurrentNode;
            pCurrentNode  = pCurrentNode->pNext;
        }
    }
    while (bFlag == FALSE);

    // Adjust the pointers
    if (*pIoList == pCurrentNode)
    {
        *pIoList = pCurrentNode->pNext;
    }
    else
    {
        pPreviousNode->pNext = pCurrentNode->pNext;
    }

    // Release access to globals
    UnlockGlobals();

    // Check the status of the Overlapped operation
    bFlag = GetOverlappedResult(
                pCurrentNode->Overlapped.hEvent,
                &(pCurrentNode->Overlapped),
                &BytesTransferred,
                FALSE           // Don't wait for completion
                );

    if (bFlag == FALSE)
    {
        if (GetLastError() == ERROR_IO_INCOMPLETE)
            return FALSE;
    }

    // Cleanup the Event Node if the operation has completed

    // Release the event handle
    CloseHandle(
        pCurrentNode->Overlapped.hEvent
        );

    // Release I/O node memory
    free(
        pCurrentNode
        );

    return TRUE;
}

RETURN_CODE PlxChipTypeGet(HANDLE  hDevice,unsigned long  *pChipType,unsigned char *pRevision)
{
    IO_NODE *pIoNode;


    if ((pChipType == NULL) ||
        (pRevision == NULL))
    {
        return ApiNullParam;
    }

    // Verify the handle
    if (DeviceListFind(hDevice) == NULL)
    {
        return ApiInvalidHandle;
    }

    pIoNode = IoPoolGetNode();

    DeviceIoControl(
        hDevice,
        PLX_IOCTL_CHIP_TYPE_GET,
        NULL,
        0,
        &(pIoNode->IoBuffer),
        sizeof(IOCTLDATA),
        NULL,
        &(pIoNode->Overlapped)
        );

    *pChipType = pIoNode->IoBuffer.MiscData.Value;
    *pRevision = (unsigned char)pIoNode->IoBuffer.MiscData.Value1;

    IoPoolReleaseNode(
        pIoNode
        );

    return ApiSuccess;
}

RETURN_CODE PlxDmaSglChannelOpen(HANDLE hDevice,DMA_CHANNEL dmaChannel,DMA_CHANNEL_DESC *pDmaChannelDesc)
{
    IO_NODE     *pIoNode;
    DEVICE_NODE *pDevice;
    RETURN_CODE  rc;


    // Verify the handle
    pDevice = DeviceListFind(
                  hDevice
                  );

⌨️ 快捷键说明

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