免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: scutan

网卡驱动注册到PCI总线这一过程的分析 [复制链接]

论坛徽章:
0
发表于 2008-12-16 16:56 |显示全部楼层
原帖由 Godbach 于 2008-12-16 16:44 发表
LZ说明一下内核版本号吧。我这2.6.18.3,dd.c中没有really_probe函数。:wink:


driver_probe_device 函数

  1. int driver_probe_device(struct device_driver * drv, struct device * dev)
  2. {
  3.         struct stupid_thread_structure *data;
  4.         struct task_struct *probe_task;
  5.         int ret = 0;

  6.         if (!device_is_registered(dev))
  7.                 return -ENODEV;
  8.         if (drv->bus->match && !drv->bus->match(dev, drv))
  9.                 goto done;

  10.         pr_debug("%s: Matched Device %s with Driver %s\n",
  11.                  drv->bus->name, dev->bus_id, drv->name);

  12.         data = kmalloc(sizeof(*data), GFP_KERNEL);
  13.         if (!data)
  14.                 return -ENOMEM;
  15.         data->drv = drv;
  16.         data->dev = dev;

  17.         if (drv->multithread_probe) {
  18.                 probe_task = kthread_run(really_probe, data,
  19.                                          "probe-%s", dev->bus_id);
  20.                 if (IS_ERR(probe_task))
  21.                         ret = really_probe(data);
  22.         } else
  23.                 ret = really_probe(data);

  24. done:
  25.         return ret;
  26. }

复制代码

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
发表于 2008-12-16 17:00 |显示全部楼层
2.6.18.3中dd.c.
函数driver_probe_device代码中dev->bus->probe对应的函数为pci_device_probe,随后调用关系为:->__pci_device_probe->pci_call_probe
该函数里面执行了 drv->probe,即e100驱动注册的e100_probe()
driver_probe_device函数的实现:
int driver_probe_device(struct device_driver * drv, struct device * dev)
{
        int ret = 0;

        if (drv->bus->match && !drv->bus->match(dev, drv))
                goto Done;

        pr_debug("%s: Matched Device %s with Driver %s\n",
                 drv->bus->name, dev->bus_id, drv->name);
        dev->driver = drv;
        if (dev->bus->probe) {
                ret = dev->bus->probe(dev);
                if (ret) {
                        dev->driver = NULL;
                        goto ProbeFailed;
                }
        } else if (drv->probe) {
                ret = drv->probe(dev);
                if (ret) {
                        dev->driver = NULL;
                        goto ProbeFailed;
                }
        }
        device_bind_driver(dev);
        ret = 1;
        pr_debug("%s: Bound Device %s to Driver %s\n",
                 drv->bus->name, dev->bus_id, drv->name);
        goto Done;

ProbeFailed:
        if (ret == -ENODEV || ret == -ENXIO) {
                /* Driver matched, but didn't support device
                 * or device not found.
                 * Not an error; keep going.
                 */
                ret = 0;
        } else {
                /* driver matched but the probe failed */
                printk(KERN_WARNING
                       "%s: probe of %s failed with error %d\n",
                       drv->name, dev->bus_id, ret);
        }
Done:
        return ret;
}


pci_call_probe函数的实现
static int pci_call_probe(struct pci_driver *drv, struct pci_dev *dev,
                          const struct pci_device_id *id)
{
        int error;
#ifdef CONFIG_NUMA
        /* Execute driver initialization on node where the
           device's bus is attached to.  This way the driver likely
           allocates its local memory on the right node without
           any need to change it. */
        struct mempolicy *oldpol;
        cpumask_t oldmask = current->cpus_allowed;
        int node = pcibus_to_node(dev->bus);
        if (node >= 0 && node_online(node))
            set_cpus_allowed(current, node_to_cpumask(node));
        /* And set default memory allocation policy */
        oldpol = current->mempolicy;
        current->mempolicy = &default_policy;
        mpol_get(current->mempolicy);
#endif
        error = drv->probe(dev, id);
#ifdef CONFIG_NUMA
        set_cpus_allowed(current, oldmask);
        mpol_free(current->mempolicy);
        current->mempolicy = oldpol;
#endif
        return error;
}

[ 本帖最后由 Godbach 于 2008-12-16 17:04 编辑 ]

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
发表于 2008-12-16 17:07 |显示全部楼层

回复 #21 scutan 的帖子

代码是变化了。应该是2.6.21的代码里面把driver_probe_device()函数的实现进行了封装。

[ 本帖最后由 Godbach 于 2008-12-16 17:09 编辑 ]

论坛徽章:
0
发表于 2008-12-16 19:16 |显示全部楼层
分析的过程很精彩,lz辛苦了。

[ 本帖最后由 qinjiana0786 于 2009-3-6 17:02 编辑 ]

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
发表于 2008-12-16 20:51 |显示全部楼层

回复 #24 qinjiana0786 的帖子

非常欢迎qinjiana0786兄来完成更详细的分析啊。

LZ在这篇文章的开篇也说了,这里整理出来一个流程,提供一个主线,帮着梳理一下。这样可以帮助希望自己熟悉和分析代码,但又不知道如何下手的朋友。

论坛徽章:
0
发表于 2008-12-17 09:19 |显示全部楼层
原帖由 Godbach 于 2008-12-16 14:33 发表
一个小问题:
从内核代码中看到USB设备时使用usb_register注册USB设备,同时使用usb自身的bus_type。那这意味着USB总线是和PCI总线属于两种不同的总线。
但为什么在pci_ids.h中,有这样的定义:


MS在PCI ...


这些是usb host controller,是一个pci device(可通过lspci找到), 和usb host controller 通信的usb devices才是挂在usb bus上的

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
发表于 2008-12-17 09:42 |显示全部楼层
原帖由 eexplorer 于 2008-12-17 09:19 发表


这些是usb host controller,是一个pci device(可通过lspci找到), 和usb host controller 通信的usb devices才是挂在usb bus上的


多谢LS。那应该还有一些USB Device是不同USB host controller通信的,这样的设备是怎么工作的呢?

论坛徽章:
0
发表于 2008-12-17 09:58 |显示全部楼层
感谢高人的讲解,认真琢磨一下

论坛徽章:
0
发表于 2008-12-17 13:40 |显示全部楼层
原帖由 qinjiana0786 于 2008-12-16 19:16 发表
分析的过程是正确的,但是在内核的PCI的过程上要是展开下就很好,不要只是用图片或者函数的调用路线来形容,毕竟内核的部分不是能用只言片语就能一笔带过的,核心部分还是围绕着PCI的过程详细一下就太精彩了,如 ...


小弟在硬件这块目前还没有精力去深入下去,所以希望qinjiana0786兄能够多多指点一下。
谢谢。

BTW: 我从您的TCP/IP核心过程分析中学到了很多东西,表示感谢!

论坛徽章:
0
发表于 2008-12-17 17:33 |显示全部楼层
原帖由 Godbach 于 2008-12-17 09:42 发表


多谢LS。那应该还有一些USB Device是不同USB host controller通信的,这样的设备是怎么工作的呢?


不太明白你的问题,USB device应该只有通过USB host controller才能和CPU交互,
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP