Поделиться через


Инициализация устройства и адаптера

В этом разделе описаны шаги для драйвера клиента NetAdapterCx для инициализации и запуска объектов WDFDEVICE и NETADAPTER. Дополнительные сведения об этих объектах и их отношениях см. в сводке объектов NetAdapterCx.

EVT_WDF_DRIVER_DEVICE_ADD

Драйвер клиента NetAdapterCx регистрирует свою функцию обратного вызова EVT_WDF_DRIVER_DEVICE_ADD при вызове WdfDriverCreate из подпрограммы DriverEntry.

В EVT_WDF_DRIVER_DEVICE_ADD драйвер клиента NetAdapterCx должен выполнять следующие действия:

  1. Вызов NetDeviceInitConfig.

    status = NetDeviceInitConfig(DeviceInit);
    if (!NT_SUCCESS(status)) 
    {
        return status;
    }
    
  2. Вызов WdfDeviceCreate.

    Совет

    Если устройство поддерживает несколько NETADAPTER, рекомендуется хранить указатели на каждый адаптер в контексте устройства.

  3. Создайте объект NETADAPTER. Для этого клиент вызывает NetAdapterInitAllocate, а затем необязательные методы NetAdapterInitSetXxx для инициализации атрибутов адаптера. Наконец, клиент вызывает NetAdapterCreate.

    В следующем примере показано, как драйвер клиента может инициализировать объект NETADAPTER. Обратите внимание, что обработка ошибок упрощена в этом примере.

    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);
    ...
    

При необходимости можно добавить пространство контекста в объект NETADAPTER. Так как контекст можно задать для любого объекта WDF, можно добавить отдельное пространство контекста для объектов WDFDEVICE и NETADAPTER. В примере на шаге 3 клиент добавляется MY_ADAPTER_CONTEXT в объект NETADAPTER. Дополнительные сведения см. в разделе "Пространство контекста объектов Платформы".

Рекомендуется поместить данные, связанные с устройством, в контекст для WDFDEVICE и сетевые данные, такие как адреса слоя ссылок в контекст NETADAPTER. Если вы переносите существующий драйвер NDIS 6.x, скорее всего, у вас будет один MiniportAdapterContext, который объединяет данные, связанные с сетью и устройства, в одну структуру данных. Чтобы упростить процесс переноса, просто преобразуйте всю структуру в контекст WDFDEVICE и сделайте контекст NETADAPTER небольшой структурой, которая указывает на контекст WDFDEVICE.

При необходимости можно предоставить 2 обратных вызова для метода NET_ADAPTER_DATAPATH_CALLBACKS_INIT:

Дополнительные сведения о том, что следует предоставить в реализации этих обратных вызовов, см. на отдельных справочных страницах.

EVT_WDF_DEVICE_PREPARE_HARDWARE

Многие драйверы клиентов NetAdapterCx запускают адаптеры из своей функции обратного вызова EVT_WDF_DEVICE_PREPARE_HARDWARE с заметным исключением драйверов клиентских драйверов расширения мобильного широкополосного подключения. Чтобы зарегистрировать функцию обратного вызова EVT_WDF_DEVICE_PREPARE_HARDWARE, драйвер клиента NetAdapterCx должен вызвать WdfDeviceInitSetPnpPowerEventCallbacks.

В EVT_WDF_DEVICE_PREPARE_HARDWARE помимо других задач подготовки оборудования драйвер клиента задает необходимые и необязательные возможности адаптера.

NetAdapterCx требует, чтобы драйвер клиента установил следующие возможности:

  • Возможности пути к данным. Драйвер вызывает NetAdapterSetDataPathCapabilities , чтобы задать эти возможности. Дополнительные сведения см. в разделе "Управление буферами сетевых данных".

  • Возможности уровня связи. Драйвер вызывает NetAdapterSetLinkLayerCapabilities , чтобы задать эти возможности.

  • Максимальный размер единицы передачи уровня связи (MTU). Драйвер вызывает NetAdapterSetLayerMtuSize , чтобы задать размер MTU.

Затем драйвер должен вызвать NetAdapterStart , чтобы запустить адаптер.

В следующем примере показано, как драйвер клиента может запустить объект NETADAPTER. Обратите внимание, что код, необходимый для настройки каждого метода возможностей адаптера, остается без краткости и ясности, а обработка ошибок упрощается.

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