USB Core 十

 

int usb_register_device_driver(struct usb_device_driver *new_udriver,
 struct module *owner)
 {
 int retval = 0;

 if (usb_disabled())//判断一下usb 子系统是不是在你启动内核的时候就被禁止了
 return -ENODEV;

 new_udriver->drvwrap.for_devices = 1;//for_devices就是在这儿被初始化为1 的
/*name 就是usb_generic_driver 的名字,即usb,所属的总线类型同样被设置为usb_bus_type,然后是指定probe 函数和remove 函数。
*/
 new_udriver->drvwrap.driver.name = (char *) new_udriver->name;
 new_udriver->drvwrap.driver.bus = &usb_bus_type;
 new_udriver->drvwrap.driver.probe = usb_probe_device;//usb_generic_driver 和usb 设备匹配成功后,就会调用682 行指定的probe 函数usb_probe_device(),
 new_udriver->drvwrap.driver.remove = usb_unbind_device;
 new_udriver->drvwrap.driver.owner = owner;

 retval = driver_register(&new_udriver->drvwrap.driver);//调用设备模型的函数driver_register 将usb_generic_driver 添加到usb 总线的那条驱动链表里,

	 if (!retval) {
 		pr_info("%s: registered new device driver %s\n",
 		usbcore_name, new_udriver->name);
 		usbfs_update_special();
	 } else {
 		printk(KERN_ERR "%s: error %d registering device "
 		" driver %s\n",
		 usbcore_name, retval, new_udriver->name);
 	}

 return retval;
 }
static int usb_probe_device(struct device *dev)
{
 struct usb_device_driver *udriver =to_usb_device_driver(dev->driver);
 struct usb_device *udev;
 int error = -ENODEV;

 dev_dbg(dev, "%s\n", __FUNCTION__);

 if (!is_usb_device(dev)) /* Sanity check */
 return error;

 udev = to_usb_device(dev);

 /* TODO: Add real matching code */
/*
提到pm_usage_cnt 时说只有它为0 时才会允许接口autosuspend,提到supports_autosuspend时说如果它为0 就不再允许绑定到这个驱动的接口autosuspend.但是不是说这里将pm_usage_cnt 轻轻松松置为0,设备就能够autosuspend 了,,驱动必须得实现一对儿suspend/resume 函数供PM 子系统那块驱使,usb_generic_driver 里的这对函数就是generic_suspend/generic_resume。此处不是久留之地,就不多说它们了.
*/
 udev->pm_usage_cnt = !(udriver->supports_autosuspend);

 error = udriver->probe(udev);//执行generic_probe()函数
 return error;
 }

//用一句话去概括它的中心思想,就是从设备可能的众多配置中选择一个合适的,然后去配置设备,从而让设备进入期待已久的Configured 状态。
static int generic_probe(struct usb_device *udev)
 {
 int err, c;

 /* put device-specific files into sysfs */
 usb_create_sysfs_dev_files(udev);

 /* Choose and set the configuration. This registers the interfaces
 * with the driver core and lets interface drivers bind to them.
 */
 c = choose_configuration(udev);
 	if (c >= 0) {
 		err = usb_set_configuration(udev, c);
 	if (err) {
		 dev_err(&udev->dev, "can't set config #%d, error
		%d\n",
 		c, err);
 /* This need not be fatal. The user can try to
 * set other configurations. */
 	}
 }

 /* USB device state == configured ... usable */
 usb_notify_add_device(udev);

 return 0;
}

static int choose_configuration(struct usb_device *udev)
{
 int i;
 int num_configs;
 int insufficient_power = 0;
 struct usb_host_config *c, *best;

 best = NULL;
 c = udev->config;

 num_configs = udev->descriptor.bNumConfigurations;
 for (i = 0; i < num_configs; (i++, c++)) {
 struct usb_interface_descriptor *desc = NULL;

 /* It's possible that a config has no interfaces! */
 if (c->desc.bNumInterfaces > 0)
 desc = &c->intf_cache[0]->altsetting->desc;

 /*
 * HP's USB bus-powered keyboard has only one configuration
 * and it claims to be self-powered; other devices may have
 * similar errors in their descriptors. If the next test
 * were allowed to execute, such configurations would always
 * be rejected and the devices would not work as expected.
 * In the meantime, we run the risk of selecting a config
 * that requires external power at a time when that power
 * isn't available. It seems to be the lesser of two evils.
 *
 * Bugzilla #6448 reports a device that appears to crash
 * when it receives a GET_DEVICE_STATUS request! We don't
 * have any other way to tell whether a device is self-powered,
 * but since we don't use that information anywhere but here,
 * the call has been removed.
 *
 * Maybe the GET_DEVICE_STATUS call and the test below can
 * be reinstated when device firmwares become more reliable.
 * Don't hold your breath.
 */
 #if 0
 /* Rule out self-powered configs for a bus-powered device */
 if (bus_powered && (c->desc.bmAttributes &
 USB_CONFIG_ATT_SELFPOWER))
 continue;
 #endif

 /*
 * The next test may not be as effective as it should be.
 * Some hubs have errors in their descriptor, claiming
 * to be self-powered when they are really bus-powered.
 * We will overestimate the amount of current such hubs
 * make available for each port.
 *
 * This is a fairly benign sort of failure. It won't
 * cause us to reject configurations that we should have

 * accepted.
 */

 /* Rule out configs that draw too much bus current */
//一个配置索取的电流比hub 所能给予的还要大,显然它不会是一个让人满意的配置。
 if (c->desc.bMaxPower * 2 > udev->bus_mA) {
 insufficient_power++;
 continue;
 }

 /* When the first config's first interface is one of Microsoft's
 * pet nonstandard Ethernet-over-USB protocols, ignore it unless
 * this kernel has enabled the necessary host side driver.
 */
 if (i == 0 && desc && (is_rndis(desc) || is_activesync(desc)))
{
 #if !defined(CONFIG_USB_NET_RNDIS_HOST)&& !defined(CONFIG_USB_NET_RNDIS_HOST_MODULE)
 continue;
 #else
 best = c;
 #endif
 }

 /* From the remaining configs, choose the first one whose
 * first interface is for a non-vendor-specific class.
 * Reason: Linux is more likely to have a class driver
 * than a vendor-specific driver. */
 else if (udev->descriptor.bDeviceClass !=
 USB_CLASS_VENDOR_SPEC &&
 (!desc || desc->bInterfaceClass !=
 USB_CLASS_VENDOR_SPEC)) {
 best = c;
 break;
 }

 /* If all the remaining configs are vendor-specific,
 * choose the first one. */
 else if (!best)
 best = c;
 }

 if (insufficient_power > 0)
 dev_info(&udev->dev, "rejected %d configuration%s "

 "due to insufficient available bus power\n",
 insufficient_power, plural(insufficient_power));

 if (best) {
 i = best->desc.bConfigurationValue;
 dev_info(&udev->dev,
 "configuration #%d chosen from %d choice%s\n",
 i, num_configs, plural(num_configs));
 } else {
 i = -1;
 dev_warn(&udev->dev,
 "no configuration chosen from %d choice%s\n",
 num_configs, plural(num_configs));
 }
 return i;
 }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值