Inizializzazione di dispositivi e adattatori
Questo argomento descrive i passaggi per un driver client NetAdapterCx per inizializzare e avviare oggetti WDFDEVICE e NETADAPTER. Per altre info su questi oggetti e sulla relativa relazione, vedi Riepilogo degli oggetti NetAdapterCx.
EVT_WDF_DRIVER_DEVICE_ADD
Un driver client NetAdapterCx registra la funzione di callback EVT_WDF_DRIVER_DEVICE_ADD quando chiama WdfDriverCreate dalla routine DriverEntry.
In EVT_WDF_DRIVER_DEVICE_ADD, un driver client NetAdapterCx deve eseguire le operazioni seguenti nell'ordine seguente:
Chiama NetDeviceInitConfig.
status = NetDeviceInitConfig(DeviceInit); if (!NT_SUCCESS(status)) { return status; }
Chiama WdfDeviceCreate.
Suggerimento
Se il dispositivo supporta più di un NETADAPTER, è consigliabile archiviare i puntatori a ogni scheda nel contesto di dispositivo.
Creare l'oggetto NETADAPTER. A tale scopo, il client chiama NetAdapterInitAllocate, seguito dai metodi Facoltativi NetAdapterInitSetXxx per inizializzare gli attributi dell'adapter. Infine, il client chiama NetAdapterCreate.
Nell'esempio seguente viene illustrato come un driver client potrebbe inizializzare un oggetto NETADAPTER. Si noti che la gestione degli errori è semplificata in questo esempio.
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); ...
Facoltativamente, è possibile aggiungere spazio di contesto all'oggetto NETADAPTER. Poiché è possibile impostare un contesto in qualsiasi oggetto WDF, è possibile aggiungere spazio di contesto separato per gli oggetti WDFDEVICE e NETADAPTER. Nell'esempio del passaggio 3 il client aggiunge MY_ADAPTER_CONTEXT
all'oggetto NETADAPTER. Per altre info, vedi Framework Object Context Space.For more info, see Framework Object Context Space.
È consigliabile inserire i dati correlati al dispositivo nel contesto per WDFDEVICE e i dati correlati alla rete, ad esempio gli indirizzi del livello di collegamento nel contesto NETADAPTER. Se si esegue la conversione di un driver NDIS 6.x esistente, probabilmente si avrà un singolo MiniportAdapterContext che combina i dati correlati alla rete e ai dispositivi in una singola struttura di dati. Per semplificare il processo di conversione, è sufficiente convertire l'intera struttura nel contesto WDFDEVICE e rendere il contesto di NETADAPTER una piccola struttura che punta al contesto di WDFDEVICE.
Facoltativamente, è possibile fornire 2 callback al metodo NET_ADAPTER_DATAPATH_CALLBACKS_INIT:
Per informazioni dettagliate su cosa fornire nelle implementazioni di questi callback, vedere le singole pagine di riferimento.
EVT_WDF_DEVICE_PREPARE_HARDWARE
Molti driver client NetAdapterCx avviano le schede dall'interno della funzione di callback EVT_WDF_DEVICE_PREPARE_HARDWARE, ad eccezione dei driver client dell'estensione della classe Mobile Broadband. Per registrare una funzione di callback EVT_WDF_DEVICE_PREPARE_HARDWARE , un driver client NetAdapterCx deve chiamare WdfDeviceInitSetPnpPowerEventCallbacks.
All'interno di EVT_WDF_DEVICE_PREPARE_HARDWARE, oltre ad altre attività di preparazione hardware, il driver client imposta le funzionalità obbligatorie e facoltative dell'adattatore.
NetAdapterCx richiede che il driver client imposti le funzionalità seguenti:
Funzionalità del percorso dati. Il driver chiama NetAdapterSetDataPathCapabilities per impostare queste funzionalità. Per altre informazioni, vedere Gestione del buffer dei dati di rete.
Funzionalità del livello di collegamento. Il driver chiama NetAdapterSetLinkLayerCapabilities per impostare queste funzionalità.
Dimensioni massime MTU (Link Layer Maximum Transfer Unit). Il driver chiama NetAdapterSetLinkLayerMtuSize per impostare le dimensioni MTU.
Il driver deve quindi chiamare NetAdapterStart per avviare l'adapter.
L'esempio seguente illustra come un driver client potrebbe avviare un oggetto NETADAPTER. Si noti che il codice necessario per configurare ogni metodo di funzionalità dell'adattatore viene lasciato fuori per brevità e chiarezza e la gestione degli errori è semplificata.
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;
}