共用方式為


如何取得裝置的連線設定

如果您的 SPB 控制器驅動程式註冊 EvtSpbTargetConnect 回 呼函式, SPB 架構擴充 功能 (SpbCx) 當控制器的用戶端 (周邊驅動程式) 傳送 IRP_MJ_CREATE 要求,以在匯流排上開啟目標裝置的邏輯連線時呼叫此函式。 為了回應 EvtSpbTargetConnect 回呼,SPB 控制器驅動程式應該呼叫 SpbTargetGetConnectionParameters 方法來取得目標裝置的連線設定。 SPB 控制器驅動程式會儲存這些設定,並在稍後使用它們來存取裝置,以回應用戶端的 I/O 要求。

例如,I2C 匯流排上目標裝置的連線設定包括裝置的匯流排位址、位址寬度 (7 或 10 位) ,以及裝置存取期間要使用的匯流排時鐘頻率。 I2C 控制器驅動程式會使用這些設定來設定控制器,以透過 I2C 匯流排存取裝置。

SPB 控制器驅動程式會呼叫 SpbTargetGetConnectionParameters ,以取得 序列匯流排連線描述元 的指標,描述目標裝置與 I2C 或 SPI 類型的序列匯流排連線。 此描述項包含這兩種序列匯流排類型通用的連接資訊,後面接著裝置所連接之序列匯流排特有的資訊。 如需此描述項格式的詳細資訊,請參閱 ACPI 5.0 規格

在下列程式碼範例中,I2C 控制器驅動程式會定義 PNP_I2C_SERIAL_BUS_DESCRIPTOR 結構。 這個結構代表 I2C 序列匯流排連線描述元,這是 ACPI 5.0 規格用來描述序列匯流排連線描述元的一詞,後面接著 I2C 匯流排特有的連線設定。 PNP_I2C_SERIAL_BUS_DESCRIPTOR結構的第一個成員SerialBusDescriptorPNP_SERIAL_BUS_DESCRIPTOR結構,代表序列匯流排連線描述元。 ConnectionSpeedSlaveAddress成員包含 I2C 特定的連線設定。

#include <reshub.h>
#include <pshpack1.h>  

//
// See the ACPI 5.0 spec, section 6.4.3.8.2.1 (I2C Serial Bus Connection Descriptor).  
//
typedef struct _PNP_I2C_SERIAL_BUS_DESCRIPTOR {  
    PNP_SERIAL_BUS_DESCRIPTOR SerialBusDescriptor;  
    ULONG ConnectionSpeed;  
    USHORT SlaveAddress;  
    // Followed by optional vendor-specific data.
    // Followed by name of serial bus controller.
} PNP_I2C_SERIAL_BUS_DESCRIPTOR, *PPNP_I2C_SERIAL_BUS_DESCRIPTOR;  
  
#include <poppack.h>

reshub.h 標頭檔會定義 PNP_SERIAL_BUS_DESCRIPTOR 結構。 pshpack1.h 和 poppack.h 標頭檔會控制編譯器所使用的結構對齊模式。

I2C 序列匯流排連接描述元是一種封裝的資料結構,其中相鄰欄位會對齊最接近的位元組界限,而不會交錯間距。 因此,這個描述元中的 16 位整數值可能會從奇數位節界限開始。 在上述程式碼範例中,包含 pshpack1.h 以告知編譯器封裝連續的結構成員,而 poppack.h 會告知編譯器繼續預設結構對齊。

PNP_I2C_SERIAL_BUS_DESCRIPTOR結構的ConnectionSpeed成員會指定在目標裝置存取期間時鐘 I2C 匯流排的頻率,以 Hertz 為單位。 SlaveAddress成員是目標裝置的匯流排位址。 對於某些 I2C 控制器驅動程式, 從屬Address 成員可能後面接著選擇性廠商特定的資料,但此資料不會由此程式碼範例中的驅動程式使用,因此不是結構定義的一部分。

在下列程式碼範例中,上一個 GetTargetSettings 範例中的 I2C 控制器驅動程式會實作呼叫 SpbTargetGetConnectionParameters 的常式,以取得 I2C 匯流排上目標裝置的連線設定。 此常式 的目標輸入參數 是目標裝置的控制碼。 Settings輸出參數是驅動程式配置的SPB_CONNECTION_PARAMETERS結構的指標,常式會寫入一組連接參數。 這些參數包含所要求連線設定的指標。

#define I2C_SERIAL_BUS_TYPE 0x01
#define I2C_SERIAL_BUS_SPECIFIC_FLAG_10BIT_ADDRESS 0x0001

typedef enum _I2C_ADDRESS_MODE
{
    AddressMode7Bit,
    AddressMode10Bit
} I2C_ADDRESS_MODE, *PI2C_ADDRESS_MODE;
  
typedef struct _I2C_TARGET_SETTINGS
{
    ULONG  ClockFrequency;
    ULONG  Address;
    I2C_ADDRESS_MODE  AddressMode;
} I2C_TARGET_SETTINGS, *PI2C_TARGET_SETTINGS;

NTSTATUS
GetTargetSettings(_In_ SPBTARGET Target, _Out_ PI2C_TARGET_SETTINGS Settings)
{
    PRH_QUERY_CONNECTION_PROPERTIES_OUTPUT_BUFFER Connection = NULL;
    SPB_CONNECTION_PARAMETERS Params;

    SPB_CONNECTION_PARAMETERS_INIT(&Params);
    SpbTargetGetConnectionParameters(Target, &Params);
    Connection = (PRH_QUERY_CONNECTION_PROPERTIES_OUTPUT_BUFFER)Params.ConnectionParameters;
    if (Connection->PropertiesLength < sizeof(PNP_SERIAL_BUS_DESCRIPTOR))
    {
        return STATUS_INVALID_PARAMETER;
    }

    PPNP_SERIAL_BUS_DESCRIPTOR Descriptor;

    Descriptor = (PPNP_SERIAL_BUS_DESCRIPTOR)Connection->ConnectionProperties;
    if (Descriptor->Tag != SERIAL_BUS_DESCRIPTOR ||
        Descriptor->SerialBusType != I2C_SERIAL_BUS_TYPE)
    {
        return STATUS_INVALID_PARAMETER;
    }

    PPNP_I2C_SERIAL_BUS_DESCRIPTOR I2CDescriptor;
    USHORT I2CFlags;

    I2CDescriptor = (PPNP_I2C_SERIAL_BUS_DESCRIPTOR)Connection->ConnectionProperties;
    Settings->Address = (ULONG)I2CDescriptor->SlaveAddress;
    I2CFlags = I2CDescriptor->SerialBusDescriptor.TypeSpecificFlags;
    Settings->AddressMode = 
                ((I2CFlags & I2C_SERIAL_BUS_SPECIFIC_FLAG_10BIT_ADDRESS) == 0) ? AddressMode7Bit : AddressMode10Bit;

    Settings->ClockFrequency = I2CDescriptor->ConnectionSpeed;

    return STATUS_SUCCESS;
}

在上述程式碼範例中, SpbTargetGetConnectionParameters 會將連接參數寫入驅動程式配置的 Params 結構。 ConnectionParameters成員 Params 指向 reshub.h) 中定義的RH_QUERY_CONNECTION_PROPERTIES_OUTPUT_BUFFER結構 (,其ConnectionProperties成員是序列匯流排連接描述元的第一個位元組;這個描述元的其餘位元組會緊接在ConnectionProperties成員後面。 的 ConnectionParameters 成員 Params 所指向的緩衝區夠大,足以包含 RH_QUERY_CONNECTION_PROPERTIES_OUTPUT_BUFFER 結構加上這個結構後面的描述元位元組。

上述程式碼範例中的驅動程式實 GetTargetSettings 作常式會對從 SpbTargetGetConnectionParameters收到的連線參數執行下列參數檢查:

  • 確認 包含在RH_QUERY_CONNECTION_PROPERTIES_OUTPUT_BUFFER 結構中的序列匯流排連線描述元大小至少為 sizeof (PNP_SERIAL_BUS_DESCRIPTOR) 。
  • 確認串列匯流排連線描述元的第一個位元組已設定為SERIAL_BUS_DESCRIPTOR (常數值0x8e) ,如 ACPI 5.0 規格所要求。
  • 確認序列匯流排連線描述元中的序列匯流排類型已設定為I2C_SERIAL_BUS_TYPE (常數值0x01) ,這會將序列匯流排類型識別為 I2C。

在上述程式碼範例結尾,* Settings 結構包含目標裝置 (匯流排位址、位址寬度和匯流排頻率頻率) 的連線設定。 I2C 控制器驅動程式會使用這些連線設定來設定控制器來存取裝置。