Inisialisasi perangkat dan adaptor

Topik ini menjelaskan langkah-langkah driver klien NetAdapterCx untuk menginisialisasi dan memulai objek WDFDEVICE dan NETADAPTER. Untuk informasi selengkapnya tentang objek ini dan hubungannya, lihat Ringkasan objek NetAdapterCx.

EVT_WDF_DRIVER_DEVICE_ADD

Driver klien NetAdapterCx mendaftarkan fungsi panggilan balik EVT_WDF_DRIVER_DEVICE_ADD ketika memanggil WdfDriverCreate dari rutinitas DriverEntry-nya .

Dalam EVT_WDF_DRIVER_DEVICE_ADD, driver klien NetAdapterCx harus melakukan hal berikut secara berurutan:

  1. Panggil NetDeviceInitConfig.

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

    Tip

    Jika perangkat Anda mendukung lebih dari satu NETADAPTER, sebaiknya simpan pointer ke setiap adaptor dalam konteks perangkat Anda.

  3. Buat objek NETADAPTER. Untuk melakukannya, klien memanggil NetAdapterInitAllocate, diikuti dengan metode NetAdapterInitSetXxx opsional untuk memulai atribut adaptor. Terakhir, klien memanggil NetAdapterCreate.

    Contoh berikut menunjukkan bagaimana driver klien mungkin menginisialisasi objek NETADAPTER. Perhatikan bahwa penanganan kesalahan disederhanakan dalam contoh ini.

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

Secara opsional, Anda dapat menambahkan ruang konteks ke objek NETADAPTER. Karena Anda dapat mengatur konteks pada objek WDF apa pun, Anda dapat menambahkan ruang konteks terpisah untuk objek WDFDEVICE dan NETADAPTER. Dalam contoh di langkah 3, klien menambahkan MY_ADAPTER_CONTEXT ke objek NETADAPTER. Untuk informasi selengkapnya, lihat Ruang Konteks Objek Kerangka Kerja.

Kami menyarankan agar Anda menempatkan data terkait perangkat dalam konteks untuk WDFDEVICE Anda, dan data terkait jaringan seperti alamat lapisan tautan ke dalam konteks NETADAPTER Anda. Jika Anda memindahkan driver NDIS 6.x yang ada, Anda mungkin akan memiliki satu MiniportAdapterContext yang menggabungkan data terkait jaringan dan terkait perangkat ke dalam satu struktur data. Untuk menyederhanakan proses porting, cukup konversikan seluruh struktur tersebut ke konteks WDFDEVICE, dan jadikan konteks NETADAPTER sebagai struktur kecil yang menunjuk ke konteks WDFDEVICE.

Anda dapat secara opsional memberikan 2 panggilan balik ke metode NET_ADAPTER_DATAPATH_CALLBACKS_INIT :

Untuk detail tentang apa yang harus diberikan dalam implementasi panggilan balik ini, lihat halaman referensi individual.

EVT_WDF_DEVICE_PREPARE_HARDWARE

Banyak driver klien NetAdapterCx memulai adaptor mereka dari dalam fungsi panggilan balik EVT_WDF_DEVICE_PREPARE_HARDWARE mereka, dengan pengecualian penting dari driver klien ekstensi kelas Mobile Broadband. Untuk mendaftarkan fungsi panggilan balik EVT_WDF_DEVICE_PREPARE_HARDWARE , driver klien NetAdapterCx harus memanggil WdfDeviceInitSetPnpowerEventCallbacks.

Dalam EVT_WDF_DEVICE_PREPARE_HARDWARE, selain tugas persiapan perangkat keras lainnya, driver klien mengatur kemampuan adaptor yang diperlukan dan opsional.

NetAdapterCx mengharuskan driver klien untuk mengatur kemampuan berikut:

Driver kemudian harus memanggil NetAdapterStart untuk memulai adaptor mereka.

Contoh berikut menunjukkan bagaimana driver klien mungkin memulai objek NETADAPTER. Perhatikan bahwa kode yang diperlukan untuk menyiapkan setiap metode kemampuan adaptor dibiarkan untuk keringkasan dan kejelasan, dan penanganan kesalahan disederhanakan.

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