From my understanding, if a USB host controller loses power (e.g. during a system syspend) then it is treated as if it has been unplugged. For devices like integrated webcams we know it cannot be unplugged, so we can enable USB persist.
USB host controllers can get reset after suspend to RAM on some systems, and you will see kernel messages such as "root hub lost power or was reset" (use dmesg to see this). In such cases, USB persist can save the day.
UBS persist keeps the USB device's core data structures persistent when power session disruption occurs. Essentially on resume the kernel checks if persist is set on the device, if so, it does a USB port reset, re-enumates and checks if the device is the same as the one before (e.g. checking descriptors and information such as produce and vendor IDs) it then re-uses the original device data structures.
USB persist for a device can be enables by echo'ing 1 to the devices persist file as root:
echo 1 >/sys/bus/usb/devices/.../power/persist
Below is a shell script to set USB persist for a device with a given IDVENDOR and IDPRODUCT USB ID.
#!/bin/sh
IDVENDOR=0123
IDPRODUCT=0afb
for I in /sys/bus/usb/devices/*/*
do
if [ -e $I/idVendor -a -e $I/idProduct ]; then
idvendor=`cat $I/idVendor`
idproduct=`cat $I/idProduct`
if [ x$idvendor = x$IDVENDOR -a x$idproduct = x$IDPRODUCT ]; then
if [ -e $I/../power/persist ]; then
echo 1 > $I/power/persist
fi
if [ -e $I/../power/persist ] ; then
echo 1 > $I/../power/persist
fi
fi
fi
done
Note that doing USB persist on pluggable USB devices is NOT recommended as it can cause kernel panics!
It seems that this behavior is now standard. For me it works very bad, as my logitech webcam is unusable after suspend..
ReplyDeleteSo i have to do the inverse of yours! But anyway, thanks for the script. :)