| 2088 | | # This function returns a hash of hashes. Each hash has some PCI information: |
| | 2088 | # This function returns a list of hashes. Each hash has some PCI information: |
| | 2089 | # 'domain', 'bus', 'slot' and 'func' uniquely identify a PCI device in a |
| | 2090 | # computer; 'vendid' and 'devid' uniquely identify a type of device. |
| | 2091 | # 'class' lets us spot unknown SMBus adapters. |
| | 2092 | # This function is used when sysfs is available (Linux 2.6). |
| | 2093 | sub read_sys_dev_pci($) |
| | 2094 | { |
| | 2095 | my $devices = shift; |
| | 2096 | my ($dev, @pci_list); |
| | 2097 | |
| | 2098 | opendir(local *DEVICES, "$devices") |
| | 2099 | or die "$devices: $!"; |
| | 2100 | |
| | 2101 | while (defined($dev = readdir(DEVICES))) { |
| | 2102 | my %record; |
| | 2103 | next unless $dev =~ |
| | 2104 | m/^(?:([\da-f]+):)?([\da-f]+):([\da-f]+)\.([\da-f]+)$/; |
| | 2105 | |
| | 2106 | $record{domain} = hex $1; |
| | 2107 | $record{bus} = hex $2; |
| | 2108 | $record{slot} = hex $3; |
| | 2109 | $record{func} = hex $4; |
| | 2110 | |
| | 2111 | $record{vendid} = oct sysfs_device_attribute("$devices/$dev", "vendor"); |
| | 2112 | $record{devid} = oct sysfs_device_attribute("$devices/$dev", "device"); |
| | 2113 | $record{class} = (oct sysfs_device_attribute("$devices/$dev", "class")) |
| | 2114 | >> 8; |
| | 2115 | |
| | 2116 | push @pci_list, \%record; |
| | 2117 | } |
| | 2118 | |
| | 2119 | return \@pci_list; |
| | 2120 | } |
| | 2121 | |
| | 2122 | # This function returns a list of hashes. Each hash has some PCI information: |
| 2113 | | %pci_list = read_proc_dev_pci; |
| 2114 | | die "Can't access /proc/bus/pci/devices!" if not defined %pci_list; |
| | 2148 | my $pci_list; |
| | 2149 | |
| | 2150 | if (defined $sysfs_root) { |
| | 2151 | $pci_list = read_sys_dev_pci("$sysfs_root/bus/pci/devices"); |
| | 2152 | } else { |
| | 2153 | $pci_list = read_proc_dev_pci(); |
| | 2154 | } |
| | 2155 | |
| | 2156 | # Note that we lose duplicate devices at this point, but we don't |
| | 2157 | # really care. What matters to us is which unique devices are present, |
| | 2158 | # not how many of each. |
| | 2159 | %pci_list = map { |
| | 2160 | sprintf("%04x:%04x", $_->{vendid}, $_->{devid}) => $_ |
| | 2161 | } @{$pci_list}; |
| 2179 | | $device->{bus},$device->{slot},$device->{func},$try->{procid}; |
| | 2226 | (defined $device->{domain} ? |
| | 2227 | sprintf("\%04x:\%02x:\%02x.\%x", $device->{domain}, |
| | 2228 | $device->{bus}, $device->{slot}, $device->{func}) : |
| | 2229 | sprintf("\%02x:\%02x.\%x", |
| | 2230 | $device->{bus}, $device->{slot}, $device->{func})), |
| | 2231 | $try->{procid}; |