I was required to disable an specific port for an specific device. If an “X” device is connected in any port of the computer I should be able to enable/disable it at will.

In our scenario the idea is to enable or disable  a Genius GK100010 Numeric Pin Pad  and other several devices when they are connected to any USB port of our computer. (I have installed Lubuntu 12.04).

There are other alternatives as the use of xinput or using udev rules but in this article I will cover the procedure with the Manual driver binding and unbinding feature included in kernel 2.6.13-rc3.

At the end of this reading you’ll learn:

  • How identify usb devices
  • How to manually bind/unbind usb ports
  • How to script an ON/OFF usb port for certain device

For this solution we’ll need:

  • Bash 4 (or higher) to use readarray | #you can replace this with your own “for/loop” to read each device
  • Kernel 2.6.13-rc3 (or higher) | #mandatory

List our device

First, we must connect the device and list it with lsusb:

In my case, the mentioned device above its recognized as “Weltrend Semiconductor”. Using those kind of names isn’t a good practice. Instead we’ll focus on it’s ID NUMBER, which is “040b:2000” when scripting, I’ll talk about this in “scripting a solution” below.

Identify which port is using

Now, we must investigate which port is being used for that device, the file uevent will store all the information about the device, there’s a correlation between that file and the Bus and Device information provided by lsusb, so we take both previous values and stick them together with a slash:

Now, using this values we’ll search for it’s respective uevent file this way:

  • grep -l # list files with coincidences and suppress matched lines

Now, the port being used by our USB device is the “2-2”, easy to see in /sys/bus/usb/devices/2-2/uevent

Turn the port on and off

We could directly turn on and off the port in this way:

Be careful, the Bus and Device change if you reconnect the device or restart your computer, to learn how to make this changes in a foolproof way keep reading through scripting a solution below.

Scripting a solution

As I’ve mentioned before the Bus and Device may change when reconnecting or restarting the computer. We must find a reliable way to always find the device. Remember the ID NUMBER I’ve mentioned?

The value: 040b:2000 is the safest identifier to enable or disable this device. Let’s take a look on our uevent file:

As you can see our previous coincidence was the “DEVNAME” when we used grep with the value “002/021”. We know that values may change but the ID NUMBER won’t and we’ll find it in the variable “PRODUCT”.

There’s a small difference between the ID NUMBER provided by lsusb: 040b:2000 and the PRODUCT in our uevent file: PRODUCT=40b/2000. The format and a missing ‘0’ make them different, anyway this is the best way to find our device.

So we must change 040b:2000 to 40b/2000 and search that device ID NUMBER in our ports:

As you can see, three files appear but the port 2-2 it’s the same in each of them. To filter the output just add tail -1 like this:

And add it to a variable:

With the help of tr and awk we split the string (/sys/bus/usb/devices/2-2/uevent) and take the column where our ports in use are (2-2):

And that’s how we should search for the port of this device, then we are able to turn it on and off at will:

I’ve written a full functional script to do this tasks with several devices listed in a text file here.

Possible errors

When you perform the operation of “turn on and off” as I’ve explained the system enables or disables a port by a symlink:

Yes, it would be a cool trick to delete or create the symlink but I prefer doing it by the “echo” procedure because I don’t know if there are other changes.

The thing with this is, check that the symlink exists or not before trying to perform an ON / OFF operation while scripting and have in mind that my mentioned script doesn’t cover corner cases when you turn it off, disconnect and change the port of the device.