For years, I have been dealing with this Ubuntu bug where my mouse freezes soon after booting and then periodically freezes after that. To fix it, I have to physically unplug the usb transceiver for the mouse and plug it back in. From my research, this bug happens with USB wireless Windows mice when dual booting Linux and Windows.

Is there a way I can programmatically (from the terminal) unplug the USB transceiver instead of doing it physically? I want to achieve this in my startup bash script.

I'm using Ubuntu 16.04

Edit: I solved my problem but it doesn't really relate to my question.

In the file..


I had to make


This fixes the mouse bug I was experiencing for years.

  • 2
    does uhubctl or an alternative work on your machine? – sbergeron May 15 '18 at 1:58
  • If this driver is a kernel module, you should be able to unload it with rmmod and reload it with modprobe. You only have to find out which module loads when you plugin the mouse. Try lsmod after you rebooted without mouse plugged in. Then plug it in and see, which module loaded. – nobody May 15 '18 at 6:57
  • 2
    @sbergeron Could you please post your idea about uhubctl as answer. It is very promising. – N0rbert May 15 '18 at 7:19
  • @deanresin Please add the solution you found as an answer below and accept it, this way others can find it easily and vote for it. – dessert May 4 '19 at 13:47

I wrote a script to show how I’d do that:


port="1-1.1" # as shown by lsusb -t: {bus}-{port}(.{subport})

bind_usb() {
  echo "$1" >/sys/bus/usb/drivers/usb/bind

unbind_usb() {
  echo "$1" >/sys/bus/usb/drivers/usb/unbind

unbind_usb "$port"
# sleep 1 # enable delay here
bind_usb "$port"

First you need to get the bus and port number of the usb port in question. You can do that with lsusb and any device you recognize in lsusb’s output, I use a Sandisk pendrive here:

$ lsusb
Bus 001 Device 005: ID 04f2:b39a Chicony Electronics Co., Ltd 
Bus 001 Device 112: ID 8087:07dc Intel Corp. 
Bus 001 Device 019: ID 04d9:1603 Holtek Semiconductor, Inc. Keyboard
Bus 001 Device 018: ID 0424:2504 Standard Microsystems Corp. USB 2.0 Hub
Bus 001 Device 022: ID 0781:5567 SanDisk Corp. Cruzer Blade
Bus 001 Device 002: ID 8087:8000 Intel Corp. 
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
$ lsusb -t
/:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=ehci-pci/3p, 480M
    |__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/8p, 480M
        |__ Port 1: Dev 22, If 0, Class=Mass Storage, Driver=usb-storage, 480M
        |__ Port 2: Dev 18, If 0, Class=Hub, Driver=hub/4p, 480M
            |__ Port 1: Dev 19, If 1, Class=Human Interface Device, Driver=usbhid, 1.5M
            |__ Port 1: Dev 19, If 0, Class=Human Interface Device, Driver=usbhid, 1.5M
        |__ Port 7: Dev 112, If 0, Class=Wireless, Driver=btusb, 12M
        |__ Port 7: Dev 112, If 1, Class=Wireless, Driver=btusb, 12M
        |__ Port 8: Dev 5, If 1, Class=Video, Driver=uvcvideo, 480M
        |__ Port 8: Dev 5, If 0, Class=Video, Driver=uvcvideo, 480M

From the output of lsusb you get the bus and device number of the device, then search this device in the output of lsusb -t to get the bus and port number (sometimes with subports). The syntax is:

1-2.3 # for Bus 1 Port 2 Subport 3 – strip leading zeroes!

Use this as port in the script. Now you just need to make it executable with chmod +x /path/to/script and run it with root permissions:

sudo /path/to/script

I didn’t need one for my pendrive, but it may be necessary for you to add a delay between unbinding and binding again, that’s what the commented out sleep 1 line is for – you can experiment with the values, e.g. sleep 0.5 for half a second.

Note that this approach shows how to disable and enable again a certain USB port, if you want a specific device to be unbound and rebound again you’ll have to use the same USB port for this to work. One could think of a way to parse lsusb’s output to dynamically get the bus and port number of a specific device every time the script is called, this would allow you to use any USB port, but I feel that would be an overkill here.

Suggestions taken from this linux.com blog article.

  • Unfortunately it doesn't work. I still have to physically remove the USB transceiver and plug it back in. Also, @reboot doesn't work on my machine (Ubuntu 16.04) – deanresin May 19 '18 at 3:53
  • I have the same problem, ans I don't thing this is equivalent to physically remove the plug, because, when I reconnect the plug, I get a new device number, which does not happen here. – Camion Apr 2 '20 at 13:22
  • @Camion did you try my edit? – deanresin Aug 14 '20 at 16:04
  • Sorry, I have been busy with something else, and it might be that the problem was due to another peripheral (Also it didn't arise all the time) – Camion Aug 16 '20 at 17:59

port="usb1" # replace '1' with actual bus number as shown by lsusb -t: {bus}-{port}(.{subport})

bind_usb() {
  echo "$1" >/sys/bus/usb/drivers/usb/bind

unbind_usb() {
  echo "$1" >/sys/bus/usb/drivers/usb/unbind

unbind_usb "$port"
# sleep 1 # enable delay here
bind_usb "$port"

Similarly to previous answers, this will reset the hub. If you observe the usb traffic in a program such as wireshark, you'll see that the previous answers don't cause the device to be re-enumerated, but simply restart the device driver. Restarting the hub goes a little deeper in the usb tree of the kernel and forces the device to completely re-enumerate.

  • This method works like physically unplugging and re-plugging USB devices. – vahid-dan Jan 28 at 20:30

you can also use ioctl to send a reset to the device in question - assuming it's still responsive

   /* usbreset -- send a USB port reset to a USB device */

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/ioctl.h>

#include <linux/usbdevice_fs.h>

int main(int argc, char **argv)
    const char *filename;
    int fd;
    int rc;

    if (argc != 2) {
        fprintf(stderr, "Usage: usbreset device-filename\n");
        return 1;
    filename = argv[1];

    fd = open(filename, O_WRONLY);
    if (fd < 0) {
        perror("Error opening output file");
        return 1;

    printf("Resetting USB device %s\n", filename);
    rc = ioctl(fd, USBDEVFS_RESET, 0);
    if (rc < 0) {
        perror("Error in ioctl");
        return 1;
    printf("Reset successful\n");

    return 0;

you would call like this

sudo ./usbreset /dev/bus/usb/002/004

not my code, but I don't know who to attribute to

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.