同步和异步编解码器命令

TransferCodecVerbs 例程允许函数驱动程序将命令发送到连接到 HD 音频控制器的音频和调制解调器编解码器。 编解码器命令可以同步或异步执行:

  • 如果对 TransferCodecVerbs 的调用提交要同步处理的命令列表,则例程仅在编解码器或编解码器处理完所有命令后返回。

  • 如果对 TransferCodecVerbs 的调用提交异步处理的命令列表,则当 HD 音频总线驱动程序将命令添加到其内部命令队列时,该例程将立即返回,而无需等待编解码器或编解码器处理命令。 编解码器处理命令后,总线驱动程序通过调用回调例程通知函数驱动程序。

根据它发送的编解码器命令的性质,函数驱动程序使用以下一种或多种技术从编解码器检索响应:

  • 如果函数驱动程序必须具有编解码器的响应,然后才能执行任何其他处理,则它使用同步模式。

  • 如果函数驱动程序不需要等待编解码器命令完成,若要查看编解码器响应,并知道命令何时完成,则它使用异步模式,忽略回调例程(除了释放编解码器命令的存储),并取消卡或忽略对编解码器命令的响应。

  • 如果函数驱动程序必须知道编解码器命令何时完成,但不需要查看响应,则它使用异步模式并依赖回调例程进行通知。 但是,它会取消卡或忽略对编解码器命令的响应。 回调例程可能使用 内核流式处理 (KS) 事件 将通知发送到驱动程序的主要部分。

  • 如果函数驱动程序必须同时知道编解码器命令何时完成和响应是什么,但必须立即恢复处理,而不是等待命令完成,则它使用异步模式并避免读取响应,直到收到回调例程。 回调例程或驱动程序的主要部分都可以检查响应。

如果 TransferCodecVerbs 成功将命令列表添加到总线驱动程序的内部命令队列,则返回STATUS_SUCCESS。 尽管调用成功,但响应可能仍然无效。 函数驱动程序必须检查编解码器响应中的状态位,以确定它们是否有效。 此规则适用于同步模式和异步模式。

无效响应的原因可能是以下项之一:

  • 该命令未到达编解码器。

  • 编解码器进行了响应,但当 RIRB 中发生首次传入、先出(FIFO)溢出时,响应会丢失。

后一个问题表示 RIRB FIFO 大小不足。

每个编解码器响应都包含一个 IsValid 标志,用于指示响应是否有效,以及一个 HasFifoOverrun 标志,用于指示是否已发生 RIRB FIFO 溢出。 如果 IsValid = 0,则指示响应无效, HasFifoOverrun 标志有助于标识故障源:

  • 如果 HasFifoOverrun = 0,则编解码器未能在所需的时间间隔内响应。 可能的原因是命令从未到达编解码器。

  • 如果 HasFifoOverrun = 1,则命令可能到达编解码器,但响应因 FIFO 溢出而丢失。

在调用 TransferCodecCommands 期间,调用方提供指向HDAUDIO_CODEC_TRANSFER结构的数组的指针。 每个结构都包含一个命令,并为响应提供空间。 总线驱动程序始终将每个响应写入包含触发响应的命令的结构中。

对于对 TransferCodecCommands 的每个调用,命令的处理顺序取决于数组中命令的顺序。 处理数组中的第一个命令始终在处理第二个命令开始之前完成,依此等。

此外,如果客户端对 TransferCodecCommands 进行异步调用,然后第二次调用 TransferCodecCommands ,而无需等待第一次调用的回调例程,则由客户端提交两组命令的顺序定义两组命令的相对顺序。 因此,总线驱动程序先处理第一次调用中的所有命令,然后再开始处理第二次调用中的命令。

但是,未定义由两个不同的函数驱动程序实例发送的命令的相对顺序。 (每个实例都有自己的物理设备对象。例如,如果实例 1 按 A-B-C 的顺序调用 TransferCodecCommands 来发送命令 A、B 和 C,而实例 2 将调用 TransferCodecCommands 以按 X-Y-Z 顺序发送命令 X、Y 和 Z,则总线驱动程序可以按 A-X-Y-B-Z-C 的顺序执行命令。

当单独的函数驱动程序线程共享对同一组硬件资源的访问权限时,来自不同驱动程序线程的命令的相对顺序可能很重要。 如果是这样,函数驱动程序负责同步线程之间资源的共享。

例如,用于将数据字节序列写入编解码器的硬件接口可能包含索引寄存器和 8 位数据寄存器。 首先,函数驱动程序提交编解码器命令,将起始索引加载到索引寄存器中。 接下来,驱动程序提交一个命令,将第一个字节的数据写入数据寄存器。 索引寄存器在每次连续写入数据寄存器后递增,直到传输完成。 但是,如果两个驱动程序线程未能正确同步索引和数据寄存器的访问,则两个线程对单个寄存器访问的相对顺序是未定义,并且可能是数据损坏或硬件配置无效。

TransferCodecVerbs 例程在 HD Audio DDI 的两个版本中都可用。