Comment obtenir les informations de configuration et d'emplacement d'un périphérique PCI

Traductions disponibles Traductions disponibles
Numéro d'article: 253232 - Voir les produits auxquels s'applique cet article
Agrandir tout | Réduire tout

Résumé

Cet article explique comment vous pouvez obtenir la configuration et informations d'emplacement (telles que la BusNumber, DeviceNumber et numéro de fonction) d'un périphérique PCI (Peripheral Component Interconnect) dans un pilote qui fait partie du pilote du périphérique cible comme une fonction de la pile ou filtrer le pilote.

Plus d'informations

Sur Windows NT 4.0, pilotes obtenir cette information en analyse le bus et en appelant les API de HalGetBusDataByOffset et HalGetBusData. Sur Windows 2000 et ultérieure systèmes d'exploitation Windows, les bus matériel sont contrôlés par leurs pilotes bus respectifs et non par la HAL. Par conséquent, toutes les API de HAL utilisé pour fournir des informations de bus sont obsolètes dans Windows 2000 et ultérieure systèmes d'exploitation Windows.

Sur Windows 2000 et ultérieure systèmes d'exploitation Windows, un pilote n'a pas besoin d'interroger le périphérique pour trouver des ressources. Le pilote Obtient les ressources à partir de la Gestionnaire Plug-and-Play (PnP) dans sa demande IRP_MN_START_DEVICE. En règle générale, un pilote bien écrite ne requiert pas une de ces informations pour fonctionner correctement. Si pour quelque raison que ce soit le pilote requiert ces informations, de suivre l'exemple de code montre comment obtenir les ressources. Le pilote doit faire partie de la pile de pilotes du périphérique, car elle nécessite les objets de périphérique physique sous-jacent (AOP) du périphérique pour envoyer la demande de plug-and-Play.

L'exemple de code suivant montre comment obtenir les informations de configuration :
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;

}
				
car vous ne pouvez envoyer le plug-and-Play d'e/S Request Packets (IRP) à PASSIVE_LEVEL, vous ne pouvez pas utiliser la fonction ci-dessus pour obtenir les informations de configuration au niveau DISPATCH_LEVEL.

Vous pouvez effectuer les étapes suivantes pour accéder à l'espace de configuration au niveau DISPATCH_LEVEL :
  1. Envoyer un IRP_MN_QUERY_INTERFACE à PASSIVE_LEVEL pour obtenir la structure d'interface d'appel direct (BUS_INTERFACE_STANDARD) à partir du pilote de bus PCI. Cela stocker dans une mémoire de réserve non paginée (généralement en DevcieExtension).
  2. Appelez le SetBusData et GetBusData accéder à l'espace de configuration au niveau DISPATCH_LEVEL.
  3. Le pilote de bus PCI est un compte de référence sur l'interface avant de renvoyer, pour vous devez déréférencer l'interface lorsqu'il est inutile.
  4. Utilisez la fonction suivante pour obtenir la BUS_INTERFACE_STANDARD au 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;
    
    }
    					
Le code suivant montre comment utiliser la fonction d'appel direct interface pour obtenir les données de bus.
    bytes = busInterfaceStandard.GetBusData(<BR/>
                    busInterfaceStandard.Context,
                    PCI_WHICHSPACE_CONFIG,
                    Buffer
                    Offset,
                    Length);
				
Lorsque vous n'avez plus besoin l'interface, utilisez le code suivant pour déréférencer l'interface avec le code ci-après. N'appelez pas les routines d'interface après déréférencement de l'interface.
    (busInterfaceStandard.InterfaceDereference)(
                (PVOID)busInterfaceStandard.Context);
				
Utiliser la fonction IoGetDeviceProperty sur le PDO du périphérique cible pour obtenir les numéros de bus, de fonction et de périphériques comme suit :
    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);

				
les numéros de PCI bus important peut être dynamiques et pouvez modifier à tout moment. Par conséquent, il est déconseillé de dépendent du nombre de bus ou d'utiliser ces informations pour accéder directement aux ports PCI. Cela peut entraîner de défaillance du système.

Propriétés

Numéro d'article: 253232 - Dernière mise à jour: jeudi 8 septembre 2005 - Version: 2.1
Les informations contenues dans cet article s'appliquent au(x) produit(s) suivant(s):
  • 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 Professionnel
  • Microsoft Windows XP Édition familiale
  • Microsoft Windows XP Professional
  • Microsoft Windows Server 2003 Service Pack 1
Mots-clés : 
kbmt kbhowto kbwdm KB253232 KbMtfr
Traduction automatique
IMPORTANT : Cet article est issu du système de traduction automatique mis au point par Microsoft (http://support.microsoft.com/gp/mtdetails). Un certain nombre d?articles obtenus par traduction automatique sont en effet mis à votre disposition en complément des articles traduits en langue française par des traducteurs professionnels. Cela vous permet d?avoir accès, dans votre propre langue, à l?ensemble des articles de la base de connaissances rédigés originellement en langue anglaise. Les articles traduits automatiquement ne sont pas toujours parfaits et peuvent comporter des erreurs de vocabulaire, de syntaxe ou de grammaire (probablement semblables aux erreurs que ferait une personne étrangère s?exprimant dans votre langue !). Néanmoins, mis à part ces imperfections, ces articles devraient suffire à vous orienter et à vous aider à résoudre votre problème. Microsoft s?efforce aussi continuellement de faire évoluer son système de traduction automatique.
La version anglaise de cet article est la suivante: 253232
L'INFORMATION CONTENUE DANS CE DOCUMENT EST FOURNIE PAR MICROSOFT SANS GARANTIE D'AUCUNE SORTE, EXPLICITE OU IMPLICITE. L'UTILISATEUR ASSUME LE RISQUE DE L'UTILISATION DU CONTENU DE CE DOCUMENT. CE DOCUMENT NE PEUT ETRE REVENDU OU CEDE EN ECHANGE D'UN QUELCONQUE PROFIT.

Envoyer des commentaires

 

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