USB serial number not shown with lsusb -v command
I have a USB-Stick from which I would like to read the serial number. If I invoke the command lsusb -v the output in the line iSerial is as follows:
Host scsi10: usb-storage Vendor: USB Product: Disk 2.0 Serial Number: 92071573E1272519149 Protocol: Transparent SCSI Transport: Bulk Quirks:
Why is there no serial output with the lsusb command on the one hand, but on the other hand I get a serial number from /proc/scsi/usb-storage . Where is the difference between the two methods to gather the serial?
3 Answers 3
lsusb may try to open the USB device as O_RDWR (read/write mode) and your user might not have the rights to do this (some error message «Couldn’t open device, some information will be missing» should be inbetween the output, if so). Started as root lsusb should also be able to output the whole iSerial value.
There are lots of different USB devices in general (keyboard, mice, webcams, . ). lsusb deals with the connected devices on the USB protocol level.
Some USB device are storage devices (USB sticks, USB harddisks, . ). They understand a different protocol (more or less SCSI) on top of the USB protocol. Within this protocol, an USB storage device has a serial number (as does an ATA device). This is what you see in /proc/scsi/usb-storage .
The iSerial number you see in lsusb has nothing to do with it.
So that’s why you see the serial number you are interested in with one method, but not with the other method. And that’s why you can’t use lsusb to get the kind of serial number you are interested in
You can use lsusb with verbose flag, but you need to make sure you use sudo with it, otherwise the serial will be incorrect.
If that is too verbose, then run lsusb to get the device id:
$ lsusb Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub Bus 001 Device 012: ID 1ab1:0e11 Rigol Technologies Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Then run lsusb with -s flag to show only specified device and grep for the serial number.
So for the serial number of Rigol device:
$ sudo lsusb -s 012 -v|grep -i iserial iSerial 3 DP8C221100000
For more information on lsusb use the —help flag:
$ lsusb --help Usage: lsusb [options]. List USB devices -v, --verbose Increase verbosity (show descriptors) -s [[bus]:][devnum] Show only devices with specified device and/or bus numbers (in decimal) -d vendor:[product] Show only devices with the specified vendor and product ID numbers (in hexadecimal) -D device Selects which device lsusb will examine -t, --tree Dump the physical USB device hierarchy as a tree -V, --version Show version of program -h, --help Show usage and help
Get unique serial number of USB device mounted to /dev folder
Just ran into this same problem and it took a bit to find the solution. Any solution which starts with «just use lsusb» is incorrect. You can figure out the devices serial, but none of the extra information it provides help you determine which /dev/video it links to.
/bin/udevadm info --name=/dev/video1 | grep SERIAL_SHORT
E: ID_SERIAL_SHORT=256DEC57
@debuti This problem came from your USB devices. They were produced with same serial number or they haven’t serial number capability which cause the same serial number. You can reconfigure their serial number for some hardware. For example you can use CP210xSetIDs.exe if you are using CP2102 USB to UART.
Based on the hint of using udevadm and the tutorial from http://www.signal11.us/oss/udev/ I got below code to get the serial info of my webcam.
#include "stdio.h" #include int main(int argc, char **argv) < struct udev *udev; struct udev_device *dev; struct udev_enumerate *enumerate; struct udev_list_entry *list, *node; const char *path; udev = udev_new(); if (!udev) < printf("can not create udev"); return 0; >enumerate = udev_enumerate_new(udev); udev_enumerate_add_match_subsystem(enumerate, "video4linux"); udev_enumerate_scan_devices(enumerate); list = udev_enumerate_get_list_entry(enumerate); udev_list_entry_foreach(node, list) < path = udev_list_entry_get_name(node); dev = udev_device_new_from_syspath(udev, path); printf("Printing serial for %s\n", path); printf("ID_SERIAL=%s\n", udev_device_get_property_value(dev, "ID_SERIAL")); printf("ID_SERIAL_SHORT=%s\n", udev_device_get_property_value(dev, "ID_SERIAL_SHORT")); udev_device_unref(dev); >return 0; >
You can use lsusb , but you need to add verbose flag and make sure you use sudo with it, otherwise the serial will be incorrect.
If that is too verbose, then run lsusb to get the device id:
$ lsusb Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub Bus 001 Device 012: ID 1ab1:0e11 Rigol Technologies Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Then run lsusb with device flag and grep the serial number.
So for the serial number of Rigol device:
$ sudo lsusb -s 012 -v|grep -i iserial iSerial 3 DP8C221100000
Thanks! This reply deserves to receive a lot more attention IMO, because it (ie lsusb with the verbose flag) is likely to be what a lot of people coming here are looking for 🙂
Playing around with libusb, it looks like there’s a standard getSerialNumber() method. Unfortunately, not all USB devices implement this. I have a couple cheap $4 webcams that return None for it. These interfaces expose other metadata, like VendorID and ProductID, which I’ve seen some code try and use as a unique identifier, but it’s not guaranteed to be unique, especially if you have multiple devices of the same make and model.
But assuming you get a serial number for your device, the next problem is figuring out which /dev/videoN file it corresponds to. I have an old version of libusb installed, so I couldn’t get the method working that returned the full sysfs path of the USB device, so instead I scrapped the output from hwinfo . I extracted all the chunks corresponding to cameras, and then from those I extracted the piece that looked like:
USB devices actually form a complicated tree, and that BusID encodes where the device is located in that tree.
You can then take that BusID to find where the device lives in the filesystem as well as the video path, which should be at:
/sys/bus/usb/devices//video4linux/
That’s a directory, and inside it you’ll find a videoN file matching one in /dev.
How to get USB vendor and product info programmatically on Linux?
Now I want to get the full strings that are associated with the vendor and product ids. I found that the file /usr/share/misc/usb.ids contains the information that I’m looking for:
13b1 Linksys 000b WUSB11 v4.0 802.11b Adapter 000d WUSB54G Wireless Adapter 0011 WUSB54GP v4.0 802.11g Adapter 0018 USB200M 10/100 Ethernet Adapter 001a HU200TS Wireless Adapter 001e WUSBF54G 802.11bg 0020 WUSB54GC 802.11g Adapter [ralink rt73] 0023 WUSB54GR 0024 WUSBF54G v1.1 802.11bg
However, it’s not clear to me how I should retrieve this data in my application. Is there an API available or should I just parse the file? If I choose to parse it, then is /usr/share/misc/usb.ids always going to be the correct location?
Here’s the most recent version: linux-usb.org/usb.ids and the interface for submitting them: linux-usb.org/usb-ids.html
On Android, my C program uses libusbhost which provides callbacks for device insertion/removal. All device descriptors are made available by the lib.
5 Answers 5
lsusb command queries information about currently plugged USB devices. You can use its -d option to query a certain vendor/product (but it seems to work only for currently plugged devices):
$ lsusb -d 0e21:0750 Bus 001 Device 005: ID 0e21:0750 Cowon Systems, Inc.
You can show information for all devices:
$ lsusb Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub Bus 001 Device 004: ID 0421:01c7 Nokia Mobile Phones Bus 001 Device 003: ID 0bda:8187 Realtek Semiconductor Corp. RTL8187 Wireless Adapter Bus 001 Device 005: ID 0e21:0750 Cowon Systems, Inc. Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub Bus 005 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub Bus 006 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub Bus 006 Device 002: ID 046d:c01b Logitech, Inc. MX310 Optical Mouse Bus 007 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub Bus 008 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
You can also make it be verbose ( lsusb -v ) and printing a lot of stuff.
Note that when accessing information about the system in Linux OS, it’s much preferred to do it via shell commands (such as lsusb ) than to directly parse the system files these commands access.
@Stacked, yes (for C), but that depends on a language you develop in. But either way you’ll be reading something from a stream, and calling lsusb -d . via popen seems to require less keystrokes than parsing the whole file with descriptions.
Haven’t tried this myself, but libudev’s udev_device_get_property_value should be it; it is used in pulseaudio’s udev-util.c as udev_device_get_property_value(card, «ID_VENDOR_FROM_DATABASE»)) .
Here is a small example I just put together, based on udev-util.c — note that I’ve used an Arduino Duemillanove with FTDI FT232 chip, whose udev path I find using udevadm (see comments in code below), and then I hardcoded it in the below program, udevl.c :
// sudo apt-get install libudev-dev // build with: gcc -o udevl -ludev -Wall -g udevl.c #include #include int main( int argc, char **argv ) < const char *v; char t[256]; struct udev *udev; struct udev_device *card = NULL; if (!(udev = udev_new())) < fprintf(stderr, "Failed to allocate udev context.\n"); return -1; >// $ lsusb | grep FT232 // Bus 002 Device 002: ID 0403:6001 Future Technology Devices International, Ltd FT232 USB-Serial (UART) IC // $ udevadm info --name=/dev/ttyUSB0 --attribute-walk | grep "looking at device" // looking at device '/devices/pci0000:00/0000:00:1d.0/usb2/2-2/2-2:1.0/ttyUSB0/tty/ttyUSB0' // (that one is under /sys) // hardcode that path below: // udev_get_sys_path(udev) for me: '/sys' sprintf(t, "%s/devices/pci0000:00/0000:00:1d.0/usb2/2-2/2-2:1.0/ttyUSB0/tty/ttyUSB0", udev_get_sys_path(udev)); fprintf(stdout, " path: %s\n", t); card = udev_device_new_from_syspath(udev, t); fprintf(stdout, " udev_device: 0x%08X\n", (unsigned int)card); if ((v = udev_device_get_property_value(card, "ID_MODEL_FROM_DATABASE")) ) fprintf(stdout, "got ID_MODEL_FROM_DATABASE: %s\n", v); else fprintf(stdout, "failed getting ID_MODEL_FROM_DATABASE: %s\n", v); fprintf(stdout, "Done.\n"); if (card) udev_device_unref(card); if (udev) udev_unref(udev); return 0; >
This program (with the Arduino attached) outputs:
$ ./udevl path: /sys/devices/pci0000:00/0000:00:1d.0/usb2/2-2/2-2:1.0/ttyUSB0/tty/ttyUSB0 udev_device: 0x09FBF080 got ID_MODEL_FROM_DATABASE: FT232 USB-Serial (UART) IC Done.
. and «FT232 USB-Serial (UART) IC» is the right entry for VID:PID 0403:6001 in usb.ids.
id usb флэш накопителя..
Утро доброе, подскажите пожалуйста как можно узнать айди флэшки и ее параметры? Потому что fdisk -l ничего путного мне не сказал, а раньше с этим несталкивался.
lsusb -v нарыл, а подобное есть? кто-нибудь юзал?
RTFM!
Всего-то несколько параметров
-v, --verbose Tells lsusb to be verbose and display detailed information about the devices shown. This includes configuration descriptors for the deviceâs current speed. Class descriptors will be shown, when available, for USB device classes including hub, audio, HID, communications, and chipcard. -s [[bus]:][devnum] Show only devices in specified bus and/or devnum. Both IDâs are given in decimal and may be omitted. -d [vendor]:[product] Show only devices with the specified vendor and product ID. Both IDâs are given in hexadecimal. -D device Do not scan the /proc/bus/usb directory, instead display only information about the device whose device file is given. The device file should be something like /proc/bus/usb/001/001. This option displays detailed information like the v option; you must be root to do this. -t Tells lsusb to dump the physical USB device hierarchy as a tree. -V, --version Print version information on standard output, then exit successfully.
А вот такой вопрос, програма пишет
допустим idProduct 0x0150 как это перевести в добоваримую форму?
В какую ещё форму? Это ID как есть, никуда его переводить не надо. Соответствие ID конкретному продукту ищи в гугле.