mirror of
https://github.com/lm-sensors/lm-sensors
synced 2025-08-30 13:57:41 +00:00
Added custom detection for some SiS chipsets. This resolves a long-
standing false detection problem. Other changes in support of this custom detection: 1) Changed pci_list to a hash, with keys of the form "1039:0016" 2) Added @kernel_version detection and comparison routine (thanks Khali) 3) Removed legacy sub: read_proc_pci git-svn-id: http://lm-sensors.org/svn/lm-sensors/trunk@2358 7894878c-1315-0410-8ee3-d5d059ff63e0
This commit is contained in:
@@ -196,22 +196,6 @@ use vars qw(@pci_adapters @chip_ids @superio_ids @undetectable_adapters);
|
|||||||
driver => "i2c-viapro",
|
driver => "i2c-viapro",
|
||||||
match => sub { $_[0] =~ /^SMBus Via Pro adapter at/ },
|
match => sub { $_[0] =~ /^SMBus Via Pro adapter at/ },
|
||||||
} ,
|
} ,
|
||||||
{
|
|
||||||
vendid => 0x1039,
|
|
||||||
devid => 0x0008,
|
|
||||||
func => 0,
|
|
||||||
procid => "Silicon Integrated Systems SIS5595",
|
|
||||||
driver => "i2c-sis5595",
|
|
||||||
match => sub { $_[0] =~ /^SMBus SIS5595 adapter at [0-9,a-f]{4}/ },
|
|
||||||
} ,
|
|
||||||
{
|
|
||||||
vendid => 0x1039,
|
|
||||||
devid => 0x0018,
|
|
||||||
func => 0,
|
|
||||||
procid => "Silicon Integrated Systems 85C503/5513 (LPC Bridge)",
|
|
||||||
driver => "i2c-sis645",
|
|
||||||
match => sub { $_[0] =~ /^SiS645 SMBus adapter at 0x[0-9,a-f]{4}/ },
|
|
||||||
} ,
|
|
||||||
{
|
{
|
||||||
vendid => 0x1039,
|
vendid => 0x1039,
|
||||||
devid => 0x5597,
|
devid => 0x5597,
|
||||||
@@ -244,70 +228,6 @@ use vars qw(@pci_adapters @chip_ids @superio_ids @undetectable_adapters);
|
|||||||
driver => "i2c-sis630",
|
driver => "i2c-sis630",
|
||||||
match => sub { $_[0] =~ /^SMBus SIS630 adapter at [0-9,a-f]{4}/ },
|
match => sub { $_[0] =~ /^SMBus SIS630 adapter at [0-9,a-f]{4}/ },
|
||||||
} ,
|
} ,
|
||||||
{
|
|
||||||
vendid => 0x1039,
|
|
||||||
devid => 0x0645,
|
|
||||||
func => 0,
|
|
||||||
procid => "Silicon Integrated Systems SIS645",
|
|
||||||
driver => "i2c-sis645",
|
|
||||||
match => sub { $_[0] =~ /^SiS645 SMBus adapter at 0x[0-9,a-f]{4}/ },
|
|
||||||
} ,
|
|
||||||
{
|
|
||||||
vendid => 0x1039,
|
|
||||||
devid => 0x0646,
|
|
||||||
func => 0,
|
|
||||||
procid => "Silicon Integrated Systems SIS645DX",
|
|
||||||
driver => "i2c-sis645",
|
|
||||||
match => sub { $_[0] =~ /^SiS645 SMBus adapter at 0x[0-9,a-f]{4}/ },
|
|
||||||
} ,
|
|
||||||
{
|
|
||||||
vendid => 0x1039,
|
|
||||||
devid => 0x0648,
|
|
||||||
func => 0,
|
|
||||||
procid => "Silicon Integrated Systems SIS648",
|
|
||||||
driver => "i2c-sis645",
|
|
||||||
match => sub { $_[0] =~ /^SiS645 SMBus adapter at 0x[0-9,a-f]{4}/ },
|
|
||||||
} ,
|
|
||||||
{
|
|
||||||
vendid => 0x1039,
|
|
||||||
devid => 0x0650,
|
|
||||||
func => 0,
|
|
||||||
procid => "Silicon Integrated Systems SIS650",
|
|
||||||
driver => "i2c-sis645",
|
|
||||||
match => sub { $_[0] =~ /^SiS645 SMBus adapter at 0x[0-9,a-f]{4}/ },
|
|
||||||
} ,
|
|
||||||
{
|
|
||||||
vendid => 0x1039,
|
|
||||||
devid => 0x0651,
|
|
||||||
func => 0,
|
|
||||||
procid => "Silicon Integrated Systems SIS651",
|
|
||||||
driver => "i2c-sis645",
|
|
||||||
match => sub { $_[0] =~ /^SiS645 SMBus adapter at 0x[0-9,a-f]{4}/ },
|
|
||||||
} ,
|
|
||||||
{
|
|
||||||
vendid => 0x1039,
|
|
||||||
devid => 0x0735,
|
|
||||||
func => 0,
|
|
||||||
procid => "Silicon Integrated Systems SIS735",
|
|
||||||
driver => "i2c-sis645",
|
|
||||||
match => sub { $_[0] =~ /^SiS645 SMBus adapter at 0x[0-9,a-f]{4}/ },
|
|
||||||
} ,
|
|
||||||
{
|
|
||||||
vendid => 0x1039,
|
|
||||||
devid => 0x0745,
|
|
||||||
func => 0,
|
|
||||||
procid => "Silicon Integrated Systems SIS745",
|
|
||||||
driver => "i2c-sis645",
|
|
||||||
match => sub { $_[0] =~ /^SiS645 SMBus adapter at 0x[0-9,a-f]{4}/ },
|
|
||||||
} ,
|
|
||||||
{
|
|
||||||
vendid => 0x1039,
|
|
||||||
devid => 0x0746,
|
|
||||||
func => 0,
|
|
||||||
procid => "Silicon Integrated Systems SIS746",
|
|
||||||
driver => "i2c-sis645",
|
|
||||||
match => sub { $_[0] =~ /^SiS645 SMBus adapter at 0x[0-9,a-f]{4}/ },
|
|
||||||
} ,
|
|
||||||
{
|
{
|
||||||
vendid => 0x1039,
|
vendid => 0x1039,
|
||||||
devid => 0x0730,
|
devid => 0x0730,
|
||||||
@@ -793,6 +713,61 @@ use vars qw(@pci_adapters @chip_ids @superio_ids @undetectable_adapters);
|
|||||||
} ,
|
} ,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
# The following entries used to appear directly in @pci_adapters.
|
||||||
|
# Because of the tendency of SiS chipsets to have their real PCI
|
||||||
|
# IDs obscured, we have to qualify these with a custom detection
|
||||||
|
# routine before we add them to the @pci_adapters list.
|
||||||
|
#
|
||||||
|
use vars qw(@pci_adapters_sis5595 @pci_adapters_sis645 @pci_adapters_sis96x);
|
||||||
|
@pci_adapters_sis5595 = (
|
||||||
|
{
|
||||||
|
vendid => 0x1039,
|
||||||
|
devid => 0x0008,
|
||||||
|
func => 0,
|
||||||
|
procid => "Silicon Integrated Systems SIS5595",
|
||||||
|
driver => "i2c-sis5595",
|
||||||
|
match => sub { $_[0] =~ /^SMBus SIS5595 adapter at [0-9,a-f]{4}/ },
|
||||||
|
} ,
|
||||||
|
);
|
||||||
|
|
||||||
|
@pci_adapters_sis645 = (
|
||||||
|
{
|
||||||
|
vendid => 0x1039,
|
||||||
|
devid => 0x0008,
|
||||||
|
func => 0,
|
||||||
|
procid => "Silicon Integrated Systems SIS5595",
|
||||||
|
driver => "i2c-sis645",
|
||||||
|
match => sub { $_[0] =~ /^SiS645 SMBus adapter at [0-9,a-f]{4}/ },
|
||||||
|
} ,
|
||||||
|
{
|
||||||
|
vendid => 0x1039,
|
||||||
|
devid => 0x0016,
|
||||||
|
func => 1,
|
||||||
|
procid => "Silicon Integrated Systems SMBus Controller",
|
||||||
|
driver => "i2c-sis645",
|
||||||
|
match => sub { $_[0] =~ /^SiS645 SMBus adapter at 0x[0-9,a-f]{4}/ },
|
||||||
|
} ,
|
||||||
|
{
|
||||||
|
vendid => 0x1039,
|
||||||
|
devid => 0x0018,
|
||||||
|
func => 0,
|
||||||
|
procid => "Silicon Integrated Systems 85C503/5513 (LPC Bridge)",
|
||||||
|
driver => "i2c-sis645",
|
||||||
|
match => sub { $_[0] =~ /^SiS645 SMBus adapter at 0x[0-9,a-f]{4}/ },
|
||||||
|
} ,
|
||||||
|
);
|
||||||
|
|
||||||
|
@pci_adapters_sis96x = (
|
||||||
|
{
|
||||||
|
vendid => 0x1039,
|
||||||
|
devid => 0x0016,
|
||||||
|
func => 1,
|
||||||
|
procid => "Silicon Integrated Systems SMBus Controller",
|
||||||
|
driver => "i2c-sis96x",
|
||||||
|
match => sub { $_[0] =~ /^SiS96x SMBus adapter at 0x[0-9,a-f]{4}/ },
|
||||||
|
} ,
|
||||||
|
);
|
||||||
|
|
||||||
use subs qw(mtp008_detect lm78_detect lm78_isa_detect lm78_alias_detect
|
use subs qw(mtp008_detect lm78_detect lm78_isa_detect lm78_alias_detect
|
||||||
lm75_detect lm80_detect w83781d_detect w83781d_alias_detect
|
lm75_detect lm80_detect w83781d_detect w83781d_alias_detect
|
||||||
adm1025_detect w83781d_isa_detect gl518sm_detect gl520sm_detect
|
adm1025_detect w83781d_isa_detect gl518sm_detect gl520sm_detect
|
||||||
@@ -1778,6 +1753,30 @@ sub initialize_conf
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# [0] -> VERSION
|
||||||
|
# [1] -> PATCHLEVEL
|
||||||
|
# [2] -> SUBLEVEL
|
||||||
|
# [3] -> EXTRAVERSION
|
||||||
|
#
|
||||||
|
use vars qw(@kernel_version);
|
||||||
|
|
||||||
|
sub initialize_kernel_version
|
||||||
|
{
|
||||||
|
`uname -r` =~ /(\d+)\.(\d+)\.(\d+)(.*)/;
|
||||||
|
@kernel_version = ($1, $2, $3, $4);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub kernel_version_at_least
|
||||||
|
{
|
||||||
|
my ($vers, $plvl, $slvl) = @_;
|
||||||
|
return 1 if ($kernel_version[0] > $vers ||
|
||||||
|
($kernel_version[0] == $vers &&
|
||||||
|
($kernel_version[1] > $plvl ||
|
||||||
|
($kernel_version[1] == $plvl &&
|
||||||
|
($kernel_version[2] >= $slvl)))));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
###########
|
###########
|
||||||
# MODULES #
|
# MODULES #
|
||||||
###########
|
###########
|
||||||
@@ -1797,16 +1796,15 @@ sub initialize_modules_list
|
|||||||
# PCI ACCESS #
|
# PCI ACCESS #
|
||||||
##############
|
##############
|
||||||
|
|
||||||
use vars qw(@pci_list);
|
use vars qw(%pci_list);
|
||||||
|
|
||||||
# This function returns a list of hashes. Each hash has some PCI information
|
# This function returns a hash of hashes. Each hash has some PCI information
|
||||||
# (more than we will ever need, probably). The most important
|
# (more than we will ever need, probably). The most important
|
||||||
# fields are 'bus', 'slot', 'func' (they uniquely identify a PCI device in
|
# fields are 'bus', 'slot', 'func' (they uniquely identify a PCI device in
|
||||||
# a computer) and 'vendid','devid' (they uniquely identify a type of device).
|
# a computer) and 'vendid','devid' (they uniquely identify a type of device).
|
||||||
# /proc/bus/pci/devices is only available on late 2.1 and 2.2 kernels.
|
|
||||||
sub read_proc_dev_pci
|
sub read_proc_dev_pci
|
||||||
{
|
{
|
||||||
my ($dfn,$vend,@pci_list);
|
my ($dfn,$vend,%pci_list);
|
||||||
open INPUTFILE, "/proc/bus/pci/devices" or return;
|
open INPUTFILE, "/proc/bus/pci/devices" or return;
|
||||||
while (<INPUTFILE>) {
|
while (<INPUTFILE>) {
|
||||||
my $record = {};
|
my $record = {};
|
||||||
@@ -1819,48 +1817,18 @@ sub read_proc_dev_pci
|
|||||||
$record->{func} = $dfn & 0x07;
|
$record->{func} = $dfn & 0x07;
|
||||||
$record->{vendid} = $vend >> 16;
|
$record->{vendid} = $vend >> 16;
|
||||||
$record->{devid} = $vend & 0xffff;
|
$record->{devid} = $vend & 0xffff;
|
||||||
push @pci_list,$record;
|
|
||||||
}
|
|
||||||
close INPUTFILE or return;
|
|
||||||
return @pci_list;
|
|
||||||
}
|
|
||||||
|
|
||||||
# This function returns a list of hashes. Each hash has some PCI
|
$pci_list{ sprintf("%04x:%04x",$record->{vendid},$record->{devid}) } =
|
||||||
# information. The important fields here are 'bus', 'slot', 'func' (they
|
$record;
|
||||||
# uniquely identify a PCI device in a computer) and 'desc' (a functional
|
|
||||||
# description of the PCI device). If this is an 'unknown device', the
|
|
||||||
# vendid and devid fields are set instead.
|
|
||||||
sub read_proc_pci
|
|
||||||
{
|
|
||||||
my @pci_list;
|
|
||||||
open INPUTFILE, "/proc/pci" or return;
|
|
||||||
while (<INPUTFILE>) {
|
|
||||||
my $record = {};
|
|
||||||
if (($record->{bus},$record->{slot},$record->{func}) =
|
|
||||||
/^\s*Bus\s*(\S)+\s*,\s*device\s*(\S+)\s*,\s*function\s*(\S+)\s*:\s*$/) {
|
|
||||||
my $desc = <INPUTFILE>;
|
|
||||||
$_ = <INPUTFILE>;
|
|
||||||
if (($desc =~ /Unknown device/) and
|
|
||||||
(($record->{vendid},$record->{devid}) =
|
|
||||||
/^\s*Vendor id=(\S+)\.\s*Device id=(\S+)\.$/)) {
|
|
||||||
$record->{vendid} = hex $record->{vendid};
|
|
||||||
$record->{devid} = hex $record->{devid};
|
|
||||||
} else {
|
|
||||||
$record->{desc} = $desc;
|
|
||||||
}
|
|
||||||
push @pci_list,$record;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
close INPUTFILE or return;
|
close INPUTFILE or return;
|
||||||
return @pci_list;
|
return %pci_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub initialize_proc_pci
|
sub initialize_proc_pci
|
||||||
{
|
{
|
||||||
@pci_list = read_proc_dev_pci;
|
%pci_list = read_proc_dev_pci;
|
||||||
@pci_list = read_proc_pci if not defined @pci_list;
|
die "Can't access /proc/bus/pci/devices!" if not defined %pci_list;
|
||||||
die "Can't access either /proc/bus/pci/ or /proc/pci!"
|
|
||||||
if not defined @pci_list;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#####################
|
#####################
|
||||||
@@ -1883,12 +1851,57 @@ sub all_available_adapters
|
|||||||
return @res;
|
return @res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub adapter_pci_detection_sis_96x
|
||||||
|
{
|
||||||
|
my $driver="";
|
||||||
|
|
||||||
|
# first, determine which driver if any...
|
||||||
|
if (kernel_version_at_least(2,6,0)) {
|
||||||
|
if (exists $pci_list{"1039:0016"}) {
|
||||||
|
$driver = "i2c-sis96x";
|
||||||
|
} elsif (exists $pci_list{"1039:0008"}) {
|
||||||
|
$driver = "i2c-sis5595";
|
||||||
|
}
|
||||||
|
} elsif (kernel_version_at_least(2,4,0)) {
|
||||||
|
if (exists $pci_list{"1039:0008"}) {
|
||||||
|
if ((exists $pci_list{"1039:0645"}) ||
|
||||||
|
(exists $pci_list{"1039:0646"}) ||
|
||||||
|
(exists $pci_list{"1039:0648"}) ||
|
||||||
|
(exists $pci_list{"1039:0650"}) ||
|
||||||
|
(exists $pci_list{"1039:0651"}) ||
|
||||||
|
(exists $pci_list{"1039:0735"}) ||
|
||||||
|
(exists $pci_list{"1039:0745"}) ||
|
||||||
|
(exists $pci_list{"1039:0746"})) {
|
||||||
|
$driver = "i2c-sis645";
|
||||||
|
} else {
|
||||||
|
$driver = "i2c-sis5595";
|
||||||
|
}
|
||||||
|
} elsif ((exists $pci_list{"1039:0016"}) ||
|
||||||
|
(exists $pci_list{"1039:0018"})) {
|
||||||
|
$driver = "i2c-sis645";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# then, add the appropriate entries to @pci_adapters
|
||||||
|
if ($driver eq "i2c-sis5595") {
|
||||||
|
push @pci_adapters, @pci_adapters_sis5595;
|
||||||
|
} elsif ($driver eq "i2c-sis645") {
|
||||||
|
push @pci_adapters, @pci_adapters_sis645;
|
||||||
|
} elsif ($driver eq "i2c-sis96x") {
|
||||||
|
push @pci_adapters, @pci_adapters_sis96x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
sub adapter_pci_detection
|
sub adapter_pci_detection
|
||||||
{
|
{
|
||||||
my ($device,$try,@res);
|
my ($key,$device,$try,@res);
|
||||||
print "Probing for PCI bus adapters...\n";
|
print "Probing for PCI bus adapters...\n";
|
||||||
|
|
||||||
foreach $device (@pci_list) {
|
# Custom detection routine for some SiS chipsets
|
||||||
|
adapter_pci_detection_sis_96x();
|
||||||
|
|
||||||
|
# Generic detection loop
|
||||||
|
while ( ($key, $device) = each %pci_list) {
|
||||||
foreach $try (@pci_adapters) {
|
foreach $try (@pci_adapters) {
|
||||||
if ((defined($device->{vendid}) and
|
if ((defined($device->{vendid}) and
|
||||||
$try->{vendid} == $device->{vendid} and
|
$try->{vendid} == $device->{vendid} and
|
||||||
@@ -3403,7 +3416,7 @@ sub adm1021_detect
|
|||||||
sub sis5595_isa_detect
|
sub sis5595_isa_detect
|
||||||
{
|
{
|
||||||
my ($addr) = @_;
|
my ($addr) = @_;
|
||||||
my ($adapter,$try,$local_try);
|
my ($key,$adapter,$try,$local_try);
|
||||||
my $found = 0;
|
my $found = 0;
|
||||||
foreach $local_try (@pci_adapters) {
|
foreach $local_try (@pci_adapters) {
|
||||||
if ($local_try->{procid} eq "Silicon Integrated Systems SIS5595") {
|
if ($local_try->{procid} eq "Silicon Integrated Systems SIS5595") {
|
||||||
@@ -3415,7 +3428,7 @@ sub sis5595_isa_detect
|
|||||||
return if not $found;
|
return if not $found;
|
||||||
|
|
||||||
$found = 0;
|
$found = 0;
|
||||||
foreach $adapter (@pci_list) {
|
while ( ($key, $adapter) = each %pci_list) {
|
||||||
if ((defined($adapter->{vendid}) and
|
if ((defined($adapter->{vendid}) and
|
||||||
$try->{vendid} == $adapter->{vendid} and
|
$try->{vendid} == $adapter->{vendid} and
|
||||||
$try->{devid} == $adapter->{devid} and
|
$try->{devid} == $adapter->{devid} and
|
||||||
@@ -3439,7 +3452,7 @@ sub sis5595_isa_detect
|
|||||||
sub via686a_isa_detect
|
sub via686a_isa_detect
|
||||||
{
|
{
|
||||||
my ($addr) = @_;
|
my ($addr) = @_;
|
||||||
my ($adapter,$try,$local_try);
|
my ($key,$adapter,$try,$local_try);
|
||||||
my $found = 0;
|
my $found = 0;
|
||||||
foreach $local_try (@pci_adapters) {
|
foreach $local_try (@pci_adapters) {
|
||||||
if ($local_try->{procid} eq "VIA Technologies VT82C686 Apollo ACPI") {
|
if ($local_try->{procid} eq "VIA Technologies VT82C686 Apollo ACPI") {
|
||||||
@@ -3451,7 +3464,7 @@ sub via686a_isa_detect
|
|||||||
return if not $found;
|
return if not $found;
|
||||||
|
|
||||||
$found = 0;
|
$found = 0;
|
||||||
foreach $adapter (@pci_list) {
|
while ( ($key, $adapter) = each %pci_list) {
|
||||||
if ((defined($adapter->{vendid}) and
|
if ((defined($adapter->{vendid}) and
|
||||||
$try->{vendid} == $adapter->{vendid} and
|
$try->{vendid} == $adapter->{vendid} and
|
||||||
$try->{devid} == $adapter->{devid} and
|
$try->{devid} == $adapter->{devid} and
|
||||||
@@ -3475,7 +3488,7 @@ sub via686a_isa_detect
|
|||||||
sub via8231_isa_detect
|
sub via8231_isa_detect
|
||||||
{
|
{
|
||||||
my ($addr) = @_;
|
my ($addr) = @_;
|
||||||
my ($adapter,$try,$local_try);
|
my ($key,$adapter,$try,$local_try);
|
||||||
my $found = 0;
|
my $found = 0;
|
||||||
foreach $local_try (@pci_adapters) {
|
foreach $local_try (@pci_adapters) {
|
||||||
if ($local_try->{procid} eq "VIA Technologies VT8231 South Bridge") {
|
if ($local_try->{procid} eq "VIA Technologies VT8231 South Bridge") {
|
||||||
@@ -3487,7 +3500,7 @@ sub via8231_isa_detect
|
|||||||
return if not $found;
|
return if not $found;
|
||||||
|
|
||||||
$found = 0;
|
$found = 0;
|
||||||
foreach $adapter (@pci_list) {
|
while ( ($key, $adapter) = each %pci_list) {
|
||||||
if ((defined($adapter->{vendid}) and
|
if ((defined($adapter->{vendid}) and
|
||||||
$try->{vendid} == $adapter->{vendid} and
|
$try->{vendid} == $adapter->{vendid} and
|
||||||
$try->{devid} == $adapter->{devid} and
|
$try->{devid} == $adapter->{devid} and
|
||||||
@@ -4265,6 +4278,7 @@ sub main
|
|||||||
initialize_conf;
|
initialize_conf;
|
||||||
initialize_proc_pci;
|
initialize_proc_pci;
|
||||||
initialize_modules_list;
|
initialize_modules_list;
|
||||||
|
initialize_kernel_version;
|
||||||
|
|
||||||
print "\nThis program will help you determine which I2C/SMBus modules you need to\n",
|
print "\nThis program will help you determine which I2C/SMBus modules you need to\n",
|
||||||
"load to use lm_sensors most effectively. You need to have i2c and\n",
|
"load to use lm_sensors most effectively. You need to have i2c and\n",
|
||||||
|
Reference in New Issue
Block a user