匯流排型別¶
定義¶
請參閱 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 *);