系统范围内唯一的设备 ID

典型音频适配器的驱动程序应该能够轻松地支持系统中相同音频适配器卡的多个实例。 驱动程序维护的几乎所有数据结构都存储在设备扩展缓冲区中(请参阅DEVICE_OBJECT结构的 DeviceExtension 字段的说明)。 但是,如果驱动程序的多个实例共享任何全局数据,则这些实例应同步对这些数据的访问。

另一个要求是,适配器特定实例上的每个子实例卡应具有唯一标识同一适配器的所有实例卡的子实例的设备 ID 字符串

实现此目的的最直接方法是将适配器上的每个子资源公开为即插即用管理器的逻辑上不同的设备卡。 这在多功能音频设备显示为选项(1)。

第二种方法是使用系统提供的多功能总线驱动程序来管理适配器上的子卡。 即使系统包含同一适配器的多个实例 卡,MF 总线驱动程序也会为每个子设备分配一个保证在整个系统中唯一的设备 ID。 MF 总线驱动程序可适应子单元共享一组通用配置寄存器的设计,但每个子设备都有自己的 PCI 基址寄存器集。 子项不应相互隐藏依赖关系,并且应该能够同时运行,而不会相互干扰或系统中的其他设备。 这是多功能音频设备中的选项(2)。

第三种方法是使用专有总线驱动程序来管理适配器卡上的子对象。 如果子级具有必须集中管理的相互依赖关系,则经常需要这样做。 此类依赖项可以通过以下几种方式发生:

  • 子资源可能会共享一些卡资源。 例如,如果子设备共享数字信号处理器(DSP),则总线驱动程序可能需要下载在 DSP 上运行的专有操作系统,然后再启动第一个子设备。

  • 设计缺陷可能会导致子项之间的依赖关系。 例如,设计缺陷可能需要在特定序列中向上或关闭子项。

当任一类型的依赖项存在时,专有总线驱动程序几乎总是比直接向即插即用管理器显示子对象并尝试隐藏依赖项更好的解决方案。

如果为适配器卡提供自己的总线驱动程序,则应确保总线驱动程序分配的设备 ID 在整个系统中是唯一的。

总线驱动程序为其中一个子级提供设备 ID,以响应来自即插即用管理器的IRP_MN_QUERY_ID查询。 可以通过以下两种方式之一指定 ID:总线驱动程序通过将DEVICE_CAPABILITIES结构的 UniqueID 字段设置为 TRUEFAL 来指示其响应IRP_MN_QUERY_CAPABILITIES查询标准版:

  • UniqueID = TRUE

    这意味着,保证子级的名称在整个系统中是唯一的。 设备 ID 字符串包含设备 ID 和实例 ID,它是唯一标识硬件实例的序列号。

  • UniqueID = FAL标准版

    这意味着子级的名称仅在父级方面是唯一的。 大多数设备都使用这种标识方式。 在这种情况下,即插即用管理器扩展它收到的设备 ID 字符串,使其通过系统是唯一的。 扩展字符串是父设备的唯一 ID 的函数。

所有音频总线驱动程序都应为其子女设置 UniqueID = FAL标准版。 这会导致即插即用管理器通过添加有关设备的父级的信息使 ID 在计算机上唯一来扩展子设备 ID 字符串。