匯流排型別

定義

請參閱 struct bus_type 的 kerneldoc。

int bus_register(struct bus_type * bus);

宣告

核心中的每種匯流排型別(PCI、USB 等)都應宣告一個此型別的靜態物件。 他們必須初始化 name 欄位,並且可以選擇初始化 match 回撥

struct bus_type pci_bus_type = {
       .name = "pci",
       .match        = pci_bus_match,
};

該結構體應該匯出到驅動程式的標頭檔案中

extern struct bus_type pci_bus_type;

註冊

當匯流排驅動程式初始化時,它會呼叫 bus_register。 這會初始化匯流排物件中的其餘欄位,並將其插入到匯流排型別的全域性列表中。 一旦匯流排物件被註冊,匯流排驅動程式就可以使用其中的欄位。

回撥

match(): 將驅動程式附加到裝置

裝置 ID 結構的格式和比較它們的語義本質上是匯流排特定的。 驅動程式通常宣告一個裝置 ID 陣列,這些裝置 ID 是它們支援的駐留在匯流排特定驅動程式結構中的裝置。

match 回撥的目的是讓匯流排有機會透過比較驅動程式支援的裝置 ID 與特定裝置的裝置 ID 來確定特定驅動程式是否支援特定裝置,而不會犧牲匯流排特定功能或型別安全。

當驅動程式註冊到匯流排時,匯流排的裝置列表會被迭代,並且對於每個沒有與驅動程式關聯的裝置,都會呼叫 match 回撥。

裝置和驅動程式列表

裝置和驅動程式的列表旨在替換許多匯流排保留的本地列表。 它們分別是 struct devices 和 struct device_drivers 的列表。 匯流排驅動程式可以隨意使用這些列表,但可能需要轉換為匯流排特定型別。

LDM 核心提供了用於迭代每個列表的輔助函式

int bus_for_each_dev(struct bus_type * bus, struct device * start,
                     void * data,
                     int (*fn)(struct device *, void *));

int bus_for_each_drv(struct bus_type * bus, struct device_driver * start,
                     void * data, int (*fn)(struct device_driver *, void *));

這些輔助函式迭代各自的列表,併為列表中的每個裝置或驅動程式呼叫回撥。 所有列表訪問都透過獲取匯流排的鎖(目前是讀)來同步。 在呼叫回撥之前,列表中每個物件的引用計數都會遞增;在獲取下一個物件後,它會遞減。 呼叫回撥時不會持有鎖。

sysfs

有一個名為“bus”的頂級目錄。

每個匯流排在匯流排目錄中都有一個目錄,以及兩個預設目錄

/sys/bus/pci/
|-- devices
`-- drivers

註冊到匯流排的驅動程式在匯流排的 drivers 目錄中獲得一個目錄

/sys/bus/pci/
|-- devices
`-- drivers
    |-- Intel ICH
    |-- Intel ICH Joystick
    |-- agpgart
    `-- e100

在該型別的總線上發現的每個裝置在匯流排的 devices 目錄中獲得一個符號連結,指向物理層次結構中裝置的目錄

/sys/bus/pci/
|-- devices
|   |-- 00:00.0 -> ../../../root/pci0/00:00.0
|   |-- 00:01.0 -> ../../../root/pci0/00:01.0
|   `-- 00:02.0 -> ../../../root/pci0/00:02.0
`-- drivers

匯出屬性

struct bus_attribute {
      struct attribute        attr;
      ssize_t (*show)(const struct bus_type *, char * buf);
      ssize_t (*store)(const struct bus_type *, const char * buf, size_t count);
};

匯流排驅動程式可以使用 BUS_ATTR_RW 宏匯出屬性,該宏的工作方式類似於裝置的 DEVICE_ATTR_RW 宏。 例如,像這樣的定義

static BUS_ATTR_RW(debug);

等同於宣告

static bus_attribute bus_attr_debug;

然後可以使用它來新增和刪除匯流排的 sysfs 目錄中的屬性,使用

int bus_create_file(struct bus_type *, struct bus_attribute *);
void bus_remove_file(struct bus_type *, struct bus_attribute *);