Implémentation d’une fonction de gestionnaire MiniportIdleNotification

NDIS appelle la fonction de gestionnaire MiniportIdleNotification du pilote miniport afin de suspendre sélectivement la carte réseau. L’adaptateur est suspendu lorsque NDIS effectue la transition de l’adaptateur vers un état d’alimentation faible.

Le pilote miniport peut opposer son veto à la notification d’inactivité si la carte réseau est toujours utilisée. Pour ce faire, le pilote retourne NDIS_STATUS_BUSY à partir de la fonction de gestionnaire MiniportIdleNotification .

Note Le pilote miniport ne peut pas mettre son veto à la notification inactive si le paramètre ForceIdle de la fonction de gestionnaire MiniportIdleNotification a la valeur TRUE.

Si le pilote miniport ne met pas son veto à la notification inactive, il peut être amené à émettre des paquets de demandes d’E/S spécifiques au bus (IRPs) spécifiques au pilote de bus sous-jacent. Ces IRP informent le pilote de bus de l’état d’inactivité de l’adaptateur et demandent la confirmation que l’adaptateur peut passer à un état de faible consommation d’alimentation.

Par exemple, lorsque MiniportIdleNotification est appelé, le pilote miniport USB prépare un paquet de demande d’E/S (IRP) pour une demande d’inactivité USB (IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION). Lorsque le pilote miniport prépare l’IRP, il doit spécifier une fonction de rappel. Le pilote doit également appeler IoSetCompletionRoutine ou IoSetCompletionRoutineEx pour spécifier une routine d’achèvement pour l’IRP. Le pilote miniport appelle ensuite IoCallDriver pour émettre l’IRP au pilote de bus USB.

Note Le pilote de bus USB ne termine pas immédiatement l’IRP. L’IRP est laissé dans un état en attente lors de la transition à faible puissance. Le pilote de bus termine l’IRP uniquement lorsqu’il est annulé par le pilote miniport ou qu’un événement matériel se produit, tel que la suppression surprise de la carte réseau du hub USB.

Voici un exemple de fonction de gestionnaire MiniportIdleNotification pour un pilote miniport USB. Cet exemple montre les étapes impliquées dans l’émission d’un IRP de demande d’inactivité USB au pilote USB sous-jacent. Cet exemple montre également comment les ressources IRP, précédemment allouées dans MiniportInitializeEx, peuvent être réutilisées pour l’IRP.

//
// MiniportIdleNotification()
//
// This routine is invoked by NDIS when it has detected that the miniport
// is idle.  The miniport must prepare to issue its selective suspend IRP
// to the USB stack.  The driver can return NDIS_STATUS_BUSY if it is
// unwilling to become idle at this moment; NDIS will then retry later.
// Otherwise, the miniport should return NDIS_STATUS_PENDING.
//
NDIS_STATUS MiniportIdleNotification(
    _In_ NDIS_HANDLE MiniportAdapterContext,
    _In_ BOOLEAN ForceIdle
    )
{
    PIO_STACK_LOCATION IoSp;

    IoReuseIrp(Adapter->UsbSsIrp, STATUS_NOT_SUPPORTED);

    IoSp = IoGetNextIrpStackLocation(Adapter->UsbSsIrp);
    IoSp->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
    IoSp->Parameters.DeviceIoControl.IoControlCode 
            = IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION;
    IoSp->Parameters.DeviceIoControl.InputBufferLength 
            = sizeof(Adapter->UsbSsCallback);
    IoSp->Parameters.DeviceIoControl.Type3InputBuffer 
            = Adapter->UsbSsCallback;

    IoSetCompletionRoutine(
            Adapter->UsbSsIrp,
            MiniportUsbIdleRequestCompletion,
            Adapter,
            TRUE,
            TRUE,
            TRUE);

    NtStatus = IoCallDriver(Adapter->Fdo, Adapter->UsbSsIrp);
    if (!NT_SUCCESS(NtStatus))
    {
       return NDIS_STATUS_FAILURE;
    }

    return NDIS_STATUS_PENDING;
}

Pour obtenir des instructions sur l’implémentation d’une routine de rappel pour un IRP de demande d’inactivité USB, consultez Implémentation d’une routine de rappel IRP de demande d’inactivité USB.