22

In Linux, is there a way to find out which PCI card is plugged into which PCI slot?

/sys/bus/pci/devices/ contains many devices (bridges, CPU channels, etc.) that are not cards and I was not able to find any information about slot-card mappings in the device directories.

magmabyte
  • 397
  • 1
  • 2
  • 10
  • could be worth setting up some udev rules: https://wiki.archlinux.org/index.php/udev – James Sep 18 '14 at 09:31
  • You use this is for fixed device symlinks, right? Looks interesting, though I want the physical mapping (like "PCI card x" connected to "Mainboard PCI slot y"). – magmabyte Sep 18 '14 at 09:43

3 Answers3

29

You can use

dmidecode –t slot

to find all available pci slots than you can run

lspci -s <slot number>

command to list device connected to specified slot. You must take bus address from first command and use this address as parameter in second command.

magmabyte
  • 397
  • 1
  • 2
  • 10
Nebojsa Susic
  • 1,220
  • 1
  • 9
  • 12
  • 1
    I get slot Slot 1-3 with dmidecode. lspci -s with these slot numbers return me each two devices from type "PCI bridge" (so 6 total). If I use lspci and grep for "PCI bridge" I get 14 devices total. I have 3 physical slots so which ones are they? – magmabyte Sep 19 '14 at 13:14
  • dmidecode requires that the bios is new enough, in order to show pci address for each slot, and many bioses encodes this information wrong. You can always try to nag on your mainboard vendor if the information given by dmidecode is wrong or incomplete. – Stian Skjelstad Apr 20 '19 at 16:44
  • 1
    For me `sudo dmidecode -t slot | grep Bus` returns addresses that look like `0000:02:1c.3` and I need to run `lspci -vvnn -s 0000:02:00` to get respective data about the hardware attached (note that I need to zero the 3rd group in address). Is that the expected result or is this a BIOS bug? For manual matching, `lspci -tvnn` and `lspci -vvvnn` is the way to go. – Mikko Rantalainen May 05 '20 at 08:11
7

Nebojsa's answer is good, but here's a little more information and an answer to magmabyte's comment.

dmidecode gives you the number of slots, however, those slots are not the only things using the PCI bridge which is why you see many more devices than slots.

Secondly, you may see multiple "devices" per slot, but they are likely just multiple ports on the same card. To give you an example using network interface cards (NICs):

megaman@someserver $ lspci | grep 10Gb
07:00.0 Ethernet controller: Emulex Corporation OneConnect 10Gb NIC (rev 02)
07:00.1 Ethernet controller: Emulex Corporation OneConnect 10Gb NIC (rev 02)

dmidecode indicates that this server has three slots (and it does). Slot 1 has the 10Gb NIC above (you can see that it has 2 ports), slot 2 has a fibre channel card (which also happens to have 2 ports), and finally slot 3 is empty.

There are three physical slots in the server, one is empty, two are filled with multi port cards (an HBA and a NIC).

To answer your question in the comment, the 3 slots you have are the ones indicated by dmidecode and they are likely populated with multi port interface cards.

Tim
  • 4,790
  • 4
  • 33
  • 41
kodywilson
  • 121
  • 2
  • 2
  • Thanks but I still have not found a reliable way using dmidecode and lspci to definitely match Network card to port. I have done so through logical deduction only on the system I am looking at - the card is PCI and there is only one PCI slot in this server model. – Imran-UK Oct 14 '17 at 11:03
0

In my kickstart, I use the following to determine the NIC to use for the OS. For example, some of our servers use an HPE 562SFP+ 2port 10Gb NIC. It would be:

NICPROD=562
USENIC=''
for NIC in /sys/class/net/e*; do
   NIC=$(basename ${NIC})
   FOUNDNIC=$(lspci -s $(ethtool -i ${NIC} | awk '/bus-info/ { print $2 }' | cut -d: -f2-) -vv  | grep -E 'Product Name:')
   if [[ "${FOUNDNIC}" == *${NICPROD}* && "${FOUNDNIC}" != *"FLR"* ]]; then
      USENIC=${NIC}
      break
   fi
done

Hopefully this helps?

S.B
  • 13,077
  • 10
  • 22
  • 49
user2664304
  • 27
  • 1
  • 5