Archive

Archive for the ‘webcam’ Category

Reset nondetachable USB devices on your laptop

2012/01/17 1 comment

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.

cd
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");

 close(fd);
 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:

lsusb
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):

#!/bin/sh
ID='xxxx:xxxx'
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"
else
 sudo ./usbreset $MATCHES
fi

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

USBReset source code:
http://marc.info/?l=linux-usb&m=121459435621262&w=2