Doğrudan G/Ç Kullanan Güvenli Dijital İstekler

Aşağıdaki kod örneği, bir sürücünün bir cihazın işlev temel yazmaç (FBR) içeriğini almak için komut isteğini nasıl kullandığını gösterir. Alınan veri miktarı küçük olduğundan, örnekte veri yolu sürücüsüne verileri CMD hattı üzerinden iletmesi talimatını veren bir doğrudan G/Ç komutu (SD belirtiminde CMD52 olarak adlandırılır) kullanılır. Genişletilmiş G/Ç'nin (SD belirtiminde CMD53 olarak adlandırılır) nasıl kullanılacağını gösteren bir kod örneği görmek için bkz. Genişletilmiş G/Ç Kullanan Güvenli Dijital İstekler .

    const SDCMD_DESCRIPTOR ReadIoDirectDesc =
    {SDCMD_IO_RW_DIRECT, SDCC_STANDARD, SDTD_READ,
    SDTT_CMD_ONLY, SDRT_5};
    
    PSDBUS_REQUEST_PACKET sdrp = NULL;
    SD_RW_DIRECT_ARGUMENT sdIoArgument;
    
    sdrp = ExAllocatePool(NonPagedPool, 
        sizeof(SDBUS_REQUEST_PACKET));
    if (!sdrp) {
        return STATUS_INSUFFICIENT_RESOURCES;
    }
    RtlZeroMemory(sdrp, sizeof(SDBUS_REQUEST_PACKET));
    sdrp->RequestFunction = SDRF_DEVICE_COMMAND;
    sdrp->Parameters.DeviceCommand.CmdDesc = ReadIoDirectDesc;
    
    // Set up the argument and command descriptor
    
    sdIoArgument.u.AsULONG = 0;
    sdIoArgument.u.bits.Address = Offset;
    
    // Function # must be initialized by SdBus GetProperty call
    
    sdIoArgument.u.bits.Function = pDevExt->FunctionNumber;
    sdrp->Parameters.DeviceCommand.Argument = sdIoArgument.u.AsULONG;
    
    // Submit the request
    
    status = SdBusSubmitRequest(pDevExt->BusInterface.Context, sdrp);
    
    if (NT_SUCCESS(status)) {
        // for direct I/O, the data comes in the response
        *Data = sdrp->ResponseData.AsUCHAR[0];
    }
    ExFreePool(sdrp);

FBR'yi okumak için kod örneği aşağıdaki adımları gerçekleştirir:

  1. Tanımlayıcıyı Başlatma

    Device-command isteği göndermenin ilk adımı, SDCMD_DESCRIPTORbir SD komut tanımlayıcısı tanımlamaktır. Tanımlayıcı genellikle sabit bir veri yapısı olarak tanımlanır. Kod örneğindeki tanımlayıcı, aşağıdaki öğelerle bir okuma işlemi tanımlar:

    Öğe Açıklama

    SD_COMMAND_CODE

    Tanımlayıcı tarafından tanımlanan işlem, FBR'den tek bir bayt veri okur; bu nedenle, kod örneği, kartın istenen veriyi DAT hatları yerine CMD hattı üzerinden bildirmesini sağlayan bir doğrudan G/Ç komutu (CMD52) kullanır. Kod örneği, bu üyeye bir SDCMD_IO_RW_DIRECT değeri atayarak doğrudan G/Ç komutunu gösterir.

    SD_COMMAND_CLASS

    Okuma işlemleri standart komut kümesine (komut kodları 0 - 63) ait olduğundan, tanımlayıcının bu üyesine atanan değer SDCC_STANDARD.

    SD_ AKTARIM_YÖNÜ

    Okuma işlemleri için cihazdan konağa aktarım gerekir, bu nedenle tanımlayıcının bu üyesine atanan değer SDTD_READ.

    SD_TRANSFER_TYPE

    Bu işlem, CMD hattı üzerinden bir yazmaçtan az miktarda veri okur. Kartın DAT satırları üzerinden veri göndermesi gerekmez, bu nedenle bu üyeye SDTT_CMD_ONLY değeri atanır.

    SD_YANIT_TİPİ

    Tanımlayıcı, SDRT_5 yanıt türünü belirtir; bu da kartın işlemin bir kesme isteğiyle tamamlandığını konağa bildirmesi gerektiği anlamına gelir. R5 yanıtının açıklaması için MultiMedia Kart Derneği spesifikasyonuna bakın.

  2. Aşağıdaki adımları tamamlayarak İstek Paketi başlatın:

    1. İstek İşlevini tanımlama:

      Bir SD tanımlayıcısı oluşturduktan sonra kod örneği, SDBUS_REQUEST_PACKETistek paketini başlatır. İstek paketinin RequestFunction üyesi, isteğin bir cihaz komutu (SDRF_DEVICE_COMMAND değeri) veya özellik işlemi (SDRF_GET_PROPERTY veya SDRF_SET_PROPERTY değeri) içerip içermediğini belirtir. Kod örneği bir cihaz komutu başlatır, bu nedenle RequestFunction üyesini SDRF_DEVICE_COMMAND olarak ayarlar.

    2. Komut Tanımlayıcısını Yükleme: Ardından, kod örneği yeni başlatılan tanımlayıcıyı istek paketinin Parameters.DeviceCommand.CmdDesc üyesinde depolar.

    3. Okuma/Yazma Argümanını Başlat:

      İstek paketi, veri yolu sürücüsünün aldığı verilerin konumunu belirten bir SD_RW_DIRECT_ARGUMENT yapısı içerir. Bu yapı, veri yolu sürücüsünün G/Ç alanını okuduğu işlevin numarasını da saklar. Örnek kod, işlev numarasını cihaz uzantısından alır ve bu da sürücünün daha önce SDRF_GET_PROPERTY bir istekle karttan (büyük olasılıkla cihazı başlattığında) bilgileri aldığı ve cihaz uzantısında depoladığı anlamına gelir.

  3. İsteği Gönder

    Tanımlayıcıyı ve istek paketini başlatan kod örneği, isteği göndermek için senkron istek yordamı SdBusSubmitRequest'yi kullanır. İstek yordamı, istek paketini ve sistemin SD arabirimini açtığında sürücüye sağladığı arabirim bağlam bilgilerini geçirir. Bu istek zaman uyumlu olduğundan, sürücünün IRQL değeri DISPATCH_LEVEL'den küçük olacak şekilde çalışıyor olması gerekir.

  4. Komut sonuçları

    Kod örneği doğrudan G/Ç kullandığından, SD istek paketindeki ResponseData alanından başka veri arabelleği gerekmez.