Where in the Linux source does recognition of specific USB devices happen?

driver, kernel, linux, usb

Solution

There are a lot of other parameters besides vendor and product ID that can influence which driver is chosen. There's a version number, device class, subclass, and protocol, and interface class, subclass, and protocol. The kernel reads all of those from the device and builds up a string containing all of them that looks like this (example is one of my devices, not yours):

usb:v15A9p0004d0001dc00dsc00dp00icFFiscFFipFF

That string is then passed to modprobe, which matches it against strings (with wildcards) found in the modules themselves. You can see the list of matching rules for a particular module by running `modinfo` on it. The source code construct that corresponds to those rules is `MODULE_DEVICE_TABLE`. The individual entries in the device table are usually built with the `USB_DEVICE` macro, so grepping `USB_DEVICE.*8187` instead of just `8187` should narrow it down.

If you have a device plugged in and working, you can find out which driver is associated with it by looking at its sysfs entry:

ls -l /sys/bus/usb/devices/*/driver

If you can build one of those device descriptor strings, you can ask modprobe to look the driver up for you without actually loading it by doing this (again my device as example):

modprobe -v -n 'usb:v15A9p0004d0001dc00dsc00dp00icFFiscFFipFF'

All of the numbers are available in the output of `lsusb -v` if you can get it. If not, try zeros and maybe you'll get a wildcard match. Make sure you use uppercase letters for your hex digits, and lowercase for everything else. This will only work if the driver is present in `/lib/modules` so it's no good for finding drivers that were left out of your kernel compile.

If all else fails, the low-tech approach is to take the human-readable device name from `lsusb`, and google it plus the word "Linux".

Using some of the above methods, I found that your device's driver is called rtl8187, with the vendor and product IDs registered from `drivers/net/wireless/rtl818x/rtl8187/dev.c`.

Problem

I have a specific USB device whose Linux driver source code I would like to examine. My understanding is that the first step a USB driver takes is to register itself capable of handling a device with a specific vendor ID and product ID. In my case, the vendor ID is `0BDA` and the product ID is `8187`. Given this information, is there a way I can find the source file that registers itself as capable of handling this device, with a view to then finding out what other source files actual implement the driver details? For reference, I am on kernel `3.2.0-26`. I have tried a `grep -rl 8187 /usr/src`, but this lists a whole bunch of files, and I don't know where to start.

Original source