linux pci 寄存器,Linux 内核 标准 PCI 配置寄存器
一些 PCI 配置寄存器是要求的, 一些是可選的. 每個 PCI 設備必須包含有意 義的值在被要求的寄存器中, 而可選寄存器的內容依賴外設的實際功能. 可選的字段不被 使用, 除非被要求的字段的內容指出它們是有效的. 因此, 被要求的字段聲稱板的功能, 包括其他的字段是否可用.
注意 PCI 寄存器一直是小端模式. 盡管標準被設計為獨立于體系, PCI 設計者有時露出 一些傾向 PC 環境. 驅動編寫者應當小心處理字節序, 當存取多字節配置寄存器時; 在 PC 上使用的代碼可能在其他平臺上不工作. Linux 開發者已經處理了這個字節序問題(見 下一節, "存取配置空間"), 但是這個問題必須記住. 如果你曾需要轉換數據從主機序到 PCI 序, 或者反之, 你可求助在 中定義的函數, 在第 11 章介紹, 知道 PCI 字節序是小端.
描述所有的配置項超出了本書的范圍. 常常地, 隨每個設備發布的技術文檔描述被支持的 寄存器. 我們感興趣的是一個驅動如何能知道它的設備以及它如何能存取設備的配置空間.
3 個或者 4 個 PCI 寄存器標識一個設備: verdorID, deviceID, 和 class 是 3 個常常 用到的. 每個 PCI 制造商分配正確的值給這些只讀寄存器, 并且驅動可使用它們來查找 設備. 另外, 字段 subsystem verdorID 和 subsystem deviceID 有時被供應商設置來進 一步區分類似的設備.
我們看這些寄存器的細節: vendorID
這個 16-位 寄存器標識一個硬件制造商. 例如, 每個 Intel 設備都標有相同的供 應商號, 0x8086. 這樣的號有一個全球的注冊, 由 PCI 特別利益體所維護, 并且 供應商必須申請有一個唯一的分配給它們的號.
deviceID
這是另一個 16-位 寄存器, 由供應商選擇; 對于這個設備 ID 沒有要求官方的注 冊. 這個 ID 常常和 供應商 ID 成對出現來組成一個唯一的 32-位 標識符給一個 硬件設備. 我們使用詞語"簽名"來指代供應商和設備 ID 對. 一個設備驅動常常依 靠簽名來標識它的設備; 你可在硬件手冊中找到對于目標設備要尋找的值.
class
每個外設都屬于一個類. 類寄存器是一個 16-位 值, 它的高 8 位標識"基類"(或 者群). 例如, "ethernet"和"token ring"是 2 個類都屬于"network"群, 而 "serial"和"parallel"屬于"communication"群. 一些驅動可支持幾個類似的設備, 每個都有一個不同的簽名但是都屬于同樣的類; 這些驅動可依賴類寄存器標識它們 的外設, 就象后面所示.
subsystem vendorID subsystem deviceID
這些字段可用來進一步標識一個設備. 如果芯片對于本地總線是一個通用接口芯片, 它常常被用在幾個完全不同的地方, 并且驅動必須標識出它在與之通話的實際設備. 子系統標志用作此目的.
使用這些不同的標識符, 一個 PCI 驅動可告知內核它支持什么類型的設備. struct pci_device_id 結構被用來定義一個驅動支持的不同類型 PCI 設備的列表. 這個結構包 含不同的成員:
u32 vendor;
u32 device;
這些指定一個設備的 PCI 供應商和設備 ID. 如果驅動可處理任何供應商或者設備 ID, 值 PCI_ANY_ID 應當用作這些成員上.
u32 subvendor;
u32 subdevice;
這些指定一個設備的 PCI 子系統供應商和子系統設備 ID. 如果驅動可處理任何類 型的子系統 ID, 值 PCI_ANY_ID 應當用作這些成員上.
u32 class;
u32 class_mask;
這 2 個值允許驅動來指定它支持一類 PCI 類設備. 不同的 PCI 設備類( 一個 VAG 控制器是一個例子 )在 PCI 規范里被描述. 如果一個驅動可處理任何子系統 ID, 值 PCI_ANY_ID 應當用作這些字段.
kernel_ulong_t driver_data;
這個值不用來匹配一個設備, 但是用來持有信息, PCI 驅動可用來區分不同的設備, 如果它想這樣.
有 2 個幫助宏定義應當被用來初始化一個 struct pci_device_id 結構: PCI_DEVICE(vendor, device)
這個創建一個 struct pci_device_id , 它只匹配特定的供應商和設備 ID. 這個 宏設置這個結構的子供應商和子設備成員為 PCI_ANY_ID.
PCI_DEVICE_CLASS(device_class, device_class_mask)
這個創建一個 struct pci_device_id, 它匹配一個特定的 PCI 類. 一個使用這些宏來定義一個驅動支持的設備類型的例子, 在下面的內核文件中可找到:
drivers/usb/host/ehci-hcd.c:
static const struct pci_device_id pci_ids[] = { {
/* handle any USB 2.0 EHCI controller */
PCI_DEVICE_CLASS(((PCI_CLASS_SERIAL_USB << 8) | 0x20), ~0),
.driver_data = (unsigned long) &ehci_driver,
},
{ /* end: all zeroes */ }
};
drivers/i2c/busses/i2c-i810.c:
static struct pci_device_id i810_ids[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82810_IG1) },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82810_IG3) },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82810E_IG) },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82815_CGC) },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82845G_IG) },
{ 0, },
};
這些例子創建一個 struct pci_device_id 結構的列表, 列表中最后一個是被設置為全零 的的空結構. 這個 ID 的數組用在 struct pci_driver (下面講述), 并且它還用來告訴 用戶空間這個特定的驅動支持哪個設備.
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的linux pci 寄存器,Linux 内核 标准 PCI 配置寄存器的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java分布式篇5——FastDFS
- 下一篇: firefox 39 linux,Moz