Gestione delle risorse IRP per la sospensione selettiva di NDIS
Se un driver miniport supporta e abilita la sospensione selettiva di NDIS, NDIS chiama MiniportIdleNotification per inviare una notifica inattiva al driver se la scheda di rete diventa inattiva. Quando il driver miniport gestisce questa notifica, potrebbe essere necessario rilasciare pacchetti di richiesta di I/O (IRP) al driver del bus sottostante. Questi IRP notificano al driver del bus lo stato di inattività dell'adattatore e richiedere la conferma che l'adattatore può passare a uno stato a bassa potenza.
Gli IRP rilasciati dal driver miniport sono specifici del bus. Ad esempio, quando NDIS chiama MiniportIdleNotification, il miniport USB genera una richiesta di inattività USB (IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION) per il driver del bus USB sottostante.
NDIS può inviare la notifica inattiva al driver miniport molte volte dopo l'inizializzazione del driver. È pertanto consigliabile allocare le risorse per l'IRP della richiesta di inattività USB nel contesto della chiamata alla funzione MiniportInitializeEx del driver.
Nell'esempio seguente viene illustrato come il driver miniport alloca le risorse di IRP.
//
// MiniportInitializeEx()
//
// In the miniport's initialization routine, the miniport should allocate
// an IRP. It can also set up the USB_IDLE_CALLBACK_INFO structure that
// will be used with each successive USB idle request.
//
NDIS_STATUS MiniportInitializeEx(
_In_ NDIS_HANDLE MiniportAdapterHandle,
_In_ NDIS_HANDLE MiniportDriverContext,
_In_ PNDIS_MINIPORT_INIT_PARAMETERS MiniportInitParameters
)
{
PIRP UsbSsIrp;
USB_IDLE_CALLBACK_INFO UsbSsCallback;
...
UsbSsIrp = IoAllocateIrp(Adapter->Fdo->StackSize, FALSE);
if (!UsbSsIrp)
{
// Handle failure
return NDIS_STATUS_RESOURCES;
}
UsbSsCallback.IdleCallback = MiniportUsbIdleRequestCallback;
UsbSsCallback.IdleContext = Adapter;
// Save these in the adapter structure for later use
Adapter->UsbSsIrp = UsbSsIrp;
Adapter->UsbSsCallback = UsbSsCallback;
...
}
Se il driver miniport alloca le risorse IRP durante la chiamata a MiniportInitializeEx, il driver deve liberare tali risorse durante la chiamata a MiniportHaltEx.
Nell'esempio seguente viene illustrato come il driver miniport libera le risorse di IRP.
//
// MiniportHaltEx
//
// During halt (or when the miniport performs its cleanup from
// MiniportInitializeEx) the miniport should free the IRP allocated
// earlier.
//
VOID MiniportHaltEx(
_In_ NDIS_HANDLE MiniportAdapterContext,
_In_ NDIS_HALT_ACTION HaltAction
)
{
...
if (Adapter->UsbSsIrp)
{
IoFreeIrp(Adapter->UsbSsIrp);
Adapter->UsbSsIrp = NULL;
}
...
}