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

📄 commonapi.c

📁 本压缩包为作者截取的PCI9054的WDM官方驱动源码。欢迎下载。
💻 C
📖 第 1 页 / 共 4 页
字号:
/*******************************************************************************
 * Copyright (c) 2006 PLX Technology, Inc.
 *
 * PLX Technology Inc. licenses this software under specific terms and
 * conditions.  Use of any of the software or derviatives thereof in any
 * product without a PLX Technology chip is strictly prohibited.
 *
 * PLX Technology, Inc. provides this software AS IS, WITHOUT ANY WARRANTY,
 * EXPRESS OR IMPLIED, INCLUDING, WITHOUT LIMITATION, ANY WARRANTY OF
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  PLX makes no guarantee
 * or representations regarding the use of, or the results of the use of,
 * the software and documentation in terms of correctness, accuracy,
 * reliability, currentness, or otherwise; and you rely on the software,
 * documentation and results solely at your own risk.
 *
 * IN NO EVENT SHALL PLX BE LIABLE FOR ANY LOSS OF USE, LOSS OF BUSINESS,
 * LOSS OF PROFITS, INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES
 * OF ANY KIND.  IN NO EVENT SHALL PLX'S TOTAL LIABILITY EXCEED THE SUM
 * PAID TO PLX FOR THE PRODUCT LICENSED HEREUNDER.
 *
 ******************************************************************************/

/******************************************************************************
 *
 * File Name:
 *
 *      CommonApi.c
 *
 * Description:
 *
 *      API functions common to all PLX chips
 *
 * Revision History:
 *
 *      03-01-06 : PCI SDK v4.40
 *
 ******************************************************************************/


#include "ApiFunctions.h"
#include "CommonApi.h"
#include "GlobalVars.h"
#include "PciSupport.h"
#include "PlxInterrupt.h"
#include "SupportFunc.h"




/******************************************************************************
 *
 * Function   :  PlxDeviceFind
 *
 * Description:  Search for a specific device using device location parameters
 *
 ******************************************************************************/
RETURN_CODE
PlxDeviceFind(
    DEVICE_EXTENSION *pdx,
    DEVICE_LOCATION  *pDeviceCriteria,
    U32              *pSelection
    )
{
    U32            MatchFound;
    BOOLEAN        ContinueComparison;
    DEVICE_OBJECT *fdo;


    // Verify pointers
    if (pDeviceCriteria == NULL || pSelection == NULL)
        return ApiNullParam;

    if (pdx->pDeviceObject == NULL)
        return ApiFailed;

    if (pdx->pDeviceObject->DriverObject == NULL)
        return ApiFailed;

    MatchFound = 0;
    fdo        = pdx->pDeviceObject->DriverObject->DeviceObject;

    // Compare with items in device list
    while (fdo != NULL)
    {
        // Get the device extension
        pdx = fdo->DeviceExtension;

        ContinueComparison = TRUE;

        // Compare Serial Number
        if ((pDeviceCriteria->SerialNumber[0] != '\0') && ContinueComparison)
        {
            if (_stricmp(
                    pdx->Device.SerialNumber,
                    pDeviceCriteria->SerialNumber
                    ) != 0)
            {
                ContinueComparison = FALSE;
            }
        }

        // Compare the Bus number
        if ((pDeviceCriteria->BusNumber != (U8)-1) && ContinueComparison)
        {
            if (pDeviceCriteria->BusNumber != pdx->Device.BusNumber)
                ContinueComparison = FALSE;
        }

        // Compare Slot Number
        if ((pDeviceCriteria->SlotNumber != (U8)-1) && ContinueComparison)
        {
            if (pDeviceCriteria->SlotNumber != pdx->Device.SlotNumber)
                ContinueComparison = FALSE;
        }

        // Compare Device ID
        if ((pDeviceCriteria->DeviceId != (U16)-1) && ContinueComparison)
        {
            if (pDeviceCriteria->DeviceId != pdx->Device.DeviceId)
                ContinueComparison = FALSE;
        }

        // Compare Vendor ID
        if ((pDeviceCriteria->VendorId != (U16)-1) && ContinueComparison)
        {
            if (pDeviceCriteria->VendorId != pdx->Device.VendorId)
                ContinueComparison = FALSE;
        }

        if (ContinueComparison == TRUE)
        {
            // Match found, check if it is the device we want
            if (MatchFound++ == *pSelection)
            {
                // Copy the device information
                RtlCopyMemory(
                    pDeviceCriteria,
                    &pdx->Device,
                    sizeof(DEVICE_LOCATION)
                    );
            }
        }

        fdo = fdo->NextDevice;
    }

    // Return the number of matched devices
    *pSelection = MatchFound;

    return ApiSuccess;
}




/*********************************************************************
 *
 * Function   :  PlxChipTypeGet
 *
 * Description:  Gets the PLX chip type and revision
 *
 *********************************************************************/
VOID
PlxChipTypeGet(
    DEVICE_EXTENSION *pdx,
    U32              *pChipType,
    U8               *pRevision
    )
{
    U32 RegValue;


    // Set chip type
    *pChipType = PLX_CHIP_TYPE;

    switch (*pChipType)
    {
        case 0x9080:
        case 0x9054:
        case 0x9056:
        case 0x9656:
            // Verify by reading hard-coded ID
            RegValue =
                PLX_REG_READ(
                    pdx,
                    0x70               // Hard-coded ID register
                    );

            if (((RegValue & 0xFFFF) == 0x10b5) &&
                ((RegValue >> 16) == *pChipType))
            {
                // Get revision
                RegValue =
                    PLX_REG_READ(
                        pdx,
                        0x74           // Revision ID
                        );

                // 9054 requires additional verification
                if (*pChipType != 0x9054)
                {
                    *pRevision = (U8)RegValue;
                }
                else
                {
                    // AA & AB versions have same revision ID
                    if (RegValue == 0xA)
                    {
                        PLX_PCI_REG_READ(
                            pdx,
                            CFG_REV_ID,
                            &RegValue
                            );

                        if ((RegValue & 0xf) == 0xb)
                            *pRevision = 0xAB;
                        else
                            *pRevision = 0xAA;
                    }
                    else
                    {
                        if (RegValue == 0xC)
                        {
                            // Set value for AC revision
                            *pRevision = 0xAC;
                        }
                        else
                        {
                            *pRevision = (U8)RegValue;
                        }
                    }
                }
            }
            break;

        case 0x9050:
        case 0x9030:
            // 9050/52 require additional verification
            if (*pChipType == 0x9030)
            {
                *pRevision = 0xAA;
            }
            else
            {
                // Read 9050/9052 PCI revision
                PLX_PCI_REG_READ(
                    pdx,
                    CFG_REV_ID,
                    &RegValue
                    );

                if ((RegValue & 0xF) == 0x2)
                {
                    *pRevision = 2;
                }
                else
                {
                    *pRevision = 1;
                }
            }
            break;

        case 0x8311:
            // Only AA revision exists
            *pRevision = 0xAA;
            break;

        default:
            *pChipType = 0x0;
            *pRevision = 0x0;
            break;
    }
}




/******************************************************************************
 *
 * Function   :  PlxNotificationRegisterFor
 *
 * Description:  Registers a wait object for notification on interrupt(s)
 *
 ******************************************************************************/
RETURN_CODE
PlxNotificationRegisterFor(
    DEVICE_EXTENSION  *pdx,
    PLX_INTR          *pPlxIntr,
    PLX_NOTIFY_OBJECT *pEvent,
    VOID              *pOwner
    )
{
    PKEVENT          pKEvent;
    NTSTATUS         status;
    PLX_WAIT_OBJECT *pWaitObject;


    // Setup driver access to the user event handle
    status =
        ObReferenceObjectByHandle(
            (HANDLE)pEvent->hEvent, // Handle
            EVENT_MODIFY_STATE,     // Desired Access
            *ExEventObjectType,     // Object type
            KernelMode,             // Access Mode
            &pKEvent,               // Object pointer
            NULL                    // Handle information
            );

    if (status != STATUS_SUCCESS)
        return ApiInvalidHandle;

    // Allocate a new wait object
    pWaitObject =
        ExAllocatePool(
            NonPagedPool,
            sizeof(PLX_WAIT_OBJECT)
            );

    if (pWaitObject == NULL)
    {
        DebugPrintf((
            "ERROR - memory allocation for interrupt wait object failed\n"
            ));

        // De-reference the object
        ObDereferenceObject(
            pKEvent
            );

        return ApiInsufficientResources;
    }

    // Record the wait object
    pEvent->pWaitObject = (PLX_UINT_PTR)pWaitObject;

    // Record the owner
    pWaitObject->pOwner = pOwner;

    // Store kernel event handle
    pWaitObject->pKEvent = pKEvent;

    // Clear interrupt source
    pWaitObject->IntSource = INTR_TYPE_NONE;

    // Set interrupt notification flags
    PlxChipSetInterruptNotifyFlags(
        pPlxIntr,
        pWaitObject
        );

    // Add to list of waiting objects
    ExInterlockedInsertTailList(
        &(pdx->List_WaitObjects),
        &(pWaitObject->ListEntry),
        &(pdx->Lock_WaitObjectsList)
        );

    DebugPrintf((
        "Registered interrupt wait object (%p)\n",
        pWaitObject
        ));

    return ApiSuccess;
}




/******************************************************************************
 *
 * Function   :  PlxNotificationWait
 *
 * Description:  Put the process to sleep until wake-up event occurs or timeout
 *
 ******************************************************************************/
RETURN_CODE
PlxNotificationWait(
    DEVICE_EXTENSION  *pdx,
    PLX_NOTIFY_OBJECT *pEvent,
    U32                Timeout_ms
    )
{
    // Implemented at API level in Windows driver
    return ApiUnsupportedFunction;
}




/******************************************************************************
 *
 * Function   :  PlxNotificationCancel
 *
 * Description:  Cancels a registered notification event
 *
 ******************************************************************************/
RETURN_CODE
PlxNotificationCancel(
    DEVICE_EXTENSION  *pdx,
    PLX_NOTIFY_OBJECT *pEvent,
    VOID              *pOwner
    )
{
    KIRQL            IrqL_Original;
    BOOLEAN          bRemove;
    PLIST_ENTRY      pEntry;
    PLX_WAIT_OBJECT *pWaitObject;


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

    pEntry = pdx->List_WaitObjects.Flink;

    // Traverse list to find the desired list object
    while (pEntry != &(pdx->List_WaitObjects))
    {
        // Get the object
        pWaitObject =
            CONTAINING_RECORD(
                pEntry,
                PLX_WAIT_OBJECT,
                ListEntry
                );

        // Default to not remove
        bRemove = FALSE;

        // Determine if object should be removed
        if (pOwner == pWaitObject->pOwner)
        {
            if (pEvent == NULL)
            {
                bRemove = TRUE;
            }
            else if ((PLX_UINT_PTR)pWaitObject == pEvent->pWaitObject)
            {
                bRemove = TRUE;
            }
        }

⌨️ 快捷键说明

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