在vxworks系统中,调用pciFindDevice()函数可以直接获取到指定设备的bus、deviceNo以及devfn数据信息。相对于linux系统,vxworks编写驱动相对简单一些。

linux系统下bus、deviceNo以及devfn数据由驱动内部函数使用 (编写驱动过程中这些数据几乎用不到),并且没有提供明确的接口,需要我们自己分析驱动函数调用这些数据的方式。

首先在Terminal输入: lspci -vmmD;

  我们看到设备信息第一行Slot:0000表示设备域,02表示bus信息,05表示deviceNo信息,0表示devfn信息;

了解到要得到数据信息后,开始追踪Pci相关文件,首先跟踪到linux/pci.h头文件找到
    #define PCI_SLOT(devfn) (((devfn) >> 3) & 0x1f)
    #define PCI_FUNC(devfn) ((devfn) & 0x07),

根据定义名称我们知道 PCI_SLOT表示PCI槽,PCI_FUNC表示PCI函数信息(或者称为描述信息),我们得到了deviceNo和devfn的转换方法。下面继续跟踪找到struct pci_dev结构体,结构体内找到了unsigned int devfn; , 到这里可以确定devfn和deviceNo就是用这个变量转换过来的。

现在还需要得到bus号,在pci_dev结构体中没有定义bus变量,说明我们的设备bus号应该不能直接获取到
继续检查pci_dev结构体发现struct pci_bus bus; / bus this device is on /,看到这个注释明白了我们要找的设备bus号在pci_bus结构体内 , 跟踪 pci_bus结构体 找到unsigned char number; / bus number */。

现在我们知道这些数据的获取方式,想要获取到数据需要用到struct pci_dev *dev指针。Pci入口函数static int __init pci_probe(struct pci_dev *dev, const struct pci_device_id *id)第一参数就是我们要用到的指针数据,结合上一篇的Pci驱动实例来描述具体实现方式,下面贴上代码:


#define DevName     "test"
#define ClassName   "class_test"
#define VendorID    0xFA01
#define DeviceID    0x1234unsigned char bus;//增加bus号定义
unsigned int deviceNo;
unsigned int devfn;struct class    *mem_class;
struct Pci_Test
{struct cdev    _cdev;dev_t     dev;char        msi_enabled;
}*pci_test;static int Test_open(struct inode *inode,struct file *filp)
{return 0;
}static int Test_release(struct inode *inode,struct file *filp)
{return 0;
}static struct file_operations test_fops = {
.owner = THIS_MODULE,
//.ioctl = Test_ioctl,
.open = Test_open,
.release = Test_release,
};//字符驱动
static init_chrdev(struct Pci_Test *test_ptr)
{int result = alloc_chrdev_region(&test_ptr->dev, 0, 2, DevName);if (result < 0){printk("Err:failed in alloc_chrdev_region!\n");return result;}mem_class = class_create(THIS_MODULE,ClassName);// /dev/ create devfile if (IS_ERR(mem_class)){printk("Err:failed in creating class!\n");}device_create(mem_class,NULL,test_ptr->dev,NULL,DevName);cdev_init(&test_ptr->_cdev,&test_fops);test_ptr->_cdev.owner = THIS_MODULE;test_ptr->_cdev.ops = &test_fops;//Create Dev and file_operations Connectedresult = cdev_add(&test_ptr->_cdev,test_ptr->dev,1);return result;
}//PCI驱动入口函数   在这个函数中增加bus、device和devfn数据获取方法
static int __init pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
{int rc = 0;pci_test = dev;pci_set_drvdata(dev, pci_test);//在这里创建字符设备驱动rc = init_chrdev(pci_test); if (rc) {dev_err(&dev->dev, "init_chrdev() failed\n");return -1;}rc = pci_enable_device(dev);if (rc) {dev_err(&dev->dev, "pci_enable_device() failed\n");return -1;} rc = pci_request_regions(dev, DevName);if (rc) {dev_err(&dev->dev, "pci_request_regions() failed\n");return -1;}pci_set_master(dev);rc = pci_enable_msi(dev);if (rc) {dev_info(&dev->dev, "pci_enable_msi() failed\n");pci_test->msi_enabled = 0;} else {dev_info(&dev->dev, "pci_enable_msi() successful\n");pci_test->msi_enabled = 1;}//在这里增加获取bus、deviceNo和devfn数据的方法
bus = dev->bus->number;
deviceNo = (((dev->devfn) >> 3 ) && 0x1f);
devfn = ((dev->devfn) && 0x07);return rc;
}static void __exit pci_remove(struct pci_dev *dev)
{if (0 != mem_class){device_destroy(mem_class,pci_test->dev);class_destroy(mem_class);mem_class = 0;}pci_test = pci_get_drvdata(dev);cdev_del(&pci_test->_cdev);unregister_chrdev_region(pci_test->dev, 1);pci_disable_device(dev);if(pci_test) {if(pci_test->msi_enabled) {pci_disable_msi(dev);pci_test->msi_enabled = 0;}}pci_release_regions(dev);
}static struct pci_device_id pci_ids[] = {{ PCI_DEVICE( VendorID, DeviceID) },{ 0 }
};static struct pci_driver driver_ops = {.name = DevName,.id_table = pci_ids,.probe = pci_probe,.remove = pci_remove,
};
//驱动模块入口函数
static int Test_init_module(void)
{int rc = 0;pci_test = kzalloc(sizeof(struct Pci_Test), GFP_KERNEL);//配对设备以及注册PCI驱动,如果找到对应设备调用PCI入口函数rc = pci_register_driver(&driver_ops);if (rc) {printk(KERN_ALERT  ": PCI driver registration failed\n");}return rc;
}static void Test_exit_module(void)
{pci_unregister_driver(&driver_ops);kfree(pci_test);
}
module_init(Test_init_module);
module_exit(Test_exit_module);
MODULE_AUTHOR(DevName);
MODULE_LICENSE("GPL");

上一篇Pci驱动调用字符设备驱动方式:http://blog.csdn.net/a29562268/article/details/78446178!

linuxPci驱动获取指定设备bus、device以及devfn数据方式相关推荐

  1. 如何获取下拉框lable的数据_如何使用Python获取指定股票的日K线数据?

    本篇仅介绍指定股票的数据拉取,批量拉取将在之后的教程中进行介绍,首先你需要安装BaoStock,参见往期教程: 如何使用Python安装BaoStock? 该数据是从2015年开始的,优点是可以用Py ...

  2. Linux设备模型、平台设备驱动、设备树(device tree)、GPIO子系统以及pinctrl子系统介绍

    文章目录 一.Linux设备模型介绍 (1)设备驱动模型总体介绍 (2)设备驱动模型文件表现 (3)设备驱动模型工作原理 [1]总线 [2]设备 [3]驱动 [4]注册流程 二.平台设备驱动介绍 (1 ...

  3. 文章id 文章标题点击量php,zblogphp函数:GetPost 获取指定ID/标题/别名的文章或页面数据...

    zblogphp辅助函数GetPost可以通过ID或别名获得指定文章或页面数据,包括文章的标题.内容.发布日期.浏览量.URL地址.文章评论.所属分类等页面数据. GetPost 函数 通过GetPo ...

  4. linux设备驱动目录,Linux设备模型(5)_device和device driver

    Linux设备模型(5)_device和device driver 作者:wowo 发布于:2014-4-2 19:28 分类:统一设备模型 1. 前言 device和device driver是Li ...

  5. linux设备模型bus,device,driver,(kobject、ktype、kset,bus_type、device、device_driver)

    1.1Linux设备驱动模型简介 1.什么是设备驱动模型 (1)类class.总线bus(负责将设备和驱动挂接起来).设备devices.驱动driver(可以看到在驱动源码中,不管是什么样的驱动,都 ...

  6. 利用ioctl获取本机指定设备的MAC地址

    // 利用ioctl获取本机指定设备的MAC地址 #include<stdio.h> #include<string.h> #include<stdlib.h> # ...

  7. 获取指定进程所占用内存、指定GPU显存信息、所有GPU型号和驱动

    ######################################################### # 获取指定进程所占用内存 ############################ ...

  8. java海康威视设备注册、获取摄像头、录像机在线状态,获取指定摄像头PTZ值

    海康威视摄像头开发第一次做确实有点恶心,我把我用到的写一下,方便以后学习 首先把所有摄像头安装到录像机上我是通过交换机,与服务器同一网络下看是否ping.telnet通 1.官网下载SDK开发包,我是 ...

  9. 【Linux】内核驱动篇九--设备模型

    内核驱动篇九--设备模型 一.起源 二.新方案 2.1 sysfs: 一种用内存模拟的文件系统,系统启动时mount到/sys目录 2.2 uevent 三.代码中自动mknod 一.起源 linux ...

最新文章

  1. CentOS安装Google浏览器
  2. 16位汇编 loop循环
  3. linux shutdown 命令 关机 重启
  4. intellij连接真实spark集群运行wordcount-Java
  5. C Primer+Plus(十七)高级数据表示 编程练习(二)
  6. 存在弱口令漏洞_【安全漏洞通告】secnet安网的AC集中管理平台存在弱口令漏洞...
  7. python调用metasploit自动攻击_Python脚本与Metasploit交互进行自动永恒之蓝攻击-Go语言中文社区...
  8. 三层结构中的数据层设计
  9. 用ASP设计购物推车
  10. Java语言课程设计——简易计算器(详细含报告和源代码)
  11. 高级维修电工实训装置
  12. 达梦数据库启用日志方法,达梦数据库查看日志是否启用,达梦数据库日志文件位置查找
  13. 彼得林奇——如何看待股市大跌
  14. android中文字体加粗,android TextView设置中文字体加粗实现方法
  15. 0day安全:软件漏洞分析技术(第2版)
  16. 1t硬盘怎么分区最好_1t硬盘怎么分区合理
  17. CentOS升级openssl修复部分ssl漏洞
  18. 使用openstack搭建私有云
  19. 虚拟机的介绍(超详细)
  20. 你有 10 年经验,为何还是败给只有 1 年经验的? | 程序员有话说

热门文章

  1. 程序员需要了解依赖冲突的原因以及解决办法
  2. redis分布式锁,面试官请随便问,我都会
  3. 架构专家梁勇:哈啰在分布式消息治理和微服务治理中的实践
  4. JeeWx_2.4.2 版本发布,免费开源微信管家系统
  5. Windows下Git Bash Here怎么整个文件夹目录上传到代码仓库(不论GitHub、GitLab、Gitee、DevCloud)
  6. Redis数据库实现原理(划重点)
  7. 学习react的心路历程(一)
  8. spring-boot两小时入门笔记
  9. springmvc-实现增删改查
  10. BaseAdapter的抽取