Inicialización de dispositivos y adaptadores
En este tema se describen los pasos para que un controlador de cliente NetAdapterCx inicialice e inicie objetos WDFDEVICE y NETADAPTER. Para obtener más información sobre estos objetos y su relación, consulte Resumen de objetos NetAdapterCx.
EVT_WDF_DRIVER_DEVICE_ADD
Un controlador de cliente NnetAdapterCx registra su función de devolución de llamada EVT_WDF_DRIVER_DEVICE_ADD cuando llama a WdfDriverCreate desde su rutina DriverEntry.
En EVT_WDF_DRIVER_DEVICE_ADD, un controlador cliente NetAdapterCx debe hacer lo siguiente en orden:
Llamar a NetDeviceInitConfig.
status = NetDeviceInitConfig(DeviceInit); if (!NT_SUCCESS(status)) { return status; }
Llamar a WdfDeviceCreate.
Sugerencia
Si el dispositivo admite más de un NETADAPTER, se recomienda almacenar punteros a cada adaptador en el contexto del dispositivo.
Crear el objeto NETADAPTER. Para ello, el cliente llama a NetAdapterInitAllocate, seguido de métodos opcionales NetAdapterInitSetXxx para inicializar los atributos del adaptador. Por último, el cliente llama a NetAdapterCreate.
En el ejemplo siguiente se muestra cómo un controlador de cliente podría inicializar un objeto NETADAPTER. Tenga en cuenta que el control de errores se simplifica en este ejemplo.
WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attribs, MY_ADAPTER_CONTEXT); // // Allocate the initialization structure // PNETADAPTER_INIT adapterInit = NetAdapterInitAllocate(device); if(adapterInit == NULL) { return status; } // // Optional: set additional attributes // // Datapath callbacks for creating packet queues NET_ADAPTER_DATAPATH_CALLBACKS datapathCallbacks; NET_ADAPTER_DATAPATH_CALLBACKS_INIT(&datapathCallbacks, MyEvtAdapterCreateTxQueue, MyEvtAdapterCreateRxQueue); NetAdapterInitSetDatapathCallbacks(adapterInit, datapathCallbacks); // // Required: create the adapter // NETADAPTER* netAdapter; status = NetAdapterCreate(adapterInit, &attribs, netAdapter); if(!NT_SUCCESS(status)) { NetAdapterInitFree(adapterInit); adapterInit = NULL; return status; } // // Required: free the adapter initialization object even // if adapter creation succeeds // NetAdapterInitFree(adapterInit); adapterInit = NULL; // // Optional: initialize the adapter's context // PMY_ADAPTER_CONTEXT adapterContext = GetMyAdapterContext(&netAdapter); ...
Opcionalmente, puede agregar espacio de contexto al objeto NETADAPTER. Como puede establecer un contexto en cualquier objeto WDF, puede agregar espacio de contexto independiente para los objetos WDFDEVICE y NETADAPTER. En el ejemplo del paso 3, el cliente agrega MY_ADAPTER_CONTEXT
al objeto NETADAPTER. Para obtener más información, consulte Espacio de contexto de objetos de marco.
Se recomienda colocar datos relacionados con el dispositivo en el contexto de WDFDEVICE y datos relacionados con redes, como direcciones de capa de vínculo en el contexto de NETADAPTER. Si va a migrar un controlador NDIS 6.x existente, es probable que tenga un único MiniportAdapterContext que combine datos relacionados con redes y relacionados con dispositivos en una sola estructura de datos. Para simplificar el proceso de portabilidad, simplemente convierta esa estructura completa en el contexto de WDFDEVICE y convierta el contexto de NETADAPTER en una estructura pequeña que apunte al contexto de WDFDEVICE.
Opcionalmente, puede proporcionar 2 devoluciones de llamada al método NET_ADAPTER_DATAPATH_CALLBACKS_INIT:
Para más información sobre qué proporcionar en las implementaciones de estas devoluciones de llamada, consulte las páginas de referencia individuales.
EVT_WDF_DEVICE_PREPARE_HARDWARE
Muchos controladores de cliente netAdapterCx inician sus adaptadores desde dentro de su función de devolución de llamada EVT_WDF_DEVICE_PREPARE_HARDWARE, con la notable excepción de los controladores cliente de extensión de clase de banda ancha móvil. Para registrar una función de devolución de llamada EVT_WDF_DEVICE_PREPARE_HARDWARE, un controlador cliente NetAdapterCx debe llamar a WdfDeviceInitSetPnpPowerEventCallbacks.
Dentro de EVT_WDF_DEVICE_PREPARE_HARDWARE, además de otras tareas de preparación de hardware, el controlador cliente establece las funcionalidades necesarias y opcionales del adaptador.
NetAdapterCx requiere que el controlador cliente establezca las siguientes funcionalidades:
Funcionalidades de ruta de acceso de datos. El controlador llama a NetAdapterSetDataPathCapabilities para establecer estas funcionalidades. Para más información, consulte Administración de búfer de datos de red.
Funcionalidades de capa de vínculo. El controlador llama a NetAdapterSetLinkLayerCapabilities para establecer estas funcionalidades.
Tamaño máximo de unidad de transferencia de capa de vínculo (MTU). El controlador llama a NetAdapterSetLinkLayerMtuSize para establecer el tamaño de MTU.
A continuación, el controlador debe llamar a NetAdapterStart para iniciar su adaptador.
En el ejemplo siguiente se muestra cómo un controlador cliente podría iniciar un objeto NETADAPTER. Tenga en cuenta que el código necesario para configurar cada método de funcionalidades de adaptador se deja fuera para mayor brevedad y claridad, y se simplifica el control de errores.
PMY_DEVICE_CONTEXT deviceContext = GetMyDeviceContext(device);
NETADAPTER netAdapter = deviceContext->NetAdapter;
PMY_ADAPTER_CONTEXT adapterContext = GetMyAdapterContext(netAdapter);
//
// Set required adapter capabilities
//
// Link layer capabilities
...
NetAdapterSetDatapathCapabilities(netAdapter,
&txCapabilities,
&rxCapabilities);
...
NetAdapterSetLinkLayerCapabilities(netAdapter,
&linkLayerCapabilities);
...
NetAdapterSetLinkLayerMtuSize(netAdapter,
MY_MAX_PACKET_SIZE - ETHERNET_HEADER_LENGTH);
//
// Set optional adapter capabilities
//
// Link layer capabilities
...
NetAdapterSetPermanentLinkLayerAddress(netAdapter,
&adapterContext->PermanentAddress);
...
NetAdapterSetCurrentLinkLayerAddress(netAdapter,
&adapterContext->CurrentAddress);
// Datapath capabilities
...
NetAdapterSetDatapathCapabilities(netAdapter,
&txCapabilities,
&rxCapabilities);
// Receive scaling capabilities
...
NetAdapterSetReceiveScalingCapabilities(netAdapter,
&receiveScalingCapabilities);
// Hardware offload capabilities
...
NetAdapterOffloadSetChecksumCapabilities(netAdapter,
&checksumCapabilities);
...
NetAdapterOffloadSetLsoCapabilities(netAdapter,
&lsoCapabilities);
...
NetAdapterOffloadSetRscCapabilities(netAdapter,
&rscCapabilities);
//
// Required: start the adapter
//
status = NetAdapterStart(netAdapter);
if(!NT_SUCCESS(status))
{
return status;
}