在开始第三个函数前,2492行至2494行还有三行代码,对udev中的speed,bus_mA,level进行赋值.

先说一下,bus_mA,struct usb_device中的成员,unsigned short bus_mA,记录的是能够从总线上获得的电流,毫无疑问就是咱们前面算出来的hub上的那个mA_per_port.上头能给多少咱们就要多少.

再说level,级别,表征usb设备树的级连关系.Root Hub当然其level就是0,其下面一层就是level 1,再下面一层就是level 2,依此类推.

然后说speed,include/linux/usb/ch9.h中定义了这么一个枚举类型的变量:

548 /* USB 2.0 defines three speeds, here's how Linux identifies them */

549

550 enum usb_device_speed {

551         USB_SPEED_UNKNOWN = 0,                  /* enumerating */

552         USB_SPEED_LOW, USB_SPEED_FULL,          /* usb 1.1 */

553         USB_SPEED_HIGH,                         /* usb 2.0 */

554         USB_SPEED_VARIABLE,                     /* wireless (usb 2.5) */

555 };

很明显的含义,用来标志设备的速度.众所周知,USB设备有三种速度,低速,全速,高速.USB1.1那会儿只有低速,全速,后来才出现了高速,高速就是所谓的480Mbps/s,不过细心的你或许注意到这里还有一个USB_SPEED_VARIABLE.两千零五年那个五月,Intel等公司推出了Wireless USB spec 1.0版,即所谓的无线USB技术,江湖上也把这个usb技术称为usb 2.5.无线技术的推出必然会让设备的速度不再稳定,当年这个标准推出的时候是号称在3米范围内,能够提供480Mbps的理论传输速度,而在10米范围左右出现递减,据说是10米内110Mbps/s.那时正值英特尔中国20周年,所以中国这边的员工每人发了一个无线USB鼠标.其实就是一个USB接头,接在电脑的usb端口上,而鼠标这边没有线,鼠标和接头之间的通信是无线的,使用传说中蓝牙技术.我的那个无线鼠标基本上四五米之外就不能用了.总之,这里的变量usb_device_speed就是用来表征设备速度的,现阶段还不知道这个设备究竟是什么速度的,所以先设置为UNKNOWN.等到知道了以后再进行真正的设置.

第三个函数,choose_address().

这个函数的目的就是为设备选择一个地址.很显然,要通信就要有地址,你要给人写情书表白,你首先得知道人家的通信地址,或者电子邮箱地址.

1132 static void choose_address(struct usb_device *udev)

1133 {

1134         int             devnum;

1135         struct usb_bus  *bus = udev->bus;

1136

1137         /* If khubd ever becomes multithreaded, this will need a lock */

1138

1139         /* Try to allocate the next devnum beginning at bus->devnum_next. */

1140         devnum = find_next_zero_bit(bus->devmap.devicemap, 128,

1141                         bus->devnum_next);

1142         if (devnum >= 128)

1143                 devnum = find_next_zero_bit(bus->devmap.devicemap, 128, 1);

1144

1145         bus->devnum_next = ( devnum >= 127 ? 1 : devnum + 1);

1146

1147         if (devnum < 128) {

1148                 set_bit(devnum, bus->devmap.devicemap);

1149                 udev->devnum = devnum;

1150         }

1151 }

那么现在是时候让我们来认识一下usb子系统里面关于地址的游戏规则了.在悠悠岁月中,一个神话就是浪花一朵,一滴苦酒就是史书一册,而在usb世界里,一条总线就是大树一棵,一个设备就是叶子一片.为了记录这棵树上的每一个叶子节点,每条总线设有一个地址映射表,即struct usb_bus结构体里有一个成员struct usb_devmap devmap,

268 /* USB device number allocation bitmap */

269 struct usb_devmap {

270         unsigned long devicemap[128 / (8*sizeof(unsigned long))];

271 };

同时struct usb_bus结构体里面还有一个成员,int devnum_next,在总线初始化的时候,其devnum_next被设置为1,而在struct usb_device中有一个int devnum,咱们这个choose_address函数的基本思想就是一个轮询的算法.

我们来介绍一下这段代码背后的哲学.首先,bus上面不是有这么一张表嘛,假设unsigned long=4bytes,那么unsigned long devicemap[128/(8*sizeof(unsigned long)]]就等价于unsigned long devicemap[128/(8*4)],进而等价于unsigned long devicemap[4],而4bytes就是32个bits,因此这个数组最终表示的就是128个bits.而这也对应于一条总线可以连接128个usb设备.之所以这里使用sizeof(unsigned long),就是为了跨平台应用,不管unsigned long到底是几,总之这个devicemap数组最终可以表示128位.

128个bits里,每当加入一个设备,就先找到下一位为0的bit,然后把该bit设置为1,同时把struct usb_device中的devnum设置为该数字,比如我们找到第19位为0,那么就把devnum设置为19,同时把bit 19设置为1,而struct usb_bus中的devnum_next就设置为20.

那么所谓轮询,即如果这个编号超过了128,那么就从1开始继续搜索,因为也许开始那段的号码原来分配给某个设备但后来这个设备撤掉了,所以这个号码将被设置为0,于是再次可用.

弄清楚了这些基本思想后,我们再来看代码就很简单了.这时候相信你可以自豪的和杨振宁先生一样,高呼:”我能!”当然,我不会像翁帆女士一样喊:”你不能,我能让你能!”

find_next_zero_bit()的意思很明显,名字解释了一切.不同的体系结构提供了自己不同的函数实现,比如i386,这个函数就定义于arch/i386/lib/bitops.c中,而x8664则对应于arch/x86_64/lib/bitops.c中,利用这个函数我们就可以找到这128位中下一个为0的那一位.这个函数的第三个参数表征从哪里开始寻找,我们注意到第一次我们是从devnum_next开始找,如果最终返回值暴掉了(大于或者等于128),那么就从1开始再找一次.而bus->devnum_next也是按我们说的那样设置,正常就是devnum+1,但如果devnum已经达到127了,那么就从头再来,设置为1.

如果 devnum 正常 , 那么就把 bus 中的 device map 中的那一位设置为 1. 同时把 udev->devnum 设置为 devnum. 然后这个函数就可以返回了 . 如果 128 个 bits 都被占用了 ,devnum 就将是零或者负的错误码 , 于是 choose_address 返回之后我们就要进行判断 , 如果真的是满掉了 , 那么咱们有心杀贼无力回天 , 也就不用往下走了 , 不过你要真的能连满 128 个设备 , 那你也蛮狠的 . 不得不把陈小春的那首 << 算你狠 >> 送给你 !

Linux那些事儿之我是Hub(19)八大重量级函数闪亮登场(三)相关推荐

  1. Linux那些事儿之我是Hub(9)While You Were Sleeping(二)

    老实说,从函数一个开始的598行直到627行都没有什么可说的.其中需要一提的是,606行,调用usb_buffer_alloc()申请内存,赋给hub->buffer.614行,调用kmallo ...

  2. 【转】Linux那些事儿之我是Hub(7)蝴蝶效应

    朋友,你相信,一只蝴蝶在北京拍拍翅膀,将使得纽约几个月后出现比狂风还厉害的龙卷风吗?看过那部经典的影片蝴蝶效应的朋友们一定会说,这不就是蝴蝶效应吗.没错.蝴蝶效应其实是混沌学理论中的一个概念.它是指对 ...

  3. Linux那些事儿之我是Hub(25)不说代码说理论

    当女作家们越来越多的使用下半身来告诉我什么是文学的时候,当模特们越来越多的使用裸体来告诉我什么是人体艺术的时候,我开始对这个社会困惑了,当行为艺术家们越来越多的使用垃圾堆砌来告诉我什么是波谱的时候,当 ...

  4. Linux那些事儿之我是Hub(4)

    这一节我们讲队列. 从前在乡下的时候是不用排队的,村里的人们都很谦让,而且人本来又不多.后来到了县城里,县城里不大,大家去走亲戚去串门去逛街不用坐车不用排队,除了街上的游戏厅人多一点以外,别的地方人都 ...

  5. Linux那些事儿之我是Hub(1)跟我走吧,现在就出发

    最早知道hub是在大学里,复旦的4人间宿舍,条件真好,每个人一张书桌,书桌下面一个网口,但是有时候网口坏了,那可急死人了,要知道当初我们买电脑初衷虽说是为了学习C语言,可是买了之后,C倒是没学,先学了 ...

  6. Linux那些事儿之我是Hub(2)

    莎士比亚曾经说过,不懂hub是怎么工作的就等于不知道usb设备驱动是怎么工作的.这句话一点没错,因为usb设备的初始化都是hub这边发起的,通常我们写usb设备驱动程序都是在已经得到了一个struct ...

  7. Linux系统USB驱动目录,Linux那些事儿之我是USB 目录

    目录 第1篇  Linux那些事儿之我是USB Core 1.引子 2 2.它从哪里来 2 3.PK 3 4.漫漫辛酸路 3 5.我型我秀 4 6.我是一棵树 5 7.我是谁 9 8.好戏开始了 11 ...

  8. Linux设备之我是usb,linux那些事儿之我是usb

    linux那些事儿之我是usb,复旦大学教授肖林甫先生给学生们解说的linux操作系统的一些硬件驱动开发的事儿. 内核说明: 我是U盘 说的是2.6.10的内核 我是Sysfs 说的是2.6.10的内 ...

  9. 读书笔记《Linux那些事儿之我是USB》

    第一篇:Linux那些事儿之我是USB Core USB诞生于inel 产生是为了解决前期计算机并口串口的问题,实现一种解决速度,扩展性,易用性的通信方式. 速度:usb2.0高速模式,480MB/s ...

最新文章

  1. 思维dp ---- Codeforces Round #142 (Div. 1) D. Towers
  2. 微软 WinGet 抄袭 AppGet 始末,个人开源的困境该如何破?
  3. f(f(x)) = -x
  4. html圆角兼容jq,IE兼容css3圆角的htc解决方法
  5. 拒绝“肌肉记忆”,卡萨帝迈进场景品牌新赛道
  6. mysql 1054 42s22_MySQL ERROR 1054(42S22)
  7. 建议收藏丨sql行转列的一千种写法!!
  8. java 正则 标签内容_java正则匹配html片段,并取得标签中的内容
  9. 软考中高项学员:2016年3月26日作业
  10. (转)阿里云CentOS 7下配置及使用mysql
  11. 3Ddungeon-------三维搜索-----偷个懒 把 亡命逃窜 的代码修改了一下 拿来用了
  12. tomcat 版本_Tomcat竟然有bug,这我能信?
  13. Ubuntu终端常用的快捷键,光标移动到开始位置
  14. java 二叉树的创建 遍历
  15. 会声会影 html5,一文了解会声会影哪个版本比较好用
  16. python柱状图颜色_Python 绘制 柱状图
  17. IDEA运行项目时停不下来
  18. 论文-OpenDialKG: Explainable Conversational Reasoning with Attention-based Walks over Knowledge Grap
  19. BAPI 创建343物料凭证
  20. 系列报道 | 组织范式“青色组织”兴起:员工骨子里透出愉悦积极气质

热门文章

  1. 面试必备--JS函数工具库手写
  2. YT-JF660E四合一无线局放传感器的几种检测方式
  3. 利用js来制作简单倒计时效果
  4. (电路设计资料)N95超声波功率发生器电路图PCB源文件方案
  5. 微信小程序开发踩坑合集
  6. 平面凸多边形顶点排序MATLAB,凸多边形顶点顺逆时针排序
  7. 书影 | 管中窥豹,读《淘宝技术这十年》上
  8. 3D游戏建模接私活外包防止被骗,请牢记这6个守则!
  9. 绝缘子泄漏电流在线监测装置
  10. ​能让德国人放弃现金支付​,也没谁了