Linux 内核注册一个 USB 驱动
所有 USB 驱动必须创建的主要结构是 struct usb_driver. 这个结构必须被 USB 驱动填 充并且包含多个函数回调和变量, 来向 USB 核心代码描述 USB 驱动:
struct module *owner
指向这个驱动的模块拥有者的指针. USB 核心使用它正确地引用计数这个 USB 驱 动, 以便它不被在不合适的时刻卸载. 这个变量应当设置到 THIS_MODULE 宏.
const char *name
指向驱动名子的指针. 它必须在内核 USB 驱动中是唯一的并且通常被设置为和驱 动的模块名相同. 它出现在 sysfs 中在 /sys/bus/usb/drivers/ 之下, 当驱动在 内核中时.
const struct usb_device_id *id_table
指向 struct usb_device_id 表的指针, 包含这个驱动可接受的所有不同类型 USB 设备的列表. 如果这个变量没被设置, USB 驱动中的探测回调函数不会被调用. 如 果你需要你的驱动给系统中每个 USB 设备一直被调用, 创建一个只设置这个 driver_info 成员的入口项:
static struct usb_device_id usb_ids[] = {
{.driver_info = 42},
{}
};
int (*probe) (struct usb_interface *intf, const struct usb_device_id *id)
指向 USB 驱动中探测函数的指针. 这个函数(在"探测和去连接的细节"一节中描述) 被 USB 核心调用当它认为它有一个这个驱动可处理的 struct usb_interface. 一 个指向 USB 核心用来做决定的 struct usb_device_id 的指针也被传递到这个函 数. 如果这个 USB 驱动主张传递给它的 struct usb_interface, 它应当正确地初 始化设备并且返回 0. 如果驱动不想主张这个设备, 或者发生一个错误, 它应当返 回一个负错误值.
void (*disconnect) (struct usb_interface *intf)
指向 USB 驱动的去连接函数的指针. 这个函数(在"探测和去连接的细节"一节中描 述)被 USB 核心调用, 当 struct usb_interface 已被从系统中清除或者当驱动被 从 USB 核心卸载.
为创建一个值 struct usb_driver 结构, 只有 5 个成员需要被初始化:
static struct usb_driver skel_driver = {
.owner = THIS_MODULE,
.name = "skeleton",
.id_table = skel_table,
.probe = skel_probe,
.disconnect = skel_disconnect,
};
struct usb_driver 确实包含更多几个回调, 它们通常不经常用到, 并且不被要求使 USB 驱动正确工作:
int (*ioctl) (struct usb_interface *intf, unsigned int code, void *buf)
指向 USB 驱动的 ioctl 函数的指针. 如果它出现, 在用户空间程序对一个关联到 USB 设备的 usbfs 文件系统设备入口, 做一个 ioctl 调用时被调用. 实际上, 只 有 USB 集线器驱动使用这个 ioctl, 因为没有其他的真实需要对于任何其他 USB 驱动要使用.
int (*suspend) (struct usb_interface *intf, u32 state)
指向 USB 驱动中的悬挂函数的指针. 当设备要被 USB 核心悬挂时被调用. int (*resume) (struct usb_interface *intf)
指向 USB 驱动中的恢复函数的指针. 当设备正被 USB 核心恢复时被调用.
为注册 struct usb_driver 到 USB 核心, 一个调用 usb_register_driver 带一个指向 struct usb_driver 的指针. 传统上在 USB 驱动的模块初始化代码做这个:
static int init usb_skel_init(void)
{
int result;
/*
register this driver with the USB subsystem */ result =
usb_register(&skel_driver);
if
(result)
err("usb_register failed. Error number
%d", result); return result;
}
当
USB 驱动被卸载, struct usb_driver 需要从内核注销. 使用对 usb_deregister_driver 的调用做这个. 当这个调用发生,
任何当前绑定到这个驱动的 USB 接口被去连接, 并且去连接函数为它们而被调用.
static void
exit usb_skel_exit(void)
{
/* deregister this driver with the USB subsystem */
usb_deregister(&skel_driver);
}
Linux 内核注册一个 USB 驱动的更多相关文章
- linux内核分析作业6:分析Linux内核创建一个新进程的过程
task_struct结构: struct task_struct { volatile long state;进程状态 void *stack; 堆栈 pid_t pid; 进程标识符 u ...
- 第六周分析Linux内核创建一个新进程的过程
潘恒 原创作品转载请注明出处<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 task_struct结构: ...
- 实验 六:分析linux内核创建一个新进程的过程
实验六:分析Linux内核创建一个新进程的过程 作者:王朝宪 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029 ...
- 20135202闫佳歆--week6 分析Linux内核创建一个新进程的过程——实验及总结
week 6 实验:分析Linux内核创建一个新进程的过程 1.使用gdb跟踪创建新进程的过程 准备工作: rm menu -rf git clone https://github.com/mengn ...
- 《Linux内核--分析Linux内核创建一个新进程的过程 》 20135311傅冬菁
20135311傅冬菁 分析Linux内核创建一个新进程的过程 一.学习内容 进程控制块——PCB task_struct数据结构 PCB task_struct中包含: 进程状态.进程打开的文件. ...
- 作业六:分析Linux内核创建一个新进程的过程
分析Linux内核创建一个新进程的过程 进程描述符PCB----task_struct数据结构 操作系统:1.进程管理 2.内存管理 3 文件系统 一.新进程如何创建和修改task_struct数据结 ...
- Linux内核分析-分析Linux内核创建一个新进程的过程
作者:江军 ID:fuchen1994 实验题目:分析Linux内核创建一个新进程的过程 阅读理解task_struct数据结构http://codelab.shiyanlou.com/xref/li ...
- 给Linux内核增加一个系统调用的方法(转)
作者:chenjieb520 给Linux内核增加一个系统调用的方法 为了更加好地调试linux内核,笔者的实验均在mini6410的arm板上运行的.这样做的原因,第一是因为本人是学嵌入式的, ...
- Linux内核分析第六周学习笔记——分析Linux内核创建一个新进程的过程
Linux内核分析第六周学习笔记--分析Linux内核创建一个新进程的过程 zl + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/U ...
随机推荐
- oracle如何利用hostname方式连接数据库
host name方式只支持tcp/ip协议的小局域网 修改listener.ora中的如下信息 (SID_DESC = (GLOBAL_DBNAME = ur_hostname) --你的机器名 ( ...
- vue @click.native
1,给vue组件绑定事件时候,必须加上native ,不然不会生效(监听根元素的原生事件,使用 .native 修饰符) 2,等同于在自组件中: 子组件内部处理click事件然后向外发送click事件 ...
- chrome://inspect调试html页面空白,DOM无法加载的解决方案
chrome://inspect调试html页面空白,DOM无法加载的解决方案 先描述一下问题 有一段时间没碰huilder hybird app 开发了,今天调试的时候 chrome://inspe ...
- Python学习之路4☞条件和循环
一.if语句 1.1 功能 计算机又被称作电脑,意指计算机可以像人脑一样,根据周围环境条件(即expession)的变化做出不同的反应(即执行代码) if语句就是来控制计算机实现这一功能 1.2 语法 ...
- hdu1525 博弈
/* n%m==0 n状态 n>=2*m 先手决定谁来面对当前的状态,并且可以知道状态,所以先手必胜. */ #include<stdio.h> int min(int x,int ...
- Nuxt.js打造旅游网站第1篇_项目环境搭建
1. 安装 使用官网提供的脚手架工具 create-nuxt-app,创建一个nuxtjs项目. npx create-nuxt-app xianyun 注意:在NPM版本5.2.0默认安装了npx, ...
- 【NS2】TCL debug (转载)
1.使用NS2进行模拟,就不可避免的会接触TCL/OTCL和C/C++.两者配合使用.一般设置场景啊,业务流啊,都使用TCL/OTCL来编写脚 本.要进行路由实验模拟的话,同一类的实验,这些脚本基本上 ...
- JavaScript void
我们经常会使用到 javascript:void(0) 这样的代码,那么在 JavaScript 中 javascript:void(0) 代表的是什么意思呢? javascript:void(0) ...
- 3DSMAX安装失败怎样卸载重新安装3DSMAX,解决3DSMAX安装失败的方法总结
技术帖:3DSMAX没有按照正确方式卸载,导致3DSMAX安装失败.楼主也查过网上关于如何解决3DSMAX安装失败的一些文章,是说删除几个3DSMAX文件和3DSMAX软件注册表就可以解决3DSMAX ...
- Jquery常用方法汇总(转)
https://blog.csdn.net/lucky___star/article/details/87883888