2
0
mirror of https://github.com/lm-sensors/lm-sensors synced 2025-09-02 23:35:57 +00:00

sensors-detect: Use sysfs for PCI device enumeration where available

(Linux 2.6). Still fallback to /proc (Linux 2.4). sysfs provides the PCI
device domain and class, which were hard to get from /proc.


git-svn-id: http://lm-sensors.org/svn/lm-sensors/trunk@4142 7894878c-1315-0410-8ee3-d5d059ff63e0
This commit is contained in:
Jean Delvare
2006-09-05 10:01:15 +00:00
parent 08253729c3
commit bd012ca251
2 changed files with 63 additions and 10 deletions

View File

@@ -81,6 +81,7 @@ lm_sensors CHANGES file
Attempt to be slightly more user-friendly Attempt to be slightly more user-friendly
Add VT8237A and VT8251 Add VT8237A and VT8251
Remove detection of nVidia graphics adapters Remove detection of nVidia graphics adapters
Use sysfs for PCI device enumeration
2.10.0 (20060214) 2.10.0 (20060214)

View File

@@ -2085,13 +2085,49 @@ sub sysfs_device_attribute($$)
use vars qw(%pci_list); use vars qw(%pci_list);
# This function returns a hash of hashes. Each hash has some PCI information: # This function returns a list of hashes. Each hash has some PCI information:
# 'domain', 'bus', 'slot' and 'func' uniquely identify a PCI device in a
# computer; 'vendid' and 'devid' uniquely identify a type of device.
# 'class' lets us spot unknown SMBus adapters.
# This function is used when sysfs is available (Linux 2.6).
sub read_sys_dev_pci($)
{
my $devices = shift;
my ($dev, @pci_list);
opendir(local *DEVICES, "$devices")
or die "$devices: $!";
while (defined($dev = readdir(DEVICES))) {
my %record;
next unless $dev =~
m/^(?:([\da-f]+):)?([\da-f]+):([\da-f]+)\.([\da-f]+)$/;
$record{domain} = hex $1;
$record{bus} = hex $2;
$record{slot} = hex $3;
$record{func} = hex $4;
$record{vendid} = oct sysfs_device_attribute("$devices/$dev", "vendor");
$record{devid} = oct sysfs_device_attribute("$devices/$dev", "device");
$record{class} = (oct sysfs_device_attribute("$devices/$dev", "class"))
>> 8;
push @pci_list, \%record;
}
return \@pci_list;
}
# This function returns a list of hashes. Each hash has some PCI information:
# 'bus', 'slot' and 'func' uniquely identify a PCI device in a computer; # 'bus', 'slot' and 'func' uniquely identify a PCI device in a computer;
# 'vendid' and 'devid' uniquely identify a type of device. # 'vendid' and 'devid' uniquely identify a type of device.
# This function is used when sysfs is not available (Linux 2.4).
sub read_proc_dev_pci sub read_proc_dev_pci
{ {
my ($dfn,$vend,%pci_list); my ($dfn, $vend, @pci_list);
open(local *INPUTFILE, "/proc/bus/pci/devices") or return; open(local *INPUTFILE, "/proc/bus/pci/devices")
or die "/proc/bus/pci/devices: $!";
local $_; local $_;
while (<INPUTFILE>) { while (<INPUTFILE>) {
my %record; my %record;
@@ -2102,16 +2138,27 @@ sub read_proc_dev_pci
$record{vendid} = $vend >> 16; $record{vendid} = $vend >> 16;
$record{devid} = $vend & 0xffff; $record{devid} = $vend & 0xffff;
$pci_list{ sprintf("%04x:%04x",$record{vendid},$record{devid}) } = push @pci_list, \%record;
\%record;
} }
return %pci_list; return \@pci_list;
} }
sub initialize_proc_pci sub initialize_proc_pci
{ {
%pci_list = read_proc_dev_pci; my $pci_list;
die "Can't access /proc/bus/pci/devices!" if not defined %pci_list;
if (defined $sysfs_root) {
$pci_list = read_sys_dev_pci("$sysfs_root/bus/pci/devices");
} else {
$pci_list = read_proc_dev_pci();
}
# Note that we lose duplicate devices at this point, but we don't
# really care. What matters to us is which unique devices are present,
# not how many of each.
%pci_list = map {
sprintf("%04x:%04x", $_->{vendid}, $_->{devid}) => $_
} @{$pci_list};
} }
##################### #####################
@@ -2174,9 +2221,14 @@ sub adapter_pci_detection
$key = sprintf("%04x:%04x", $try->{vendid}, $try->{devid}); $key = sprintf("%04x:%04x", $try->{vendid}, $try->{devid});
if (exists $pci_list{$key}) { if (exists $pci_list{$key}) {
$device = $pci_list{$key}; $device = $pci_list{$key};
printf "Use driver `%s' for device %02x:%02x.%x: %s\n", printf "Use driver `\%s' for device \%s: \%s\n",
$try->{driver}, $try->{driver},
$device->{bus},$device->{slot},$device->{func},$try->{procid}; (defined $device->{domain} ?
sprintf("\%04x:\%02x:\%02x.\%x", $device->{domain},
$device->{bus}, $device->{slot}, $device->{func}) :
sprintf("\%02x:\%02x.\%x",
$device->{bus}, $device->{slot}, $device->{func})),
$try->{procid};
if ($try->{driver} eq "to-be-tested") { if ($try->{driver} eq "to-be-tested") {
print "\nWe are currently looking for testers for this adapter!\n". print "\nWe are currently looking for testers for this adapter!\n".
"Please see http://www.lm-sensors.org/wiki/NewDrivers\n". "Please see http://www.lm-sensors.org/wiki/NewDrivers\n".