Bagaimana untuk mendapatkan informasi konfigurasi dan lokasi perangkat PCI

Terjemahan Artikel Terjemahan Artikel
ID Artikel: 253232 - Melihat produk di mana artikel ini berlaku.
Perbesar semua | Perkecil semua

RINGKASAN

Artikel ini menjelaskan bagaimana Anda bisa mendapatkan konfigurasi dan informasi lokasi (seperti BusNumber, DeviceNumber, dan fungsi nomor) perangkat perifer komponen interkoneksi (PCI) seorang sopir yang merupakan bagian dari pengandar perangkat target tumpukan baik sebagai fungsi atau filter sopir.

INFORMASI LEBIH LANJUT

Pada Windows NT 4.0, driver mendapatkan informasi ini dengan pemindaian bus dan memanggil HalGetBusData dan HalGetBusDataByOffset api. Pada Windows 2000 dan kemudian sistem operasi Windows, perangkat keras bus yang dikendalikan oleh sopir bus masing-masing mereka dan bukan oleh HAL. Oleh karena itu, semua api Hal yang digunakan untuk memberikan informasi yang berhubungan dengan bus jarang digunakan dalam Windows 2000 dan kemudian sistem operasi Windows.

Pada Windows 2000 dan kemudian sistem operasi Windows, sopir perlu query perangkat untuk menemukan sumber daya. Driver mendapatkan sumber daya dari manajer Plug and Play (PnP) dalam permintaan IRP_MN_START_DEVICE. Biasanya, sopir yang ditulis dengan baik tidak akan memerlukan informasi ini untuk berfungsi dengan benar. Jika untuk beberapa alasan pengandar memerlukan informasi ini, contoh kode untuk mengikuti menunjukkan bagaimana untuk mendapatkan sumber daya. Pengemudi harus menjadi bagian dari memori pengandar perangkat karena memerlukan objek fisik perangkat mendasari (PDO) perangkat untuk mengirim permintaan PnP.

Berikut kode sampel menunjukkan bagaimana untuk mendapatkan informasi konfigurasi:
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;

}
				
Karena Anda hanya dapat mengirimkan PnP paket permintaan (IRPs) di PASSIVE_LEVEL, Anda tidak dapat menggunakan fungsi di atas untuk mendapatkan informasi konfigurasi DISPATCH_LEVEL.

Anda dapat melakukan langkah-langkah berikut untuk mengakses konfigurasi ruang di DISPATCH_LEVEL:
  1. Mengirim IRP_MN_QUERY_INTERFACE di PASSIVE_LEVEL untuk mendapatkan struktur antarmuka langsung-panggilan (BUS_INTERFACE_STANDARD) dari sopir bus PCI. Menyimpan ini dalam memori kolam nonpaged (biasanya di DevcieExtension).
  2. Panggilan SetBusData dan GetBusData untuk mengakses konfigurasi ruang di DISPATCH_LEVEL.
  3. Sopir bus PCI mengambil hitungan referensi pada antarmuka sebelum kembali, sehingga Anda harus dereference antarmuka ketika itu tidak lagi diperlukan.
  4. Menggunakan fungsi berikut untuk mendapatkan BUS_INTERFACE_STANDARD di 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;
    
    }
    					
Kode berikut menunjukkan bagaimana Anda dapat menggunakan antarmuka langsung-panggilan fungsi untuk mendapatkan bus data.
    bytes = busInterfaceStandard.GetBusData(<BR/>
                    busInterfaceStandard.Context,
                    PCI_WHICHSPACE_CONFIG,
                    Buffer
                    Offset,
                    Length);
				
Ketika Anda tidak lagi memerlukan antarmuka, gunakan kode berikut untuk dereference antarmuka dengan kode untuk mengikuti. Jangan Panggil setiap antarmuka rutinitas setelah Anda dereference antarmuka.
    (busInterfaceStandard.InterfaceDereference)(
                (PVOID)busInterfaceStandard.Context);
				
Penggunaan IoGetDeviceProperty fungsi pada PDO perangkat sasaran untuk mendapatkan nomor Bus, fungsi, dan perangkat sebagai berikut:
    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);

				
Penting Nomor PCI Bus mungkin dinamis dan dapat berubah setiap saat. Oleh karena itu, hal ini tidak baik untuk bergantung pada nomor bus atau menggunakan informasi tersebut untuk mengakses port PCI secara langsung. Ini dapat menyebabkan kegagalan sistem.

Properti

ID Artikel: 253232 - Kajian Terakhir: 21 September 2011 - Revisi: 2.0
Berlaku bagi:
  • Microsoft Windows XP Driver Development Kit
  • Microsoft Windows 2000 Professional Edition
  • Microsoft Windows XP Home Edition
  • Microsoft Windows XP Professional
  • Microsoft Windows Server 2003 Service Pack 1
Kata kunci: 
kbhowto kbwdm kbmt KB253232 KbMtid
Penerjemahan Mesin
PENTING: Artikel ini diterjemahkan menggunakan perangkat lunak mesin penerjemah Microsoft dan bukan oleh seorang penerjemah. Microsoft menawarkan artikel yang diterjemahkan oleh seorang penerjemah maupun artikel yang diterjemahkan menggunakan mesin sehingga Anda akan memiliki akses ke seluruh artikel baru yang diterbitkan di Pangkalan Pengetahuan (Knowledge Base) dalam bahasa yang Anda gunakan. Namun, artikel yang diterjemahkan menggunakan mesin tidak selalu sempurna. Artikel tersebut mungkin memiliki kesalahan kosa kata, sintaksis, atau tata bahasa, hampir sama seperti orang asing yang berbicara dalam bahasa Anda. Microsoft tidak bertanggung jawab terhadap akurasi, kesalahan atau kerusakan yang disebabkan karena kesalahan penerjemahan konten atau penggunaannya oleh para pelanggan. Microsoft juga sering memperbarui perangkat lunak mesin penerjemah.
Klik disini untuk melihat versi Inggris dari artikel ini:253232

Berikan Masukan

 

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