1*4882a593Smuzhiyun.. _usb-persist: 2*4882a593Smuzhiyun 3*4882a593SmuzhiyunUSB device persistence during system suspend 4*4882a593Smuzhiyun~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 5*4882a593Smuzhiyun 6*4882a593Smuzhiyun:Author: Alan Stern <stern@rowland.harvard.edu> 7*4882a593Smuzhiyun:Date: September 2, 2006 (Updated February 25, 2008) 8*4882a593Smuzhiyun 9*4882a593Smuzhiyun 10*4882a593SmuzhiyunWhat is the problem? 11*4882a593Smuzhiyun==================== 12*4882a593Smuzhiyun 13*4882a593SmuzhiyunAccording to the USB specification, when a USB bus is suspended the 14*4882a593Smuzhiyunbus must continue to supply suspend current (around 1-5 mA). This 15*4882a593Smuzhiyunis so that devices can maintain their internal state and hubs can 16*4882a593Smuzhiyundetect connect-change events (devices being plugged in or unplugged). 17*4882a593SmuzhiyunThe technical term is "power session". 18*4882a593Smuzhiyun 19*4882a593SmuzhiyunIf a USB device's power session is interrupted then the system is 20*4882a593Smuzhiyunrequired to behave as though the device has been unplugged. It's a 21*4882a593Smuzhiyunconservative approach; in the absence of suspend current the computer 22*4882a593Smuzhiyunhas no way to know what has actually happened. Perhaps the same 23*4882a593Smuzhiyundevice is still attached or perhaps it was removed and a different 24*4882a593Smuzhiyundevice plugged into the port. The system must assume the worst. 25*4882a593Smuzhiyun 26*4882a593SmuzhiyunBy default, Linux behaves according to the spec. If a USB host 27*4882a593Smuzhiyuncontroller loses power during a system suspend, then when the system 28*4882a593Smuzhiyunwakes up all the devices attached to that controller are treated as 29*4882a593Smuzhiyunthough they had disconnected. This is always safe and it is the 30*4882a593Smuzhiyun"officially correct" thing to do. 31*4882a593Smuzhiyun 32*4882a593SmuzhiyunFor many sorts of devices this behavior doesn't matter in the least. 33*4882a593SmuzhiyunIf the kernel wants to believe that your USB keyboard was unplugged 34*4882a593Smuzhiyunwhile the system was asleep and a new keyboard was plugged in when the 35*4882a593Smuzhiyunsystem woke up, who cares? It'll still work the same when you type on 36*4882a593Smuzhiyunit. 37*4882a593Smuzhiyun 38*4882a593SmuzhiyunUnfortunately problems _can_ arise, particularly with mass-storage 39*4882a593Smuzhiyundevices. The effect is exactly the same as if the device really had 40*4882a593Smuzhiyunbeen unplugged while the system was suspended. If you had a mounted 41*4882a593Smuzhiyunfilesystem on the device, you're out of luck -- everything in that 42*4882a593Smuzhiyunfilesystem is now inaccessible. This is especially annoying if your 43*4882a593Smuzhiyunroot filesystem was located on the device, since your system will 44*4882a593Smuzhiyuninstantly crash. 45*4882a593Smuzhiyun 46*4882a593SmuzhiyunLoss of power isn't the only mechanism to worry about. Anything that 47*4882a593Smuzhiyuninterrupts a power session will have the same effect. For example, 48*4882a593Smuzhiyuneven though suspend current may have been maintained while the system 49*4882a593Smuzhiyunwas asleep, on many systems during the initial stages of wakeup the 50*4882a593Smuzhiyunfirmware (i.e., the BIOS) resets the motherboard's USB host 51*4882a593Smuzhiyuncontrollers. Result: all the power sessions are destroyed and again 52*4882a593Smuzhiyunit's as though you had unplugged all the USB devices. Yes, it's 53*4882a593Smuzhiyunentirely the BIOS's fault, but that doesn't do _you_ any good unless 54*4882a593Smuzhiyunyou can convince the BIOS supplier to fix the problem (lots of luck!). 55*4882a593Smuzhiyun 56*4882a593SmuzhiyunOn many systems the USB host controllers will get reset after a 57*4882a593Smuzhiyunsuspend-to-RAM. On almost all systems, no suspend current is 58*4882a593Smuzhiyunavailable during hibernation (also known as swsusp or suspend-to-disk). 59*4882a593SmuzhiyunYou can check the kernel log after resuming to see if either of these 60*4882a593Smuzhiyunhas happened; look for lines saying "root hub lost power or was reset". 61*4882a593Smuzhiyun 62*4882a593SmuzhiyunIn practice, people are forced to unmount any filesystems on a USB 63*4882a593Smuzhiyundevice before suspending. If the root filesystem is on a USB device, 64*4882a593Smuzhiyunthe system can't be suspended at all. (All right, it _can_ be 65*4882a593Smuzhiyunsuspended -- but it will crash as soon as it wakes up, which isn't 66*4882a593Smuzhiyunmuch better.) 67*4882a593Smuzhiyun 68*4882a593Smuzhiyun 69*4882a593SmuzhiyunWhat is the solution? 70*4882a593Smuzhiyun===================== 71*4882a593Smuzhiyun 72*4882a593SmuzhiyunThe kernel includes a feature called USB-persist. It tries to work 73*4882a593Smuzhiyunaround these issues by allowing the core USB device data structures to 74*4882a593Smuzhiyunpersist across a power-session disruption. 75*4882a593Smuzhiyun 76*4882a593SmuzhiyunIt works like this. If the kernel sees that a USB host controller is 77*4882a593Smuzhiyunnot in the expected state during resume (i.e., if the controller was 78*4882a593Smuzhiyunreset or otherwise had lost power) then it applies a persistence check 79*4882a593Smuzhiyunto each of the USB devices below that controller for which the 80*4882a593Smuzhiyun"persist" attribute is set. It doesn't try to resume the device; that 81*4882a593Smuzhiyuncan't work once the power session is gone. Instead it issues a USB 82*4882a593Smuzhiyunport reset and then re-enumerates the device. (This is exactly the 83*4882a593Smuzhiyunsame thing that happens whenever a USB device is reset.) If the 84*4882a593Smuzhiyunre-enumeration shows that the device now attached to that port has the 85*4882a593Smuzhiyunsame descriptors as before, including the Vendor and Product IDs, then 86*4882a593Smuzhiyunthe kernel continues to use the same device structure. In effect, the 87*4882a593Smuzhiyunkernel treats the device as though it had merely been reset instead of 88*4882a593Smuzhiyununplugged. 89*4882a593Smuzhiyun 90*4882a593SmuzhiyunThe same thing happens if the host controller is in the expected state 91*4882a593Smuzhiyunbut a USB device was unplugged and then replugged, or if a USB device 92*4882a593Smuzhiyunfails to carry out a normal resume. 93*4882a593Smuzhiyun 94*4882a593SmuzhiyunIf no device is now attached to the port, or if the descriptors are 95*4882a593Smuzhiyundifferent from what the kernel remembers, then the treatment is what 96*4882a593Smuzhiyunyou would expect. The kernel destroys the old device structure and 97*4882a593Smuzhiyunbehaves as though the old device had been unplugged and a new device 98*4882a593Smuzhiyunplugged in. 99*4882a593Smuzhiyun 100*4882a593SmuzhiyunThe end result is that the USB device remains available and usable. 101*4882a593SmuzhiyunFilesystem mounts and memory mappings are unaffected, and the world is 102*4882a593Smuzhiyunnow a good and happy place. 103*4882a593Smuzhiyun 104*4882a593SmuzhiyunNote that the "USB-persist" feature will be applied only to those 105*4882a593Smuzhiyundevices for which it is enabled. You can enable the feature by doing 106*4882a593Smuzhiyun(as root):: 107*4882a593Smuzhiyun 108*4882a593Smuzhiyun echo 1 >/sys/bus/usb/devices/.../power/persist 109*4882a593Smuzhiyun 110*4882a593Smuzhiyunwhere the "..." should be filled in the with the device's ID. Disable 111*4882a593Smuzhiyunthe feature by writing 0 instead of 1. For hubs the feature is 112*4882a593Smuzhiyunautomatically and permanently enabled and the power/persist file 113*4882a593Smuzhiyundoesn't even exist, so you only have to worry about setting it for 114*4882a593Smuzhiyundevices where it really matters. 115*4882a593Smuzhiyun 116*4882a593Smuzhiyun 117*4882a593SmuzhiyunIs this the best solution? 118*4882a593Smuzhiyun========================== 119*4882a593Smuzhiyun 120*4882a593SmuzhiyunPerhaps not. Arguably, keeping track of mounted filesystems and 121*4882a593Smuzhiyunmemory mappings across device disconnects should be handled by a 122*4882a593Smuzhiyuncentralized Logical Volume Manager. Such a solution would allow you 123*4882a593Smuzhiyunto plug in a USB flash device, create a persistent volume associated 124*4882a593Smuzhiyunwith it, unplug the flash device, plug it back in later, and still 125*4882a593Smuzhiyunhave the same persistent volume associated with the device. As such 126*4882a593Smuzhiyunit would be more far-reaching than USB-persist. 127*4882a593Smuzhiyun 128*4882a593SmuzhiyunOn the other hand, writing a persistent volume manager would be a big 129*4882a593Smuzhiyunjob and using it would require significant input from the user. This 130*4882a593Smuzhiyunsolution is much quicker and easier -- and it exists now, a giant 131*4882a593Smuzhiyunpoint in its favor! 132*4882a593Smuzhiyun 133*4882a593SmuzhiyunFurthermore, the USB-persist feature applies to _all_ USB devices, not 134*4882a593Smuzhiyunjust mass-storage devices. It might turn out to be equally useful for 135*4882a593Smuzhiyunother device types, such as network interfaces. 136*4882a593Smuzhiyun 137*4882a593Smuzhiyun 138*4882a593SmuzhiyunWARNING: USB-persist can be dangerous!! 139*4882a593Smuzhiyun======================================= 140*4882a593Smuzhiyun 141*4882a593SmuzhiyunWhen recovering an interrupted power session the kernel does its best 142*4882a593Smuzhiyunto make sure the USB device hasn't been changed; that is, the same 143*4882a593Smuzhiyundevice is still plugged into the port as before. But the checks 144*4882a593Smuzhiyunaren't guaranteed to be 100% accurate. 145*4882a593Smuzhiyun 146*4882a593SmuzhiyunIf you replace one USB device with another of the same type (same 147*4882a593Smuzhiyunmanufacturer, same IDs, and so on) there's an excellent chance the 148*4882a593Smuzhiyunkernel won't detect the change. The serial number string and other 149*4882a593Smuzhiyundescriptors are compared with the kernel's stored values, but this 150*4882a593Smuzhiyunmight not help since manufacturers frequently omit serial numbers 151*4882a593Smuzhiyunentirely in their devices. 152*4882a593Smuzhiyun 153*4882a593SmuzhiyunFurthermore it's quite possible to leave a USB device exactly the same 154*4882a593Smuzhiyunwhile changing its media. If you replace the flash memory card in a 155*4882a593SmuzhiyunUSB card reader while the system is asleep, the kernel will have no 156*4882a593Smuzhiyunway to know you did it. The kernel will assume that nothing has 157*4882a593Smuzhiyunhappened and will continue to use the partition tables, inodes, and 158*4882a593Smuzhiyunmemory mappings for the old card. 159*4882a593Smuzhiyun 160*4882a593SmuzhiyunIf the kernel gets fooled in this way, it's almost certain to cause 161*4882a593Smuzhiyundata corruption and to crash your system. You'll have no one to blame 162*4882a593Smuzhiyunbut yourself. 163*4882a593Smuzhiyun 164*4882a593SmuzhiyunFor those devices with avoid_reset_quirk attribute being set, persist 165*4882a593Smuzhiyunmaybe fail because they may morph after reset. 166*4882a593Smuzhiyun 167*4882a593SmuzhiyunYOU HAVE BEEN WARNED! USE AT YOUR OWN RISK! 168*4882a593Smuzhiyun 169*4882a593SmuzhiyunThat having been said, most of the time there shouldn't be any trouble 170*4882a593Smuzhiyunat all. The USB-persist feature can be extremely useful. Make the 171*4882a593Smuzhiyunmost of it. 172