This howto describes how to reinitialize the state of a USB device without unplugging it. It does not work for USB devices not listed by “lsusb” command.

This howto is tested on:

  • Ubuntu 15.10 Wily Werewolf
  • Debian 10.0 Buster

Settings

Provide the search text identifying the USB device in “lsusb” command results (in this example, for Bluetooth receivers):

usbSearchString="Bluetooth"

Reset of the USB devices

Detect if sudo is available (“command” is used if not):

cmdProxy='command'
command type -f 'sudo' &>'/dev/null' && cmdProxy='sudo'

Fetch the complete USB ids of the chosen devices:

usbIds="$(command lsusb \
  | command egrep -i "${usbSearchString}" \
  | command cut -c 24-32)"

Detect the chosen USB devices ports:

declare -a usbInfos=()
for usbId in ${usbIds}; do
  idVendor="${usbId%:*}"
  idProduct="${usbId#*:}"
  while read idVendorPath; do
    devicePath="$(command dirname "${idVendorPath}")"
    if [[ -n "$(command grep "${idProduct}" "${devicePath}/idProduct")" ]]; then
      usbInfos+=("${usbId}|$(command basename "${devicePath}")")
    fi
  done <<<"$(command grep -l "${idVendor}" '/sys/bus/usb/devices/'*'/idVendor')"
done

Reset the USB devices by unbinding them from and then rebinding them to their kernel modules:

for usbInfo in "${usbInfos[@]}"; do
  usbId="${usbInfo%|*}"
  usbHwId="${usbInfo#*|}"
  if [[ -e "/sys/bus/usb/drivers/usb/${usbHwId}" ]]; then
    echo "Unbinding ${usbId}"
    echo " echo '${usbHwId}' > '/sys/bus/usb/drivers/usb/unbind'"
    echo "${usbHwId}" | ${cmdProxy} tee "/sys/bus/usb/drivers/usb/unbind" > '/dev/null'
  fi
  if [[ -n "${usbId}" && -e "/sys/bus/usb/drivers/usb/bind" ]]; then
    echo "Binding ${usbId} to ${driver}"
    echo " echo '${usbHwId}' > '/sys/bus/usb/drivers/usb/bind'"
    echo "${usbHwId}" | ${cmdProxy} tee "/sys/bus/usb/drivers/usb/bind" > '/dev/null'
  fi
  if [[ -e "/sys/bus/usb/devices/${usbHwId}" ]]; then
    echo "Get infos on ${usbId} with:"
    echo " udevadm info -p '/sys/bus/usb/devices/${usbHwId}'"
  fi
done

Check that the USB devices has been reset with dmesg:

${cmdProxy} dmesg

Thanks

Categories: Setup

2 Comments

Marc Ballat · March 15, 2023 at 9:04 pm

Thank you for your scripts. I think that there is a missing ‘done’ at the end of the reset script.

Kind regards.

Leave a Reply

Avatar placeholder

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.