使用直接 I/O 的安全數位要求
下列程式代碼範例說明驅動程式如何使用命令要求來擷取裝置函式基本緩存器的內容, (FBR) 。 由於擷取的數據量很小,因此此範例會使用SD規格中稱為 CMD52 (的直接 I/O 命令) ,指示總線驅動程式在 CMD 線路之間傳輸數據。 若要查看程式代碼範例,說明如何在 SD 規格) 中使用稱為 CMD53 的擴充 I/O (,請參閱 使用擴充 I/O 的安全數位要求。
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,程式代碼範例會執行下列步驟:
初始化描述項
傳送 device-command 要求的第一個步驟是定義 SD 命令描述項, SDCMD_DESCRIPTOR。 一般而言,描述項會定義為常數數據結構。 程式代碼範例中的描述項會使用下列元素來定義讀取作業:
元素 Description 描述項定義的作業會從 FBR 讀取單一位元組的數據,因此程式碼範例會使用直接 I/O 命令 (CMD52) ,指示卡片跨 CMD 行報告所要求的數據,而不是 DAT 行。 程式代碼範例會藉由將 SDCMD_IO_RW_DIRECT 的值指派給這個成員,以指出直接 I/O 命令。
讀取作業屬於標準命令集, (命令代碼 0 到 63) ,因此指派給描述項成員的值SDCC_STANDARD。
讀取作業需要從裝置傳輸到主機,因此指派給描述項成員的值SDTD_READ。
此作業會從 CMD 行上的緩存器讀取少量數據。 卡片不需要透過 DAT 行傳送數據,因此,此成員會獲指派SDTT_CMD_ONLY的值。
描述項會指定SDRT_5的回應類型,這表示卡片必須通知主機作業已完成且有中斷要求。 如需 R5 回應的說明,請參閱 多媒體卡片關聯 規格。
完成下列步驟來初始化要求封包:
定義要求函式:
建立 SD 描述元之後,程式代碼範例會初始化要求封包, SDBUS_REQUEST_PACKET。 要求封包的 RequestFunction 成員會指定要求是否包含裝置命令 (值SDRF_DEVICE_COMMAND) 或属性作业 (值SDRF_GET_PROPERTY或SDRF_SET_PROPERTY) 。 程序代碼範例會起始裝置命令,因此會將 RequestFunction 成員設定為 SDRF_DEVICE_COMMAND。
載入命令描述項:接下來,程式代碼範例會將新初始化的描述項儲存在要求封包的 Parameters.DeviceCommand.CmdDesc 成員中。
初始化讀取/寫入自變數:
要求封包包含 SD_RW_DIRECT_ARGUMENT 結構,該結構會保存總線驅動程式擷取的數據位置。 此結構也會儲存函式的數目,其 I/O 空間可供總線驅動程式讀取。 範例程式代碼會從裝置擴充功能擷取函式號碼,這表示驅動程式先前從卡片擷取資訊, (在啟動裝置) 時,可能會使用SDRF_GET_PROPERTY要求將它儲存在裝置擴充功能中。
提交要求
初始化描述元和要求封包之後,程式代碼範例會使用同步要求例程 SdBusSubmitRequest 來提交要求。 要求例程會傳入要求封包,以及系統在開啟 SD 介面時提供給驅動程式的介面內容資訊。 因為這是同步要求,所以驅動程式必須在 IRQL 中執行,小於 DISPATCH_LEVEL。
命令的結果
由於程式代碼範例使用直接 I/O,因此 SD 要求封包中的 ResponseData 欄位不需要任何數據緩衝區。