Implementación de una función de controlador MiniportIdleNotification

NDIS llama a la función de controlador MiniportIdleNotification del controlador de miniporte para suspender selectivamente el adaptador de red. El adaptador se suspende cuando NDIS pasa el adaptador a un estado de bajo consumo.

El controlador de minipuerto puede vetar la notificación inactiva si el adaptador de red todavía se está usando. El controlador lo hace devolviendo NDIS_STATUS_BUSY de la función de controlador MiniportIdleNotification .

Nota El controlador de minipuerto no puede vetar la notificación inactiva si el parámetro ForceIdle de la función de controlador MiniportIdleNotification está establecido en TRUE.

Si el controlador de minipuerto no veta la notificación inactiva, es posible que tenga que emitir paquetes de solicitud de E/S específicos del bus (IRP) al controlador de autobús subyacente. Estos IRP notifican al controlador de bus el estado de inactividad del adaptador y solicitan confirmación de que el adaptador puede pasar a un estado de bajo consumo.

Por ejemplo, cuando se llama a MiniportIdleNotification , el controlador de miniporte USB prepara un paquete de solicitud de E/S (IRP) para una solicitud de inactividad USB (IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION). Cuando el controlador de minipuerto prepara el IRP, debe especificar una función de devolución de llamada. El controlador también debe llamar a IoSetCompletionRoutine o IoSetCompletionRoutineEx para especificar una rutina de finalización para irP. A continuación, el controlador de minipuerto llama a IoCallDriver para emitir el IRP al controlador de bus USB.

Nota El controlador de bus USB no completa inmediatamente el IRP. El IRP se deja en un estado pendiente a través de la transición de bajo consumo. El controlador de bus completa el IRP solo cuando se cancela por el controlador de minipuerto o se produce un evento de hardware, como la eliminación sorpresa del adaptador de red del concentrador USB.

A continuación se muestra un ejemplo de una función de controlador MiniportIdleNotification para un controlador de minipuerto USB. En este ejemplo se muestran los pasos implicados en la emisión de un IRP de solicitud inactiva USB al controlador USB subyacente. En este ejemplo también se muestra cómo se pueden reutilizar los recursos IRP, que se asignaron anteriormente en MiniportInitializeEx, para 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;
}

Para obtener instrucciones sobre la implementación de una rutina de devolución de llamada para un IRP de solicitud inactiva USB, consulte Implementación de una rutina de devolución de llamada IRP de solicitud inactiva USB.