Home > Linux, Programming, webcam > Reset nondetachable USB devices on your laptop

Reset nondetachable USB devices on your laptop

I’ve had problems with Ubuntu and my laptop’s integrated webcam for quite some time. Because of these problems, a couple of developers started working on some alternative drivers, but the project seems to be abandoned right now (7 months without commits).

With no appropriate drivers, the device displays odd colours and randomly hangs up (specially when using Flash Player) leaving the power led on. This is very unpleasant because it gives you the impression that somebody might be spying on you.

So I googled a bit searching for a way to reset the devices that I can’t detach, and found this great post by Alan Stern in which he gives us a piece of code to do just that.

mkdir usbreset
cd usbreset

Copy the code into usbreset.c:

/* 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;

Then build it:

cc  usbreset.c -o usbreset
chmod +x usbreset

Now we have to know which is the bus and device our webcam is attached to:

Bus 002 Device 005: ID xxxx:xxxx (...) Webcam

Last, call usbreset with the path of the device as a parameter:

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

And that’s it. Bus and Device might change after the reset but ID won’t. So, we note down that ID and make a little sh script to avoid the lsusb step (put it in the same place as the usbreset binary). Let’s call it usbreset.sh (for originality’s sake):

MATCHES=$(lsusb | sed -n 's/Bus \([0-9]*\) Device \([0-9]*\): ID '$ID'.*/\/dev\/bus\/usb\/\1\/\2/p')
if [ -z ${MATCHES} ]; then
 echo "No match found"
 sudo ./usbreset $MATCHES

And now we can reset our webcam by simply calling ./usbreset.sh.

USBReset source code:

  1. 2014/04/15 at 18:04

    Great post.
    Like you wrote, the usb file handle changes often to hard code this and to use without a batch script, consider using udev. http://www.signal11.us/oss/udev/

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: