USB驱动分析1_第1页
USB驱动分析1_第2页
USB驱动分析1_第3页
USB驱动分析1_第4页
USB驱动分析1_第5页
已阅读5页,还剩8页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1 USB 驱动分析 一 这个故事中使用的是 2 6 10 的内核代码 Linux 内核代码目录中 所有去设备驱动程序 有关的代码都在 drivers 目录下面 在这个目录中我们用 ls 命令可以看到很多子目录 localhost usr src linux 2 6 10 drivers ls Kconfig atm cdrom eisa ide macintosh message net parport s390 tc w1 Makefile base char fc4 ieee1394 mca misc nubus pci sbus telephony zorro acorn block cpufreq firmware input md mmc oprofile pcmcia scsi usb acpi bluetooth dio i2c isdn media mtd parisc pnp serial video 其中 usb 目录包含了所有 usb 设备的驱动 而 usb 目录下面又有它自己的子目录 进去看 一下 localhost usr src linux 2 6 10 drivers cd usb locahost usr src linux 2 6 10 drivers usb ls Kconfig Makefile README atm class core gadget host image input me dia misc net serial storage usb skeleton c 注意到每一个目录下面都有一个 Kconfig 文件和一个 Makefile 这很重要 稍后会有介绍 而我们的故事其实是围绕着 drivers usb storage 这个目录来展开的 实际上这里边的代 码清清楚楚地展示了我们日常频繁接触的 U 盘是如何工作的 是如何被驱动起来的 但是 这个目录里边的冬冬并不是生活在世外桃源 他们总是和外面的世界有着千丝万缕的瓜葛 可以继续进来看一下 localhost usr src linux 2 6 10 drivers usb cd storage localhost usr src linux 2 6 10 drivers usb storage ls Kconfig debug c freecom c isd200 c protocol c sddr09 c shuttle usbat c unusual devs h Makefile debug h freecom h isd200 h protocol h sddr09 h shuttle usbat h usb c datafab c dpcm c initializers c jumpshot c scsiglue c sddr55 c transport c usb h datafab h dpcm h initializers h jumpshot h scsiglue h sddr55 h transport h 咋一看 着实吓了一跳 用 wc l 这个命令统计一下 12076 行 晕死 wc c m l w 文件 或者 wc k c l w 文件 注 缺省情况下 wc 命令对 File 参数指定的文件中的行数 字数和字节数进行计数 这个命令将换行符数 字数和字节数写到标准输出并为所有指定的文件保留一个总数 当使用 File 参数时 wc 命令显示文件名以及请求的计数 如果没有给 File 参数指定 一个文件名 wc 命令使用标准输入 wc 命令受 LANG LC ALL LC CTYPE 和 LC MESSAGES 环境变量影响 wc 命令将一个字看作是被一个空格 如空白和跳格 分隔的非零长度字符串 c 统计字节数 除非指定 k 标志 如果指定 k 标志 wc 命令统计字符数 2 k 统计字符数 指定 k 标志等同于指定 klwc 标志 如果将 k 标志同其他标志一 起使用 那么必须包含 c 标志 否则 将会忽略 k 标志 注 这个标志在将来的发行版中将会撤销 l 统计行数 m 统计字符数 这个标志不能与 c 标志一起使用 w 统计字数 一个字被定义为由空白 跳格或换行字符分隔的字符串 但是 也许 生活中总是充满了跌宕起伏 认真看了一下 Makefile 和 Kconfig 之后 心情明显好了许多 出来混 迟早要还的 从前在复旦 混了四年 没有学到任何东西 每天就是逃课 上网 玩游戏 睡觉 毕业的时候 身边的人读研的读研 出国的出国 找工作的吧 去麦肯锡的去麦肯锡 去 IBM 的去 IBM 而 自己却一无所长 没有任何技能 直到这时候才发现那四年欠了很多债 早知今日 何必当初 幸运的是 我还有一张复旦的文凭 依靠着这张文凭 混进了 Intel 然而 工作以后 更是发现 当初在校期间没有好好读书其实真是在欠债 当初没学 工作以后还是要学 的确是迟早要 还的 逃是逃不掉的 毕业的时候 人家跟我说 Makefile 我完全不知 但是一说 Make Love 我就来劲了 现在想 来依然觉得丢人 基本上 Linux 内核中每一个目录下边都有一个 Makefile Makefile 和 Kconfig 就像一个 城市的地图 地图带领我们去认识一个城市 而 Makefile 和 Kconfig 则可以让我们了解这 个目录下面的结构 drivers usb storage 目录下边的 Makefile 内容如下 Makefile for the USB Mass Storage device drivers 15 Aug 2000 Christoph Hellwig Rewritten to use lists instead of if statements EXTRA CFLAGS Idrivers scsi obj CONFIG USB STORAGE usb storage o usb storage obj CONFIG USB STORAGE DEBUG debug o usb storage obj CONFIG USB STORAGE HP8200e shuttle usbat o usb storage obj CONFIG USB STORAGE SDDR09 sddr09 o usb storage obj CONFIG USB STORAGE SDDR55 sddr55 o usb storage obj CONFIG USB STORAGE FREECOM freecom o usb storage obj CONFIG USB STORAGE DPCM dpcm o usb storage obj CONFIG USB STORAGE ISD200 isd200 o usb storage obj CONFIG USB STORAGE DATAFAB datafab o usb storage obj CONFIG USB STORAGE JUMPSHOT jumpshot o usb storage objs scsiglue o protocol o transport o usb o initializers o usb storage obj y 关于 Kconfig 文件 在故事的最后会介绍 此刻暂且不表 Kconfig 文件比较长 就不贴出来 了 但是通过看 Kconfig 文件 我们可以知道 除了 CONFIG USB STORAGE 这个编译 选项是我们真正需要的以外 别的选项我们都可以不予理睬 比如 关于 CONFIG USB STORAGE DATAFAB Kconfig 文件中有这么一段 3 config USB STORAGE DATAFAB bool Datafab Compact Flash Reader support EXPERIMENTAL depends on USB STORAGE 4 MODULE AUTHOR fudan abc 5 6 static int init hello init void 7 8 printk KERN ALERT Hello world n 9 return 0 10 11 12 static void exit hello exit void 13 14 printk KERN ALERT Goodbye cruel world n 15 16 17 module init hello init 18 module exit hello exit 你需要使用 module init 和 module exit 你可以称她们为函数 不过实际上她们 是一些宏 macro 现在你可以不用去知道她们背后的故事 只需要知道 在 Linux Kernel 2 6 的世界里 你写的任何一个模块都需要使用她们来初始化或退出 或者说注册以及后来 的注销 当你用 module init 为一个模块注册了之后 在你使用 insmod 这个命令去安 装的时候 module init 注册的函数将会被执行 而当你用 rmmod 这个命令去卸载一个 模块的时候 module exit 注册的函数将会被执行 module init 被称为驱动程序的初 始化入口 driver initialization entry point 怎么样演示以上代码的运行呢 没错 你需要一个 Makefile Makefile 1 To build modules outside of the kernel tree we run make 2 in the kernel source tree the Makefile these then includes this 3 Makefile once again 5 4 This conditional selects whether we are being included from the 5 kernel Makefile or not 6 ifeq KERNELRELEASE 7 8 Assume the source tree is where the running kernel was built 9 You should set KERNELDIR in the environment if it s elsewhere 10 KERNELDIR lib modules shell uname r build 11 The current directory is passed to sub makes as argument 12 PWD shell pwd 13 14 modules 15 MAKE C KERNELDIR M PWD modules 16 17 modules install 18 MAKE C KERNELDIR M PWD modules install 19 20 clean 21 rm rf o core depend cmd ko mod c tmp versions 22 23 PHONY modules modules install clean 24 25 else 26 called from kernel build system just declare what our modules are 27 obj m hello o 28 endif 在 lwn 上可以找到这个例子 你可以把以上两个文件放在你的某个目录下 然后执行 make 也许你不一定能成功 因为 LK 2 6 要求你编译模块之前 必须先在内核源代码目录 下执行 make 换言之 你必须先配置过内核 执行过 make 然后才能 make 你自己的模块 原 因我就不细说了 你按着她要求的这么去做就行了 在内核顶层目录 make 过之后 你就可 以在你当前放置 Makefile 的目录下执行 make 了 Ok make 之后你就应该看到一个叫 做 hello ko 的文件生成了 恭喜你 这就是你将要测试的模块 执行命令 insmod hello ko 同时在另一个窗口 用命令 tail f var log messages 察看日志文件 你会看到 Hello world 被打印了出来 再执行命令 rmmod hello ko 此时 在另一窗口你会看到 Goodbye cruel world 被打印了出来 到这里 我该恭喜你 因为你已经能够编写 Linux 内核模块了 这种感觉很美妙 不是吗 你可以嘲笑秦皇汉武略输文采唐宗宋祖稍逊风骚 还可以嘲笑一代天骄成吉思汗只识弯弓 射大雕了 是的 Twins 姐姐 s 告诉我们 只要我喜欢 还有什么不可以 6 日后我们会看到 2 6 内核中 每个模块都是以 module init 开始 以 module exit 结束 大 多数来说没有必要知道这是为什么 记住就可以了 相信每一个对 Linux 有一点常识的人 都会知道这一点的 对大多数人来说 这就像是 1 1 为什么等于 2 一样 就像是两点之间最 短的是直线 不需要证明 如果一定要证明两点之间直线最短 可以扔一块骨头在 B 点 让一 条狗从 A 点出发 你会发现狗走的是直线 是的 狗都知道 你还能不知道吗 既然知道了怎么编写一个模块 那么编写设备驱动程序自然也就不难了 我相信 每一个会 写模块的人都不会觉得写设备驱动有困难 对自己行不行不确定的话 可以去问一下葛优 他准说 神州行 我看行 真的 我没说假话 写驱动不是什么难事 你完全可以很自信的说 你已经可以写 Device Driver 了 对 没错 飘柔 就这么自信 前面说了每一个模块都是以 module init 开始 以 module exit 结束 那么我们就来看 一下 U 盘的驱动的这个模块 在茫茫人海中 我们很容易找到这个文件 drivers usb storage usb c 在这个文件中又不难发现下面这段 1056 Initialization and registration 1057 1058 1059 static int init usb stor init void 1060 1061 int retval 1062 printk KERN INFO Initializing USB Mass Storage driver n 1063 1064 register the driver return usb register return code if error 1065 retval usb register 1066 if retval 0 1067 printk KERN INFO USB Mass Storage support registered n 1068 1069 return retval 1070 1071 1072 static void exit usb stor exit void 1073 1074 US DEBUGP usb stor exit called n 1075 1076 Deregister the driver 1077 This will cause disconnect to be called for each 1078 attached unit 1079 7 1080 US DEBUGP calling usb deregister n 1081 usb deregister 1082 1083 1084 module init usb stor init 1085 module exit usb stor exit 其实 module init module exit 只是一个宏 通常写模块的人为了彰显自己的个性 会 给自己的初始化函数和注销函数另外起个名字 比如这里 module init usb stor init 以及 module exit usb stor exit 实际上就是告诉这个世界 真正的函数是 usb stor init 和 usb stor exit 这种伎俩在 Linux 内核代码中屡见不鲜 见多了也就 不必大惊小怪了 天要下雨娘要嫁人 随她去吧 我们下面当然就从 usb stor init 正式开 始我们的探索之旅 看代码之前 我曾经认真的思考过这么一个问题 我需要关注的仅仅是 drivers usb storage 目录下面那相关的 3000 多行代码吗 就是这样几个文件就能让 一个个不同的 U 盘在 Linux 下面工作起来吗 像一开始那样把这个目录比作一个小城的 话 也许 城里的月光很漂亮 她能够把人的梦照亮 能够温暖人的心房 但我们真的就能厮守 在这个城里 一生一世吗 很不幸 问题远不是这样简单 外面的世界很精彩 作为 U 盘 她需要与 usb core 打交道 需 要与 scsi core 打交道 需要与内存管理单元打交道 还有内核中许许多多其它模块打交道 外 面的世界很大 远比我们想象的大 什么是 usb core 她负责实现一些核心的功能 为别的设备驱动程序提供服务 比如申请内 存 比如实现一些所有的设备都会需要的公共的函数 事实上 在 usb 的世界里 一个普通的 设备要正常的工作 除了要有设备本身以外 还需要有一个叫做控制器的冬冬 老外把它叫 做 host controller 和这个控制器相连接在一起的有另一个咚咚 她叫 root hub hub 我 们应该不会陌生 在大学里 有的宿舍里网口有限 但是我们这一代人上大学基本上是每人 一台电脑 所以网口不够 于是有人会使用 hub 让多个人共用一个网口 这是以太网上的 hub 而 usb 的世界里同样有 hub 其实原理是一样的 任何支持 usb 的电脑不会说只允许 你只能一个时刻使用一个 usb 设备 比如你插入了 u 盘 你同样还可以插入 usb 键盘 还可 以再插一个 usb 鼠标 因为你会发现你的电脑里并不只是一个 usb 接口 这些口实际上就 是所谓的 hub 口 而现实中经常是让一个 usb 控制器和一个 hub 绑定在一起 专业一点说 叫集成 而这个 hub 也被称作 root hub 换言之 和 usb 控制器绑定在一起的 hub 就是系 统中最根本的 hub 其它的 hub 可以连接到她这里 然后可以延伸出去 外接别的设备 当 然也可以不用别的 hub 让 usb 设备直接接到 root hub 上 hub 干嘛用的我们知道了 那 么 usb host controller 本身是干什么用的呢 controller 控制器 顾名思义 用于控制 控 制什么 控制所有的 usb 设备的通信 通常计算机的 cpu 并不是直接和 usb 设备打交道 而是和控制器打交道 他要对设备做什么 他会告诉控制器 而不是直接把指令发给设备 然 后控制器再去负责处理这件事情 他会去指挥设备执行命令 而 cpu 就不用管剩下的事情 他还是该干嘛干嘛去 控制器替他去完成剩下的事情 事情办完了再通知 cpu 否则让 cpu 去盯着每一个设备做每一件事情 那是不现实的 那就好比让一个学院的院长去盯着我们每 一个本科生上课 去管理我们的出勤 只能说 不现实 所以我们就被分成了几个系 通常院长 有什么指示直接跟各系领导说就可以了 如果他要和三个系主任说事情 他即使不把三个人 都召集起来开个会 也可以给三个人各打一个电话 打完电话他就忙他自己的事情去了 比 如去和他带的女硕士风花雪月 而三个系主任就会去安排下面的人去执行具体的任务 完了 8 之后他们就会像院长汇报 所以 Linux 内核开发者们 专门写了一些代码 并美其名曰 usb core 时代总在发展 当年 胖杨贵妃照样迷死唐明皇 而如今人们欣赏的则是林志玲这样的魔鬼身材 同样 早期的 Linux 内核 其结构并不是如今天这般有层次感 远不像今天这般错落有致 那时候 drivers usb 这个目录下边放了很多很多文件 usb core 与其他各种设备的驱动程序的 代码都堆砌在这里 后来 怎奈世间万千的变幻 总爱把有情的人分两端 于是在 drivers usb 目录下面出来了一个 core 目录 就专门放一些核心的代码 比如初始化整个 usb 系统 初始化 root hub 初始化 host controller 的代码 再后来甚至把 host controller 相关的代码也单独建了一个目录 叫 host 目录 这是因为 usb host controller 随着时代的发展 也开始有了好几种 不再像刚开始那样只有一种 所以呢 设计 者们把一些 host controller 公共的代码仍然留在 core 目录下 而一些各 host controller 单独的代码则移到 host 目录下面让负责各种 host controller 的人去维护 常 见的 host controller 有三种 分别叫做 EHCI UHCI OHCI 所以这样 出来了三个概念 usb core usb host usb device 即原本是一家人 却被活生生的分成了两岸三地 的确 现实总是很无奈 然而 心若知道灵犀的方向 哪怕不能够朝夕相伴 没错 usb 通信的灵魂 就是 usb 协议 usb 协议将是所有 usb 设备和 usb 主机所必须遵循的游戏规则 这种规 则也很自然的体现在了代码中 于是 我们需要了解的不仅仅是 drivers usb storage 目 录下面的冬冬 还得去了解那外面的世界 虽然 只需要了解一点点 还是回到那个初始化函数吧 usb stor init 看了它的代码每一个人的心中都有一种莫名 的兴奋 因为它太短了 就那么几行 除了两个 printk 语句以外 就是一个函数的调用 usb register printk 不用我说 每一个有志青年都该知道 就算没见过 printk 也该见过 printf 吧 否则 的话 你扪心自问 你对得起谭浩强大哥吗 在谭浩强大哥的带领下我们学会了用 include main printf 来打印 hello world 从而向全世界展示了我们懂 C 语言 而 stdio h 就是一个 C 库 printf 是一个函数 来自函数库 可是内核中没有标准 C 库 所以 开发者们自己准备了一些函数 专门用于内核代码中 所以就出来了一个 printk printk 的 k 就是 kernel 内核 所以我们只要把它当作 printf 的兄弟即可 如果感兴趣 可以去研究 一下 printk 的特点 她和 printf 多少有些不同 但基本思想是一样的 所以我们就不多讲了 当 然驱动程序中所有的 printk 语句对 U 盘的工作都没有什么用 她无非是打出来给我们看 的 或者说打印给用户看 或者呢 打印给开发者看 特别是开发者要调试程序的时候 就会很 有用 于是我们更开心了 不用看 printk 的话 那就只有一个函数调用了 usb register 这个函 数是干嘛的 首先这个函数正是来自 usb core 凡是 usb 设备驱动 都要调用这个函数来 向 usb core 注册 从而让 usb core 知道有这么一个设备 这就像政府规定 一对夫妻结婚 要到相关部门那里去登记是一样的 我们无需知道政府是如何管理的 只需要知道去政府那 里登记即可 这样 insmod 的时候 usb stor init 这个函数会被调用 初始化就算完成了 于是设备就 开始工作了 而当我们 rmmod 的时候 usb stor exit 这个函数会被调用 我们发现 这 个函数也很短 我们能看出来 US DEBUG 也就是打印一些咚咚 因此 这里实际上也就是 调用了一个函数 usb deregister 她和 usb register 是一对 完成了注销的工作 从 此设备就从 usb core 中消失了 于是我们惊人的发现 编写设备驱动竟是如此的简单 驱 动程序真的就这么结束了 这一切 不禁让人产生了一种幻觉 让人分不清故事从哪里开始 又从哪里结束 一切都太短 暂了 仿佛开始在结束的时候开始 而结束却在开始的时候就早已结束 9 真的吗 答案是否定的 孔子已经教育过我们 不光要看懂代码 更要理解代码背后的哲学 所以我们在继续之前 先来看看这里到底有什么哲学 而这 就是伟大的 Linux Kernel 2 6 中的统一的设备模型 我们并无意去详细介绍 2 6 中的设备模型 但是不懂设备模型又怎能说自己懂设备驱动呢 读 代码的人 写代码的人 都要知道 什么是设备驱动 什么又是设备 设备和驱动之间究竟是 什么关系 设备如何与计算机主机联系起来 我相信在中关村买盗版光盘的哥们儿也能回 答这个问题 计算机世界里 设备有很多种类 比如 PCI 设备 比如 ISA 设备 再比如 SCSI 设备 再比如我们这里的 USB 设备 为设备联姻的是总线 是他把设备连入了计算机主机 但是与其说设备是嫁给了计算机主机 倒不如说设备是嫁给了设备驱动程序 很显然 在计 算机世界里 无论风里雨里 陪伴着设备的正是驱动程序 唯一的遗憾是 计算机中的设备和驱动程序的关系却并非如可乐和拉环的关系那样 一对一 然 而世上又有多少事情总能如人愿呢 Linux 设备模型中三个很重要的概念就是总线 设备 驱动 即 bus device driver 而实际 上内核中也定义了这么一些数据结构 他们是 struct bus type struct device struct device driver 这三个重要的数据结构都来自一个地方 include linux device h 我们 知道总线有很多种 pci 总线 scsi 总线 usb 总线 所以我们会看到 Linux 内核代码中出现 pci bus type scsi bus type usb bus type 他们都是 struct bus type 类型的变 量 而 struct bus type 结构中两个非常重要的成员就是 struct kset drivers 和 struct kset devices kset 和另一个叫做 kobject 正是 Linux Kernel 2 6 中设备模型的基本元 素 但此处我们却不愿多讲 因为暂时不用去认识他们 我们的生命中会遇见许许多多的人 和事 但更多的人和事与我们只是擦肩而过 只是我们生命中的过客而已 在我们人生的电 影中 他们也许只有一个镜头 甚至那一个镜头后来也被剪辑掉了 这里我们只需要知道 drivers 和 devices 的存在 让 struct bus type 与两个链表联系了起来 一个是 devices 的链表 一个是 drivers 的链表 也就是说 知道一条总线所对应的数据结构 就可 以找到这条总线所关联的设备有哪些 又有哪些支持这类设备的驱动程序 而要实现这些 就要求每次出现一个设备就要向总线汇报 或者说注册 每次出现一个驱动 也要向总线汇报 或者说注册 比如系统初始化的时候 会扫描连接了哪些设备 并为每一个 设备建立起一个 struct device 的变量 每一次有一个驱动程序 就要准备一个 struct device driver 结构的变量 把这些变量统统加入相应的链表 device 插入 devices 链表 driver 插入 drivers 链表 这样通过总线就能找到每一个设备 每一个驱动 然而 假如计算机里只有设备却没有对应的驱动 那么设备无法工作 反过来 倘若只有驱动 却没有设备 驱动也起不了任何作用 在他们遇见彼此之前 双方都如同路埂的野草 一个飘 啊飘 一个摇啊摇 谁也不知道未来在哪里 只能在生命的风里飘摇 于是总线上的两张表里 就慢慢的就挂上了那许多孤单的灵魂 devices 开始多了 drivers 开始多了 他们像是两个 来自世界 devices 们彼此取暖 drivers 们一起狂欢 但他们有一点是相同的 都只是在等 待属于自己的那个另一半 看代码的我 一直好奇的想知道 他们是否和我们现实中一样 有些人注定是等别人 而有些 人是注定被人等的 struct bus type 中为 devices 和 drivers 准备了两个链表 而代表 device 的结构体 struct device 中又有两个成员 struct bus type bus 和 struct device driver driver 同样 代表 driver 的结构体 struct device driver 同样有两个成员 struct bus type bus 和 struct list head devices struct device 和 struct device driver 的定义和 struct bus type 一样 在 include linux device h 中 凭一种 10 男人的直觉 可以知晓 struct device 中的 bus 记录的是这个设备连在哪条总线上 driver 记录的是这个设备用的是哪个驱动 反过来 struct device driver 中的 bus 代表 的也是这个驱动属于哪条总线 devices 记录的是这个驱动支持的那些设备 没错 是 devices 复数 而不是 device 单数 因为一个驱动程序可以支持一个或多个设备 反过 来一个设备则只会绑定给一个驱动程序 于是我们想知道 关于 bus 关于 device 关于 driver 他们是如何建立联系的呢 换言之 这三个数据结构中的指针是如何被赋值的 绝对不可能发生的事情是 一旦为一条总线申请 了一个 struct bus type 的数据结构之后 它就知道它的 devices 链表和 drivers 链表会 包含哪些东西 这些咚咚一定不会是先天就有的 只能是后天填进来的 而具体到 usb 系统 完成这个工作的就是 usb core usb core 的代码会进行整个 usb 系统的初始化 比如申请 struct bus type usb bus type 然后会扫描 usb 总线 看线上连接了哪些 usb 设备 或 者说 root hub 上连了哪些 usb 设备 比如说连了一个 usb 键盘 那么就为它准备一个 struct device 根据它的实际情况 为这个 struct device 赋值 并插入 devices 链表中来 又比如 root hub 上连了一个普通的 hub 那么除了要为这个 hub 本身准备一个 struct device 以外 还得继续扫描看这个 hub 上是否又连了别的设备 有的话继续重复之前的事 情 这样一直进行下去 直到完成整个扫描 最终就把 usb bus type 中的 devices 链表给 建立了起来 那么 drivers 链表呢 这个就不用 bus 方面主动了 而该由每一个 driver 本身去 bus 上面 登记 或者说挂牌 具体到 usb 系统 每一个 usb 设备的驱动程序都会有一个 struct usb driver 结构体 其代码如下 来自 include linux usb h 485 486 487 488 struct usb driver identifies USB driver to usbcore 489 owner Pointer to the module owner of this driver initialize 490 it using THIS MODULE 491 name The driver name should be unique among USB drivers 492 and should normally be the same as the module name 493 probe Called to see if the driver is willing to manage a particular 494 interface on a device If it is probe returns zero and uses 495 dev set drvdata to associate driver specific data with the 496 interface It may also use usb set interface to specify the 497 appropriate altsetting If unwilling to manage the interface 498 return a negative errno value 499 disconnect Called when the interface is no longer accessible usually 500 because its device has been or is being disconnected or the 501 driver module is being unloaded 502 ioctl Used for drivers that want to talk to userspace through 503 the usbfs filesystem This lets devices provide ways to 504 expose information to user space regardless of where they 505 do or don t show up otherwise in the filesystem 506 suspend Called when the device is going to be suspended by the 11 system 507 resume Called when the device is being resumed by the system 508 id table USB drivers use ID table to support hotplugging 509 Export this with MODULE DEVICE TABLE usb This must be set 510 or your driver s probe function will never get called 511 driver the driver model core driver structure 512 513 USB drivers must provide a name probe and disconnect methods 514 and an id table Other driver fields are optional 515 516 The id table is used in hotplugging It holds a set of descriptors 517 and specialized data may be associated with each entry That table 518 is used by both user and kernel mode hotplugging support 519 520 The probe and disconnect methods are called in a context where 521 they can sleep but they should avoid abusing the privilege Most 522 work to connect to a device should be done when the device is opened 523 and undone at the last close The disconnect code needs to address 524 concurrency issues with respect to open and close methods as 525 well as forcing all pending I O requests to complete by unlinking 526 them as necessary and blocking until the unlinks complete 527 528 struct usb driver 529 struct module owner 530 531 const char name 532 533 int probe struct usb interface intf 534 const struct usb device id id 535 536 void disconnect struct usb interface intf 537 538 int ioctl struct usb interface intf unsigned int code void buf 539 540 int suspend struct usb interface intf u32 state 541 int resume struct usb interface intf 542 543 const struct usb device id id table 544 545 struct device driver driver 12 546 547 define to usb driver d container of d struct usb driver driver 看似很长一段 实际上也就是注释为主 而此刻我们只需注意到其中的 struct device driver driver 这个成员 usb core 为每一个设备驱动准备了一个函数 让它把自 己的这个 struct device driver driver 插入到 usb bus type 中的 drivers 链表中去 而这个函数正是我们此前看到的 usb register 而与之对应的 usb deregister 所从事的 正是与之相反的工作 把这个结构体从 drivers 链表中删除 可以说 usb core 的确是用心 良苦 为每一个 usb 设备驱动做足了功课 正因为如此 作为一个实际的 usb 设备驱动 它在 初始化阶段所要做的事情就很少 很简单了 直接调用 usb register 即可 事实上 没有人是 理所当然应该为你做什么的 但 usb core 这么做了 所以每一个写 usb 设备驱动的人应该 铭记 usb device driver 绝不是一个人在工作 在他身后 是 usb core 所提供的默默无闻 又不可或缺的支持 bus 上的两张链表记录了每一个 device 和 driver 那么 device 和 dr

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论