PCI 장치의 구성 및 위치 정보를 가져오는 방법

기술 자료 번역 기술 자료 번역
기술 자료: 253232 - 이 문서가 적용되는 제품 보기.
모두 확대 | 모두 축소

요약

이 문서에서는 구성을 가져올 방법과 대상 장치 드라이버를 일부인 드라이버에서 주변 구성 요소 상호 연결 (PCI) 장치의 위치 정보 (예: BusNumber, DeviceNumber, 및 함수 번호) 하나를 함수로 스택 또는 필터 드라이버를 설명합니다.

추가 정보

Windows NT 4 .0에서 드라이버가 버스 검색 및 HalGetBusData 및 HalGetBusDataByOffset API를 호출하여 이 정보를 가져옵니다. Windows 2000 및 이후 Windows 운영 체제, 하드웨어 버스는 각각의 버스 드라이버 및 HAL을 않는 제어됩니다. 따라서, 버스 관련 정보를 제공하는 데 사용되는 Hal API의 모든 Windows 2000 및 이후 Windows 운영 체제에서 사용되지 않습니다.

Windows 2000 및 이후 Windows 운영 체제에 따라 드라이버를 장치 리소스를 찾기 위해 쿼리할 필요가 없습니다. 드라이버가 IRP_MN_START_DEVICE 요청 플러그 앤 플레이 (PnP) 관리자가 리소스를 가져옵니다. 일반적으로 잘 작성된 드라이버가 제대로 작동하려면 이 정보가 필요하지 않습니다. 어떤 이유로 드라이버가 이 정보를 요구하는 경우 따라야 하는 코드 샘플에서는 리소스를 가져오는 방법을 보여 줍니다. PnP 요청을 보낼 수 있는 장치 (PDO가) 내부 실제 장치 개체를 필요하므로 드라이버가 있는 장치 드라이버 스택에 포함되어야 합니다.

다음 코드 샘플에서는 구성 정보를 가져오는 방법을 보여 줍니다.
NTSTATUS
ReadWriteConfigSpace(
    IN PDEVICE_OBJECT DeviceObject,
    IN ULONG	      ReadOrWrite, // 0 for read 1 for write
    IN PVOID	      Buffer,
    IN ULONG	      Offset,
    IN ULONG	      Length
    )
{
    KEVENT event;
    NTSTATUS status;
    PIRP irp;
    IO_STATUS_BLOCK ioStatusBlock;
    PIO_STACK_LOCATION irpStack;
    PDEVICE_OBJECT targetObject;

    PAGED_CODE();

    KeInitializeEvent( &event, NotificationEvent, FALSE );

    targetObject = IoGetAttachedDeviceReference( DeviceObject );

    irp = IoBuildSynchronousFsdRequest( IRP_MJ_PNP,
                                        targetObject,
                                        NULL,
                                        0,
                                        NULL,
                                        &event,
                                        &ioStatusBlock );

    if (irp == NULL) {
        status = STATUS_INSUFFICIENT_RESOURCES;
        goto End;
    }

    irpStack = IoGetNextIrpStackLocation( irp );

    if (ReadOrWrite == 0) {
        irpStack->MinorFunction = IRP_MN_READ_CONFIG;
    }else {
        irpStack->MinorFunction = IRP_MN_WRITE_CONFIG;
    }

    irpStack->Parameters.ReadWriteConfig.WhichSpace = PCI_WHICHSPACE_CONFIG;
    irpStack->Parameters.ReadWriteConfig.Buffer = Buffer;
    irpStack->Parameters.ReadWriteConfig.Offset = Offset;
    irpStack->Parameters.ReadWriteConfig.Length = Length;

    // 
    // Initialize the status to error in case the bus driver does not 
    // set it correctly.
    // 

    irp->IoStatus.Status = STATUS_NOT_SUPPORTED ;

    status = IoCallDriver( targetObject, irp );

    if (status == STATUS_PENDING) {

        KeWaitForSingleObject( &event, Executive, KernelMode, FALSE, NULL );
        status = ioStatusBlock.Status;
    }

End:
    // 
    // Done with reference
    // 
    ObDereferenceObject( targetObject );

    return status;

}
				
PASSIVE_LEVEL 때 해당 PnP I/O 요청 패킷 (IRP) 보낼 수만 있습니다 때문에 DISPATCH_LEVEL 때 구성 정보를 얻을 수 위의 함수를 사용할 수 없습니다.

DISPATCH_LEVEL 구성 공간을 액세스하려면 다음 단계를 수행할 수 있습니다.
  1. IRP_MN_QUERY_INTERFACE PASSIVE_LEVEL PCI 버스 드라이버에서 직접 호출을 인터페이스 구조 (BUS_INTERFACE_STANDARD) 가져올 때 보냅니다. 비페이징된 풀 메모리 (일반적으로 DevcieExtension) 에 저장하십시오.
  2. SetBusData 및 GetBusData DISPATCH_LEVEL 때 구성 공간을 액세스하려면 호출하십시오.
  3. 반환하기 전에 더 이상 필요하지 않은 경우 인터페이스를 역참조해야 합니다 있으므로 PCI 버스 드라이버 인터페이스의 참조 횟수를 걸립니다.
  4. 다음 함수는 해당 BUS_INTERFACE_STANDARD PASSIVE_LEVEL 때 얻을 수:
    NTSTATUS
    GetPCIBusInterfaceStandard(
        IN  PDEVICE_OBJECT DeviceObject,
        OUT PBUS_INTERFACE_STANDARD	BusInterfaceStandard
        )
    /*++
    
    Routine Description:
    
        This routine gets the bus interface standard information from the PDO.
    
    Arguments:
    
        DeviceObject - Device object to query for this information.
    
        BusInterface - Supplies a pointer to the retrieved information.
    
    Return Value:
    
        NT status.
    
    --*/ 
    {
        KEVENT event;
        NTSTATUS status;
        PIRP irp;
        IO_STATUS_BLOCK ioStatusBlock;
        PIO_STACK_LOCATION irpStack;
        PDEVICE_OBJECT targetObject;
    
        Bus_KdPrint(("GetPciBusInterfaceStandard entered.\n"));
    
        KeInitializeEvent( &event, NotificationEvent, FALSE );
    
        targetObject = IoGetAttachedDeviceReference( DeviceObject );
    
        irp = IoBuildSynchronousFsdRequest( IRP_MJ_PNP,
                                            targetObject,
                                            NULL,
                                            0,
                                            NULL,
                                            &event,
                                            &ioStatusBlock );
    
        if (irp == NULL) {
            status = STATUS_INSUFFICIENT_RESOURCES;
            goto End;
        }
    
        irpStack = IoGetNextIrpStackLocation( irp );
        irpStack->MinorFunction = IRP_MN_QUERY_INTERFACE;
        irpStack->Parameters.QueryInterface.InterfaceType = 
                            (LPGUID) &GUID_BUS_INTERFACE_STANDARD ;
        irpStack->Parameters.QueryInterface.Size = sizeof(BUS_INTERFACE_STANDARD);
        irpStack->Parameters.QueryInterface.Version = 1;
        irpStack->Parameters.QueryInterface.Interface = (PINTERFACE)
    BusInterfaceStandard;
        irpStack->Parameters.QueryInterface.InterfaceSpecificData = NULL;
    
        // 
        // Initialize the status to error in case the bus driver does not 
        // set it correctly.
        // 
    
        irp->IoStatus.Status = STATUS_NOT_SUPPORTED ;
    
        status = IoCallDriver( targetObject, irp );
    
        if (status == STATUS_PENDING) {
    
            KeWaitForSingleObject( &event, Executive, KernelMode, FALSE, NULL );
            status = ioStatusBlock.Status;
        }
    
    End:
        // 
        // Done with reference
        // 
        ObDereferenceObject( targetObject );
    
        return status;
    
    }
    					
인터페이스를 직접 호출 함수를 버스 데이터를 가져오는 방법을 보여 주는 코드입니다.
    bytes = busInterfaceStandard.GetBusData(<BR/>
                    busInterfaceStandard.Context,
                    PCI_WHICHSPACE_CONFIG,
                    Buffer
                    Offset,
                    Length);
				
인터페이스를 더 이상 필요할 때 따라야 하는 코드 사용하여 인터페이스를 역참조할 수 다음 코드를 사용합니다. 인터페이스를 역참조 후 모든 인터페이스 루틴을 호출하지 마십시오.
    (busInterfaceStandard.InterfaceDereference)(
                (PVOID)busInterfaceStandard.Context);
				
IoGetDeviceProperty 함수를 대상 장치에 대해 PDO를 버스, 함수 및 장치 번호 같이 가져올 수:
    ULONG   propertyAddress, length;
    USHORT  FunctionNumber; DeviceNumber;
    
    // 
    // Get the BusNumber. Please read the warning to follow.
    // 

    IoGetDeviceProperty(PhysicalDeviceObject,
                        DevicePropertyBusNumber,
                        sizeof(ULONG),
                        (PVOID)&BusNumber,
                        &length);

    // 
    // Get the DevicePropertyAddress
    // 
    IoGetDeviceProperty(PhysicalDeviceObject,
                     DevicePropertyAddress,
                     sizeof(ULONG),
                     (PVOID)&propertyAddress,
                     &length);
    // 
    // For PCI, the DevicePropertyAddress has device number 
    // in the high word and the function number in the low word. 
    // 
    FunctionNumber = (USHORT)((propertyAddress) & 0x0000FFFF);
    DeviceNumber = (USHORT)(((propertyAddress) >> 16) & 0x0000FFFF);

				
중요 PCI 버스 번호가 동적 수 있으며 시점에 변경할 수 있습니다. 따라서 좋은 버스 번호에서 종속된 또는 정보를 PCI 포트에 직접 액세스할 수 없습니다. 시스템 오류가 발생할 수 있습니다.

속성

기술 자료: 253232 - 마지막 검토: 2005년 9월 8일 목요일 - 수정: 2.1
본 문서의 정보는 다음의 제품에 적용됩니다.
  • Microsoft Win32 Device Driver Kit for Windows 2000
  • Microsoft Windows XP Driver Development Kit
  • Microsoft Windows Server 2003 Driver Development Kit (DDK)
  • Microsoft Windows 2000 Professional Edition
  • Microsoft Windows XP Home Edition
  • Microsoft Windows XP Professional
  • Microsoft Windows Server 2003 Service Pack 1
키워드:?
kbmt kbhowto kbwdm KB253232 KbMtko
기계 번역된 문서
중요: 본 문서는 전문 번역가가 번역한 것이 아니라 Microsoft 기계 번역 소프트웨어로 번역한 것입니다. Microsoft는 번역가가 번역한 문서 및 기계 번역된 문서를 모두 제공하므로 Microsoft 기술 자료에 있는 모든 문서를 한글로 접할 수 있습니다. 그러나 기계 번역 문서가 항상 완벽한 것은 아닙니다. 따라서 기계 번역 문서에는 마치 외국인이 한국어로 말할 때 실수를 하는 것처럼 어휘, 구문 또는 문법에 오류가 있을 수 있습니다. Microsoft는 내용상의 오역 또는 Microsoft 고객이 이러한 오역을 사용함으로써 발생하는 부 정확성, 오류 또는 손해에 대해 책임을 지지 않습니다. Microsoft는 이러한 문제를 해결하기 위해 기계 번역 소프트웨어를 자주 업데이트하고 있습니다.

피드백 보내기

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com