SD 卡请求
安全数字 (SD) 卡设备驱动程序打开并初始化 SD 总线驱动程序的接口后,它可以提交请求。 有两种方法可以提交请求:通过 SdBusSubmitRequest 例程同步提交请求,以及通过 SdBusSubmitRequestAsync 例程异步提交请求。 SD 总线库 (sdbus.lib) 导出这两个例程。
同步请求例程采用两个参数:接口上下文和请求数据包。
接口上下文
使用 SdBusOpenInterface 打开 SD 接口后,设备驱动程序从 SDBUS_INTERFACE_STANDARD 结构的 Context 成员检索接口上下文。 每当驱动程序调用 接口中的方法时,它都必须在 中传递此上下文信息。
请求数据包
设备驱动程序必须分配和初始化 SDBUS_REQUEST_PACKET 结构。 此结构指定请求函数和请求的其他特征。
由于 SdBusSubmitRequest 是同步的,因此它不会返回STATUS_PENDING。 设备驱动程序必须在 IRQL < DISPATCH_LEVEL调用此例程时运行。
异步请求例程采用以下五个参数:接口上下文、请求数据包、IRP、指向完成例程的指针和完成上下文。
Irp
此参数包含设备驱动程序已分配的 IRP,或驱动程序从驱动程序堆栈中位于其上方的驱动程序收到的 IRP。 IRP 用作请求的载体。
完成例程
此参数保存 IRP 参数中提供的 IRP 的 IoCompletion 例程。
用户上下文
此参数包含一个指针,指向系统传递给完成例程参数中指定的完成例程的用户上下文数据。
设备驱动程序在调用 SdBusSubmitRequestAsync 例程时,必须在 IRQL <= DISPATCH_LEVEL 运行。 SdBusSubmitRequest 是分配自己的 IRP 并调用 SdBusSubmitRequestAsync 的包装器。 为方便驱动程序编写器提供。
以下部分提供代码示例,说明设备驱动程序如何提交 SD 请求的两个主要类别:有关不同请求的说明,请参阅 SD_REQUEST_FUNCTION。
保护数字 (SD) 属性请求
安全数字 (SD) 卡驱动程序使用属性请求来读取或设置卡属性。 例如,SD 卡驱动程序可能会读取 属性以确定 SD 卡上的写保护开关是否处于锁定位置,或者多功能 SDIO 卡上的特定函数的驱动程序可能会请求总线驱动程序分配给它所管理的函数的编号。
下面的代码示例演示了多功能卡上的函数的驱动程序如何从总线驱动程序请求其函数编号:
sdrp = ExAllocatePool(NonPagedPool,
sizeof(SDBUS_REQUEST_PACKET));
if (!sdrp) {
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlZeroMemory(sdrp, sizeof(SDBUS_REQUEST_PACKET));
sdrp->RequestFunction = SDRF_GET_PROPERTY;
sdrp->Parameters.GetSetProperty.Property =
SDP_FUNCTION_NUMBER;
sdrp->Parameters.GetSetProperty.Buffer =
&pDevExt->FunctionNumber;
sdrp->Parameters.GetSetProperty.Length =
sizeof(pDevExt->FunctionNumber);
status = SdBusSubmitRequest (pDevExt->BusInterface.Context,sdrp);
ExFreePool(sdrp);
if (!NT_SUCCESS(status)) {
return status;
}
在此代码示例中,设备驱动程序初始化 SD 总线请求数据包 ,SDBUS_REQUEST_PACKET,并将其传递给 SdBusSubmitRequest。 完全初始化的请求数据包具有以下特征:
请求的类型
代码示例在请求数据包的 RequestFunction 成员中指定一个SDRF_GET_PROPERTY请求,该成员指示总线驱动程序从卡检索属性。 有关SDRF_GET_PROPERTY请求的说明,请参阅 SD_REQUEST_FUNCTION。
要检索的属性
代码示例指定请求数据包的 Parameters.GetSetProperty.Property 成员中的 SDP_FUNCTION_NUMBER 属性,该属性指示总线驱动程序检索函数编号属性的内容。 有关 SDP_FUNCTION_NUMBER 属性的说明,请参阅 SDBUS_PROPERTY。
属性内容和长度
该代码示例将指向缓冲区的指针放在 设备扩展的 中
请求数据包的 Parameters.GetSetProperty.Buffer 成员。 总线驱动程序会将函数编号存储在此位置。 示例代码还将此缓冲区的大小存储在请求数据包的 Parameters.GetSetProperty.Length 成员中。
保护数字 (SD) 设备命令请求
驱动程序使用安全数字 (SD) 卡命令请求将命令发送到 SD 设备。 SD 命令的协议在 安全数字卡 规范中定义。 启动设备的 IRP_MN_START_DEVICE IRP 成功完成后,驱动程序可以随时发送命令请求。
本部分包含两个代码示例:使用直接 I/O 从 SD 卡寄存器读取字节数据的命令请求,以及使用扩展 I/O 将大量数据写入 SD 卡的设备命令请求。 第二节的解释取决于第一部分,因此,读者应该先研究第一节,然后再研究第二节: