| Alan Stern | 0458d5b | 2007-05-04 11:52:20 -0400 | [diff] [blame] | 1 | 		USB device persistence during system suspend | 
 | 2 |  | 
 | 3 | 		   Alan Stern <stern@rowland.harvard.edu> | 
 | 4 |  | 
| Alan Stern | feccc30 | 2008-03-03 15:15:59 -0500 | [diff] [blame] | 5 | 		September 2, 2006 (Updated February 25, 2008) | 
| Alan Stern | 0458d5b | 2007-05-04 11:52:20 -0400 | [diff] [blame] | 6 |  | 
 | 7 |  | 
 | 8 | 	What is the problem? | 
 | 9 |  | 
 | 10 | According to the USB specification, when a USB bus is suspended the | 
 | 11 | bus must continue to supply suspend current (around 1-5 mA).  This | 
 | 12 | is so that devices can maintain their internal state and hubs can | 
 | 13 | detect connect-change events (devices being plugged in or unplugged). | 
 | 14 | The technical term is "power session". | 
 | 15 |  | 
 | 16 | If a USB device's power session is interrupted then the system is | 
 | 17 | required to behave as though the device has been unplugged.  It's a | 
 | 18 | conservative approach; in the absence of suspend current the computer | 
 | 19 | has no way to know what has actually happened.  Perhaps the same | 
 | 20 | device is still attached or perhaps it was removed and a different | 
 | 21 | device plugged into the port.  The system must assume the worst. | 
 | 22 |  | 
 | 23 | By default, Linux behaves according to the spec.  If a USB host | 
 | 24 | controller loses power during a system suspend, then when the system | 
 | 25 | wakes up all the devices attached to that controller are treated as | 
 | 26 | though they had disconnected.  This is always safe and it is the | 
 | 27 | "officially correct" thing to do. | 
 | 28 |  | 
 | 29 | For many sorts of devices this behavior doesn't matter in the least. | 
 | 30 | If the kernel wants to believe that your USB keyboard was unplugged | 
 | 31 | while the system was asleep and a new keyboard was plugged in when the | 
 | 32 | system woke up, who cares?  It'll still work the same when you type on | 
 | 33 | it. | 
 | 34 |  | 
 | 35 | Unfortunately problems _can_ arise, particularly with mass-storage | 
 | 36 | devices.  The effect is exactly the same as if the device really had | 
 | 37 | been unplugged while the system was suspended.  If you had a mounted | 
 | 38 | filesystem on the device, you're out of luck -- everything in that | 
 | 39 | filesystem is now inaccessible.  This is especially annoying if your | 
 | 40 | root filesystem was located on the device, since your system will | 
 | 41 | instantly crash. | 
 | 42 |  | 
 | 43 | Loss of power isn't the only mechanism to worry about.  Anything that | 
 | 44 | interrupts a power session will have the same effect.  For example, | 
 | 45 | even though suspend current may have been maintained while the system | 
 | 46 | was asleep, on many systems during the initial stages of wakeup the | 
 | 47 | firmware (i.e., the BIOS) resets the motherboard's USB host | 
 | 48 | controllers.  Result: all the power sessions are destroyed and again | 
 | 49 | it's as though you had unplugged all the USB devices.  Yes, it's | 
 | 50 | entirely the BIOS's fault, but that doesn't do _you_ any good unless | 
 | 51 | you can convince the BIOS supplier to fix the problem (lots of luck!). | 
 | 52 |  | 
 | 53 | On many systems the USB host controllers will get reset after a | 
 | 54 | suspend-to-RAM.  On almost all systems, no suspend current is | 
| Alan Stern | b41a60e | 2007-05-30 15:39:33 -0400 | [diff] [blame] | 55 | available during hibernation (also known as swsusp or suspend-to-disk). | 
 | 56 | You can check the kernel log after resuming to see if either of these | 
 | 57 | has happened; look for lines saying "root hub lost power or was reset". | 
| Alan Stern | 0458d5b | 2007-05-04 11:52:20 -0400 | [diff] [blame] | 58 |  | 
 | 59 | In practice, people are forced to unmount any filesystems on a USB | 
 | 60 | device before suspending.  If the root filesystem is on a USB device, | 
 | 61 | the system can't be suspended at all.  (All right, it _can_ be | 
 | 62 | suspended -- but it will crash as soon as it wakes up, which isn't | 
 | 63 | much better.) | 
 | 64 |  | 
 | 65 |  | 
 | 66 | 	What is the solution? | 
 | 67 |  | 
| Alan Stern | feccc30 | 2008-03-03 15:15:59 -0500 | [diff] [blame] | 68 | The kernel includes a feature called USB-persist.  It tries to work | 
 | 69 | around these issues by allowing the core USB device data structures to | 
 | 70 | persist across a power-session disruption. | 
 | 71 |  | 
| Alan Stern | 0458d5b | 2007-05-04 11:52:20 -0400 | [diff] [blame] | 72 | It works like this.  If the kernel sees that a USB host controller is | 
 | 73 | not in the expected state during resume (i.e., if the controller was | 
 | 74 | reset or otherwise had lost power) then it applies a persistence check | 
| Alan Stern | b41a60e | 2007-05-30 15:39:33 -0400 | [diff] [blame] | 75 | to each of the USB devices below that controller for which the | 
 | 76 | "persist" attribute is set.  It doesn't try to resume the device; that | 
 | 77 | can't work once the power session is gone.  Instead it issues a USB | 
 | 78 | port reset and then re-enumerates the device.  (This is exactly the | 
 | 79 | same thing that happens whenever a USB device is reset.)  If the | 
 | 80 | re-enumeration shows that the device now attached to that port has the | 
 | 81 | same descriptors as before, including the Vendor and Product IDs, then | 
 | 82 | the kernel continues to use the same device structure.  In effect, the | 
 | 83 | kernel treats the device as though it had merely been reset instead of | 
| Alan Stern | 86c57ed | 2008-06-30 11:14:43 -0400 | [diff] [blame] | 84 | unplugged. | 
 | 85 |  | 
 | 86 | The same thing happens if the host controller is in the expected state | 
 | 87 | but a USB device was unplugged and then replugged, or if a USB device | 
 | 88 | fails to carry out a normal resume. | 
| Alan Stern | 0458d5b | 2007-05-04 11:52:20 -0400 | [diff] [blame] | 89 |  | 
 | 90 | If no device is now attached to the port, or if the descriptors are | 
 | 91 | different from what the kernel remembers, then the treatment is what | 
 | 92 | you would expect.  The kernel destroys the old device structure and | 
 | 93 | behaves as though the old device had been unplugged and a new device | 
| Alan Stern | feccc30 | 2008-03-03 15:15:59 -0500 | [diff] [blame] | 94 | plugged in. | 
| Alan Stern | 0458d5b | 2007-05-04 11:52:20 -0400 | [diff] [blame] | 95 |  | 
 | 96 | The end result is that the USB device remains available and usable. | 
 | 97 | Filesystem mounts and memory mappings are unaffected, and the world is | 
 | 98 | now a good and happy place. | 
 | 99 |  | 
| Alan Stern | feccc30 | 2008-03-03 15:15:59 -0500 | [diff] [blame] | 100 | Note that the "USB-persist" feature will be applied only to those | 
 | 101 | devices for which it is enabled.  You can enable the feature by doing | 
 | 102 | (as root): | 
| Alan Stern | b41a60e | 2007-05-30 15:39:33 -0400 | [diff] [blame] | 103 |  | 
 | 104 | 	echo 1 >/sys/bus/usb/devices/.../power/persist | 
 | 105 |  | 
 | 106 | where the "..." should be filled in the with the device's ID.  Disable | 
 | 107 | the feature by writing 0 instead of 1.  For hubs the feature is | 
| Alan Stern | feccc30 | 2008-03-03 15:15:59 -0500 | [diff] [blame] | 108 | automatically and permanently enabled and the power/persist file | 
 | 109 | doesn't even exist, so you only have to worry about setting it for | 
 | 110 | devices where it really matters. | 
| Alan Stern | b41a60e | 2007-05-30 15:39:33 -0400 | [diff] [blame] | 111 |  | 
| Alan Stern | 0458d5b | 2007-05-04 11:52:20 -0400 | [diff] [blame] | 112 |  | 
 | 113 | 	Is this the best solution? | 
 | 114 |  | 
 | 115 | Perhaps not.  Arguably, keeping track of mounted filesystems and | 
 | 116 | memory mappings across device disconnects should be handled by a | 
 | 117 | centralized Logical Volume Manager.  Such a solution would allow you | 
 | 118 | to plug in a USB flash device, create a persistent volume associated | 
 | 119 | with it, unplug the flash device, plug it back in later, and still | 
 | 120 | have the same persistent volume associated with the device.  As such | 
| Alan Stern | feccc30 | 2008-03-03 15:15:59 -0500 | [diff] [blame] | 121 | it would be more far-reaching than USB-persist. | 
| Alan Stern | 0458d5b | 2007-05-04 11:52:20 -0400 | [diff] [blame] | 122 |  | 
 | 123 | On the other hand, writing a persistent volume manager would be a big | 
 | 124 | job and using it would require significant input from the user.  This | 
 | 125 | solution is much quicker and easier -- and it exists now, a giant | 
 | 126 | point in its favor! | 
 | 127 |  | 
| Alan Stern | feccc30 | 2008-03-03 15:15:59 -0500 | [diff] [blame] | 128 | Furthermore, the USB-persist feature applies to _all_ USB devices, not | 
| Alan Stern | 0458d5b | 2007-05-04 11:52:20 -0400 | [diff] [blame] | 129 | just mass-storage devices.  It might turn out to be equally useful for | 
 | 130 | other device types, such as network interfaces. | 
 | 131 |  | 
 | 132 |  | 
| Alan Stern | feccc30 | 2008-03-03 15:15:59 -0500 | [diff] [blame] | 133 | 	WARNING: USB-persist can be dangerous!! | 
| Alan Stern | 0458d5b | 2007-05-04 11:52:20 -0400 | [diff] [blame] | 134 |  | 
 | 135 | When recovering an interrupted power session the kernel does its best | 
 | 136 | to make sure the USB device hasn't been changed; that is, the same | 
 | 137 | device is still plugged into the port as before.  But the checks | 
 | 138 | aren't guaranteed to be 100% accurate. | 
 | 139 |  | 
 | 140 | If you replace one USB device with another of the same type (same | 
 | 141 | manufacturer, same IDs, and so on) there's an excellent chance the | 
| Alan Stern | eb764c4 | 2008-03-03 15:16:04 -0500 | [diff] [blame] | 142 | kernel won't detect the change.  The serial number string and other | 
 | 143 | descriptors are compared with the kernel's stored values, but this | 
 | 144 | might not help since manufacturers frequently omit serial numbers | 
 | 145 | entirely in their devices. | 
| Alan Stern | 0458d5b | 2007-05-04 11:52:20 -0400 | [diff] [blame] | 146 |  | 
 | 147 | Furthermore it's quite possible to leave a USB device exactly the same | 
 | 148 | while changing its media.  If you replace the flash memory card in a | 
 | 149 | USB card reader while the system is asleep, the kernel will have no | 
 | 150 | way to know you did it.  The kernel will assume that nothing has | 
 | 151 | happened and will continue to use the partition tables, inodes, and | 
 | 152 | memory mappings for the old card. | 
 | 153 |  | 
 | 154 | If the kernel gets fooled in this way, it's almost certain to cause | 
 | 155 | data corruption and to crash your system.  You'll have no one to blame | 
 | 156 | but yourself. | 
 | 157 |  | 
 | 158 | YOU HAVE BEEN WARNED!  USE AT YOUR OWN RISK! | 
 | 159 |  | 
 | 160 | That having been said, most of the time there shouldn't be any trouble | 
| Alan Stern | feccc30 | 2008-03-03 15:15:59 -0500 | [diff] [blame] | 161 | at all.  The USB-persist feature can be extremely useful.  Make the | 
 | 162 | most of it. |