Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

USB: remove CONFIG_USB_PERSIST setting

This patch (as1047) removes the USB_PERSIST Kconfig option, enabling
it permanently. It also prevents the power/persist attribute from
being created for hub devices; there's no point in having it since
USB-PERSIST is always turned on for hubs.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

authored by

Alan Stern and committed by
Greg Kroah-Hartman
feccc30d 5e6effae

+53 -81
+19 -16
Documentation/usb/persist.txt
··· 2 2 3 3 Alan Stern <stern@rowland.harvard.edu> 4 4 5 - September 2, 2006 (Updated May 29, 2007) 5 + September 2, 2006 (Updated February 25, 2008) 6 6 7 7 8 8 What is the problem? ··· 65 65 66 66 What is the solution? 67 67 68 - Setting CONFIG_USB_PERSIST will cause the kernel to work around these 69 - issues. It enables a mode in which the core USB device data 70 - structures are allowed to persist across a power-session disruption. 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 + 71 72 It works like this. If the kernel sees that a USB host controller is 72 73 not in the expected state during resume (i.e., if the controller was 73 74 reset or otherwise had lost power) then it applies a persistence check ··· 81 80 same descriptors as before, including the Vendor and Product IDs, then 82 81 the kernel continues to use the same device structure. In effect, the 83 82 kernel treats the device as though it had merely been reset instead of 84 - unplugged. 83 + unplugged. The same thing happens if the host controller is in the 84 + expected state but a USB device was unplugged and then replugged. 85 85 86 86 If no device is now attached to the port, or if the descriptors are 87 87 different from what the kernel remembers, then the treatment is what 88 88 you would expect. The kernel destroys the old device structure and 89 89 behaves as though the old device had been unplugged and a new device 90 - plugged in, just as it would without the CONFIG_USB_PERSIST option. 90 + plugged in. 91 91 92 92 The end result is that the USB device remains available and usable. 93 93 Filesystem mounts and memory mappings are unaffected, and the world is 94 94 now a good and happy place. 95 95 96 - Note that even when CONFIG_USB_PERSIST is set, the "persist" feature 97 - will be applied only to those devices for which it is enabled. You 98 - can enable the feature by doing (as root): 96 + Note that the "USB-persist" feature will be applied only to those 97 + devices for which it is enabled. You can enable the feature by doing 98 + (as root): 99 99 100 100 echo 1 >/sys/bus/usb/devices/.../power/persist 101 101 102 102 where the "..." should be filled in the with the device's ID. Disable 103 103 the feature by writing 0 instead of 1. For hubs the feature is 104 - automatically and permanently enabled, so you only have to worry about 105 - setting it for devices where it really matters. 104 + automatically and permanently enabled and the power/persist file 105 + doesn't even exist, so you only have to worry about setting it for 106 + devices where it really matters. 106 107 107 108 108 109 Is this the best solution? ··· 115 112 to plug in a USB flash device, create a persistent volume associated 116 113 with it, unplug the flash device, plug it back in later, and still 117 114 have the same persistent volume associated with the device. As such 118 - it would be more far-reaching than CONFIG_USB_PERSIST. 115 + it would be more far-reaching than USB-persist. 119 116 120 117 On the other hand, writing a persistent volume manager would be a big 121 118 job and using it would require significant input from the user. This 122 119 solution is much quicker and easier -- and it exists now, a giant 123 120 point in its favor! 124 121 125 - Furthermore, the USB_PERSIST option applies to _all_ USB devices, not 122 + Furthermore, the USB-persist feature applies to _all_ USB devices, not 126 123 just mass-storage devices. It might turn out to be equally useful for 127 124 other device types, such as network interfaces. 128 125 129 126 130 - WARNING: Using CONFIG_USB_PERSIST can be dangerous!! 127 + WARNING: USB-persist can be dangerous!! 131 128 132 129 When recovering an interrupted power session the kernel does its best 133 130 to make sure the USB device hasn't been changed; that is, the same ··· 155 152 YOU HAVE BEEN WARNED! USE AT YOUR OWN RISK! 156 153 157 154 That having been said, most of the time there shouldn't be any trouble 158 - at all. The "persist" feature can be extremely useful. Make the most 159 - of it. 155 + at all. The USB-persist feature can be extremely useful. Make the 156 + most of it.
-25
drivers/usb/core/Kconfig
··· 102 102 103 103 If you are unsure about this, say N here. 104 104 105 - config USB_PERSIST 106 - bool "USB device persistence during system suspend (DANGEROUS)" 107 - depends on USB && PM && EXPERIMENTAL 108 - default n 109 - help 110 - 111 - If you say Y here and enable the "power/persist" attribute 112 - for a USB device, the device's data structures will remain 113 - persistent across system suspend, even if the USB bus loses 114 - power. (This includes hibernation, also known as swsusp or 115 - suspend-to-disk.) The devices will reappear as if by magic 116 - when the system wakes up, with no need to unmount USB 117 - filesystems, rmmod host-controller drivers, or do anything 118 - else. 119 - 120 - WARNING: This option can be dangerous! 121 - 122 - If a USB device is replaced by another of the same type while 123 - the system is asleep, there's a good chance the kernel won't 124 - detect the change. Likewise if the media in a USB storage 125 - device is replaced. When this happens it's almost certain to 126 - cause data corruption and maybe even crash your system. 127 - 128 - If you are unsure, say N here. 129 - 130 105 config USB_OTG 131 106 bool 132 107 depends on USB && EXPERIMENTAL
+10 -17
drivers/usb/core/hub.c
··· 30 30 #include "hcd.h" 31 31 #include "hub.h" 32 32 33 - #ifdef CONFIG_USB_PERSIST 34 - #define USB_PERSIST 1 35 - #else 36 - #define USB_PERSIST 0 37 - #endif 38 - 39 33 /* if we are in debug mode, always announce new devices */ 40 34 #ifdef DEBUG 41 35 #ifndef CONFIG_USB_ANNOUNCE_NEW_DEVICES ··· 689 695 * turn off the various status changes to prevent 690 696 * khubd from disconnecting it later. 691 697 */ 692 - if (USB_PERSIST && udev->persist_enabled && status == 0 && 698 + if (udev->persist_enabled && status == 0 && 693 699 !(portstatus & USB_PORT_STAT_ENABLE)) { 694 700 if (portchange & USB_PORT_STAT_C_ENABLE) 695 701 clear_port_feature(hub->hdev, port1, ··· 1917 1923 * the host and the device is the same as it was when the device 1918 1924 * suspended. 1919 1925 * 1920 - * If CONFIG_USB_PERSIST and @udev->reset_resume are both set then this 1921 - * routine won't check that the port is still enabled. Furthermore, 1922 - * if @udev->reset_resume is set then finish_port_resume() above will 1926 + * If @udev->reset_resume is set then this routine won't check that the 1927 + * port is still enabled. Furthermore, finish_port_resume() above will 1923 1928 * reset @udev. The end result is that a broken power session can be 1924 1929 * recovered and @udev will appear to persist across a loss of VBUS power. 1925 1930 * ··· 1930 1937 * to it will be lost. Using the USB_PERSIST facility, the device can be 1931 1938 * made to appear as if it had not disconnected. 1932 1939 * 1933 - * This facility is inherently dangerous. Although usb_reset_device() 1934 - * makes every effort to insure that the same device is present after the 1940 + * This facility can be dangerous. Although usb_reset_device() makes 1941 + * every effort to insure that the same device is present after the 1935 1942 * reset as before, it cannot provide a 100% guarantee. Furthermore it's 1936 1943 * quite possible for a device to remain unaltered but its media to be 1937 1944 * changed. If the user replaces a flash memory card while the system is ··· 1976 1983 status = hub_port_status(hub, port1, &portstatus, &portchange); 1977 1984 1978 1985 SuspendCleared: 1979 - if (USB_PERSIST && udev->reset_resume) 1986 + if (udev->reset_resume) 1980 1987 want_flags = USB_PORT_STAT_POWER 1981 1988 | USB_PORT_STAT_CONNECTION; 1982 1989 else ··· 2106 2113 * 2107 2114 * The USB host controller driver calls this function when its root hub 2108 2115 * is resumed and Vbus power has been interrupted or the controller 2109 - * has been reset. The routine marks @rhdev as having lost power. When 2110 - * the hub driver is resumed it will take notice; if CONFIG_USB_PERSIST 2111 - * is enabled then it will carry out power-session recovery, otherwise 2112 - * it will disconnect all the child devices. 2116 + * has been reset. The routine marks @rhdev as having lost power. 2117 + * When the hub driver is resumed it will take notice and carry out 2118 + * power-session recovery for all the "USB-PERSIST"-enabled child devices; 2119 + * the others will be disconnected. 2113 2120 */ 2114 2121 void usb_root_hub_lost_power(struct usb_device *rhdev) 2115 2122 {
+12
drivers/usb/core/quirks.c
··· 97 97 if (udev->descriptor.bDeviceClass != USB_CLASS_HUB) 98 98 udev->autosuspend_disabled = 1; 99 99 #endif 100 + 101 + #ifdef CONFIG_PM 102 + /* Hubs are automatically enabled for USB-PERSIST */ 103 + if (udev->descriptor.bDeviceClass == USB_CLASS_HUB) 104 + udev->persist_enabled = 1; 105 + #else 106 + /* In the absense of PM, we can safely enable USB-PERSIST 107 + * for all devices. It will affect things like hub resets 108 + * and EMF-related port disables. 109 + */ 110 + udev->persist_enabled = 1; 111 + #endif /* CONFIG_PM */ 100 112 }
+10 -12
drivers/usb/core/sysfs.c
··· 180 180 static DEVICE_ATTR(urbnum, S_IRUGO, show_urbnum, NULL); 181 181 182 182 183 - #if defined(CONFIG_USB_PERSIST) || defined(CONFIG_USB_SUSPEND) 184 - static const char power_group[] = "power"; 185 - #endif 183 + #ifdef CONFIG_PM 186 184 187 - #ifdef CONFIG_USB_PERSIST 185 + static const char power_group[] = "power"; 188 186 189 187 static ssize_t 190 188 show_persist(struct device *dev, struct device_attribute *attr, char *buf) ··· 220 222 if (is_usb_device(dev)) { 221 223 struct usb_device *udev = to_usb_device(dev); 222 224 223 - /* Hubs are automatically enabled for USB_PERSIST */ 224 - if (udev->descriptor.bDeviceClass == USB_CLASS_HUB) 225 - udev->persist_enabled = 1; 226 - rc = sysfs_add_file_to_group(&dev->kobj, 227 - &dev_attr_persist.attr, 228 - power_group); 225 + /* Hubs are automatically enabled for USB_PERSIST, 226 + * no point in creating the attribute file. 227 + */ 228 + if (udev->descriptor.bDeviceClass != USB_CLASS_HUB) 229 + rc = sysfs_add_file_to_group(&dev->kobj, 230 + &dev_attr_persist.attr, 231 + power_group); 229 232 } 230 233 return rc; 231 234 } ··· 237 238 &dev_attr_persist.attr, 238 239 power_group); 239 240 } 240 - 241 241 #else 242 242 243 243 #define add_persist_attributes(dev) 0 244 244 #define remove_persist_attributes(dev) do {} while (0) 245 245 246 - #endif /* CONFIG_USB_PERSIST */ 246 + #endif /* CONFIG_PM */ 247 247 248 248 #ifdef CONFIG_USB_SUSPEND 249 249
+1 -10
drivers/usb/host/ehci-hub.c
··· 28 28 29 29 /*-------------------------------------------------------------------------*/ 30 30 31 - #ifdef CONFIG_USB_PERSIST 31 + #ifdef CONFIG_PM 32 32 33 33 static int ehci_hub_control( 34 34 struct usb_hcd *hcd, ··· 103 103 104 104 ehci->owned_ports = 0; 105 105 } 106 - 107 - #else /* CONFIG_USB_PERSIST */ 108 - 109 - static inline void ehci_handover_companion_ports(struct ehci_hcd *ehci) 110 - { } 111 - 112 - #endif 113 - 114 - #ifdef CONFIG_PM 115 106 116 107 static int ehci_bus_suspend (struct usb_hcd *hcd) 117 108 {
+1 -1
include/linux/usb.h
··· 387 387 388 388 unsigned can_submit:1; /* URBs may be submitted */ 389 389 unsigned discon_suspended:1; /* Disconnected while suspended */ 390 + unsigned persist_enabled:1; /* USB_PERSIST enabled for this dev */ 390 391 unsigned have_langid:1; /* whether string_langid is valid */ 391 392 unsigned authorized:1; /* Policy has said we can use it */ 392 393 unsigned wusb:1; /* Device is Wireless USB */ ··· 434 433 unsigned auto_pm:1; /* autosuspend/resume in progress */ 435 434 unsigned do_remote_wakeup:1; /* remote wakeup should be enabled */ 436 435 unsigned reset_resume:1; /* needs reset instead of resume */ 437 - unsigned persist_enabled:1; /* USB_PERSIST enabled for this dev */ 438 436 unsigned autosuspend_disabled:1; /* autosuspend and autoresume */ 439 437 unsigned autoresume_disabled:1; /* disabled by the user */ 440 438 unsigned skip_sys_resume:1; /* skip the next system resume */