·LINUX设备驱动之serio总线(二)
来源:互联网 发布:端口号的目的是什么 编辑:程序博客网 时间:2024/06/11 21:01
三.serio驱动的注册
serio驱动注册的函数为serio_register_driver():
static inline int __must_check serio_register_driver(struct serio_driver *drv)
{
return __serio_register_driver(drv, THIS_MODULE, KBUILD_MODNAME);
}
转如__serio_register_driver():
int __serio_register_driver(struct serio_driver *drv, struct module *owner, const char *mod_name)
{
bool manual_bind = drv->manual_bind;
int error;
drv->driver.bus = &serio_bus;
drv->driver.owner = owner;
drv->driver.mod_name = mod_name;
/*
* Temporarily disable automatic binding because probing
* takes long time and we are better off doing it in kseriod
*/
drv->manual_bind = true;
error = driver_register(&drv->driver);
if (error) {
printk(KERN_ERR
"serio: driver_register() failed for %s, error: %d\n",
drv->driver.name, error);
return error;
}
/*
* Restore original bind mode and let kseriod bind the
* driver to free ports
*/
if (!manual_bind) {
drv->manual_bind = false;
error = serio_queue_event(drv, NULL, SERIO_ATTACH_DRIVER);
if (error) {
driver_unregister(&drv->driver);
return error;
}
}
return 0;
}
有了上面的分析,这个函数就很好理解了,它根据输入参数和一些默认值进行部分字段的初始化,然后调用driver_register()注册内嵌的driver,如果manual_bind为0则产生一个SERIO_ATTACH_DRIVER类型事件,内核线程将会进行一次设备驱动匹配。按照linux的思想,应该是设置manual_bind为1,等到需要的时候再进行设备驱动绑定,这样做的好处是可以节省系统资源。
在设备驱动的匹配过程中会调用总线上的match和probe接口函数,这两个函数为serio_bus_match()和serio_driver_probe(),分别进行分析:
static int serio_bus_match(struct device *dev, struct device_driver *drv)
{
struct serio *serio = to_serio_port(dev);
struct serio_driver *serio_drv = to_serio_driver(drv);
if (serio->manual_bind || serio_drv->manual_bind)
return 0;
return serio_match_port(serio_drv->id_table, serio);
}
如果对应的设备和驱动有一个指定为手动绑定,则直接退出,否则调用serio_match_port(serio_drv->id_table, serio)进行匹配:
static int serio_match_port(const struct serio_device_id *ids, struct serio *serio)
{
while (ids->type || ids->proto) {
if ((ids->type == SERIO_ANY || ids->type == serio->id.type) &&
(ids->proto == SERIO_ANY || ids->proto == serio->id.proto) &&
(ids->extra == SERIO_ANY || ids->extra == serio->id.extra) &&
(ids->id == SERIO_ANY || ids->id == serio->id.id))
return 1;
ids++;
}
return 0;
}
由此看出如果驱动的id_table中包含了设备的id字段中的信息,则会匹配成功。
接着看serio_driver_probe()函数:
static int serio_driver_probe(struct device *dev)
{
struct serio *serio = to_serio_port(dev);
struct serio_driver *drv = to_serio_driver(dev->driver);
return serio_connect_driver(serio, drv);
}
static int serio_connect_driver(struct serio *serio, struct serio_driver *drv)
{
int retval;
mutex_lock(&serio->drv_mutex);
retval = drv->connect(serio, drv);
mutex_unlock(&serio->drv_mutex);
return retval;
}
最终会调用驱动的connect()函数,这个函数在具体的驱动程序实现,以后我们会分析到。
四.serio驱动的中断处理
Serio设备的中断都会流入serio_interrupt()中:
irqreturn_t serio_interrupt(struct serio *serio,
unsigned char data, unsigned int dfl)
{
unsigned long flags;
irqreturn_t ret = IRQ_NONE;
spin_lock_irqsave(&serio->lock, flags);
if (likely(serio->drv)) {
ret = serio->drv->interrupt(serio, data, dfl);
} else if (!dfl && serio->registered) {
serio_rescan(serio);
ret = IRQ_HANDLED;
}
spin_unlock_irqrestore(&serio->lock, flags);
return ret;
}
先判断serio->drv是否存在,这里的likely()为了进行代码的优化,提高系统执行速度。如果serio->drv存在,则调用它;如果不存在则会进一步判断dfl参数和serio->registered标志,并调用serio_rescan(serio)函数,这个函数如下:
void serio_rescan(struct serio *serio)
{
serio_queue_event(serio, NULL, SERIO_RESCAN_PORT);
}
产生一个SERIO_RESCAN_PORT类型事件,断开设备驱动的关联(实际上这里还没关联),再重新匹配驱动。
到此,serio总线基本分析完了,后面将分析serio设备的一些实际例子。
- LINUX设备驱动之serio总线(二)
- ·LINUX设备驱动之serio总线(二)
- LINUX设备驱动之serio总线(一)
- LINUX设备驱动之serio总线(一)
- Linux设备驱动之——serio总线
- Linux设备驱动之——serio总线
- Linux设备驱动之——serio总线
- serio总线------向serio总线注册设备
- 深入浅出linux之总线之上的总线(serio总线)
- linux设备驱动之总线、设备、驱动
- linux设备驱动之总线,设备,驱动
- linux设备驱动之总线、设备、驱动
- linux设备驱动之总线、设备、驱动
- 设备模型之二 总线设备驱动
- linux 驱动机制之设备,驱动,总线
- 代码详解Linux总线serio
- linux设备总线驱动模型 之 platform总线驱动
- linux设备总线驱动模型 之 platform总线驱动
- 使用std:min(),std:max()
- 第六周上机任务2
- Android开发必备的21个免费资源和工具
- LINUX设备驱动之输入子系统(一)
- POJ-3630(静态trie树,动态分配空间会TLE)(Phone List)
- ·LINUX设备驱动之serio总线(二)
- Android学习笔记Android必备开发工具之一命令行创建Git库(Dean)
- LINUX设备驱动之serio总线(一)
- 关于java.net.URLConnection
- 中国BIM意识和实践在世界BIM大潮中没有落伍,令人欣慰
- IM设计思考:点对点消息交换
- LINUX设备驱动之platform总线
- CStringList不完全用法
- LINUX设备驱动之设备模型五--device&driver&bus(三)