xref: /OK3568_Linux_fs/kernel/Documentation/driver-api/usb/persist.rst (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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