Udostępnij przez


Inicjowanie urządzenia i adaptera

W tym temacie opisano kroki dotyczące sterownika klienta NetAdapterCx w celu zainicjowania i uruchomienia obiektów WDFDEVICE i NETADAPTER. Aby uzyskać więcej informacji na temat tych obiektów i ich relacji, zobacz Podsumowanie obiektów NetAdapterCx.

EVT_WDF_DRIVER_DEVICE_ADD

Sterownik klienta NetAdapterCx rejestruje funkcję wywołania zwrotnego EVT_WDF_DRIVER_DEVICE_ADD podczas wywoływania WdfDriverCreate ze swojej procedury DriverEntry.

W EVT_WDF_DRIVER_DEVICE_ADDsterownik klienta NetAdapterCx powinien wykonać następujące czynności:

  1. Wywołaj NetDeviceInitConfig.

    status = NetDeviceInitConfig(DeviceInit);
    if (!NT_SUCCESS(status)) 
    {
        return status;
    }
    
  2. Wywołaj WdfDeviceUtwórz.

    Napiwek

    Jeśli urządzenie obsługuje więcej niż jeden NETADAPTER, zalecamy przechowywanie wskaźników do każdego z adapterów w kontekście urządzenia.

  3. Utwórz obiekt NETADAPTER. W tym celu klient wywołuje metodę NetAdapterInitAllocate, a następnie opcjonalnie metody NetAdapterInitSetXxx do inicjowania atrybutów karty. Na koniec klient wywołuje NetAdapterCreate.

    W poniższym przykładzie pokazano, jak sterownik klienta może zainicjować obiekt NETADAPTER. Pamiętaj, że obsługa błędów jest uproszczona w tym przykładzie.

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

Opcjonalnie możesz dodać przestrzeń kontekstową do obiektu NETADAPTER. Ponieważ można ustawić kontekst dla dowolnego obiektu WDF, można dodać oddzielne miejsce kontekstowe dla obiektów WDFDEVICE i NETADAPTER. W przykładzie w kroku 3 klient dodaje MY_ADAPTER_CONTEXT do obiektu NETADAPTER. Aby uzyskać więcej informacji, zobacz Framework Object Context Space.

Zalecamy umieszczenie danych związanych z urządzeniem w kontekście dla urządzenia WDFDEVICE oraz danych związanych z siecią, takich jak adresy warstwy łącza danych, w kontekście NETADAPTER. Jeśli przenosisz istniejący sterownik NDIS 6.x, prawdopodobnie będziesz mieć jeden MiniportAdapterContext, który łączy dane związane z siecią oraz urządzeniem w jedną strukturę danych. Aby uprościć proces przenoszenia, wystarczy przekonwertować całą strukturę na kontekst WDFDEVICE i sprawić, aby kontekst NETADAPTER był małą strukturą wskazującą kontekst WDFDEVICE.

Opcjonalnie możesz podać 2 wywołania zwrotne do metody NET_ADAPTER_DATAPATH_CALLBACKS_INIT:

Aby uzyskać szczegółowe informacje na temat tego, co należy podać w implementacjach tych wywołań zwrotnych, zobacz poszczególne strony referencyjne.

EVT_WDF_DEVICE_PREPARE_HARDWARE (przygotowanie sprzętu urządzenia w systemie WDF)

Wiele sterowników klienta NetAdapterCx uruchamia swoje adaptery z poziomu funkcji wywołania zwrotnego EVT_WDF_DEVICE_PREPARE_HARDWARE, z wyjątkiem sterowników klientów rozszerzeń klasy mobilnego internetu szerokopasmowego. Aby zarejestrować funkcję wywołania zwrotnego EVT_WDF_DEVICE_PREPARE_HARDWARE, sterownik klienta NetAdapterCx musi wywołać WdfDeviceInitSetPnpPowerEventCallbacks.

W EVT_WDF_DEVICE_PREPARE_HARDWARE, sterownik klienta, oprócz wykonywania innych zadań związanych z przygotowaniem sprzętu, ustawia wymagane i opcjonalne funkcje adaptera.

NetAdapterCx wymaga sterownika klienta, aby ustawić następujące możliwości:

Sterownik musi następnie wywołać NetAdapterStart, aby uruchomić kartę.

W poniższym przykładzie pokazano, jak sterownik klienta może uruchomić obiekt NETADAPTER. Należy pamiętać, że kod wymagany do skonfigurowania każdej metody możliwości adaptera jest pominięty w celu zwięzłości i jasności, a obsługa błędów jest uproszczona.

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