关系是跑出来的,感情是喝出来的,朋友是处出来的,事业是干出来的,但设备是配置出来的,绝非吹出来的。core配置设备使用的是message.c里的usb_set_configuration函数
1389* usb_set_configuration - Makes a particular device setting be current
1390* @dev: the device whose configuration is being updated
1391* @configuration: the configuration being chosen.
1392* Context: !in_interrupt(), caller owns the device lock
1394* This is used to enable non-default device modes.Not all devices
1395* use this kind of configurability; many devices only have one
1398* @configuration is the value of the configuration to be installed.
1399* According to the USB spec (e.g. section 9.1.1.5), configuration values
1400* must be non-zero; a value of zero indicates that the device in
1401* unconfigured.However some devices erroneously use 0 as one of their
1402* configuration values.To help manage such devices, this routine will
1403* accept @configuration = -1 as indicating the device should be put in
1404* an unconfigured state.
1406* USB device configurations may affect Linux interoperability,
1407* power consumption and the functionality available.For example,
1408* the default configuration is limited to using 100mA of bus power,
1409* so that when certain device functionality requires more power,
1410* and the device is bus powered, that functionality should be in some
1411* non-default device configuration.Other device modes may also be
1412* reflected as configuration options, such as whether two ISDN
1413* channels are available independently; and choosing between open
1414* standard device protocols (like CDC) or proprietary ones.
1416* Note that USB has an additional level of device configurability,
1417* associated with interfaces.That configurability is accessed using
1418* usb_set_interface().
1420* This call is synchronous. The calling context must be able to sleep,
1421* must own the device lock, and must not hold the driver model's USB
1422* bus mutex; usb device driver probe() methods cannot use this routine.
1424* Returns zero on success, or else the status code returned by the
1425* underlying call that failed.On successful completion, each interface
1426* in the original device configuration has been destroyed, and each one
1427* in the new configuration has been probed by all relevant usb device
1428* drivers currently known to the kernel.
1437 if (configuration == -1)
1448 if ((!cp && configuration != 0))
1451 /* The USB spec says configuration 0 means unconfigured.
1452 * But if a device includes a configuration numbered 0,
1453 * we will accept it as a correctly configured state.
1454 * Use -1 if you really want to unconfigure the device.
1456 if (cp && configuration == 0)
1459 /* Allocate memory for new interfaces before doing anything else,
1460 * so that if we run out then nothing will have changed. */
1464 new_interfaces = kmalloc(nintf * sizeof(*new_interfaces),
1466 if (!new_interfaces) {
1471 for (; n < nintf; ++n) {
1475 if (!new_interfaces[n]) {
1493 /* Wake up the device so we can send it the Set-Config request */
1496 goto free_interfaces;
1498 /* if it's already configured, clear out old state first.
1499 * getting rid of old interfaces means unbinding their drivers.
1508 /* All the old state is gone, so what else can we do?
1509 * The device is probably useless now anyway.
1518 goto free_interfaces;
1522 /* Initialize the new interface structures and the
1523 * hc/hcd/usbcore interface/endpoint state.
1533 intf->num_altsetting = intfc->num_altsetting;
1538 /* No altsetting 0?We'll assume the first altsetting.
1539 * We could use a GetInterface call, but if a device is
1540 * so non-compliant that it doesn't have altsetting 0
1541 * then I wouldn't trust its reply anyway.
1564 /* Now that all the interfaces are set up, register them
1565 * to trigger binding of drivers to interfaces.probe()
1566 * routines may install different altsettings and may
1567 * claim() any interfaces not yet bound.Many class drivers
1568 * need that: CDC, audio, video, etc.
1574 "adding %s (config #%d, interface %d)/n",
1576 intf->cur_altsetting->desc.bInterfaceNumber);
这个函数很迷信,从1388行开始,到1588行结束,怎么着它都要发发,希望咱们看的时候也能沾上点财气运气。那就先对着它许个愿吧,并不是真的相信它,但是反正也是免费的,而且也没有证据证明它不灵。
说代码前咱们再聊点这个函数背后的人生哲学,你设备不是和usb_generic_driver这个大美女配对成功了么,可是这并不是就说你可以高枕无忧了,要想保持和她的这种亲密关系,你得想办法让她得到满足,你就得抱着一颗勇敢的心,准备着让她去配置,准备着她想让你什么样你就什么样。你要明白,吸引住男人的办法就是让他一直得不到,吸引住女人的办法正好相反,就是让她一直满足。从这个角度看,这个函数就可以泾渭分明的分成三个部分三个阶段,从1432到1491的这几十行是准备阶段,做做常规检查啊,申请申请内存啊,搞点前戏什么的。1498到1520这部分可是重头戏,就是在这里设备从Address发展到了Configured,可算是高潮阶段,别看它短,这是事物发展的规律,也是每个男人女人的规律。1522到1584这阶段也挺重要的,主要就是充实充实设备的每个接口并提交给设备模型,为它们寻找命中注定的接口驱动,最后温存温存,过了这个后戏阶段,usb_generic_driver也就彻底从你设备那儿得到满足了,generic_probe的历史使命也就完成了。事物的发展大体上就脱离不了这三个阶段,再比如股票,买、卖、回味。
先看第一阶段,要做一个好男人,按顺序一步一步来。1437行,configuration是前边儿choose_configuration()那里返回回来的,找到合意的配置的话,就返回那个配置的bConfigurationValue值,没有找到称心的配置的话,就返回-1,所以这里的configuration值就可能有两种情况,或者为-1,或者为配置的bConfigurationValue值。当configuration为-1时这里为啥又要把它改为0捏?要知道configuration这个值是要在后面的高潮阶段里发送SET_CONFIGURATION请求时用的,关于SET_CONFIGURATION请求,spec里说,这个值必须为0或者与配置描述符的bConfigurationValue一致,如果为0,则设备收到SET_CONFIGURATION请求后,仍然会待在Address状态。这里当configuration为-1也就是没有发现满意的配置时,设备不能进入Configured,所以要把configuration的值改为0,以便满足SET_CONFIGURATION请求的要求。
那接下来的问题就出来了,在没有找到合适配置的时候直接给configuration这个参数传个0,也就是让choose_configuration()返回个0不就得了,干吗还这么麻烦先返回个-1再把它改成0,不是脱裤子放屁多此一举么?你别愤怒,这归根结底还是那句话,林子大了什么鸟都有,有些设备就是有拿0当配置bConfigurationValue值的毛病,你又不能不让它用,不是有句俗话么:既然说人生是本书,那出现几个错别字就没什么大不了的。人生都能出现错字,那usb世界里出现几个有毛病的设备也没啥大不了的,这里妥协一下就是了,想让设备回到Address状态时,usb_set_configuration()就别传递0了,传递个-1,里边儿去处理一下。如果configuration值为0或大于0的值,就从设备struct usb_device结构体的config数组里将相应配置的描述信息,也就是struct usb_host_config结构体给取出来。
1448行,如果没有拿到配置的内容,configuration值就必须为0了,让设备待在Address那儿别动。这也很好理解,配置的内容都找不到了,还配置个什么劲儿。当然,如果拿到了配置的内容,但同时configuration为0,这就是对应了上面说的那种有毛病的设备的情况,就提出一下警告,告诉你不正常现象出现了。
1461行,过了这个if,第一阶段就告结束了。如果配置是实实在在存在的,就为它使用的那些接口都准备一个struct usb_interface结构体。new_interfaces是开头儿就定义好的一个struct usb_interface结构体指针数组,数组的每一项都指向了一个struct usb_interface结构体,所以这里申请内存也要分两步走,先申请指针数组的,再申请每一项的。
分享到:
相关推荐
2.6.22内核的usb core源码分析。原文为blog.csdn.net/fudan_abc上的《linux那些事儿之戏说USB》。
我是U盘 说的是2.6.10的内核 我是Sysfs 说的是2.6.10的内核 戏说USB 说的是2.6.22的内核 我是Hub/UHCI/EHCI 说的是2.6.22.1的内核
作者用通俗幽默的语言简述了linux的相关知识点,很容易掌握的,建议大家好好学哦 我是U盘 说的是2.6.10的内核 我是Sysfs 说的是2.6.10的内核 戏说USB 说的是2.6.22的内核 我是Hub/UHCI/EHCI 说的是2.6.22.1的内核 ...
第二章代码规范、重构 第三章复制 VS复用 第四章业务的封装 第五章体会简单工厂模式的美妙 第六章工厂不好用了? 第七章用“策略模式”是一种好策略 第八章反射——程序员的快乐! 第九章会修电脑不会修收音机?——...
兄弟连Linux基础知识与系统管理课件
大班音乐:戏说脸谱.ppt
戏说指针 如何分析指针类型 细说指针 指针的类型 指针所指向的类型 指针的值 指针本身所占据的内存区
C# 面向对象设计 让你了解C#的面向对象的设计原理 更好的掌握C#的学习 真正的成为C#高手
一本很不错的讲面向对象的书,给大家分享下 !
指针的本质、指针的三要素、类型与变量名
幼儿园大班歌唱教案:戏说脸谱.doc
简单明了的解释 很实用
1.使用轻松的方式解释23种设计模式,很容易理解
戏说面向对象程序设计(C#版)面向对象程序设计(C#版)
戏说国学.doc
戏说绩效工资.doc
幼儿园教案2021-幼儿园大班歌唱教案:戏说脸谱.doc
戏说面向对象程序设计之C#版,适合初学者的再进一步学习,里面包含了一些设计模式,如工厂模式等,内容轻松幽默,适合初学者和有一定面向对象基础的对象,推荐阅读。
戏说信号与系统,大家可以参考一下,很浅显易懂