functions.c文件说明
程序员文章站
2024-03-01 16:30:46
...
说明
drivers/usb/gadget/functions.c
这个文件里面就7个函数,所以单独给拿出来说一下。从名字可以看出,这文件是个中间层的作用,连接configfs和实际的function驱动。还是挺有意思的,大家一起来看看。
usb_function_register/unregister
将usb_function_driver结构体加入到func_list全局链表当中,就是将list变量加入进去。除了这个啥也没有干,下面就是这个结构体的说明。
struct usb_function_driver {
const char *name;
struct module *mod;
struct list_head list;
struct usb_function_instance *(*alloc_inst)(void);
struct usb_function *(*alloc_func)(struct usb_function_instance *inst);
};
usb_get/put_function_instance
struct usb_function_instance *usb_get_function_instance(const char *name)
{
struct usb_function_instance *fi;
int ret;
fi = try_get_usb_function_instance(name);
if (!IS_ERR(fi))
return fi;
ret = PTR_ERR(fi);
if (ret != -ENOENT)
return fi;
ret = request_module("usbfunc:%s", name);
if (ret < 0)
return ERR_PTR(ret);
return try_get_usb_function_instance(name);
}
这里分为两个部分,首先直接获取function_instance,如果失败了,可能对应的驱动没有加载进去,那么去搜索一下对应的module,然后继续再来一次。如果真的没有,那就还是不行了。以上代码就是这个逻辑,我们接着走成功的那条路 try_get_usb_function_instance。
list_for_each_entry(fd, &func_list, list),通过这个函数从func_list中搜索对应的usb_function_driver。找到后,调用对应的alloc_inst()。函数还做了一些特殊操作,如果失败,还会去卸载module。
struct usb_function_driver *fd;
struct usb_function_instance *fi;
fi = fd->alloc_inst();
if (IS_ERR(fi))
module_put(fd->mod);
else
fi->fd = fd;
接着看一下put函数
void usb_put_function_instance(struct usb_function_instance *fi)
{
struct module *mod;
if (!fi)
return;
mod = fi->fd->mod;
fi->free_func_inst(fi);
module_put(mod);
}
这个函数调用的是usb_function_instance中的free_func_inst方式,如下所示给出一个结构体
struct usb_function_instance {
struct config_group group;
struct list_head cfs_list;
struct usb_function_driver *fd;
int (*set_inst_name)(struct usb_function_instance *inst, const char *name);
void (*free_func_inst)(struct usb_function_instance *inst);
};
usb_get/put_function
struct usb_function *usb_get_function(struct usb_function_instance *fi)
{
struct usb_function *f;
f = fi->fd->alloc_func(fi);
if (IS_ERR(f))
return f;
f->fi = fi;
return f;
}
void usb_put_function(struct usb_function *f)
{
if (!f)
return;
f->free_func(f);
}
以上,函数逻辑比较清楚。
总结
从上面来看,functions.c中的函数就是用来作为usb_function_driver和configfs链接用的。大部分函数的调用口,都是从configfs.c上面下来的。这个文件和functions.c在同一个目录中,都是为了gadget服务。