北大校长马寅初先生曾斩钉截铁地跟毛主席讲:”中国人口太多是因为农村晚上没有电.”
因此,为了支持计划生育这项基本国策,每一个男人都有义务认真看一下电源管理的代码.
另一方面,虽然现在已经不住在农村了,但我一直坚定不移的认为,这个世界,最慢的是我家的网速,最快的是我家电表的转速.
所以,为了了解如何让电表转速更慢,让我们一起来看看usb子系统里是如何支持电源管理的吧.
上节说了应该从usb_suspend/usb_resume开始看,那就开始吧.
usb_suspend/usb_resume这两个函数很显然是一对,但是我们不可能同时讲,只能一个一个来.倒不是故意把它们拆开,实在是没有办法.须知,形影不离并不代表相知相惜,感情在乎的是心与心的距离.两情若是久长时,又岂在朝朝暮暮. 先讲usb_suspend,再讲usb_resume.
来看usb_suspend,定义于drivers/usb/core/driver.c:
1497 static int usb_suspend(struct device *dev, pm_message_t message)
1498 {
1499 if (!is_usb_device(dev)) /* Ignore PM for interfaces */
1500 return 0;
1501 return usb_external_suspend_device(to_usb_device(dev), message);
1502 }
刚说过,usb_suspend是usb子系统提供给PM core调用的,所以这里两个参数dev/message都是那边传递过来的,要不是usb device当然就不用做什么了.直接返回.然后调用usb_external_suspend_device(),后者也是来自drivers/usb/core/driver.c.
1443 /**
1444 * usb_external_suspend_device - external suspend of a USB device and its interfaces
1445 * @udev: the usb_device to suspend
1446 * @msg: Power Management message describing this state transition
1447 *
1448 * This routine handles external suspend requests: ones not generated
1449 * internally by a USB driver (autosuspend) but rather coming from the user
1450 * (via sysfs) or the PM core (system sleep). The suspend will be carried
1451 * out regardless of @udev's usage counter or those of its interfaces,
1452 * and regardless of whether or not remote wakeup is enabled. Of course,
1453 * interface drivers still have the option of failing the suspend (if
1454 * there are unsuspended children, for example).
1455 *
1456 * The caller must hold @udev's device lock.
1457 */
1458 int usb_external_suspend_device(struct usb_device *udev, pm_message_t msg)
1459 {
1460 int status;
1461
1462 usb_pm_lock(udev);
1463 udev->auto_pm = 0;
1464 status = usb_suspend_both(udev, msg);
1465 usb_pm_unlock(udev);
1466 return status;
1467 }
1462行和1465行,锁的代码暂时先一律飘过.
我们看到,这个函数就做了两件事情,第一,让udev的auto_pm为0,第二,调用usb_suspend_both.
继续跟踪usb_suspend_both.仍然是来自于drivers/usb/core/driver.c:
993 /**
994 * usb_suspend_both - suspend a USB device and its interfaces
995 * @udev: the usb_device to suspend
996 * @msg: Power Management message describing this state transition
997 *
998 * This is the central routine for suspending USB devices. It calls the
999 * suspend methods for all the interface drivers in @udev and then calls
1000 * the suspend method for @udev itself. If an error occurs at any stage,
1001 * all the interfaces which were suspended are resumed so that they remain
1002 * in the same state as the device.
1003 *
1004 * If an autosuspend is in progress (@udev->auto_pm is set), the routine
1005 * checks first to make sure that neither the device itself or any of its
1006 * active interfaces is in use (pm_usage_cnt is greater than 0). If they
1007 * are, the autosuspend fails.
1008 *
1009 * If the suspend succeeds, the routine recursively queues an autosuspend
1010 * request for @udev's parent device, thereby propagating the change up
1011 * the device tree. If all of the parent's children are now suspended,
1012 * the parent will autosuspend in turn.
1013 *
1014 * The suspend method calls are subject to mutual exclusion under control
1015 * of @udev's pm_mutex. Many of these calls are also under the protection
1016 * of @udev's device lock (including all requests originating outside the
1017 * USB subsystem), but autosuspend requests generated by a child device or
1018 * interface driver may not be. Usbcore will insure that the method calls
1019 * do not arrive during bind, unbind, or reset operations. However, drivers
1020 * must be prepared to handle suspend calls arriving at unpredictable times.
1021 * The only way to block such calls is to do an autoresume (preventing
1022 * autosuspends) while holding @udev's device lock (preventing outside
1023 * suspends).
1024 *
1025 * The caller must hold @udev->pm_mutex.
1026 *
1027 * This routine can run only in process context.
1028 */
1029 static int usb_suspend_both(struct usb_device *udev, pm_message_t msg)
1030 {
1031 int status = 0;
1032 int i = 0;
1033 struct usb_interface *intf;
1034 struct usb_device *parent = udev->parent;
1035
1036 if (udev->state == USB_STATE_NOTATTACHED ||
1037 udev->state == USB_STATE_SUSPENDED)
1038 goto done;
1039
1040 udev->do_remote_wakeup = device_may_wakeup(&udev->dev);
1041
1042 if (udev->auto_pm) {
1043 status = autosuspend_check(udev);
1044 if (status < 0)
1045 goto done;
1046 }
1047
1048 /* Suspend all the interfaces and then udev itself */
1049 if (udev->actconfig) {
1050 for (; i < udev->actconfig->desc.bNumInterfaces; i++) {
1051 intf = udev->actconfig->interface[i];
1052 status = usb_suspend_interface(intf, msg);
1053 if (status != 0)
1054 break;
1055 }
1056 }
1057 if (status == 0)
1058 status = usb_suspend_device(udev, msg);
1059
1060 /* If the suspend failed, resume interfaces that did get suspended */
1061 if (status != 0) {
1062 while (--i >= 0) {
1063 intf = udev->actconfig->interface[i];
1064 usb_resume_interface(intf);
1065 }
1066
1067 /* Try another autosuspend when the interfaces aren't busy */
1068 if (udev->auto_pm)
1069 autosuspend_check(udev);
1070
1071 /* If the suspend succeeded, propagate it up the tree */
1072 } else {
1073 cancel_delayed_work(&udev->autosuspend);
1074 if (parent)
1075 usb_autosuspend_device(parent);
1076 }
1077
1078 done:
1079 // dev_dbg(&udev->dev, "%s: status %d/n", __FUNCTION__, status);
1080 return status;
1081 }
这里有两个重要的概念,autosuspend/autoresume.autosuspend,即自动挂起,这是由driver自行决定,它自己进行判断,当它觉得应该挂起设备的时候,它就会去Just do it!关于autosuspend我们后面会讲.
1040行, device_may_wakeup(),我们前面说过,设备有没有被唤醒的能力有一个flag可以标志,即can_wakeup,那么如果有这种能力,用户仍然可以根据实际需要关掉这种能力,或者打开这种能力,这就体现在sysfs下的一个文件.比如:
localhost:~ # cat /sys/bus/usb/devices/1-5/power/wakeup
enabled
localhost:~ # cat /sys/bus/usb/devices/1-5/:1.0/power/wakeup
localhost:~ #
可以看到后者的输出值为空,这说明该设备是不支持remote wakeup的,换句话说,其can_wakeup也应该是设置为了0,这种情况device_may_wakeup返回值必然是false,而前者的输出值为enabled,说明该设备是支持remote wakeup的,并且此刻remote wakeup的特性是打开的.别的设备也一样,用户可以通过sysfs来进行设置,你可以把wakeup从enabled改为disabled.
为什么需要有这么一个sysfs的接口呢?我们知道usb设备有一种特性,叫做remote wakeup,这种特性不是每个usb设备都支持