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

📄 findpci.c

📁 dma驱动开发程序
💻 C
字号:
/*++

Copyright (c) 1997-1998  Microsoft Corporation

Module Name:

    findpci.c

Abstract:

    This file contains generic routines to locate a PCI device.

Author:

    Steve Dziok (SteveDz)

Environment:

    Kernel mode

Revision History:


--*/

#include "pcidma.h"


NTSTATUS
FindPciDevice(
    IN USHORT   VendorId,
    IN USHORT   DeviceId,
    OUT PPCI_DEVICE_LIST PciDeviceList
    )

/*++

Routine Description:

    Find all the PCI devices for the VendorId and DeviceId specified by the
    caller.  The located devices are in the returned PCI_DEVICE_LIST.

    If the caller specifies VendorId == PC_INVALID_VENDORID, then return all
    valid PCI devices on the system.

Arguments:

    VendorId - The manufacturer of the device.  Assigned by the PCI SIG.  If
               this value is PC_INVALID_VENDORID (0xFFFF), then all valid PCI
               devices on the machine will be located.

    DeviceId - The particular device created by the manufacturer.  Assigned by
               the manufacturer.

    PciDeviceList - A list of all the PCI devices that match the VendorId and
                    DeviceId.  The list simply indicates the bus number and slot
                    number for each location.  A count field in the list indicates
                    how many devices were found.

Return Value:

    NTSTATUS

--*/
{
    ULONG                   busNumber = 0;
    ULONG                   count = 0;

    ULONG                   deviceNumber;
    ULONG                   functionNumber;

    NTSTATUS                status = STATUS_DEVICE_DOES_NOT_EXIST;

    PCI_SLOT_NUMBER         slotNumber;
    PCI_COMMON_CONFIG       pciData;
    PPCI_DEVICE_LOCATION    pciDeviceLocation;

    DebugPrint((3, "FindPciDevice \n"));

    //
    //
    // typedef struct _PCI_SLOT_NUMBER {
    //     union {
    //         struct {
    //             ULONG   DeviceNumber:5;
    //             ULONG   FunctionNumber:3;
    //             ULONG   Reserved:24;
    //         } bits;
    //         ULONG   AsULONG;
    //     } u;
    // } PCI_SLOT_NUMBER, *PPCI_SLOT_NUMBER;
    //

    slotNumber.u.AsULONG = 0;

    PciDeviceList->Count = 0;
    pciDeviceLocation = &PciDeviceList->List[0];

    //
    // Scan each bus.
    //

    for ( busNumber = 0;
            busNumber < MAX_PCI_BUSES;
            busNumber++ ) {

        //
        // Scan each device.
        //

        for ( deviceNumber = 0;
                deviceNumber < PCI_MAX_DEVICES;
                deviceNumber++ ) {

            slotNumber.u.bits.DeviceNumber = deviceNumber;

            //
            // Scan each function.
            //

            for ( functionNumber = 0;
                    functionNumber < PCI_MAX_FUNCTION;
                    functionNumber++ ) {

                slotNumber.u.bits.FunctionNumber = functionNumber;

                //
                // Check what's in the current slot.
                //

                if (!HalGetBusData(PCIConfiguration,
                                   busNumber,
                                   slotNumber.u.AsULONG,
                                   &pciData,
                                   sizeof(ULONG)
                                   ) ) {

                    //
                    // The specified PCI bus does not exist.  We are done
                    // with this bus.  Set the device number to the maximum
                    // and break out of the function loop.  This will scan
                    // the next system bus.  There is no guarantee that the
                    // system buses are sequentially ordered.
                    //

                    deviceNumber = PCI_MAX_DEVICES;

                    break;

                }

                if (pciData.VendorID == PCI_INVALID_VENDORID ) {

                    //
                    // Although the current function may show an invalid
                    // device, we really have to keep checking for functions
                    // on the current device.  This is required because the
                    // PCI specification is unclear whether function numbers
                    // in a PCI device must be numerically sequential.  For
                    // example, a particular PCI device could respond to
                    // functions 1, 3, and 4.
                    //

                    //
                    // Check next function.
                    //

                    continue;

                }

                DebugPrint((3,
                            "PCI device found: bus = 0x%x  slot = 0x%x\n",
                            busNumber,
                            slotNumber
                            ));

                //
                // Check if we need to return all devices or only those specified
                // by the caller.
                //

                if ( ( VendorId != PCI_INVALID_VENDORID ) &&
                        ( pciData.VendorID != VendorId || pciData.DeviceID != DeviceId )) {

                    DebugPrint((3,
                               "VendorId (0x%0x) or DeviceId (0x%0x) not as requested. \n",
                                pciData.VendorID,
                                pciData.DeviceID
                                ));

                    //
                    // Check next function.
                    //

                    continue;

                }

                DebugPrint((3, "VendorId and DeviceId match! \n"));

                //
                // At this point, we've found a valid PCI device.
                //

                //
                // Save the found information.
                //

                pciDeviceLocation->BusNumber = busNumber;
                pciDeviceLocation->SlotNumber = slotNumber;

                //
                // Increment the PCI device found count.
                //
                //
                // Point to the next location to store data.
                //

                pciDeviceLocation = &PciDeviceList->List[++count];

                //
                // Indicate at least one device found.
                //

                status = STATUS_SUCCESS;


            }   // functionNumber

        }   // deviceNumber

    }   // busNumber


    DebugPrint((1, "%d matching PCI devices found. \n", count));

    //
    // Update the number of devices in the found list.
    //

    PciDeviceList->Count = count;

    return status;

}   // FindPciDevice


⌨️ 快捷键说明

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