This idea came about as my Xbox 360 Controller does not work on Archlinux without re-plugging the device after booting the system.
I wanted a way to reset the device in linux cli to save physically unplugging the device.
I found a C example from 2008 on linux-usb mailing list which required a few steps & had a few drawbacks.
In the end I used libusb to implement the same reset function using vendorid & productid.
Tip
This can also be useful for resetting a usb device after updating the firmware.
Basic Example (usbfs) #
Fri, 27 Jun 2008 - linux-usb - Re: re-enumerating the device
To use this example you need to:
- run
lsusb
(read device bus id & device id) - use the above for path of device (
/dev/bus/usb/<bus id>/<device id>
) - run command using the path above
$ lsusb
Bus 001 Device 006: ID 045e:028e Microsoft Corp. Xbox360 Controller
$ sudo ./usbreset /dev/bus/usb/001/006
Info
This example uses the bus id which ties to the usb port the device is plugged into.
I wanted to use the vendor id
+ product id
to make it easier & also to eliminate the problem of being tied to a specific usb port.
Using libusb #
libusb
allows connecting to usb devices using vendor id
& product id
.
libusb: Device handling and enumeration
Test App #
libusb_open_device_with_vid_pid()
is good for creating a test app.
libusb_init(NULL);
libusb_device_handle *handle = libusb_open_device_with_vid_pid(NULL, vid, pid);
result = libusb_reset_device(handle);
libusb_open_device_with_vid_pid()
This function is intended for those scenarios where you are using libusb to knock up a quick test application
Final Implementation #
Use libusb_get_device_list()
to check the device exists in the system before calling libusb_open()
to open the connection.
libusb_get_device_list()
Returns a list of USB devices currently attached to the system.
This is your entry point into finding a USB device to operate.
libusb_open()
Open a device and obtain a device handle.
This is a non-blocking function; no requests are sent over the bus.
int deviceCount = libusb_get_device_list(context, &device_list);
int i;
for (i = 0; i < deviceCount; i++)
{
struct libusb_device *device = device_list[i];
struct libusb_device_descriptor desc;
libusb_get_device_descriptor(device, &desc);
if (desc.idVendor == venid && desc.idProduct == devid)
{
libusb_open(device, &handle);
break;
}
}
If no handle is opened give cli feedback to user.
if (handle == NULL)
{
fprintf(stderr, "ERROR: USB device not found [%04x:%04x]\n", vid, pid);
return 1;
}
Adding CLI Arguments #
To make the tool usable for any device I added arguments for vendor id
& product id
.
if (argc != 3)
{
printf("USB Device Reset\n");
printf("----------------\n\n");
printf("No input given or input invalid\n\n");
printf("Usage: %s <vid> <pid>\n", argv[0]);
return 1;
}
int vid, pid;
sscanf(argv[1], "%04x", &vid);
sscanf(argv[2], "%04x", &pid);
Final CLI App #
The final implementation has error handling, cli feedback & takes in cli arguments to allow it to be used for different devices.
It also requires root access due to connecting over usb.
Example #
Here is an example output for Microsoft Xbox360 Controller reset.
$ sudo usbreset 045e 028e
Checking USB Device Connected ...
Resetting USB Device [045e:028e]
USB Device reset [045e:028e]
Source Code #
The source for this project is available on github.
Related #
📝 January 23, 2016 - BlackWidow Macro Keys In Linux (libusb)
Xbox 360 Controller Info #
On Archlinux startup the controller blinks all 4 LEDs & does not work.
An example can be seen on the external site below (Slow Blink).
Xbox 360 Controller LED Animations Information - Parts Not Included
On resetting the controller LED1 blinks 3 times, then stays illuminated.
The controller then works as exprected.
Not sure if this is a bug with xpad
or something with the kernel.
Webmentions
No Comments Yet