Skip to content

Instantly share code, notes, and snippets.

@joevt

joevt/pcitree.sh

Last active Apr 7, 2021
Embed
What would you like to do?
A bash script to produce more informative output than lspci -nntv
#!/bin/bash
# by joevt May 8, 2020
#===================
if [[ $EUID -ne 0 ]]; then
echo "This script must be run as root like this:"
echo "sudo $0"
exit 1
fi
#===================
style="wide"
style="narrow"
encoding="ascii"
encoding="utf8"
#method="-H1" # -A intel-conf1
method="" # default method which for macOS is -A darwin
#===================
if [ $encoding == "ascii" ]; then
box='\-\+|.'
else
box='┐─└├│┬'
fi
if [ $style == "wide" ]; then
if [ $encoding == "ascii" ]; then
# since we're using \, we want to indent one extra space
rootindent=' '
subindent=' '
else
rootindent=' '
subindent=' '
fi
domainprefix="\\${box:1:1}\\["
domainsuffix="\\]\\${box:1:1}\\${box:0:1}"
bridgeprefix="\\${box:3:1}\\${box:1:1}"
bridgesuffixlong="\\${box:1:1}\\${box:1:1}\\${box:1:1}\\${box:1:1}\\${box:0:1}"
bridgesuffix="\\${box:1:1}\\${box:0:1}"
deviceprefix="\\${box:3:1}\\${box:1:1}"
devicesuffix=""
else
rootindent=''
subindent=' '
domainprefix="\\${box:5:1}\\["
domainsuffix="\\]"
bridgeprefix="\\${box:3:1}\\${box:5:1}"
bridgesuffixlong=""
bridgesuffix=""
deviceprefix="\\${box:3:1}\\${box:1:1}"
devicesuffix=""
fulladdress=1
fi
#===================
# Get header type and bus information for all pci devices - reverse sort so last bus is first (required for device path substitution step below).
# Format is "domain:bus%device.function domain:primary domain:secondary domain:subordinate".
# Keep the domain number for device path substitution step below.
# -0777 allows perl to process all lines at once - here we process two lines at a time.
setpci $method -v -s '*:*:*' HEADER_TYPE.b PRIMARY_BUS.l 2> /dev/null | perl -0777 -pe '
s/((.{4}):(..):(..\..)) \@0e = ([08][12])\n\g1 \@18 = ..(.{2})(.{2})(.{2})\n/$2:$3%$4 $2:$8 $2:$7 $2:$6\n/g; # bridge(01) or card bus(02) header type, multifunction(80) or not (00).
s/((.{4}):(..):(..\..)) \@0e = (..)\n\g1 \@18 = ..(.{2})(.{2})(.{2})\n/$2:$3%$4\n/g # endpoint (or anything else) header type
' \
| sort -r > /tmp/pcilist.txt
# If primary = secondary = subordinate then that is a problem - change them to XX.
sed '/^\(....:..%..\..\) \(\(.\{4\}:\)..\) \2 \2$/s//\1 \3XX \3XX \3XX/' /tmp/pcilist.txt > /tmp/pcilist2.txt
echo '/ ....:/s// /g' > /tmp/pcipaths.txt # Add a command that will remove domain from primary, secondary, and subordinate bus numbers.
# Create device path substitution commands that will add parent bus to each secondary bus.
# When applied to the list of pci devices, the commands will create a full device path for
# each pci device. Multiple commands will be applied to each device to build the device
# path from right to left: end point (greatest bus number) to domain (lowest bus number).
# The commands are sorted from highest bus number to lowest bus number to make that possible.
sed -nE '/^(....:..%..\..) .{4}:.. (.{4}:..) .*/s//\/(\2)\/s\/\/\1%\\1\/g/p' /tmp/pcilist2.txt >> /tmp/pcipaths.txt
sed -E -f /tmp/pcipaths.txt /tmp/pcilist2.txt > /tmp/pcitree1.txt # Apply the device path substitution commands.
sed -E '/^(....:..).*/s//\1/g' /tmp/pcitree1.txt | sort -u > /tmp/pcitree2.txt # Get all root complexes (usually just 0000:00).
cat /tmp/pcitree1.txt /tmp/pcitree2.txt | LC_ALL=C sort > /tmp/pcitree3.txt # Concatenate the devices and root complexes and sort.
# Use perl to do some formatting.
perl -CSDA -Mutf8 -pe '
s/^(.*(\w\w\w\w:\w\w%\w\w\.\w).*)/\1 # \2/; # save domain/bus/device/function after a " # " - this will be used to append name and ids
s/^\w\w\w\w:\w\w%/'"$rootindent"'/; # remove domain/bus number from left side and indent
s/\w\w\.\w%\w\w\w\w:\w\w%/'"$subindent"'/g; # use the paths to do more indenting
s/(\w\w\.\w) \w\w (\w\w) \g2/'"${bridgeprefix}"'\1-[\2]'"${bridgesuffixlong}"'/; # format the secondary and subordinate bus numbers for single bus bridge
s/(\w\w\.\w) \w\w (\w\w) (\w\w)/'"${bridgeprefix}"'\1-[\2-\3]'"${bridgesuffix}"'/; # format the secondary and subordinate bus numbers for multiple bus bridge
s/%/:/; # replace % bus/device delimiter with standard ":"
s/(\w\w\.\w )/'"${deviceprefix}"'\1'"${devicesuffix}"'/; # add the "+-" formating for devices
s/^(\w\w\w\w:\w\w)$/'"${domainprefix}"'\1'"${domainsuffix}"'/ # add the -[ ]\" for domain/bus
' \
/tmp/pcitree3.txt > /tmp/pcitree4.txt
# https://perldoc.perl.org/perlrun.html
# The -C flag controls some of the Perl Unicode features.
# S: STDIN, STDOUT and STDERR are assumed to be in UTF-8.
# D: UTF-8 is the default PerlIO layer for both input and output streams.
# A: @ARGV elements are expected to be strings encoded in UTF-8.
# -0[octal/hexadecimal] specifies the input record separator ($/ ) as an octal or hexadecimal number.
# Any value 0400 or above will cause Perl to slurp files whole, but by convention the value 0777 is the one normally used for this purpose.
# -Mmodule executes use module ; before executing your program. This loads the module and calls its import method, causing the module to have its default effect, typically importing subroutines or giving effect to a pragma.
# -p causes Perl to assume a loop around your program, which makes it iterate over filename arguments somewhat like sed.
# -e commandline May be used to enter one line of program.
perl -CSDA -Mutf8 -0777 -pe '
# add | between devices of the same bus
do {
$good=0;
while (
/ # begin regular expression
( # begin g1
\n # \n
([\ '"\\${box:4:1}"']*) # [ |]* -> g2
['"\\${box:3:1}\\${box:4:1}"'] # [+|]
[^\n]*+ # rest of the line up to \n, give nothing back
(?{$X=pos()}) # mark position
\n # \n
) # end g1
(?= # begin lookahead
( # begin group
\g2\ [^\n]*+ # following line(s) start with g2 also
\n #
)++ # end group, match one or more, give nothing back
\g2 # the line after those start with g2
'"\\${box:3:1}"' # and "+" meaning that another device follows g1 on the same bus
) # end lookahead
(
\g2 #
(?{$C=pos()}) # $C is the position where we want to insert the |
\ # the character at position $C to be modified is a space character
) #
/gx # end regular expression
) {
$good = 1;
substr($_,$C,1) = "'"\\${box:4:1}"'"; # replace the space character at position $C with a |
pos() = $X; # start next search at $X which is the end of the previous line
}
} until ($good == 0);
# replace + with \ for last device of a bus
s/(\n[\ '"\\${box:4:1}"']*)'"\\${box:3:1}"'(?![^\n]*\g1['"\\${box:3:1}\\${box:4:1}"'])/\1'"\\${box:2:1}"'/g;
' /tmp/pcitree4.txt > /tmp/pcitree5.txt
# Get the length of the longest line so we can align device information in a detail column.
spaces=$(sed -E 's/./ /g' /tmp/pcitree5.txt | sort -r | head -n 1)
lspci $method -nn -D 2> /dev/null > /tmp/pcidevices0.txt
perl -pe '
s/\//\\\//g;
s/^(....:..:..\..) ([^[]*) (\[....\])(.*) (\[....:....\])(( \(rev ..\)))?/\/# (\1)\$\/s\/\/'" "'# \\1 \5 \3:\7 : \2 \4\//;
s/\]:([^:]{9}.*?) *:([^:]{26}.*?) *:/]\1\2 :/ # rev column is 9 characters and type column is 25 characters
' \
> /tmp/pcidevices1.txt < /tmp/pcidevices0.txt
echo '/^(.{'"$((${#spaces} - 14))"'}) *(.*)/s//\1\2/' >> /tmp/pcidevices1.txt # create the substitutions for the detail column
# Get link width and speed max/current.
pat="(....:..:..\..) @00 = (....)(....)"
IFS=$'\n'
echo "" > /tmp/pcidevices2.txt
for thedevice in $(sudo setpci $method -v -s '*:*:*' VENDOR_ID.l 2> /dev/null); do
if [[ $thedevice =~ $pat ]]; then
pcidevice=${BASH_REMATCH[1]}
# We have to do this in a loop because setpci stops if express capability doesn't exist
LinkRegisters=$(sudo setpci $method -s $pcidevice CAP_EXP+12.w CAP_EXP+c.l 2> /dev/null)
if [[ -n $LinkRegisters ]]; then
LinkStatusRegister=${LinkRegisters:0:4}
LinkWidth=$((0x$LinkStatusRegister >> 4 & 31))
if [[ $LinkWidth -ge 0 ]]; then
LinkSpeed=$((0x$LinkStatusRegister & 15))
LinkCapabilitiesRegister=${LinkRegisters:5:8}
MaxLinkWidth=$((0x$LinkCapabilitiesRegister >> 4 & 31))
MaxLinkSpeed=$((0x$LinkCapabilitiesRegister & 15))
echo "/# ($pcidevice .*$)/s//# g${MaxLinkSpeed}x${MaxLinkWidth} > g${LinkSpeed}x${LinkWidth} \1/" >> /tmp/pcidevices2.txt
fi
fi
else
echo "# Unexpected pattern $thedevice"
fi
done
perl -CSDA -Mutf8 -pe '
s/# (g.x..?) > \g1 /# \1 /;
s/(\/s\/\/#.{16}) */\1/;
' -i /tmp/pcidevices2.txt
# If there's only one domain/segment then remove them from the output.
if [[ $(wc -l < /tmp/pcitree2.txt) -eq 1 ]]; then
echo "/(#.{16}).{4}:/s//\\1/" >> /tmp/pcidevices2.txt
fi
if [[ $fulladdress -eq 1 ]]; then
echo "/..\..([^#]*#.{16})([0-9a-f.:]+) /s//\\2\\1/" >> /tmp/pcidevices2.txt
fi
sed -E -f /tmp/pcidevices1.txt -f /tmp/pcidevices2.txt /tmp/pcitree5.txt > /tmp/pcitree6.txt # apply the substitutions
echo '#========================================================================================='
cat /tmp/pcitree6.txt # final output
@joevt

This comment has been minimized.

Copy link
Owner Author

@joevt joevt commented May 9, 2020

Tested in Ubuntu and macOS. Use it like this:
sudo pcitree.sh
Output should look like this:

#=========================================================================================
┬[0000:00]
├─00:00.0             # g1x4           [8086:4003] [0600] (rev 20) Host bridge               : Intel Corporation 5400 Chipset Memory Controller Hub
├┬00:01.0-[21-3b]     # g2x16          [8086:4021] [0604] (rev 20) PCI bridge                : Intel Corporation 5400 Chipset PCI Express Port 1
│└┬21:00.0-[22-3b]    # g3x16 > g2x16  [10b5:8747] [0604] (rev ca) PCI bridge                : PLX Technology, Inc. PEX 8747 48-Lane, 5-Port PCI Express Gen 3 (8.0 GT/s) Switch
│ ├┬22:08.0-[29-2e]   # g3x8 > g3x4    [10b5:8747] [0604] (rev ca) PCI bridge                : PLX Technology, Inc. PEX 8747 48-Lane, 5-Port PCI Express Gen 3 (8.0 GT/s) Switch
│ │└┬29:00.0-[2a-2e]  # g3x4           [8086:15ea] [0604] (rev 06) PCI bridge                : Intel Corporation JHL7540 Thunderbolt 3 Bridge [Titan Ridge 4C 2018]
│ │ ├┬2a:00.0-[2e]    # g1x4           [8086:15ea] [0604] (rev 06) PCI bridge                : Intel Corporation JHL7540 Thunderbolt 3 Bridge [Titan Ridge 4C 2018]
│ │ │└─2e:00.0        # g1x4           [8086:15eb] [0880] (rev 06) System peripheral         : Intel Corporation JHL7540 Thunderbolt 3 NHI [Titan Ridge 4C 2018]
│ │ ├┬2a:01.0-[2d]    # g1x4           [8086:15ea] [0604] (rev 06) PCI bridge                : Intel Corporation JHL7540 Thunderbolt 3 Bridge [Titan Ridge 4C 2018]
│ │ ├┬2a:02.0-[2c]    # g1x4           [8086:15ea] [0604] (rev 06) PCI bridge                : Intel Corporation JHL7540 Thunderbolt 3 Bridge [Titan Ridge 4C 2018]
│ │ │└─2c:00.0        # g1x4           [8086:15ec] [0c03] (rev 06) USB controller            : Intel Corporation JHL7540 Thunderbolt 3 USB Controller [Titan Ridge 4C 2018]
│ │ └┬2a:04.0-[2b]    # g1x4           [8086:15ea] [0604] (rev 06) PCI bridge                : Intel Corporation JHL7540 Thunderbolt 3 Bridge [Titan Ridge 4C 2018]
│ ├┬22:09.0-[23-28]   # g3x8 > g3x4    [10b5:8747] [0604] (rev ca) PCI bridge                : PLX Technology, Inc. PEX 8747 48-Lane, 5-Port PCI Express Gen 3 (8.0 GT/s) Switch
│ │└┬23:00.0-[24-28]  # g3x4           [8086:15ea] [0604] (rev 06) PCI bridge                : Intel Corporation JHL7540 Thunderbolt 3 Bridge [Titan Ridge 4C 2018]
│ │ ├┬24:00.0-[28]    # g1x4           [8086:15ea] [0604] (rev 06) PCI bridge                : Intel Corporation JHL7540 Thunderbolt 3 Bridge [Titan Ridge 4C 2018]
│ │ │└─28:00.0        # g1x4           [8086:15eb] [0880] (rev 06) System peripheral         : Intel Corporation JHL7540 Thunderbolt 3 NHI [Titan Ridge 4C 2018]
│ │ ├┬24:01.0-[27]    # g1x4           [8086:15ea] [0604] (rev 06) PCI bridge                : Intel Corporation JHL7540 Thunderbolt 3 Bridge [Titan Ridge 4C 2018]
│ │ ├┬24:02.0-[26]    # g1x4           [8086:15ea] [0604] (rev 06) PCI bridge                : Intel Corporation JHL7540 Thunderbolt 3 Bridge [Titan Ridge 4C 2018]
│ │ │└─26:00.0        # g1x4           [8086:15ec] [0c03] (rev 06) USB controller            : Intel Corporation JHL7540 Thunderbolt 3 USB Controller [Titan Ridge 4C 2018]
│ │ └┬24:04.0-[25]    # g1x4           [8086:15ea] [0604] (rev 06) PCI bridge                : Intel Corporation JHL7540 Thunderbolt 3 Bridge [Titan Ridge 4C 2018]
│ ├┬22:10.0-[30-35]   # g3x8 > g3x4    [10b5:8747] [0604] (rev ca) PCI bridge                : PLX Technology, Inc. PEX 8747 48-Lane, 5-Port PCI Express Gen 3 (8.0 GT/s) Switch
│ │└┬30:00.0-[31-35]  # g3x4           [8086:1578] [0604]          PCI bridge                : Intel Corporation DSL6540 Thunderbolt 3 Bridge [Alpine Ridge 4C 2015]
│ │ ├┬31:00.0-[35]    # g1x4           [8086:1578] [0604]          PCI bridge                : Intel Corporation DSL6540 Thunderbolt 3 Bridge [Alpine Ridge 4C 2015]
│ │ │└─35:00.0        # g1x4           [8086:1577] [0880]          System peripheral         : Intel Corporation DSL6540 Thunderbolt 3 NHI [Alpine Ridge 4C 2015]
│ │ ├┬31:01.0-[34]    # g1x4           [8086:1578] [0604]          PCI bridge                : Intel Corporation DSL6540 Thunderbolt 3 Bridge [Alpine Ridge 4C 2015]
│ │ ├┬31:02.0-[33]    # g1x4           [8086:1578] [0604]          PCI bridge                : Intel Corporation DSL6540 Thunderbolt 3 Bridge [Alpine Ridge 4C 2015]
│ │ │└─33:00.0        # g1x4           [8086:15b6] [0c03]          USB controller            : Intel Corporation DSL6540 USB 3.1 Controller [Alpine Ridge]
│ │ └┬31:04.0-[32]    # g1x4           [8086:1578] [0604]          PCI bridge                : Intel Corporation DSL6540 Thunderbolt 3 Bridge [Alpine Ridge 4C 2015]
│ └┬22:11.0-[36-3b]   # g3x8 > g3x4    [10b5:8747] [0604] (rev ca) PCI bridge                : PLX Technology, Inc. PEX 8747 48-Lane, 5-Port PCI Express Gen 3 (8.0 GT/s) Switch
│  └┬36:00.0-[37-3b]  # g3x4           [8086:1578] [0604]          PCI bridge                : Intel Corporation DSL6540 Thunderbolt 3 Bridge [Alpine Ridge 4C 2015]
│   ├┬37:00.0-[3b]    # g1x4           [8086:1578] [0604]          PCI bridge                : Intel Corporation DSL6540 Thunderbolt 3 Bridge [Alpine Ridge 4C 2015]
│   │└─3b:00.0        # g1x4           [8086:1577] [0880]          System peripheral         : Intel Corporation DSL6540 Thunderbolt 3 NHI [Alpine Ridge 4C 2015]
│   ├┬37:01.0-[3a]    # g1x4           [8086:1578] [0604]          PCI bridge                : Intel Corporation DSL6540 Thunderbolt 3 Bridge [Alpine Ridge 4C 2015]
│   ├┬37:02.0-[39]    # g1x4           [8086:1578] [0604]          PCI bridge                : Intel Corporation DSL6540 Thunderbolt 3 Bridge [Alpine Ridge 4C 2015]
│   │└─39:00.0        # g1x4           [8086:15b6] [0c03]          USB controller            : Intel Corporation DSL6540 USB 3.1 Controller [Alpine Ridge]
│   └┬37:04.0-[38]    # g1x4           [8086:1578] [0604]          PCI bridge                : Intel Corporation DSL6540 Thunderbolt 3 Bridge [Alpine Ridge 4C 2015]
├┬00:05.0-[11]        # g2x16 > g1x16  [8086:4025] [0604] (rev 20) PCI bridge                : Intel Corporation 5400 Chipset PCI Express Port 5
│├─11:00.0            # g2x16 > g1x16  [10de:1180] [0300] (rev a1) VGA compatible controller : NVIDIA Corporation GK104 [GeForce GTX 680]
│└─11:00.1            # g2x16 > g1x16  [10de:0e0a] [0403] (rev a1) Audio device              : NVIDIA Corporation GK104 HDMI Audio Controller
├┬00:09.0-[12-1a]     # g2x4 > g1x4    [8086:4029] [0604] (rev 20) PCI bridge                : Intel Corporation 5400 Chipset PCI Express Port 9
│├┬12:00.0-[13-19]    # g1x8 > g1x4    [8086:3500] [0604] (rev 01) PCI bridge                : Intel Corporation 6311ESB/6321ESB PCI Express Upstream Port
││├┬13:00.0-[14-17]   # g1x4           [8086:3510] [0604] (rev 01) PCI bridge                : Intel Corporation 6311ESB/6321ESB PCI Express Downstream Port E1
│││└┬14:00.0-[15-17]  # g2x4 > g1x4    [12d8:2308] [0604]          PCI bridge                : Pericom Semiconductor Device
│││ ├┬15:01.0-[16]    # g2x2           [12d8:2308] [0604]          PCI bridge                : Pericom Semiconductor Device
│││ │└─16:00.0        # g2x2           [1b21:1242] [0c03]          USB controller            : ASMedia Technology Inc. ASM1142 USB 3.1 Host Controller
│││ └┬15:02.0-[17]    # g2x2           [12d8:2308] [0604]          PCI bridge                : Pericom Semiconductor Device
│││  └─17:00.0        # g2x2           [1b21:0625] [0106] (rev 01) SATA controller           : ASMedia Technology Inc. Device
││├┬13:01.0-[18]      # g1x4 > g1x0    [8086:3514] [0604] (rev 01) PCI bridge                : Intel Corporation 6311ESB/6321ESB PCI Express Downstream Port E2
││└┬13:02.0-[19]      # g1x4           [8086:3518] [0604] (rev 01) PCI bridge                : Intel Corporation 6311ESB/6321ESB PCI Express Downstream Port E3
││ ├─19:00.0          # g1x4           [8086:1096] [0200] (rev 01) Ethernet controller       : Intel Corporation 80003ES2LAN Gigabit Ethernet Controller (Copper)
││ └─19:00.1          # g1x4           [8086:1096] [0200] (rev 01) Ethernet controller       : Intel Corporation 80003ES2LAN Gigabit Ethernet Controller (Copper)
│└┬12:00.3-[1a]       # g1x8 > g1x4    [8086:350c] [0604] (rev 01) PCI bridge                : Intel Corporation 6311ESB/6321ESB PCI Express to PCI-X Bridge
├─00:0f.0             # g0x0           [8086:402f] [0880] (rev 20) System peripheral         : Intel Corporation 5400 Chipset QuickData Technology Device
├─00:10.0             #                [8086:4030] [0600] (rev 20) Host bridge               : Intel Corporation 5400 Chipset FSB Registers
├─00:10.1             #                [8086:4030] [0600] (rev 20) Host bridge               : Intel Corporation 5400 Chipset FSB Registers
├─00:10.2             #                [8086:4030] [0600] (rev 20) Host bridge               : Intel Corporation 5400 Chipset FSB Registers
├─00:10.3             #                [8086:4030] [0600] (rev 20) Host bridge               : Intel Corporation 5400 Chipset FSB Registers
├─00:10.4             #                [8086:4030] [0600] (rev 20) Host bridge               : Intel Corporation 5400 Chipset FSB Registers
├─00:11.0             #                [8086:4031] [0600] (rev 20) Host bridge               : Intel Corporation 5400 Chipset CE/SF Registers
├─00:15.0             #                [8086:4035] [0600] (rev 20) Host bridge               : Intel Corporation 5400 Chipset FBD Registers
├─00:15.1             #                [8086:4035] [0600] (rev 20) Host bridge               : Intel Corporation 5400 Chipset FBD Registers
├─00:16.0             #                [8086:4036] [0600] (rev 20) Host bridge               : Intel Corporation 5400 Chipset FBD Registers
├─00:16.1             #                [8086:4036] [0600] (rev 20) Host bridge               : Intel Corporation 5400 Chipset FBD Registers
├─00:1b.0             # g0x0           [8086:269a] [0403] (rev 09) Audio device              : Intel Corporation 631xESB/632xESB High Definition Audio Controller
├┬00:1c.0-[1b]        # g1x1 > g1x0    [8086:2690] [0604] (rev 09) PCI bridge                : Intel Corporation 631xESB/632xESB/3100 Chipset PCI Express Root Port 1
├┬00:1c.1-[1c]        # g1x1 > g1x0    [8086:2692] [0604] (rev 09) PCI bridge                : Intel Corporation 631xESB/632xESB/3100 Chipset PCI Express Root Port 2
├┬00:1c.2-[1d-1e]     # g1x1           [8086:2694] [0604] (rev 09) PCI bridge                : Intel Corporation 631xESB/632xESB/3100 Chipset PCI Express Root Port 3
│└┬1d:00.0-[1e]       # g1x1           [104c:823e] [0604]          PCI bridge                : Texas Instruments XIO2213A/B/XIO2221 PCI Express to PCI Bridge [Cheetah Express]
│ └─1e:00.0           #                [104c:823f] [0c00]          FireWire (IEEE 1394)      : Texas Instruments XIO2213A/B/XIO2221 IEEE-1394b OHCI Controller [Cheetah Express]
├┬00:1c.3-[1f]        # g1x1           [8086:2696] [0604] (rev 09) PCI bridge                : Intel Corporation 631xESB/632xESB/3100 Chipset PCI Express Root Port 4
│└─1f:00.0            # g1x1           [14e4:4328] [0280] (rev 03) Network controller        : Broadcom Inc. and subsidiaries BCM4321 802.11a/b/g/n
├─00:1d.0             #                [8086:2688] [0c03] (rev 09) USB controller            : Intel Corporation 631xESB/632xESB/3100 Chipset UHCI USB Controller #1
├─00:1d.1             #                [8086:2689] [0c03] (rev 09) USB controller            : Intel Corporation 631xESB/632xESB/3100 Chipset UHCI USB Controller #2
├─00:1d.2             #                [8086:268a] [0c03] (rev 09) USB controller            : Intel Corporation 631xESB/632xESB/3100 Chipset UHCI USB Controller #3
├─00:1d.3             #                [8086:268b] [0c03] (rev 09) USB controller            : Intel Corporation 631xESB/632xESB/3100 Chipset UHCI USB Controller #4
├─00:1d.7             #                [8086:268c] [0c03] (rev 09) USB controller            : Intel Corporation 631xESB/632xESB/3100 Chipset EHCI USB2 Controller
├┬00:1e.0-[20]        #                [8086:244e] [0604] (rev d9) PCI bridge                : Intel Corporation 82801 PCI Bridge
├─00:1f.0             #                [8086:2670] [0601] (rev 09) ISA bridge                : Intel Corporation 631xESB/632xESB/3100 Chipset LPC Interface Controller
├─00:1f.1             #                [8086:269e] [0101] (rev 09) IDE interface             : Intel Corporation 631xESB/632xESB IDE Controller
├─00:1f.2             #                [8086:2681] [0106] (rev 09) SATA controller           : Intel Corporation 631xESB/632xESB SATA AHCI Controller
└─00:1f.3             #                [8086:269b] [0c05] (rev 09) SMBus                     : Intel Corporation 631xESB/632xESB/3100 Chipset SMBus Controller
@joevt

This comment has been minimized.

Copy link
Owner Author

@joevt joevt commented Jul 24, 2020

Setup

The script should work unmodified for Linux.

For macOS El Capitan or earlier, DirectHW.kext is required. For PPC and M1 Macs, a modified DirectHW.kext is probably required (doesn't exist yet?)

For Intel Macs running macOS Sierra or later without DirectHW.kext, nvram boot-args must have at least this: debug=0x144. If it does not, then add it:
sudo nvram boot-args="debug=0x144"
(don't forget to include the existing contents of boot-args inside the quotes)
This may require SIP to be disabled, otherwise execute the command without sudo in Recovery's Terminal.app.

Download the script

cd ~
git clone https://gist.github.com/e3cd4ff08aae06279134969c98ca3ab7.git pcitree
cd pcitree
chmod +x pcitree.sh

(Optional) Install pciutils (this example uses my fork)

If the lspci command doesn't exist already (likely for macOS but not Linux), then you need to install pciutils.

cd ~
git clone https://github.com/joevt/pciutils.git
cd pciutils
make
sudo make install
grep -q /usr/local/sbin /etc/paths || sudo sed -e $'1i\\\n/usr/local/sbin\\\n' -i "" /etc/paths
cd ~

Create a new Terminal window to start using the new commands.

Occasionally, update the pciids database:

sudo update-pciids

Test the pciutils commands (-A detect is new option in my fork):

sudo lspci -A detect
sudo lspci

Finally, try the pcitree script:

cd ~/pcitree
sudo ./pcitree.sh
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment