Skip to content

USB Reset

kpine edited this page May 5, 2022 · 4 revisions

Resetting a USB device

There are several ways to perform a USB reset. Note that all commands that install software and modify the USB device will require root or sudo access.

usbreset utility

If you run a Debian-based OS, chances are you already have the usbreset utility installed (from usbutils). If not, it can be installed via:

$ sudo apt install -y usbutils

Run the command without options to see example usage:

$ usbreset
Usage:
  usbreset PPPP:VVVV - reset by product and vendor id
  usbreset BBB/DDD   - reset by bus and device number
  usbreset "Product" - reset by product name

Devices:
  Number 001/004  ID 04f2:b452  HD WebCam
  Number 001/003  ID 8087:07dc
  Number 001/063  ID 10c4:ea60  CP2102N USB to UART Bridge Controller

It lists the currently connected USB devices. In this case, the CP2102N USB to UART Bridge Controller device is the USB Z-Wave controller. Reset it via one of the suggested commands (here using bus and device number):

$ sudo usbreset 001/063
Resetting CP2102N USB to UART Bridge Controller ... ok

If you're watching dmesg you'll see messages indicating the reset occurred:

$ sudo dmesg -e -w
[May 4 17:43] cp210x ttyUSB0: cp210x converter now disconnected from ttyUSB0
[  +0.000236] cp210x 1-2:1.0: device disconnected
[  +0.131520] usb 1-2: reset full-speed USB device number 63 using xhci_hcd
[  +0.150865] cp210x 1-2:1.0: cp210x converter detected
[  +0.002730] usb 1-2: cp210x converter now attached to ttyUSB0

USB driver unbind/bind

Unbinding and re-binding the USB driver will disconnect and reconnect the USB device.

First find the bus id of the USB stick, specifying its device path (/dev/ttyUSB0 here):

$ udevadm info -q all /dev/ttyUSB0 | grep DEVPATH
E: DEVPATH=/devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.4/1-1.4:1.0/ttyUSB0/tty/ttyUSB0

In the above example, the bus id is 1-1.4. You can confirm this by listing the usb driver path, where we see 1-1.4.

$ ls /sys/bus/usb/drivers/usb
1-1  1-1.3  1-1.4  2-2  bind  uevent  unbind  usb1  usb2

These paths will vary by platform, Z-Wave controller, which port the controller is plugged into, etc.

Remove

To remove, or unbind the device, write the bus id to the unbind file:

$ echo "1-1.4" | sudo tee /sys/bus/usb/drivers/usb/unbind

If you're watching the system logs or dmesg, you might see something like this:

[1020191.886070] cp210x ttyUSB0: cp210x converter now disconnected from ttyUSB0
[1020191.887599] cp210x 1-1.4:1.0: device disconnected

Or you might not see anything. The above message was displayed for a 700-series controller, while a 500-series did not log anything. The device path /dev/ttyUSB0 will no longer be present.

Add

To re-add, or bind the device, write the bus id to the bind file:

$ echo "1-1.4" | sudo tee /sys/bus/usb/drivers/usb/bind

dmesg showed:

[1020740.342487] cp210x 1-1.4:1.0: cp210x converter detected
[1020740.355019] usb 1-1.4: cp210x converter now attached to ttyUSB0

The device path /dev/ttyUSB0 will be present again.

Soft resetting a Z-Wave controller with the Serial API

The Z-Wave Serial API defines a command to perform a soft reset. This command is required prior to performing some device actions such as changing the RF region or restoring an NVM backup.

You can send a reset command by directly writing it to the serial port.

$ printf '\x01\x03\x00\x08\xf4' > /dev/ttyACM0

In the case of the UZB3 (Silicon Labs 500-series controller) this results in the USB device being removed and added.

[3870490.095837] usb 1-3: USB disconnect, device number 41
[3870490.407383] usb 1-3: new full-speed USB device number 42 using xhci_hcd
[3870490.556570] usb 1-3: New USB device found, idVendor=0658, idProduct=0200, bcdDevice= 0.00
[3870490.556575] usb 1-3: New USB device strings: Mfr=0, Product=0, SerialNumber=1
[3870490.556578] usb 1-3: SerialNumber: E2061B02-4A02-0114-3A06-FD1871291660
[3870490.562969] cdc_acm 1-3:1.0: ttyACM0: USB ACM device

If Z-Wave JS is running, it will detect that the serial port was disconnected and throw an error. Depending on the application, it can handle the error and reload the driver, or simply exit.

The same command used with a UZB7 (Silicon Labs 700-series controller) did not exhibit a USB disconnect. Instead, the device will send a FUNC_ID_SERIAL_API_STARTED command to the driver software (Z-Wave JS), and if it's running it will just log that the message was received. Meanwhile the network will continue to operate without as if nothing happened.