Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
NDIS вызывает функцию обработчика минипорта MiniportIdleNotification, чтобы выборочно приостановить сетевой адаптер. Адаптер приостанавливается, когда NDIS переводит его в состояние низкого энергопотребления.
Минипорт-драйвер может наложить вето на уведомление о простое, если сетевой адаптер по-прежнему используется. Драйвер делает это, возвращая NDIS_STATUS_BUSY из функции обработчика MiniportIdleNotification.
Примечание Драйвер минипорта не может ветоировать уведомление об простое, если параметр ForceIdle функции обработчика MiniportIdleNotification имеет значение TRUE.
Если минипорт-драйвер не накладывает вето на уведомление о простое, может потребоваться выдавать пакеты запросов ввода-вывода для конкретной шины (IRPs) основному драйверу шины. Эти IRP уведомляют водителя шины о состоянии простоя адаптера и просят подтвердить, что адаптер может перейти в энергосберегающий режим.
Например, при вызове MiniportIdleNotification драйвер USB-минипорта подготавливает пакет запроса ввода-вывода (IRP) для запроса простоя USB (IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION). Когда минипорт-драйвер подготавливает IRP, он должен указать функцию обратного вызова. Драйвер также должен вызывать IoSetCompletionRoutine или IoSetCompletionRoutineEx, чтобы указать подпрограмму завершения для IRP. Затем драйвер минипорта вызывает IoCallDriver, чтобы передать IRP драйверу USB-шины.
Примечание Драйвер USB шины не сразу завершает IRP. IRP остается в состоянии ожидания в результате перехода на малую мощность. Драйвер шины завершает IRP только в том случае, если он отменен драйвером мини-порта или событием оборудования, например неожиданное удаление сетевого адаптера из USB-концентратора.
Ниже приведен пример функции обработчика MiniportIdleNotification для USB-драйвера минипорта. В этом примере показаны шаги, связанные с выдачей IRP запроса на простой режим USB в базовый USB-драйвер. В этом примере также показано, как ресурсы IRP, которые ранее были выделены в MiniportInitializeEx, можно повторно использовать для 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;
}
Рекомендации по реализации подпрограммы обратного вызова для IRP запроса на бездействие USB см. в Implementing a USB Idle Request IRP Callback Routine.