Sdílet prostřednictvím


Inicializace zařízení a adaptéru

Toto téma popisuje kroky pro klientský ovladač NetAdapterCx pro inicializaci a spuštění objektů WDFDEVICE a NETADAPTER. Další informace o těchto objektech a jejich relaci naleznete v tématu Souhrn objektů NetAdapterCx.

EVT_WDF_DRIVER_DEVICE_ADD

Klientský ovladač NetAdapterCx zaregistruje funkci zpětného volání EVT_WDF_DRIVER_DEVICE_ADD, když zavolá WdfDriverCreate ze své rutiny DriverEntry.

V EVT_WDF_DRIVER_DEVICE_ADDby měl klientský ovladač NetAdapterCx provést následující kroky:

  1. Volání NetDeviceInitConfig.

    status = NetDeviceInitConfig(DeviceInit);
    if (!NT_SUCCESS(status)) 
    {
        return status;
    }
    
  2. Volání WdfDeviceCreate.

    Spropitné

    Pokud vaše zařízení podporuje více než jeden NETADAPTER, doporučujeme uložit ukazatele na každý adaptér v kontextu vašeho zařízení.

  3. Vytvořte objekt NETADAPTER. Za tímto účelem klient volá NetAdapterInitAllocate, následované volitelnou metodou NetAdapterInitSetXxx pro inicializaci atributů adaptéru. Nakonec klient volá NetAdapterCreate.

    Následující příklad ukazuje, jak může klientský ovladač inicializovat objekt NETADAPTER. Všimněte si, že zpracování chyb je v tomto příkladu zjednodušené.

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

Volitelně můžete do objektu NETADAPTER přidat kontextový prostor. Vzhledem k tomu, že můžete nastavit kontext u libovolného objektu WDF, můžete přidat samostatný kontextový prostor pro objekty WDFDEVICE a NETADAPTER. V příkladu v kroku 3 klient přidá MY_ADAPTER_CONTEXT do objektu NETADAPTER. Další informace najdete v tématu Framework Object Context Space.

Doporučujeme umístit data související se zařízeními do kontextu pro WDFDEVICE a síťová data, jako jsou adresy vrstvy propojení do kontextu NETADAPTER. Pokud portujete existující ovladač NDIS 6.x, pravděpodobně budete mít jeden MiniportAdapterContext, který kombinuje data související se sítěmi a zařízeními do jedné datové struktury. Pokud chcete zjednodušit proces přenosu, stačí převést celou strukturu na kontext WDFDEVICE a vytvořit z kontextu NETADAPTER malou strukturu, která odkazuje na kontext WDFDEVICE.

Volitelně můžete metodě NET_ADAPTER_DATAPATH_CALLBACKS_INIT poskytnout 2 zpětné volání:

Podrobnosti o tom, co zahrnout do implementací těchto zpětných volání, najdete na jednotlivých referenčních stránkách.

EVT_WDF_DEVICE_PREPARE_HARDWARE

Mnoho klientských ovladačů NetAdapterCx spouští své adaptéry z jejich EVT_WDF_DEVICE_PREPARE_HARDWARE funkce zpětného volání, s výjimkou rozšiřujících klientských ovladačů třídy mobilního širokopásmového připojení. Chcete-li zaregistrovat funkci zpětného volání EVT_WDF_DEVICE_PREPARE_HARDWARE, musí klientský ovladač NetAdapterCx volat WdfDeviceInitSetPnpPowerEventCallbacks.

Kromě dalších úloh přípravy hardwaru v rámci EVT_WDF_DEVICE_PREPARE_HARDWAREklientský ovladač nastaví požadované a volitelné možnosti adaptéru.

NetAdapterCx vyžaduje, aby klientský ovladač nastavil následující možnosti:

Ovladač pak musí volat NetAdapterStart pro spuštění adaptéru.

Následující příklad ukazuje, jak může klientský ovladač spustit objekt NETADAPTER. Všimněte si, že kód vyžadovaný pro nastavení jednotlivých metod funkcí adaptéru je vynecháván pro stručnost a srozumitelnost a zjednodušuje se zpracování chyb.

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