Inicialização de dispositivo e adaptador

Este tópico descreve as etapas para um driver de cliente NetAdapterCx inicializar e iniciar objetos WDFDEVICE e NETADAPTER. Para obter mais informações sobre esses objetos e sua relação, consulte Resumo dos objetos NetAdapterCx.

EVT_WDF_DRIVER_DEVICE_ADD

Um driver cliente NetAdapterCx registra sua função de retorno de chamada EVT_WDF_DRIVER_DEVICE_ADD quando chama WdfDriverCreate de sua rotina driverEntry .

Em EVT_WDF_DRIVER_DEVICE_ADD, um driver de cliente NetAdapterCx deve fazer o seguinte na ordem:

  1. Chame NetDeviceInitConfig.

    status = NetDeviceInitConfig(DeviceInit);
    if (!NT_SUCCESS(status)) 
    {
        return status;
    }
    
  2. Chame WdfDeviceCreate.

    Dica

    Se o dispositivo der suporte a mais de um NETADAPTER, recomendamos armazenar ponteiros para cada adaptador no contexto do dispositivo.

  3. Crie o objeto NETADAPTER. Para fazer isso, o cliente chama NetAdapterInitAllocate, seguido pelos métodos opcionais NetAdapterInitSetXxxx para initailizar os atributos do adaptador. Por fim, o cliente chama NetAdapterCreate.

    O exemplo a seguir mostra como um driver de cliente pode inicializar um objeto NETADAPTER. Observe que o tratamento de erros é simplificado neste exemplo.

    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, você pode adicionar espaço de contexto ao objeto NETADAPTER. Como você pode definir um contexto em qualquer objeto WDF, você pode adicionar espaço de contexto separado para os objetos WDFDEVICE e NETADAPTER. No exemplo na etapa 3, o cliente adiciona MY_ADAPTER_CONTEXT ao objeto NETADAPTER. Para obter mais informações, consulte Espaço de contexto do objeto framework.

Recomendamos que você coloque dados relacionados ao dispositivo no contexto para o WDFDEVICE e dados relacionados à rede, como endereços de camada de link no contexto NETADAPTER. Se você estiver portando um driver NDIS 6.x existente, provavelmente terá um único MiniportAdapterContext que combina dados relacionados à rede e ao dispositivo em uma única estrutura de dados. Para simplificar o processo de portabilidade, basta converter toda essa estrutura no contexto WDFDEVICE e tornar o contexto do NETADAPTER uma pequena estrutura que aponta para o contexto do WDFDEVICE.

Opcionalmente, você pode fornecer dois retornos de chamada para o método NET_ADAPTER_DATAPATH_CALLBACKS_INIT :

Para obter detalhes sobre o que fornecer em suas implementações desses retornos de chamada, consulte as páginas de referência individuais.

EVT_WDF_DEVICE_PREPARE_HARDWARE

Muitos drivers de cliente NetAdapterCx iniciam seus adaptadores de dentro de sua função de retorno de chamada EVT_WDF_DEVICE_PREPARE_HARDWARE, com a notável exceção dos drivers de cliente de extensão de classe de Banda Larga Móvel. Para registrar uma função de retorno de chamada EVT_WDF_DEVICE_PREPARE_HARDWARE , um driver de cliente NetAdapterCx deve chamar WdfDeviceInitSetPnpPowerEventCallbacks.

No EVT_WDF_DEVICE_PREPARE_HARDWARE, além de outras tarefas de preparação de hardware, o driver do cliente define os recursos obrigatórios e opcionais do adaptador.

NetAdapterCx requer que o driver cliente defina os seguintes recursos:

Em seguida, o driver deve chamar NetAdapterStart para iniciar o adaptador.

O exemplo a seguir mostra como um driver cliente pode iniciar um objeto NETADAPTER. Observe que o código necessário para configurar cada método de funcionalidades do adaptador é deixado de fora por brevidade e clareza, e o tratamento de erros é simplificado.

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;
}