PCI在linux系统中注册与注销示例
1. pci_driver结构
struct pci_driver {
struct list_head node;
const char *name;
const struct pci_device_id *id_table; /* must be non-NULL for probe to be called */
int (*probe) (struct pci_dev *dev, const struct pci_device_id *id); /* New device inserted */
void (*remove) (struct pci_dev *dev); /* Device removed (NULL if not a hot-plug capable driver) */
int (*suspend) (struct pci_dev *dev, pm_message_t state); /* Device suspended */
int (*suspend_late) (struct pci_dev *dev, pm_message_t state);
int (*resume_early) (struct pci_dev *dev);
int (*resume) (struct pci_dev *dev); /* Device woken up */
void (*shutdown) (struct pci_dev *dev);
int (*sriov_configure) (struct pci_dev *dev, int num_vfs); /* PF pdev */
const struct pci_error_handlers *err_handler;
struct device_driver driver;
struct pci_dynids dynids;
};
1. name 名称,如下:
# ls /sys/bus/pci/drivers/
JMicron IDE Promise_IDE ata_piix e100 e1000e igb ixgbe
2. id_table
是一个指向pci设备的id编号的指针,用于描述当前PCI设备的编号,一般用做probe的输入参数。如下表:
/* ixgbe_pci_tbl - PCI Device ID Table
*
* Wildcard entries (PCI_ANY_ID) should come last
* Last entry must be all 0s
*
* { Vendor ID, Device ID, SubVendor ID, SubDevice ID,
* Class, Class Mask, private data (not used) }
*/
static DEFINE_PCI_DEVICE_TABLE(ixgbe_pci_tbl) = {
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598), board_82598 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598AF_DUAL_PORT), board_82598 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598AF_SINGLE_PORT), board_82598 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598AT), board_82598 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598AT2), board_82598 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598EB_CX4), board_82598 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598_CX4_DUAL_PORT), board_82598 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598_DA_DUAL_PORT), board_82598 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM), board_82598 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598EB_XF_LR), board_82598 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598EB_SFP_LOM), board_82598 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598_BX), board_82598 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_KX4), board_82599 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_XAUI_LOM), board_82599 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_KR), board_82599 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_SFP), board_82599 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_SFP_EM), board_82599 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_KX4_MEZZ), board_82599 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_CX4), board_82599 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_BACKPLANE_FCOE), board_82599 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_SFP_FCOE), board_82599 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_T3_LOM), board_82599 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_COMBO_BACKPLANE), board_82599 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X540T), board_X540 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_SFP_SF2), board_82599 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_LS), board_82599 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599EN_SFP), board_82599 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_SFP_SF_QP), board_82599 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X540T1), board_X540 },
/* required last entry */
{0, }
};
MODULE_DEVICE_TABLE(pci, ixgbe_pci_tbl);
pci_device_id 结构如下:
struct pci_device_id {
__u32 vendor, device; /* Vendor and device ID or PCI_ANY_ID*/
__u32 subvendor, subdevice; /* Subsystem ID's or PCI_ANY_ID */
__u32 class, class_mask; /* (class,subclass,prog-if) triplet */
kernel_ulong_t driver_data; /* Data private to the driver */
};
3. probe
int (*probe) (struct pci_dev *dev, const struct pci_device_id *id)
指向PCI驱动中的probe函数指针,这个函数被PCI核心调用,当它有一个它认为这个驱动想控制的 struct pci_dev时,
一个指向pci_device_id的指针,PCI核心用来做这个决定,也被告传递给这个函数,如果这个PCI驱动需要这个传递给它的struct pci_dev,
它应当正初始化这个设备,并返回0, 如果这个驱动不想拥有这个设备,或者产生一个错误,它应当返回一个负的错误值。
4. remove
void (*remove) (struct pci_dev *dev)
指向PCI核心在struct pci_dev被告从系统中去除时调用的函数指针,或者当PCI驱动被从内核中卸载时。
5. suspend
int (*suspend) (struct pci_dev *dev, pm_message_t state)
当struct pci_dev被挂起时PCI核心调用的函数指针,挂起状态在state 变量时传递,这个函数是可选的
6. resume
int (*resume) (struct pci_def *dev)
当pci_dev被告恢复时PCI核心调用的函数指针,它的调用一定是在suspend函数执行之后,这个函数可选。
7. shutdown
void (*shutdown) (struct pci_dev *dev)
当此设备需要关闭时,此函数指针所指向的函数将会被调用。
8. ixgbe注册
static struct pci_driver ixgbe_driver = {
.name = ixgbe_driver_name,
.id_table = ixgbe_pci_tbl,
.probe = ixgbe_probe,
.remove = __devexit_p(ixgbe_remove),
#ifdef CONFIG_PM
.suspend = ixgbe_suspend,
.resume = ixgbe_resume,
#endif
#ifndef USE_REBOOT_NOTIFIER
.shutdown = ixgbe_shutdown,
#endif
#ifdef HAVE_PCI_ERS
.err_handler = &ixgbe_err_handler
#endif
};
static int __init ixgbe_init_module(void)
{
int ret;
...
ret = pci_register_driver(&ixgbe_driver);
return ret;
}
module_init(ixgbe_init_module);
9. ixgbe注销
static void __exit ixgbe_exit_module(void)
{
pci_unregister_driver(&ixgbe_driver);
...
}
module_exit(ixgbe_exit_module);
http://blog.chinaunix.net/uid-7187477-id-3220913.html
PCI在linux系统中注册与注销示例的更多相关文章
- Linux系统中的硬件问题如何排查?(3)
Linux系统中的硬件问题如何排查?(3) 2013-03-27 10:32 核子可乐译 51CTO.com 字号:T | T 在Linux系统中,对于硬件故障问题的排查可能是计算机管理领域最棘手的工 ...
- 在 Linux 系统中安装Load Generator ,并在windows 调用方法
在 Linux 系统中安装Load Generator ,并在windows 调用 由于公司需要测试系统的最大用户承受能力,所以需要学习使用loadrunner.在安装的时候碰到了不少问题,所以写下此 ...
- 为什么在 Linux 系统中,不建议超频
CPU 是一部计算机内的心脏啦!因为不论你做什么事情都需要 CPU 来加以运作的!(虽然有时工作量大.有时工作量小!),在 586 以前的计算机( 包含 386, 486, 与 586 ) ,CPU ...
- Linux系统中Oracle11g数据库的安装与验证
1.查看Linux系统的位数 2.下载Oracle10g数据库软件 https://blog.csdn.net/xiezuoyong/article/details/81197688 (需要注册Ora ...
- 在 Linux 系统中安装Load Generator ,并在windows 调用
原文地址:http://www.blogjava.net/qileilove/archive/2012/03/14/371861.html 由于公司需要测试系统的最大用户承受能力,所以需要学习使用lo ...
- 详解在Linux系统中安装JDK
本文以在CentOS 7.6中安装JDK8为例进行安装,其他系统和版本都是大同小异的. 下载 进入Oracle官方网站的下载页面. 首先,接受许可协议,如下图: 然后,根据Linux系统的位数选择要下 ...
- Linux系统中的硬件问题如何排查?(4)
Linux系统中的硬件问题如何排查?(4) 2013-03-27 10:32 核子可乐译 51CTO.com 字号:T | T 在Linux系统中,对于硬件故障问题的排查可能是计算机管理领域最棘手的工 ...
- Linux 系统中如何查看日志 (常用命令) tail -f
Linux 系统中如何查看日志 (常用命令) tail -f 日志文件 日 志 文 件 说 明 /var/log/message 系统启动后的信息和错误日志,是Red Hat Linux中最常用的日 ...
- Linux系统中安装软件方法总结
Linux系统中安装软件方法总结 [1]Linux系统中安装软件的几种方式 [2] Linux配置yum源(本地源和网络源) [3] SuSE下zypper源配置 [4] SUSE zypper 本地 ...
随机推荐
- TestNG 三 测试方法
一.设置参数 测试方法是可以带有参数的.每个测试方法都可以带有任意数量的参数,并且可以通过使用TestNG的@Parameters向方法传递正确的参数. 设置方式有两种方法:使用testng.xml或 ...
- 使用CTE解决复杂查询的问题
最近,同事需要从数个表中查询用户的业务和报告数据,写了一个SQL语句,查询比较慢: Select S.Name, S.AccountantCode, ( Select COUNT(*) from ( ...
- springmvc 多数据源 SSM java redis
A集成代码生成器 [正反双向(单表.主表.明细表.树形表,开发利器)+快速构建表单; freemaker模版技术 ,0个代码不用写,生成完整的一个模块,带页面.建表sql脚本,处理类,servic ...
- Mega Dropdown - 带子分类的响应式下拉菜单
当你在开发一个内容很多的 Web 项目的时候,最具挑战性的部分之一是为了如果更方便用户浏览这些内容.我们都能想到的一个例子是 Amazon,无限的类别以及它们的子类别.Mega Dropdown 是带 ...
- CSS3简单动画
css3的动画确实非常绚丽!浏览器兼容性很重要!. 分享两个小动画 <!doctype html> <html lang="en"> <head> ...
- 闭包和this
一.闭包 最开始理解闭包是在一个函数内部定义一个函数,可以在外面的环境里进行调用.现在对于闭包的理解是利用函数来保存作用域内的对象. 理解闭包首先要理解执行上下文,变量对象,活动对象,作用域链.因为执 ...
- [原创]html5游戏_贪吃蛇
代码随便写写,尚有许多不足,PC与手机端皆可运行 手机端滑屏操作,PC端方向键操作 疑问: 生成食物,与判断是否可以移动方面 有两种实现方式, 1.使用js内存,数组循环判断 2.使用dom的quer ...
- 浅析css布局模型1
css是网页的外衣,好不好看全凭css样式,而布局是css中比较重要的部分,下面来分析一下常见的几种布局. 流动模型 流动模型是网页布局的默认模式,也是最常见的布局模式,他有两个特点: 1.块状元素都 ...
- Atitit.提升电子商务安全性 在线充值功能安全方面的设计
Atitit.提升电子商务安全性 在线充值功能安全方面的设计 1. 防止dataservcie对充值订单表的直接改写,只能通过api,不能通过sql1 1.1. Order_id的安全取值,注入检测1 ...
- Visual Studio将Delop之后生成的dll或者wsp复制到指定目录
用VS开发sharepoint项目的时候,有很多个project,每个project都会生成一个wsp包,如果手工把wsp文件找到,复制出来,拷贝到服务器上,再部署,就有点麻烦. 所以写了个批处理命令 ...