标题:
Linux那些事儿 之 戏说USB(13)面纱
[打印本页]
作者:
bingchentiao
时间:
2013-5-22 09:55
标题:
Linux那些事儿 之 戏说USB(13)面纱
在爱情、背叛与死亡的漩涡中挣扎的凯蒂,亲历了幻想破灭与生死离别之后,终将生活的面纱从她的眼前渐渐揭去,从此踏上了不悔的精神成长之路。
向大家推荐这部片子《面纱》,没有那些小电影精彩,但是绝对值得一看。为什么会想到它,只在乎于现在的心情。前面说了那么多,才接触到usb_init,有点一窥usb面纱下神秘容颜的味道。当然,我们并不需要去经历爱情、被判与死亡,所需要经历的只是忍受前面大段大段的唠叨。
人往往可以被高尚感动,但始终不能因为高尚而爱上。因为被__init给盯上,usb_init在做牛做马的辛勤劳作之后便不得不灰飞烟灭,不可谓不高尚,但它始终只能是我们了解面纱后面内容的跳板,是起点,却不是终点,我们不会为它停留太久,有太多的精彩和苦恼在等着我们。
865
int retval;
866
if (
nousb
) {
867
pr_info
("%s: USB support disabled/n",
usbcore_name
);
868
return 0;
869
}
866行,知道C语言的人都会知道nousb是一个标志,只是不同的标志有不一样的精彩,这里的nousb是用来让我们在启动内核的时候通过内核参数去掉USB子系统的,linux社会是一个很人性化的世界,它不会去逼迫我们接受USB,一切都只关乎我们自己的需要。不过我想我们一般来说是不会去指定nousb的吧,毕竟它那么的讨人可爱。如果你真的定义了nousb,那它就只会幽怨的说一句“USB support disabled”,然后退出usb_init。
867行,pr_info只是一个打印信息的宏,printk的变体,在
include/linux/kernel.h
里定义:
242
#define
pr_info
(
fmt
,
arg
...) /
243
printk
(
KERN_INFO
fmt
,##arg)
这个可变参数宏要不要说一下?地球人都知道了,不过还是聊一下吧,我有多话症。99年的ISO C标准里规定了可变参数宏,和函数语法类似,给个例子
#define debug(format, ...) fprintf (stderr, format, __VA_ARGS__)
里面的“…”就表示可变参数,调用时,它们就会替代宏体里的__VA_ARGS__。GCC总是会显得特立独行一些,它支持更复杂的形式,可以给可变参数取个名字,再给个这种形式的例子
#define debug(format, args...) fprintf (stderr, format, args)
是不是显得更容易读了些?有了名字总是会容易交流一些。是不是与咱们的pr_info比较接近了?除了‘##’,它主要是针对空参数的情况。既然说是可变参数,那传递空参数也总是可以的,空即是多,多即是空,股市里的哲理这里同样也是适合的。如果没有‘##’,传递空参数的时候,比如
debug ("A message")
宏展开后,里面的字符串后面会多个多余的逗号。这个逗号你应该不会喜欢,它是表错情了,而‘##’则会使预处理器去掉这个多余的逗号。
871
retval =
ksuspend_usb_init
();
872
if (retval)
873
goto
out
;
874
retval =
bus_register
(&
usb_bus_type
);
875
if (retval)
876
goto bus_register_failed;
877
retval =
usb_host_init
();
878
if (retval)
879
goto host_init_failed;
880
retval =
usb_major_init
();
881
if (retval)
882
goto major_init_failed;
883
retval =
usb_register
(&
usbfs_driver
);
884
if (retval)
885
goto driver_register_failed;
886
retval =
usb_devio_init
();
887
if (retval)
888
goto usb_devio_init_failed;
889
retval =
usbfs_init
();
890
if (retval)
891
goto fs_init_failed;
892
retval =
usb_hub_init
();
893
if (retval)
894
goto hub_init_failed;
895
retval =
usb_register_device_driver
(&
usb_generic_driver
,
THIS_MODULE
);
896
if (!retval)
897
goto
out
;
871到897这些行是代码里的排比句,相似的init不相似的内容,很显然都是在完成一些初始化,也是usb_init任劳任怨所付出的全部。这里先简单的说一下。
871行,电源管理方面的。如果在编译内核时没有打开电源管理,也就是说没有定义CONFIG_PM,它就什么也不做。
874行,注册USB总线,只有成功的将USB总线子系统注册到系统中,我们才可以向这个总线添加USB设备。基于它显要的江湖地位,就拿它做为日后突破的方向了,擒贼先擒王,这个越老越青春的道理在linux中也是同样适用的。
877行,执行host controller相关的初始化。
880行,一个实际的总线也是一个设备,必须单独注册,因为USB是通过快速串行通信来读写数据,这里把它当作了字符设备来注册。
883~891行,都是usbfs相关的初始化。
892行,hub的初始化,这个复旦人甲正在讲。
895行,注册USB device driver,戴好眼镜看清楚了,是USB device driver而不是USB driver,前面说过,一个设备可以有多个接口,每个接口对应不同的驱动程序,这里所谓的device driver对应的是整个设备,而不是某个接口。内核里结构到处有,只是USB这儿格外多。
剩下的几行代码都是有关资源清除的,usb_init这个短短的函数在承载着我们的希望的时候嘎然而止了,你的感觉是什么?我的感觉是:这哪是我能说的清楚的啊。它的每个分叉都更像是一个陷阱,黑黝黝看不到底,但是已经没有回头的路。
欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/)
Powered by Discuz! 7.0.0