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

📄 pcisupport.c

📁 本压缩包为作者截取的PCI9054的WDM官方驱动源码。欢迎下载。
💻 C
📖 第 1 页 / 共 2 页
字号:
/*******************************************************************************
 * 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:
 *
 *      PciSupport.c
 *
 * Description:
 *
 *      This file contains the PCI support functions
 *
 * Revision History:
 *
 *      02-01-06 : PCI SDK v4.40
 *
 ******************************************************************************/


#include "PciSupport.h"
#include "PlugPlay.h"
#include "PlxChip.h"




/******************************************************************************
 *
 * Function   :  PlxPciRegisterRead
 *
 * Description:  Reads a PCI register at the specified offset
 *
 ******************************************************************************/
U32
PlxPciRegisterRead(
    DEVICE_EXTENSION *pdx,
    U8                bus,
    U8                slot,
    U16               offset,
    RETURN_CODE      *pReturnCode
    )
{
    U32            RegisterValue;
    NTSTATUS       status;
    PDEVICE_OBJECT fdo;


    if (pdx->pDeviceObject == NULL)
    {
        if (pReturnCode != NULL)
            *pReturnCode = ApiNullParam;
        return (U32)-1;
    }

    if (pdx->pDeviceObject->DriverObject == NULL)
    {
        if (pReturnCode != NULL)
            *pReturnCode = ApiNullParam;
        return (U32)-1;
    }

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

    // Now parse through all the functional devices objects
    while (fdo != NULL)
    {
        pdx = fdo->DeviceExtension;

        if (pdx == NULL)
        {
            DebugPrintf(("ERROR - ConfigRegisterRead() NULL driver object\n"));
            if (pReturnCode != NULL)
                *pReturnCode = ApiConfigAccessFailed;
            return (U32)-1;
        }

        // Compare the bus and slot numbers
        if ((bus  == pdx->Device.BusNumber) &&
            (slot == pdx->Device.SlotNumber))
        {
            // Read the register
            status =
                PciRegisterBufferRead(
                    fdo,
                    offset,
                    &RegisterValue,
                    sizeof(U32)
                    );

            if ( !NT_SUCCESS(status) )
            {
                DebugPrintf(("ERROR - Unable to read PCI Config Register\n"));
                if (pReturnCode != NULL)
                    *pReturnCode = ApiConfigAccessFailed;

                return (U32)-1;
            }

            if (pReturnCode != NULL)
                *pReturnCode = ApiSuccess;

            return RegisterValue;
        }

        // Increment to next device
        fdo = fdo->NextDevice;
    }

    // If we reach here, then the device was not located

    if (pReturnCode != NULL)
        *pReturnCode = ApiConfigAccessFailed;

    return (U32)-1;
}




/******************************************************************************
 *
 * Function   :  PlxPciRegisterWrite
 *
 * Description:  Writes a value to a PCI register at the specified offset
 *
 ******************************************************************************/
RETURN_CODE
PlxPciRegisterWrite(
    DEVICE_EXTENSION *pdx,
    U8                bus,
    U8                slot,
    U16               offset,
    U32               value
    )
{
    NTSTATUS       status;
    PDEVICE_OBJECT fdo;


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

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

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

    // Now parse through all the functional devices objects
    while (fdo != NULL)
    {
        pdx = fdo->DeviceExtension;

        if (pdx == NULL)
        {
            DebugPrintf(("ERROR - ConfigRegisterRead() NULL driver object\n"));
            return ApiConfigAccessFailed;
        }

        // Compare the bus and slot numbers
        if ((bus  == pdx->Device.BusNumber) &&
            (slot == pdx->Device.SlotNumber))
        {
            // Read the register
            status =
                PciRegisterBufferWrite(
                    fdo,
                    offset,
                    value
                    );

            if ( !NT_SUCCESS(status) )
            {
                DebugPrintf(("ERROR - Unable to write PCI Config Register\n"));
                return ApiConfigAccessFailed;
            }

            return ApiSuccess;
        }

        // Increment to next device
        fdo = fdo->NextDevice;
    }

    // If we reach here, then the device was not located

    return ApiConfigAccessFailed;
}




/******************************************************************************
 *
 * Function   :  PciRegisterBufferRead
 *
 * Description:  Read a PCI register of a device using the PnP Bus Manager
 *
 ******************************************************************************/
NTSTATUS
PciRegisterBufferRead(
    PDEVICE_OBJECT  fdo,
    U16             offset,
    VOID           *buffer,
    U16             size
    )
{
    PIRP               pIrp;
    KEVENT             event;
    NTSTATUS           status;
    PIO_STACK_LOCATION stack;


    pIrp =
        IoAllocateIrp(
            fdo->StackSize,
            FALSE
            );

    if (pIrp == NULL)
    {
        DebugPrintf(("ERROR - ConfigRegisterBufferRead() unable to allocate IRP\n"));
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    // Initialize kernel event
    KeInitializeEvent(
        &event,
        NotificationEvent,
        FALSE
        );

    stack =
        IoGetNextIrpStackLocation(
            pIrp
            );

    // Fill the IRP
    pIrp->IoStatus.Status                        = STATUS_NOT_SUPPORTED;
    stack->MajorFunction                         = IRP_MJ_PNP;
    stack->MinorFunction                         = IRP_MN_READ_CONFIG;
    stack->Parameters.ReadWriteConfig.WhichSpace = PCI_WHICHSPACE_CONFIG;
    stack->Parameters.ReadWriteConfig.Buffer     = buffer;
    stack->Parameters.ReadWriteConfig.Offset     = offset;
    stack->Parameters.ReadWriteConfig.Length     = size;

    IoSetCompletionRoutine(
        pIrp,
        (PIO_COMPLETION_ROUTINE)OnRequestComplete,
        (PVOID)&event,
        TRUE,
        TRUE,
        TRUE
        );

    // Send the packet
    status =
        IoCallDriver(
            ((DEVICE_EXTENSION *) fdo->DeviceExtension)->pLowerDeviceObject,
            pIrp
            );

    if (status == STATUS_PENDING)
    {
        // Wait for completion
        KeWaitForSingleObject(
            &event,
            Executive,
            KernelMode,
            FALSE,
            NULL
            );

        status = pIrp->IoStatus.Status;
    }

    // Release the IRP
    IoFreeIrp(
        pIrp
        );

    return status;
}




/******************************************************************************
 *
 * Function   :  PciRegisterBufferWrite
 *
 * Description:  Writes to a PCI register of a device using the PnP Bus Manager
 *
 ******************************************************************************/
NTSTATUS
PciRegisterBufferWrite(
    PDEVICE_OBJECT  fdo,
    U16             offset,
    U32             value
    )
{
    PIRP               pIrp;
    KEVENT             event;
    NTSTATUS           status;
    PIO_STACK_LOCATION stack;


    pIrp =
        IoAllocateIrp(
            fdo->StackSize,
            FALSE
            );

    if (pIrp == NULL)
    {
        DebugPrintf(("ERROR - ConfigRegisterBufferWrite() unable to allocate IRP\n"));
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    // Initialize kernel event
    KeInitializeEvent(
        &event,
        NotificationEvent,
        FALSE
        );

    stack =
        IoGetNextIrpStackLocation(
            pIrp
            );

    // Fill the IRP
    pIrp->IoStatus.Status                        = STATUS_NOT_SUPPORTED;
    stack->MajorFunction                         = IRP_MJ_PNP;
    stack->MinorFunction                         = IRP_MN_WRITE_CONFIG;
    stack->Parameters.ReadWriteConfig.WhichSpace = PCI_WHICHSPACE_CONFIG;
    stack->Parameters.ReadWriteConfig.Buffer     = &value;
    stack->Parameters.ReadWriteConfig.Offset     = offset;
    stack->Parameters.ReadWriteConfig.Length     = sizeof(U32);

    IoSetCompletionRoutine(
        pIrp,
        (PIO_COMPLETION_ROUTINE)OnRequestComplete,
        (PVOID)&event,
        TRUE,
        TRUE,
        TRUE
        );

    // Send the packet
    status =
        IoCallDriver(
            ((DEVICE_EXTENSION *)fdo->DeviceExtension)->pLowerDeviceObject,
            pIrp
            );

    if (status == STATUS_PENDING)
    {
        // Wait for completion
        KeWaitForSingleObject(
            &event,
            Executive,
            KernelMode,
            FALSE,
            NULL
            );
        status = pIrp->IoStatus.Status;
    }

    IoFreeIrp(
        pIrp
        );

    return STATUS_SUCCESS;
}




/******************************************************************************
 *
 * Function   :  PlxPciRegisterRead_Unsupported
 *
 * Description:  Reads a PCI register by bypassing the OS services
 *
 ******************************************************************************/
U32
PlxPciRegisterRead_Unsupported(
    DEVICE_EXTENSION *pdx,
    U8                bus,
    U8                slot,
    U16               offset,
    RETURN_CODE      *pReturnCode
    )

⌨️ 快捷键说明

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