pci 驱动总结
/driver/pci/probe.c
/arch/powerpc/kernel/pci_64.c
在pci驅動中pci調用pci_scan_device掃描每個設備的每個功能,當發現該功能存在時(通過讀設備的vendor及product ID確定),就為該設備功能建立一個完整的pci_dev(通過pci_setup_device 完成),并將該設備功能加入到全局鏈表及總線鏈表中,當加載設備驅動程序時,設備驅動根據總線類型掃描總線上連接的設備,然后讀取pci_dev數據結構中的vendor ID及product Id號來確定是否支持該設備通過與自己的 product table id 比較完成。
1. pci驅動分為總線驅動和設備驅動。總線驅動是linux內核完成,主要完成設備的枚舉,常規64個字節配置空間的訪問。設備驅動是針對PCI接口具體設備需要實現的功能。例如PCIE網卡的驅動,肯定是實現一個網卡的收發。
2.linux啟動過程中pci總線初始化主要包括2部分,pci控制器的注冊和pci設備的枚舉,pci總線和其他總線一個很重要的區別就是pci總線的枚舉,在啟動過程中遍歷pci總線樹上所有可能的dev func,記錄下所有存在的設備的vendor id? 設備名等,這個是做為后面pci設備驅動初始化中注冊pci設備驅動需要匹配(例如設備驅動id)的重要依據,類似于platform驅動。
3. PCI 名稱以及裝置名稱為 09:00.0 0c04: 1077:2432 (rev 03) 先來看看這些數字所代表的意義.
前面的 3 個數字 "09:00.0" 是各代表什麼意思.
在 PCI 的裝置使用三個編號用來當作識別值,個別為 1. "匯流排(bus number)", 2. "裝置(device number) 以及 3. "功能(function number)".
所以剛剛的 09:00.0 就是 bus number = 09 ,device number = 00 function = 0 .
這3個編號會組合成一個 16-bits 的識別碼,
匯流排(bus number) 8bits 2^8 至多可連接 256 個匯流排(0 to ff), ?
裝置(device number) 5bits 2^5 至多可接 32 種裝置(0 to 1f) 以及 ?
功能(function number) 3bits 2^3 至多每種裝置可有 8 項功能(0 to 7).
關於更多 #lspci 的資訊請參考 http://benjr.tw/node/543
不過在 Linux 使用 Class ID + Vendor ID + Device ID? 來代表裝置,如剛剛的? 0c04: 1077:2432 所代表裝置名稱為 (Class ID = 0c04 ,Vendor ID = 1077,Device ID =2432) .
0c04 : class 0c04 表示是 "Fiber Channel controller"
1077 : vendor ID 1077 製造廠商 "Qlogic Corp"
2432 : device ID 2432 產品名稱 "ISP2432-based 4Gb Fiber Channel to PCI Express HBA"
4.在PCIE鏈路只能連接一個下游設備,而這個下游設備的Device Number只能為0
5.在PCIe總線的物理鏈路的一個數據通路(Lane)中,由兩組差分信號,共4根信號線組成, PCIe鏈路可以由多條Lane組成,目前PCIe鏈路可以支持1、2、4、8、12、16和32個Lane,即×1、×2、×4、×8、×12、×16和×32寬度的PCIe鏈路。每一個Lane上使用的總線頻率與PCIe總線使用的版本相關。
6.研究了一下PCIE熱插拔,跟蹤內核驅動發現,目前來看,不僅需要linux內核支持,還需要PCIE設備本身支持(PCIE支持熱插拔寄存器擴展)---
? 6.1 linux內核支持
?
? Bus options ---> support for PCI Hotplug
??????????? ---> PCI Express support ---> PCI EXpress hotplug driver
?
?? 6.2 PCIE設備支持,參考PCIE 3.0標準手冊,必須有該寄存器擴展(slot capabilities Register),且第7位hot-????? plug capalbe為1
7. rtl8139 設備驅動初始化
static int __init demo_init_module (void)
{
??? /* 檢查系統是否支持PCI總線 */
??? if (!pci_present())
??????? return -ENODEV;
??? /* 注冊硬件驅動程序 */
??? if (!pci_register_driver(&demo_pci_driver)) {
??????? pci_unregister_driver(&demo_pci_driver);
??????????????? return -ENODEV;
??? }
??? /* ... */
? ?
??? return 0;
}
pci_register_driver做了三件事情。
①是把帶過來的參數rtl8139_pci_driver在內核中進行了注冊,內核中有一個PCI設備的大的鏈表,這里負責把這個PCI驅動掛到里面去。
②是查看總線上所有PCI設備(網卡設備屬于PCI設備的一種)的配置空間如果發現標識信息與rtl8139_pci_driver中的id_table相同即rtl8139_pci_tbl,而它的定義如下:
static struct pci_device_id rtl8139_pci_tbl[] __devinitdata = {
{0x10ec, 0x8129, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
{PCI_ANY_ID, 0x8139, 0x10ec, 0x8139, 0, 0,0 },
{0,}
};
,那么就說明這個驅動程序就是用來驅動這個設備的,這里需要注意一下pci_device_id是內核定義的用來辨別不同PCI設備的一個結構,例如在我們這里0x10ec代表的是Realtek公司,我們掃描PCI設備配置空間如果發現有Realtek公司制造的設備時,兩者就對上了,就是調用probe函數了。當然對上了公司號后還得看其他的設備號什么的,都對上了才說明這個驅動是可以為這個設備服務的。
③是把這個rtl8139_pci_driver結構掛在這個設備的數據結構(pci_dev)上,表示這個設備從此就有了自己的驅動了。而驅動也找到了它服務的對象了。
8. pci橋一般不存在私有寄存器,操作系統也不需要為PCE橋提供驅動,這類橋稱為透明橋
PCI學習筆記
http://blog.chinaunix.net/uid-24148050-id-101021.html
Linux下的PCI總線驅動
http://blog.csdn.net/weiqing1981127/article/details/8031541
Linux PCI網卡驅動的詳細分析
http://soft.chinabyte.com/os/13/12304513.shtml
Linux kernel中網絡設備的管理
http://www.linuxidc.com/Linux/2013-08/88472.htm
PCI驅動初始化流程--基于POWERPC85xx架構的Linux內核PCI初始化
http://blog.csdn.net/luwei860123/article/details/38816473
PowerPC的PCI總線的dts配置【轉】 ?
http://blog.163.com/liuqiang_mail@126/blog/static/10996887520126192504668/
/arch/powerpc/kernel/pci_64.c
在pci驅動中pci調用pci_scan_device掃描每個設備的每個功能,當發現該功能存在時(通過讀設備的vendor及product ID確定),就為該設備功能建立一個完整的pci_dev(通過pci_setup_device 完成),并將該設備功能加入到全局鏈表及總線鏈表中,當加載設備驅動程序時,設備驅動根據總線類型掃描總線上連接的設備,然后讀取pci_dev數據結構中的vendor ID及product Id號來確定是否支持該設備通過與自己的 product table id 比較完成。
1. pci驅動分為總線驅動和設備驅動。總線驅動是linux內核完成,主要完成設備的枚舉,常規64個字節配置空間的訪問。設備驅動是針對PCI接口具體設備需要實現的功能。例如PCIE網卡的驅動,肯定是實現一個網卡的收發。
2.linux啟動過程中pci總線初始化主要包括2部分,pci控制器的注冊和pci設備的枚舉,pci總線和其他總線一個很重要的區別就是pci總線的枚舉,在啟動過程中遍歷pci總線樹上所有可能的dev func,記錄下所有存在的設備的vendor id? 設備名等,這個是做為后面pci設備驅動初始化中注冊pci設備驅動需要匹配(例如設備驅動id)的重要依據,類似于platform驅動。
3. PCI 名稱以及裝置名稱為 09:00.0 0c04: 1077:2432 (rev 03) 先來看看這些數字所代表的意義.
前面的 3 個數字 "09:00.0" 是各代表什麼意思.
在 PCI 的裝置使用三個編號用來當作識別值,個別為 1. "匯流排(bus number)", 2. "裝置(device number) 以及 3. "功能(function number)".
所以剛剛的 09:00.0 就是 bus number = 09 ,device number = 00 function = 0 .
這3個編號會組合成一個 16-bits 的識別碼,
匯流排(bus number) 8bits 2^8 至多可連接 256 個匯流排(0 to ff), ?
裝置(device number) 5bits 2^5 至多可接 32 種裝置(0 to 1f) 以及 ?
功能(function number) 3bits 2^3 至多每種裝置可有 8 項功能(0 to 7).
關於更多 #lspci 的資訊請參考 http://benjr.tw/node/543
不過在 Linux 使用 Class ID + Vendor ID + Device ID? 來代表裝置,如剛剛的? 0c04: 1077:2432 所代表裝置名稱為 (Class ID = 0c04 ,Vendor ID = 1077,Device ID =2432) .
0c04 : class 0c04 表示是 "Fiber Channel controller"
1077 : vendor ID 1077 製造廠商 "Qlogic Corp"
2432 : device ID 2432 產品名稱 "ISP2432-based 4Gb Fiber Channel to PCI Express HBA"
4.在PCIE鏈路只能連接一個下游設備,而這個下游設備的Device Number只能為0
5.在PCIe總線的物理鏈路的一個數據通路(Lane)中,由兩組差分信號,共4根信號線組成, PCIe鏈路可以由多條Lane組成,目前PCIe鏈路可以支持1、2、4、8、12、16和32個Lane,即×1、×2、×4、×8、×12、×16和×32寬度的PCIe鏈路。每一個Lane上使用的總線頻率與PCIe總線使用的版本相關。
6.研究了一下PCIE熱插拔,跟蹤內核驅動發現,目前來看,不僅需要linux內核支持,還需要PCIE設備本身支持(PCIE支持熱插拔寄存器擴展)---
? 6.1 linux內核支持
?
? Bus options ---> support for PCI Hotplug
??????????? ---> PCI Express support ---> PCI EXpress hotplug driver
?
?? 6.2 PCIE設備支持,參考PCIE 3.0標準手冊,必須有該寄存器擴展(slot capabilities Register),且第7位hot-????? plug capalbe為1
7. rtl8139 設備驅動初始化
static int __init demo_init_module (void)
{
??? /* 檢查系統是否支持PCI總線 */
??? if (!pci_present())
??????? return -ENODEV;
??? /* 注冊硬件驅動程序 */
??? if (!pci_register_driver(&demo_pci_driver)) {
??????? pci_unregister_driver(&demo_pci_driver);
??????????????? return -ENODEV;
??? }
??? /* ... */
? ?
??? return 0;
}
pci_register_driver做了三件事情。
①是把帶過來的參數rtl8139_pci_driver在內核中進行了注冊,內核中有一個PCI設備的大的鏈表,這里負責把這個PCI驅動掛到里面去。
②是查看總線上所有PCI設備(網卡設備屬于PCI設備的一種)的配置空間如果發現標識信息與rtl8139_pci_driver中的id_table相同即rtl8139_pci_tbl,而它的定義如下:
static struct pci_device_id rtl8139_pci_tbl[] __devinitdata = {
{0x10ec, 0x8129, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
{PCI_ANY_ID, 0x8139, 0x10ec, 0x8139, 0, 0,0 },
{0,}
};
,那么就說明這個驅動程序就是用來驅動這個設備的,這里需要注意一下pci_device_id是內核定義的用來辨別不同PCI設備的一個結構,例如在我們這里0x10ec代表的是Realtek公司,我們掃描PCI設備配置空間如果發現有Realtek公司制造的設備時,兩者就對上了,就是調用probe函數了。當然對上了公司號后還得看其他的設備號什么的,都對上了才說明這個驅動是可以為這個設備服務的。
③是把這個rtl8139_pci_driver結構掛在這個設備的數據結構(pci_dev)上,表示這個設備從此就有了自己的驅動了。而驅動也找到了它服務的對象了。
8. pci橋一般不存在私有寄存器,操作系統也不需要為PCE橋提供驅動,這類橋稱為透明橋
PCI學習筆記
http://blog.chinaunix.net/uid-24148050-id-101021.html
Linux下的PCI總線驅動
http://blog.csdn.net/weiqing1981127/article/details/8031541
Linux PCI網卡驅動的詳細分析
http://soft.chinabyte.com/os/13/12304513.shtml
Linux kernel中網絡設備的管理
http://www.linuxidc.com/Linux/2013-08/88472.htm
PCI驅動初始化流程--基于POWERPC85xx架構的Linux內核PCI初始化
http://blog.csdn.net/luwei860123/article/details/38816473
PowerPC的PCI總線的dts配置【轉】 ?
http://blog.163.com/liuqiang_mail@126/blog/static/10996887520126192504668/
總結
- 上一篇: oracle数据库year函数怎么用,数
- 下一篇: 物料移动类型和后勤自动科目设置-转