9.1. 设备对象名称冲突
同时包含 _HID 和 _CID 的设备,可能具有分别对应于 _HID 中设备 ID 和 _CID 中设备 ID 的设备专用控制方法。这些设备专用控制方法由设备所有者(标准组织、供应商或供应商合作伙伴组)定义。由于这些对象名称不受中央机构控制,因此两个定义方之间的对象名称有可能发生冲突。下一节中描述的 _DSM 对象解决了这一冲突。
9.1.1. _DSM(设备专用方法)
该可选对象是一个控制方法,使设备能够提供由设备驱动程序使用的设备专用控制功能。
参数:(4)
Arg0 - 包含 UUID 的缓冲区
Arg1 - 包含修订版本 ID 的整数
Arg2 - 包含函数索引的整数
Arg3 - 包含函数专用参数的包
返回值:
如果函数索引 = 0,则返回一个包含函数索引位字段的缓冲区。否则,返回值及其类型取决于 UUID 和修订版本 ID(见下文)。
参数信息:
Arg0: UUID - 包含 16 字节 UUID 的缓冲区(见第 5.2.4 节)
Arg1: 修订版本 ID - 函数的修订版本。此修订版本特定于该 UUID。
Arg2: 函数索引 - 表示一个特定函数,其含义特定于 UUID 和修订版本 ID。函数索引应从 1 开始。函数编号 0 是查询函数(见下文定义的特殊返回码)。
Arg3: 函数参数 - 一个包,包含由 UUID、修订版本 ID 和函数索引指定的函数所需的参数。
函数参数的后续修订版本必须与先前修订版本向后兼容。OEM 和 IHV 也可以为自定义设备以及其他接口或设备管理机构(例如 PCI SIG)创建新的 UUID,只要该 UUID 不同于其他已发布的 UUID。只有 UUID 的发布者才能为该 UUID 授权新的函数索引、修订版本 ID 或函数参数。
返回值信息:
如果函数索引为零,则返回一个缓冲区,其中从零开始为每个函数索引包含一位。位 0 表示对于指定的 UUID 和修订版本 ID,是否支持除函数 0 之外的任何函数。如果设置为零,则表示对于指定的 UUID 和修订版本 ID,不支持任何函数(除函数零外)。如果设置为一,则表示至少支持一个附加函数。对于缓冲区中的所有其他位,某一位设置为零表示对于特定的 UUID 和修订版本 ID 不支持该函数索引。(例如,位 1 设置为 0 表示对于特定的 UUID 和修订版本 ID,不支持函数索引 1。)
如果表示某个特定函数索引的位将位于缓冲区之外,则应假定其为 0(即不受支持)。
如果函数索引非零,则返回值可以是任意数据对象。返回数据对象的类型和含义取决于 UUID、修订版本 ID、函数索引和函数参数。
注意
为了向后兼容,_DSM 要求每个修订版本 ID 都支持为同一 UUID 的所有先前修订版本 ID 定义的全部函数。*
实现说明
由于 _DSM 方法的目的是避免命名空间冲突,因此除非某个驱动程序及其用法完全由平台供应商控制,否则该方法的实现不得使用本规范中未定义的任何其他方法或数据对象。
示例:
// _DSM - Device Specific Method
//
// Arg0: UUID Unique function identifier
// Arg1: Integer Revision Level
// Arg2: Integer Function Index (0 = Return Supported Functions)
// Arg3: Package Parameters
Function(_DSM,{IntObj,BuffObj},{BuffObj, IntObj, IntObj, PkgObj})
{
//
// Switch based on which unique function identifier was passed in
//
switch(Arg0)
{
//
// First function identifier
//
case(ToUUID("893f00a6-660c-494e-bcfd-3043f4fb67c0"))
{
switch(Arg2)
{
//
// Function 0: Return supported functions, based on revision
//
case(0)
{
switch(Arg1)
{
// revision 0: functions 1-4 are supported
case(0) {return (Buffer() {0x1F})}
// revision 1: functions 1-5 are supported
case(1) {return (Buffer() {0x3F})}
}
// revision 2+: functions 1-7 are supported
return (Buffer() {0xFF})
}
//
// Function 1:
//
case(1)
{
... function 1 code ...
Return(Zero)
}
//
// Function 2:
//
case(2)
{
... function 2 code ...
Return(Buffer(){0x00})
}
case(3) { ... function 3 code ...}
case(4) { ... function 4 code ...}
case(5) { if (LLess(Arg1,1) BreakPoint; ... function 5 code ... }
case(6) { if (LLess(Arg1,2) BreakPoint; ... function 6 code ... )
case(7) { if (LLess(Arg1,3) BreakPoint; ... function 7 code ... )
default {BreakPoint }
}
}
//
// Second function identifier
//
case(ToUUID("107ededd-d381-4fd7-8da9-08e9a6c79644"))
{
//
// Function 0: Return supported functions (there is only one revision)
//
if (LEqual(Arg2,Zero))
return (Buffer() {0x3}) // only one function supported
//
// Function 1
//
if (LEqual(Arg2,One))
{
... function 1 code ...
Return(Unicode("text"))
}
//
// Function 2+: Runtime Error
//
else
BreakPoint;
}
}
//
// If not one of the UUIDs we recognize, then return a buffer
// with bit 0 set to 0 indicating no functions supported.
//
return(Buffer(){0})
}