您的位置:首页 > 运维架构 > Linux

linux4.3.2 块设备驱动简析-2

2016-02-07 21:54 447 查看
       上次我们了解到,mmc card设备驱动通过mmc_bus_type这条总线找到了block驱动,由block驱动去加载该设备。今天我们再进一步去了解这整个过程。
       我们都知道,mmc card的驱动需要启动中断并配合定时器去检测是否有卡插入,那这个功能是在哪里实现的呢?
       在函数mmc_alloc_host中有这一个调用INIT_DELAYED_WORK(&host->detect, mmc_rescan),它将函数工作队列执行函数mmc_rescan放置到一个延时工作队列中,等待启动。
       在平台设备驱动sdhci_arasan_probe中:sdhci_add_host(host)->sdhci_enable_card_detection(host)->sdhci_unmask_irqs(host, irqs)去启动中断检测功能,接着我们看看中断检测功能里面有些什么。在中断函数sdhci_irq里面如果发现有card插入就会调用tasklet_schedule(&host->card_tasklet),执行注册在该card_tasklet上的函数实体——sdhci_tasklet_card,该函数里面调用了2个函数,从命名上看,我们应该更加关心后面一个函数mmc_detect_change,传入的参数是将200ms转化为系统能够是别的jiffies,一层一层最后调用函数mmc_schedule_delayed_work(&host->detect, delay),延时200ms启动mmc_rescan函数。
       我们回到函数mmc_rescan,该函数里面调用了mmc_rescan_try_freq(host, max(freqs[i], host->f_min))去进一步扫描card,调用mmc_attach_sdio(host)去扫描是否是sdio接口的卡,如果是则主要调用函数mmc_sdio_init_card(host, rocr, NULL, 0)去初始化该卡,里面最为重要的函数调用时mmc_alloc_card(host, NULL),因为在该函数中,对card
device进行初始化和参数配置的,可以看到最重要一句——card->dev.bus = &mmc_bus_type,此处就真正的将device和driver通过总线关联起来了。
       我们把整个流程串起来看,简单来说就是:
       加载platform设备 -> 启动平台驱动 -> 生成 host驱动,包含一个中断检测功能 ----> 在/dev目录下生成mmc0、mmc1等设备文件

       此时中断触发->构造一个card设备驱动,并注册到mmc总线上线->->关联到总线上的block驱动->在/dev目录下生成mmcblk0、mmcblk1等文件---->至此生成了块设备文件。
       接下来看看如何才和mmc总线上的block驱动关联起来,主要流程如下:
       1. 通过总线函数bus_mach对device和driver做匹配,返回非0表示匹配成功,好像mmc的mach函数直接返回1
       2. 把该drv赋值给dev,通过调用bus的probe函数对该dev进行探测

       3. 通过drv的probe函数对该dev进行探测

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息