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