- Linux: How to find the device driver used for a device?
- 8 Answers 8
- Determine linux driver that owns a disk
- 2 Answers 2
- How to Find the Device Driver Used for a Device in Linux?
- Method 1: Using “modinfo” Command
- Method 2: Using “lsusb” Command(For USB Device)
- Conclusion
- Find out which modules are associated with a usb device?
- 4 Answers 4
- Finding the Kernel Driver(s)
- The victim device
- Method 1: Using usbutils (easy)
- Method 2: Using debugfs (requires root)
- Method 3: Using only basic utilities to read /sys directly (best for scripting or recovery)
- What about userspace (usbfs) drivers?
Linux: How to find the device driver used for a device?
If my target has one device connected and many drivers for that device loaded, how can I understand what device is using which driver?
8 Answers 8
Example. I want to find the driver for my Ethernet card:
$ sudo lspci . 02:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8111/8168B PCI Express Gigabit Ethernet controller (rev 01) $ find /sys | grep drivers.*02:00 /sys/bus/pci/drivers/r8169/0000:02:00.0
First I need to find coordinates of the device using lspci ; then I find driver that is used for the devices with these coordinates.
I know the OP asked for «drivers being used», but what if the driver is not installed nor being used? How to find out just by the vendorID:productID ? Also, what if it is not a PCI device, and you only see it in lsusb for example?
@DrBeco: But if driver is not installed, what do you want to find? You should just google in this case
#!/bin/bash for f in /sys/class/net/*; do dev=$(basename $f) driver=$(readlink $f/device/driver/module) if [ $driver ]; then driver=$(basename $driver) fi addr=$(cat $f/address) operstate=$(cat $f/operstate) printf "%10s [%s]: %10s (%s)\n" "$dev" "$addr" "$driver" "$operstate" done
$ ~/what_eth_drivers.sh eth0 [52:54:00:aa:bb:cc]: virtio_net (up) eth1 [52:54:00:dd:ee:ff]: virtio_net (up) eth2 [52:54:00:99:88:77]: virtio_net (up) lo [00:00:00:00:00:00]: (unknown)
I’d like to find solution which would find also veth and other virtual drivers. IMHO the only solution is to use ethtool or lshw .
sudo lspci -v will show it. like this:
$ sudo lspci -v 00:01.0 VGA compatible controller: Advanced Micro Devices, Inc. . Kernel driver in use: radeon Kernel modules: radeon
You can also combine it with grep like this:
$ sudo lspci -v | grep -A 20 VGA
For USB based devices you can see the driver name by using the lsusb command:
And/or you use lshw which enumerates the devices on all buses including USB, PCI, etc so you can see which driver it uses:
FTR: the driver is shown at line titled configuration , for example: configuration: driver=btusb maxpower=100mA speed=12Mbit/s
If you just want to plainly use sysfs and doesn’t want to deal with all these commands which eventually looks inside sysfs anyways, here’s how:
say, what is the module/driver for eth6? «sfc» it is
# ls -l /sys/class/net/eth6/device/driver lrwxrwxrwx 1 root root 0 Jan 22 12:30 /sys/class/net/eth6/device/driver -> ../../../../bus/pci/drivers/sfc
or better yet.. let readlink resolve the path for you.
# readlink -f /sys/class/net/eth6/device/driver /sys/bus/pci/drivers/sfc
so. to figure out what are the drivers for all of your network interfaces:
# ls -1 /sys/class/net/ | grep -v lo | xargs -n1 -I<> bash -c 'echo -n <> :" " ; basename `readlink -f /sys/class/net/<>/device/driver`' eth0 : tg3 eth1 : tg3 eth10 : mlx4_core eth11 : mlx4_core eth2 : tg3 eth3 : tg3 eth4 : mlx4_core eth5 : mlx4_core eth6 : sfc eth7 : sfc eth8 : sfc eth9 : sfc
Determine linux driver that owns a disk
I am trying to debug a situation where the SSD on my hardware is not being detected by the right device driver. The device driver that should own the SSD’s is a software RAID driver (megasr) that will automically configure 2 SSD’s in mirroring mode. I am pretty sure that the megasr driver is not detecting/owning the SSD’s, but I am unsure which driver actually detects them. Is there a way in Linux that I can determine which device driver owns a particular disk inside the /dev directory. So I would like to determine which driver owns the device /dev/sda, for example. The OS is RHEL 6.x. Many thanks.
2 Answers 2
You can see the kernel log
dmesg | grep sda [ 0.618438] sd 2:0:0:0: [sda] Attached SCSI disk
The log is talking about a scsi disk, and sd 2:0:0:0 is the device that generated that message. You can inspect the sysfs for more details:
cd /sys/block/ cd /sys/block/sda/
Here you can find the information about all your block devices. If you look into the directory of your specific device you should see its information.
Here the information about the scsi bus. There are two directories: drivers and devices.
cd /sys/bus/scsi cd /sys/bus/scsi/devices cd /sys/bus/scsi/drivers
Here there is the list of drivers on the scsi bus.
ls /sys/bus/scsi/drivers sd sr
cd /sys/bus/scsi/drivers/sd/2:0:0:0
Here my device, so sd is my driver.
The disk is a block device, you should see the directory block
cd /sys/bus/scsi/drivers/sd/2:0:0:0/block/sda
Probably there is a program that do this automatically 🙂
If the wrong driver is handling your device you can unbind the device from that driver, and you can bind it to another one.
ls /sys/bus/scsi/drivers/sd 2:0:0:0 bind uevent unbind
You can write the device identifier on the unbind file to detach that device from the driver.
Then you can attach your device to another driver
cd /sys/bus/scsi/drivers/ echo -n "2:0:0:0" > bind
Obviously (1), you cannot bind a scsi device to non scsi driver. Obviously (2), this is not the answer for your specific problem, but it is a way to retrieve the information that you need to resolve the problem
How to Find the Device Driver Used for a Device in Linux?
The device drivers are the software packages having no user interface that manage and control the system hardware devices. The external and internal devices require the drivers because they build up the connection between the device and the operating system. If the driver of a specific device is not installed, it can not work properly.
Keeping this in view, this article lists all possible ways to find the device drivers used for a device in Linux:
Method 1: Using “modinfo” Command
The “modinfo” command displays the Linux kernel modules/drivers information. It returns the list of all the modules/drivers in the terminal without passing any argument.
To get the particular device driver information, specify the device name with it as follows:
The “e1000” device driver detail has been displayed in the output.
Method 2: Using “lsusb” Command(For USB Device)
The “lsusb” command is the built-in command line tool that lists down the USB device information connected to the system. It also provides the driver details that are installed for it. Let’s see how this command displays the USB device drivers.
Execute the “lsusb” command followed by the “-t(tree format)” flag to get the “usb” device drivers:
The above command has displayed the “usb” device busses and drivers in the terminal.
Conclusion
In Linux, to find the specific device drivers use the “modinfo” command with the particular device name. Apart from other hardware devices, the user can use the “lsusb” command only to get the USB device driver details.
This article has covered all possible ways to find the device driver used for a device in Linux.
Find out which modules are associated with a usb device?
Could you recommend a way to figure out which driver is being used for a USB device. Sort of a usb equivalent of lspci -k command.
4 Answers 4
Finding the Kernel Driver(s)
The victim device
$ lsusb Bus 010 Device 002: ID 046d:c01e Logitech, Inc. MX518 Optical Mouse Bus 010 Device 003: ID 051d:0002 American Power Conversion Uninterruptible Power Supply
We’re going to try to find out what driver is used for the APC UPS. Note that there are two answers to this question: The driver that the kernel would use, and the driver that is currently in use. Userspace can instruct the kernel to use a different driver (and in the case of my APC UPS, nut has).
Method 1: Using usbutils (easy)
The usbutils package (on Debian, at least) includes a script called usb-devices . If you run it, it outputs information about the devices on the system, including which driver is used:
$ usb-devices ⋮ T: Bus=10 Lev=01 Prnt=01 Port=01 Cnt=02 Dev#= 3 Spd=1.5 MxCh= 0 D: Ver= 1.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1 P: Vendor=051d ProdID=0002 Rev=01.06 S: Manufacturer=American Power Conversion S: Product=Back-UPS RS 1500 FW:8.g9 .D USB FW:g9 S: SerialNumber=XXXXXXXXXXXX C: #Ifs= 1 Cfg#= 1 Atr=a0 MxPwr=24mA I: If#= 0 Alt= 0 #EPs= 1 Cls=03(HID ) Sub=00 Prot=00 Driver=usbfs ⋮
Note that this lists the current driver, not the default one. There isn’t a way to find the default one.
Method 2: Using debugfs (requires root)
If you have debugfs mounted, the kernel maintains a file in the same format as usb-devices prints out at /sys/kernel/debug/usb/devices ; you can view with less , etc. Note that debugfs interfaces are not stable, so different kernel versions may print in a different format, or be missing the file entirely.
Once again, this only shows the current driver, not the default.
Method 3: Using only basic utilities to read /sys directly (best for scripting or recovery)
You can get the information out of /sys , thought its more painful than lspci . These /sys interfaces should be reasonably stable, so if you’re writing a shell script, this is probably how you want to do it.
Initially, lsusb seems to count devices from 1, /sys from 0. So 10-2 is a good guess for where to find the APC UPS lsusb gives as bus 10, device 3. Unfortunately, over time that mapping breaks down—sysfs re-uses numbers even when device numbers aren’t. The devnum file’s contents will match the device number given by lsusb, so you can do something like this:
$ grep -l '^3$' /sys/bus/usb/devices/10-*/devnum # the ^ and $ to prevent also matching 13, 31, etc. /sys/bus/usb/devices/10-2/devnum
So, in this case, it’s definitely 10-2 .
$ cd /sys/bus/usb/devices/10-2 $ ls 10-2:1.0 bDeviceClass bMaxPower descriptors ep_00 maxchild remove urbnum authorized bDeviceProtocol bNumConfigurations dev idProduct power serial version avoid_reset_quirk bDeviceSubClass bNumInterfaces devnum idVendor product speed bcdDevice bmAttributes busnum devpath ltm_capable quirks subsystem bConfigurationValue bMaxPacketSize0 configuration driver manufacturer removable uevent
We can be sure this is the right device by cat ing a few of the files:
$ cat idVendor idProduct manufacturer product 051d 0002 American Power Conversion Back-UPS RS 1500 FW:8.g9 .D USB FW:g9
If you look in 10-2:1.0 ( :1 is the «configuration», .0 the interface—a single USB device can do multiple things, and have multiple drivers; lsusb -v will show these), there is a modalias file and a driver symlink:
$ cat 10-2\:1.0/modalias usb:v051Dp0002d0106dc00dsc00dp00ic03isc00ip00in00 $ readlink driver ../../../../../../bus/usb/drivers/usbfs
So, the current driver is usbfs . You can find the default driver by asking modinfo about the modalias:
$ /sbin/modinfo `cat 10-2\:1.0/modalias` filename: /lib/modules/3.6-trunk-amd64/kernel/drivers/hid/usbhid/usbhid.ko license: GPL description: USB HID core driver author: Jiri Kosina author: Vojtech Pavlik author: Andreas Gal alias: usb:v*p*d*dc*dsc*dp*ic03isc*ip*in* depends: hid,usbcore intree: Y vermagic: 3.6-trunk-amd64 SMP mod_unload modversions parm: mousepoll:Polling interval of mice (uint) parm: ignoreled:Autosuspend with active leds (uint) parm: quirks:Add/modify USB HID quirks by specifying quirks=vendorID:productID:quirks where vendorID, productID, and quirks are all in 0x-prefixed hex (array of charp)
So, the APC UPS defaults to the hid driver, which is indeed correct. And its currently using usbfs, which is correct since nut ‘s usbhid-ups is monitoring it.
What about userspace (usbfs) drivers?
When the driver is usbfs , it basically means a userspace (non-kernel) program is functioning as the driver. Finding which program it is requires root (unless the program is running as your user) and is fairly easy: whichever program has the device file open.
We know that our «victim» device is bus 10, device 3. So the device file is /dev/bus/usb/010/003 (at least on a modern Debian), and lsof provides the answer:
# lsof /dev/bus/usb/010/003 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME usbhid-up 4951 nut 4u CHR 189,1154 0t0 8332 /dev/bus/usb/010/003
And indeed, its usbhid-ups as expected (lsof truncated the command name to make the layout fit, if you need the full name, you can use ps 4951 to get it, or probably some lsof output formatting options).