Bir PCI aygıtında yapılandırma ve konum bilgilerinin nasıl edinilir

Makale çevirileri Makale çevirileri
Makale numarası: 253232 - Bu makalenin geçerli olduğu ürünleri görün.
Hepsini aç | Hepsini kapa

Özet

Bu makalede, nasıl yapılandırmasını alabilir ve konum bilgilerinin (örneğin, BusNumber DeviceNumber ve işlev numarası) bir çevre Bileşen Bağlantısı (PCI) hedef aygıtın sürücüsü bir parçası olan bir sürücü aygıt bir işlev olarak yığın veya sürücü süzgeç açıklanır.

Daha fazla bilgi

Windows NT 4. 0'da, veri yolu tarama ve HalGetBusData ve HalGetBusDataByOffset Apı'lerini çağırmadan sürücüleri bu bilgileri alın. Windows 2000 ve sonraki Windows işletim sistemlerinde, donanım veri değil, HAL ve ilgili veri yoluna sürücüleri tarafından denetlenmektedir. Bu nedenle, veri yolu ile ilgili bilgi sağlamak için kullanılan HAL Apı'leri tüm Windows 2000 ve sonraki Windows işletim sistemlerinde eskidir.

Windows 2000 ve sonraki Windows işletim sistemlerinde, bir sürücü aygıtı kaynakları bulmak üzere sorgulama gerekmez. Sürücü, IRP_MN_START_DEVICE isteğinde Tak ve Kullan (PnP) Yöneticisi kaynakları alır. Genellikle, well-written sürücü düzgün çalışabilmesi için bu bilgileri gerektirecek değil. Herhangi bir nedenle, bu bilgileri sürücü gerektiriyorsa, kod örneğini izlemek için kaynakların nasıl edinilir gösterir. Aygıtın PnP isteği göndermek için temel (PDO) fiziksel aygıt nesnesi gerektirdiğinden, sürücü aygıtın sürücü yığının parçası olmalıdır.

Aşağıdaki kod örneği, yapılandırma bilgilerini almak gösterilmiştir:
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 g/Ç isteği paketleri (ırp'leri) yalnızca gönderebilirsiniz için DISPATCH_LEVEL yapılandırma bilgilerini almak için yukarıdaki işlevi kullanamazsınız.

Yapılandırma alanı DISPATCH_LEVEL adresindeki erişmek için aşağıdaki adımları gerçekleştirebilirsiniz:
  1. PCI veri yolu sürücüsünden (BUS_INTERFACE_STANDARD) doğrudan arama arabirimi yapısını almak için PASSIVE_LEVEL adresindeki bir IRP_MN_QUERY_INTERFACE gönderin. Bu bir disk belleği olmayan havuz belleğinde (genellikle DevcieExtension) depolar.
  2. GetBusData ve SetBusData DISPATCH_LEVEL adresindeki konfigürasyon alanına erişmeye arayın.
  3. Döndürdüğü önce PCI veri yolu sürücüsü bir başvuru sayısı; bu nedenle, artık gerekli olmadığında arabirimi KQUEUE arabirimde alır.
  4. Aşağıdaki işlevi PASSIVE_LEVEL BUS_INTERFACE_STANDARD almak için kullanın:
    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;
    
    }
    					
Aşağıdaki kod, nasıl Veriyolu veri almak için <a0>Arabirim</a0> doğrudan arama işlevini kullanabilirsiniz gösterir.
    bytes = busInterfaceStandard.GetBusData(<BR/>
                    busInterfaceStandard.Context,
                    PCI_WHICHSPACE_CONFIG,
                    Buffer
                    Offset,
                    Length);
				
Arabirim artık gerekmeyen izlemek için bu kodu olan arabirim KQUEUE için şu kodu kullanın. Arabirim KQUEUE sonra herhangi bir arabirim yordamlar çağırmayın.
    (busInterfaceStandard.InterfaceDereference)(
                (PVOID)busInterfaceStandard.Context);
				
Bus, işlev ve aygıt numaraları gibi almak için hedef aygıt PDO ilgili olarak üzerinde IoGetDeviceProperty işlevini kullanın:
    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);

				
önemli PCI veri yolu numarası dinamik olabilir ve herhangi bir anda değiştirebilirsiniz. Bu nedenle, veri yolu numarası üzerinde bağımlı bilgileri PCI bağlantı noktalarını doğrudan erişmek için veya iyi değildir. Bu, sistem hatasına neden olabilir.

Özellikler

Makale numarası: 253232 - Last Review: 8 Eylül 2005 Perşembe - Gözden geçirme: 2.1
Bu makaledeki bilginin uygulandığı durum:
  • 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 Edition
  • Microsoft Windows Server 2003 Service Pack 1
Anahtar Kelimeler: 
kbmt kbhowto kbwdm KB253232 KbMttr
Machine-translated Article
ÖNEMLİ: Bu makale, bir kişi tarafından çevrilmek yerine, Microsoft makine-çevirisi yazılımı ile çevrilmiştir. Microsoft size hem kişiler tarafından çevrilmiş, hem de makine-çevrisi ile çevrilmiş makaleler sunar. Böylelikle, bilgi bankamızdaki tüm makalelere, kendi dilinizde ulaşmış olursunuz. Bununla birlikte, makine tarafından çevrilmiş makaleler mükemmel değildir. Bir yabancının sizin dilinizde konuşurken yapabileceği hatalar gibi, makale; kelime dağarcığı, söz dizim kuralları veya dil bilgisi açısından yanlışlar içerebilir. Microsoft, içeriğin yanlış çevrimi veya onun müşteri tarafından kullanımından doğan; kusur, hata veya zarardan sorumlu değildir. Microsoft ayrıca makine çevirisi yazılımını sıkça güncellemektedir.
Makalenin İngilizcesi aşağıdaki gibidir:253232

Geri Bildirim Ver

 

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