Gestion des ressources IRP pour la suspension sélective NDIS
Si un pilote miniport prend en charge et active la suspension sélective NDIS, NDIS appelle MiniportIdleNotification pour émettre une notification d’inactivité au pilote si la carte réseau devient inactive. Lorsque le pilote miniport gère cette notification, il peut avoir besoin d’émettre des paquets de demandes d’E/S (IRP) 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.
Les IRP émises par le pilote miniport sont spécifiques au bus. Par exemple, lorsque NDIS appelle MiniportIdleNotification, le miniport USB émet une demande d’inactivité USB (IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION) IRP au pilote de bus USB sous-jacent.
NDIS peut émettre la notification d’inactivité au pilote miniport plusieurs fois après l’initialisation du pilote. Par conséquent, nous recommandons que le pilote alloue les ressources pour l’IRP de la demande d’inactivité USB dans le contexte de l’appel à la fonction MiniportInitializeEx du pilote.
L’exemple suivant montre comment le pilote miniport alloue les ressources 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;
...
}
Si le pilote miniport alloue les ressources IRP pendant l’appel à MiniportInitializeEx, le pilote doit libérer ces ressources pendant l’appel à MiniportHaltEx.
L’exemple suivant montre comment le pilote miniport libère les ressources 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;
}
...
}