====== Linux - Kernel - PCI Devices ======
The PCI standard has become the de-facto standard for system buses.
Linux provide extensive support for PCI, and contains numerous drivers for network, storage and 3rd party adapters.
----
The Linux kernel represents PCI devices as pseudo-devices in the sysfs file system:
ls -la /sys/bus/pci/devices
returns:
total 0
drwxr-xr-x 2 root root 0 Jan 29 03:47 .
drwxr-xr-x 5 root root 0 Jan 29 03:47 ..
lrwxrwxrwx 1 root root 0 Jan 29 03:47 0000:00:00.0 -> ../../../devices/pci0000:00/0000:00:00.0
lrwxrwxrwx 1 root root 0 Jan 29 03:47 0000:00:00.2 -> ../../../devices/pci0000:00/0000:00:00.2
lrwxrwxrwx 1 root root 0 Jan 29 03:47 0000:00:01.0 -> ../../../devices/pci0000:00/0000:00:01.0
lrwxrwxrwx 1 root root 0 Jan 29 03:47 0000:00:01.2 -> ../../../devices/pci0000:00/0000:00:01.2
lrwxrwxrwx 1 root root 0 Jan 29 03:47 0000:00:02.0 -> ../../../devices/pci0000:00/0000:00:02.0
lrwxrwxrwx 1 root root 0 Jan 29 03:47 0000:00:03.0 -> ../../../devices/pci0000:00/0000:00:03.0
lrwxrwxrwx 1 root root 0 Jan 29 03:47 0000:00:03.1 -> ../../../devices/pci0000:00/0000:00:03.1
lrwxrwxrwx 1 root root 0 Jan 29 03:47 0000:00:04.0 -> ../../../devices/pci0000:00/0000:00:04.0
lrwxrwxrwx 1 root root 0 Jan 29 03:47 0000:00:05.0 -> ../../../devices/pci0000:00/0000:00:05.0
lrwxrwxrwx 1 root root 0 Jan 29 03:47 0000:00:07.0 -> ../../../devices/pci0000:00/0000:00:07.0
lrwxrwxrwx 1 root root 0 Jan 29 03:47 0000:00:07.1 -> ../../../devices/pci0000:00/0000:00:07.1
lrwxrwxrwx 1 root root 0 Jan 29 03:47 0000:00:08.0 -> ../../../devices/pci0000:00/0000:00:08.0
lrwxrwxrwx 1 root root 0 Jan 29 03:47 0000:00:08.1 -> ../../../devices/pci0000:00/0000:00:08.1
lrwxrwxrwx 1 root root 0 Jan 29 03:47 0000:00:14.0 -> ../../../devices/pci0000:00/0000:00:14.0
lrwxrwxrwx 1 root root 0 Jan 29 03:47 0000:00:14.3 -> ../../../devices/pci0000:00/0000:00:14.3
lrwxrwxrwx 1 root root 0 Jan 29 03:47 0000:00:18.0 -> ../../../devices/pci0000:00/0000:00:18.0
lrwxrwxrwx 1 root root 0 Jan 29 03:47 0000:00:18.1 -> ../../../devices/pci0000:00/0000:00:18.1
lrwxrwxrwx 1 root root 0 Jan 29 03:47 0000:00:18.2 -> ../../../devices/pci0000:00/0000:00:18.2
lrwxrwxrwx 1 root root 0 Jan 29 03:47 0000:00:18.3 -> ../../../devices/pci0000:00/0000:00:18.3
lrwxrwxrwx 1 root root 0 Jan 29 03:47 0000:00:18.4 -> ../../../devices/pci0000:00/0000:00:18.4
lrwxrwxrwx 1 root root 0 Jan 29 03:47 0000:00:18.5 -> ../../../devices/pci0000:00/0000:00:18.5
lrwxrwxrwx 1 root root 0 Jan 29 03:47 0000:00:18.6 -> ../../../devices/pci0000:00/0000:00:18.6
lrwxrwxrwx 1 root root 0 Jan 29 03:47 0000:00:18.7 -> ../../../devices/pci0000:00/0000:00:18.7
lrwxrwxrwx 1 root root 0 Jan 29 03:47 0000:01:00.0 -> ../../../devices/pci0000:00/0000:00:01.2/0000:01:00.0
lrwxrwxrwx 1 root root 0 Jan 29 03:47 0000:02:03.0 -> ../../../devices/pci0000:00/0000:00:01.2/0000:01:00.0/0000:02:03.0
lrwxrwxrwx 1 root root 0 Jan 29 03:47 0000:02:04.0 -> ../../../devices/pci0000:00/0000:00:01.2/0000:01:00.0/0000:02:04.0
lrwxrwxrwx 1 root root 0 Jan 29 03:47 0000:02:05.0 -> ../../../devices/pci0000:00/0000:00:01.2/0000:01:00.0/0000:02:05.0
lrwxrwxrwx 1 root root 0 Jan 29 03:47 0000:02:08.0 -> ../../../devices/pci0000:00/0000:00:01.2/0000:01:00.0/0000:02:08.0
lrwxrwxrwx 1 root root 0 Jan 29 03:47 0000:02:09.0 -> ../../../devices/pci0000:00/0000:00:01.2/0000:01:00.0/0000:02:09.0
lrwxrwxrwx 1 root root 0 Jan 29 03:47 0000:02:0a.0 -> ../../../devices/pci0000:00/0000:00:01.2/0000:01:00.0/0000:02:0a.0
lrwxrwxrwx 1 root root 0 Jan 29 03:47 0000:03:00.0 -> ../../../devices/pci0000:00/0000:00:01.2/0000:01:00.0/0000:02:03.0/0000:03:00.0
lrwxrwxrwx 1 root root 0 Jan 29 03:47 0000:04:00.0 -> ../../../devices/pci0000:00/0000:00:01.2/0000:01:00.0/0000:02:04.0/0000:04:00.0
lrwxrwxrwx 1 root root 0 Jan 29 03:47 0000:05:00.0 -> ../../../devices/pci0000:00/0000:00:01.2/0000:01:00.0/0000:02:05.0/0000:05:00.0
lrwxrwxrwx 1 root root 0 Jan 29 03:47 0000:06:00.0 -> ../../../devices/pci0000:00/0000:00:01.2/0000:01:00.0/0000:02:08.0/0000:06:00.0
lrwxrwxrwx 1 root root 0 Jan 29 03:47 0000:06:00.1 -> ../../../devices/pci0000:00/0000:00:01.2/0000:01:00.0/0000:02:08.0/0000:06:00.1
lrwxrwxrwx 1 root root 0 Jan 29 03:47 0000:06:00.3 -> ../../../devices/pci0000:00/0000:00:01.2/0000:01:00.0/0000:02:08.0/0000:06:00.3
lrwxrwxrwx 1 root root 0 Jan 29 03:47 0000:07:00.0 -> ../../../devices/pci0000:00/0000:00:01.2/0000:01:00.0/0000:02:09.0/0000:07:00.0
lrwxrwxrwx 1 root root 0 Jan 29 03:47 0000:08:00.0 -> ../../../devices/pci0000:00/0000:00:01.2/0000:01:00.0/0000:02:0a.0/0000:08:00.0
lrwxrwxrwx 1 root root 0 Jan 29 03:47 0000:09:00.0 -> ../../../devices/pci0000:00/0000:00:03.1/0000:09:00.0
lrwxrwxrwx 1 root root 0 Jan 29 03:47 0000:09:00.1 -> ../../../devices/pci0000:00/0000:00:03.1/0000:09:00.1
lrwxrwxrwx 1 root root 0 Jan 29 03:47 0000:0a:00.0 -> ../../../devices/pci0000:00/0000:00:07.1/0000:0a:00.0
lrwxrwxrwx 1 root root 0 Jan 29 03:47 0000:0b:00.0 -> ../../../devices/pci0000:00/0000:00:08.1/0000:0b:00.0
lrwxrwxrwx 1 root root 0 Jan 29 03:47 0000:0b:00.1 -> ../../../devices/pci0000:00/0000:00:08.1/0000:0b:00.1
lrwxrwxrwx 1 root root 0 Jan 29 03:47 0000:0b:00.3 -> ../../../devices/pci0000:00/0000:00:08.1/0000:0b:00.3
lrwxrwxrwx 1 root root 0 Jan 29 03:47 0000:0b:00.4 -> ../../../devices/pci0000:00/0000:00:08.1/0000:0b:00.4
----
===== Analyze one device =====
Take one example from the list:
lrwxrwxrwx 1 root root 0 Jan 29 03:47 0000:00:03.0 -> ../../../devices/pci0000:00/0000:00:03.0
**NOTE:** Break the device string **0000:03:00.0** down as follows:
* **0000** : PCI domain. Each domain can contain up to 256 PCI buses.
* **03** : The bus number the device is attached to.
* **00** : The device number.
* **.0** : PCI device function.
Vendor and device information is stored in a centralized [[http://pci-ids.ucw.cz/|PCI ID repository]], so you can figure out what a given device is by decoding the PCI data manually.
----
===== Obtain Information on a specific PCI device =====
cd /sys/devices/pci0000:00/0000:00:03.0
ls -al
returns:
total 0
drwxr-xr-x 4 root root 0 Jan 29 03:47 .
drwxr-xr-x 28 root root 0 Jan 23 13:03 ..
-r--r--r-- 1 root root 4.0K Jan 29 10:35 ari_enabled
-rw-r--r-- 1 root root 4.0K Jan 29 10:35 broken_parity_status
-r--r--r-- 1 root root 4.0K Jan 29 10:35 class
-rw-r--r-- 1 root root 4.0K Jan 29 10:35 config
-r--r--r-- 1 root root 4.0K Jan 29 10:35 consistent_dma_mask_bits
-rw-r--r-- 1 root root 4.0K Jan 29 10:35 d3cold_allowed
-r--r--r-- 1 root root 4.0K Jan 29 03:47 device
-r--r--r-- 1 root root 4.0K Jan 29 10:35 dma_mask_bits
-rw-r--r-- 1 root root 4.0K Jan 29 10:35 driver_override
-rw-r--r-- 1 root root 4.0K Jan 29 10:35 enable
lrwxrwxrwx 1 root root 0 Jan 29 10:35 iommu -> ../0000:00:00.2/iommu/ivhd0
lrwxrwxrwx 1 root root 0 Jan 29 10:35 iommu_group -> ../../../kernel/iommu_groups/3
-r--r--r-- 1 root root 4.0K Jan 29 10:35 irq
drwxr-xr-x 2 root root 0 Jan 29 10:35 link
-r--r--r-- 1 root root 4.0K Jan 29 10:35 local_cpulist
-r--r--r-- 1 root root 4.0K Jan 29 10:35 local_cpus
-r--r--r-- 1 root root 4.0K Jan 29 10:35 modalias
-rw-r--r-- 1 root root 4.0K Jan 29 10:35 msi_bus
-rw-r--r-- 1 root root 4.0K Jan 29 10:35 numa_node
drwxr-xr-x 2 root root 0 Jan 29 10:35 power
--w--w---- 1 root root 4.0K Jan 29 10:35 remove
--w------- 1 root root 4.0K Jan 29 10:35 rescan
-r--r--r-- 1 root root 4.0K Jan 29 10:35 resource
-r--r--r-- 1 root root 4.0K Jan 29 03:47 revision
lrwxrwxrwx 1 root root 0 Jan 29 03:47 subsystem -> ../../../bus/pci
-r--r--r-- 1 root root 4.0K Jan 29 10:35 subsystem_device
-r--r--r-- 1 root root 4.0K Jan 29 10:35 subsystem_vendor
-rw-r--r-- 1 root root 4.0K Jan 29 03:47 uevent
-r--r--r-- 1 root root 4.0K Jan 29 03:47 vendor
----
**NOTE:** Each sysfs entry contains a unique piece of data, such as the PCI vendor id (vendor) the device class (class), the device identifier (device), and information on irq and resource assignments.
==== Get Vendor ====
cat vendor 0x14e4
returns:
0x1022
----
==== Get Device ====
cat device
returns:
0x1482
----
==== Get Class ====
cat class
returns:
0x060000
----
===== Viewing PCI data with lspci =====
View the devices connected to your system:
lspci | tail -10
returns:
06:00.3 USB controller: Advanced Micro Devices, Inc. [AMD] Matisse USB 3.0 Host Controller
07:00.0 SATA controller: Advanced Micro Devices, Inc. [AMD] FCH SATA Controller [AHCI mode] (rev 51)
08:00.0 SATA controller: Advanced Micro Devices, Inc. [AMD] FCH SATA Controller [AHCI mode] (rev 51)
09:00.0 VGA compatible controller: NVIDIA Corporation GP107 [GeForce GTX 1050 Ti] (rev a1)
09:00.1 Audio device: NVIDIA Corporation GP107GL High Definition Audio Controller (rev a1)
0a:00.0 Non-Essential Instrumentation [1300]: Advanced Micro Devices, Inc. [AMD] Starship/Matisse PCIe Dummy Function
0b:00.0 Non-Essential Instrumentation [1300]: Advanced Micro Devices, Inc. [AMD] Starship/Matisse Reserved SPP
0b:00.1 Encryption controller: Advanced Micro Devices, Inc. [AMD] Starship/Matisse Cryptographic Coprocessor PSPCPP
0b:00.3 USB controller: Advanced Micro Devices, Inc. [AMD] Matisse USB 3.0 Host Controller
0b:00.4 Audio device: Advanced Micro Devices, Inc. [AMD] Starship/Matisse HD Audio Controller
**NOTE:** lspci read through the sysfs entries and decoded the vendor and device numbers using the vendor and device information in **/usr/share/hwdata/pci.ids**.
lspci uses libpci, which returns the data using the PCI identification data in /usr/share/hwdata/pci.ids.
----
lspci -n | tail -10
returns:
06:00.3 0c03: 1022:149c
07:00.0 0106: 1022:7901 (rev 51)
08:00.0 0106: 1022:7901 (rev 51)
09:00.0 0300: 10de:1c82 (rev a1)
09:00.1 0403: 10de:0fb9 (rev a1)
0a:00.0 1300: 1022:148a
0b:00.0 1300: 1022:1485
0b:00.1 1080: 1022:1486
0b:00.3 0c03: 1022:149c
0b:00.4 0403: 1022:1487
**NOTE:** lspci displays the raw PCI identification data.
----
==== Expand on one device ====
As an example, taking this from above list:
09:00.0 0300: 10de:1c82 (rev a1)
**NOTE:**
* 09:00.0 : Bus number (09), Device number (00) and Function (0).
* 0300 : Device class.
* 10de : Vendor ID.
* 1c82 : Device ID.
Looking up the identifiers in the [[http://pci-ids.ucw.cz/|PCI ID repository]]:
* 0300 : Device class => Display controller.
* 10de : Vendor ID => NVIDIA Corporation.
* 1c82 : Device ID => GP107 [GeForce GTX 1050 Ti].
which matches the output from the default **lspci | tail -10**:
09:00.0 VGA compatible controller: NVIDIA Corporation GP107 [GeForce GTX 1050 Ti] (rev a1)
----
===== Updating the PCI identification list =====
The lspci utility uses the pci.ids file to determine the vendor and device type.
This file will grow as new vendors and devices are added, and can be updated automatically by running the update-pciids utility:
/sbin/update-pciids
returns:
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 264k 100 264k 0 0 494k 0 --:--:-- --:--:-- --:--:-- 493k
----
===== References =====
http://pci-ids.ucw.cz/
http://www.pcisig.com/home