linux sdio总线学习

本文主要从以下几个方向来感觉sdio驱动框架
1、sdio总线的加载
2、sdio驱动与设备的匹配逻辑
3、sdio控制器驱动的加载
4、sdio设备驱动的加载

sdio总线的加载

源码位置:
kernel/driver/mmc/core/core.c
在这里插入图片描述

static struct bus_type sdio_bus_type = {
   
   
	.name		= "sdio",
	.dev_groups	
Linux系统中,SDIO总线设备的创建与管理是由SDIO总线驱动负责的,该总线驱动通过 `struct bus_type` 定义了总线的基本属性和操作函数,其中 `probe` 和 `match` 函数用于设备与驱动的匹配和绑定过程[^1]。SDIO总线驱动通过 `sdio_register_driver` 接口向内核注册,当系统检测到匹配的SDIO设备时,会调用驱动的 `probe` 函数进行初始化和绑定。 创建SDIO总线设备的核心函数是 `sdio_register_driver` 和 `sdio_add_func`。前者用于注册一个SDIO驱动,后者用于在检测到SDIO设备时添加该设备到系统中。`sdio_add_func` 是由SDIO核心调用的函数,用于创建并初始化一个SDIO功能设备实例,通常在主机控制器驱动检测到卡插入并完成初始化后调用。 SDIO功能设备的结构体定义如下: ```c struct sdio_func { struct sdio_common common; struct mmc_card *card; unsigned int num; /* function number */ unsigned int enable_timeout; /* max enable timeout in ms */ unsigned int disable_timeout; /* max disable timeout in ms */ struct sdio_func_driver *drv; /* function driver */ void *private_data; /* for driver use */ }; ``` 在SDIO驱动中,通过 `struct sdio_driver` 定义驱动的名称、匹配表以及 `probe` 和 `remove` 函数指针。当系统检测到匹配的设备时,会调用 `probe` 函数进行初始化[^2]。 例如,一个典型的SDIO Wi-Fi驱动实现如下: ```c static const struct sdio_device_id if_sdio_ids[] = { { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_LIBERTAS) }, { /* end: all zeroes */ } }; MODULE_DEVICE_TABLE(sdio, if_sdio_ids); static struct sdio_driver if_sdio_driver = { .name = "if_sdio", .id_table = if_sdio_ids, .probe = if_sdio_probe, .remove = if_sdio_remove, }; ``` 驱动通过 `sdio_register_driver(&if_sdio_driver)` 注册到系统中。当设备插入并被检测到时,系统会调用 `if_sdio_probe` 函数进行初始化和绑定。 在内核中,SDIO核心通过 `mmc` 子系统与SDIO设备通信。`mmc_card` 结构体代表一个MMC/SD卡,而 `sdio_func` 则代表卡上的一个功能。`sdio_add_func` 函数用于创建并注册一个功能设备到系统中。 ```c int sdio_add_func(struct mmc_card *card, unsigned int fun_num) { struct sdio_func *func; ... func = kzalloc(sizeof(struct sdio_func), GFP_KERNEL); ... func->card = card; func->num = fun_num; ... device_initialize(&func->dev); ... error = device_add(&func->dev); ... } ``` 该函数负责分配并初始化 `sdio_func` 结构体,并通过 `device_add` 将设备注册到设备模型中,从而触发驱动的 `probe` 函数执行。 ### 示例:注册SDIO驱动 ```c static int __init if_sdio_init(void) { return sdio_register_driver(&if_sdio_driver); } static void __exit if_sdio_exit(void) { sdio_unregister_driver(&if_sdio_driver); } module_init(if_sdio_init); module_exit(if_sdio_exit); ``` ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bruk_spp

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值