Come ottenere le informazioni sulla configurazione e il percorso di una periferica PCI

Traduzione articoli Traduzione articoli
Identificativo articolo: 253232 - Visualizza i prodotti a cui si riferisce l?articolo.
Espandi tutto | Chiudi tutto

Sommario

In questo articolo viene descritto come è possibile ottenere la configurazione, e le informazioni di percorso (ad esempio BusNumber, DeviceNumber e numero funzione) di una periferica PCI (Peripheral Component Interconnect) in un driver che fa parte di driver del dispositivo di destinazione dello stack come una funzione o driver di filtro.

Informazioni

In Windows NT 4.0, i driver ottenere questa informazione analisi il bus e chiamando l'API di HalGetBusDataByOffset e HalGetBusData. In Windows 2000 e sistemi operativi successivi, i bus di hardware sono controllati dai driver del bus rispettivi e non da HAL. Pertanto, tutte le API di HAL che utilizzato per fornire informazioni relative al bus sono obsolete in Windows 2000 e sistemi operativi successivi.

In Windows 2000 e sistemi operativi successivi, un driver non è necessario eseguire una query il dispositivo per trovare le risorse. Il driver ottiene le risorse dal gestore Plug and Play (PnP) nella propria richiesta IRP_MN_START_DEVICE. In genere, un driver ben scritto non richiederebbe che queste informazioni per il corretto funzionamento. Se per qualche motivo il driver richiede queste informazioni, codice di esempio che attenersi alla seguente viene illustrato come ottenere le risorse. Il driver deve essere parte dello stack di driver della periferica perché richiede gli oggetti di dispositivo fisico (PDO) sottostanti del dispositivo per inviare la richiesta Plug and Play.

Nell'esempio di codice riportato di seguito viene illustrato come ottenere le informazioni di configurazione:
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;

}
				
poiché è solo possibile inviare il PnP pacchetti richiesta I/O (IRP) alla PASSIVE_LEVEL, è Impossibile utilizzare la funzione precedente per ottenere le informazioni di configurazione in DISPATCH_LEVEL.

È possibile eseguire la procedura seguente per accedere lo spazio di configurazione in DISPATCH_LEVEL:
  1. Inviare un IRP_MN_QUERY_INTERFACE alla PASSIVE_LEVEL per ottenere la struttura di interfaccia chiamata diretta (BUS_INTERFACE_STANDARD) dal driver del bus PCI. Archiviare questa in una memoria di pool non di paging (in genere in DevcieExtension).
  2. Chiamare il SetBusData e GetBusData per lo spazio di configurazione in DISPATCH_LEVEL di accedere.
  3. Il driver del bus PCI richiede un conteggio dei riferimenti sull'interfaccia prima della restituzione, in modo che è necessario risolvere l'interfaccia quando non è più necessario.
  4. Utilizzare la funzione riportata di seguito per ottenere il 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;
    
    }
    					
Il codice riportato di seguito viene illustrato come è possibile utilizzare la funzione di chiamata diretta di interfaccia per ottenere i dati del bus.
    bytes = busInterfaceStandard.GetBusData(<BR/>
                    busInterfaceStandard.Context,
                    PCI_WHICHSPACE_CONFIG,
                    Buffer
                    Offset,
                    Length);
				
non è più l'interfaccia, utilizzare il codice riportato di seguito per risolvere il riferimento dell'interfaccia con il codice seguente. Non chiamare qualsiasi routine interfaccia dopo risolvere il riferimento dell'interfaccia.
    (busInterfaceStandard.InterfaceDereference)(
                (PVOID)busInterfaceStandard.Context);
				
come indicato di seguito per i numeri di bus, la funzione e periferiche, utilizzare la funzione IoGetDeviceProperty nel PDO del dispositivo di destinazione:
    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);

				
importante i numeri di bus PCI potrebbe essere dinamici e modificabili in qualsiasi momento. Di conseguenza, è opportuno non dipendono dal numero bus o di utilizzare tali informazioni per accedere direttamente alle porte PCI. Questo può causare errori di sistema.

Proprietà

Identificativo articolo: 253232 - Ultima modifica: giovedì 8 settembre 2005 - Revisione: 2.1
Le informazioni in questo articolo si applicano a:
  • 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
Chiavi: 
kbmt kbhowto kbwdm KB253232 KbMtit
Traduzione automatica articoli
Il presente articolo è stato tradotto tramite il software di traduzione automatica di Microsoft e non da una persona. Microsoft offre sia articoli tradotti da persone fisiche sia articoli tradotti automaticamente da un software, in modo da rendere disponibili tutti gli articoli presenti nella nostra Knowledge Base nella lingua madre dell?utente. Tuttavia, un articolo tradotto in modo automatico non è sempre perfetto. Potrebbe contenere errori di sintassi, di grammatica o di utilizzo dei vocaboli, più o meno allo stesso modo di come una persona straniera potrebbe commettere degli errori parlando una lingua che non è la sua. Microsoft non è responsabile di alcuna imprecisione, errore o danno cagionato da qualsiasi traduzione non corretta dei contenuti o dell?utilizzo degli stessi fatto dai propri clienti. Microsoft, inoltre, aggiorna frequentemente il software di traduzione automatica.
Clicca qui per visualizzare la versione originale in inglese dell?articolo: 253232
LE INFORMAZIONI CONTENUTE NELLA MICROSOFT KNOWLEDGE BASE SONO FORNITE SENZA GARANZIA DI ALCUN TIPO, IMPLICITA OD ESPLICITA, COMPRESA QUELLA RIGUARDO ALLA COMMERCIALIZZAZIONE E/O COMPATIBILITA' IN IMPIEGHI PARTICOLARI. L'UTENTE SI ASSUME L'INTERA RESPONSABILITA' PER L'UTILIZZO DI QUESTE INFORMAZIONI. IN NESSUN CASO MICROSOFT CORPORATION E I SUOI FORNITORI SI RENDONO RESPONSABILI PER DANNI DIRETTI, INDIRETTI O ACCIDENTALI CHE POSSANO PROVOCARE PERDITA DI DENARO O DI DATI, ANCHE SE MICROSOFT O I SUOI FORNITORI FOSSERO STATI AVVISATI. IL DOCUMENTO PUO' ESSERE COPIATO E DISTRIBUITO ALLE SEGUENTI CONDIZIONI: 1) IL TESTO DEVE ESSERE COPIATO INTEGRALMENTE E TUTTE LE PAGINE DEVONO ESSERE INCLUSE. 2) I PROGRAMMI SE PRESENTI, DEVONO ESSERE COPIATI SENZA MODIFICHE, 3) IL DOCUMENTO DEVE ESSERE DISTRIBUITO INTERAMENTE IN OGNI SUA PARTE. 4) IL DOCUMENTO NON PUO' ESSERE DISTRIBUITO A SCOPO DI LUCRO.

Invia suggerimenti

 

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