Changeset 5496

Show
Ignore:
Timestamp:
12/02/08 12:13:38 (5 years ago)
Author:
khali
Message:

Move alias detection after all chip detections. This is slightly less
efficient, but this makes it possible to later change the probing order.

Location:
lm-sensors/branches/lm-sensors-3.0.0
Files:
2 modified

Legend:

Unmodified
Added
Removed
  • lm-sensors/branches/lm-sensors-3.0.0/CHANGES

    r5494 r5496  
    3333                  Suggest the sbs driver for smart batteries 
    3434                  Drop alias detection for Super-I/O chips 
     35                  Move alias detection after all chip detections 
    3536 
    36373.0.3 (2008-09-28) 
  • lm-sensors/branches/lm-sensors-3.0.0/prog/detect/sensors-detect

    r5495 r5496  
    24352435#  with field 'conf', containing the confidence level of this detection 
    24362436#  with field 'chipname', containing the chip name 
    2437  
    2438 # This adds a detection to the above structure. We do no alias detection 
    2439 # here; so you should do ISA detections *after* all I2C detections. 
     2437#  with optional field 'alias_detect', containing a reference to an alias 
     2438#       detection function for this chip 
     2439 
     2440# This adds a detection to the above structure. 
    24402441# Not all possibilities of i2c_addr and i2c_sub_addrs are exhausted. 
    24412442# In all normal cases, it should be all right. 
     
    25072508} 
    25082509 
    2509 # This adds a detection to the above structure. We also do alias detection 
    2510 # here; so you should do ISA detections *after* all I2C detections. 
     2510# This adds a detection to the above structure. 
    25112511# $_[0]: chip driver 
    25122512# $_[1]: reference to data hash 
    2513 # $_[2]: alias detection function (optional) 
    2514 # Returns: 0 if it is not an alias, datahash reference if it is. 
    25152513sub add_isa_to_chips_detected 
    25162514{ 
    2517         my ($chipdriver, $datahash, $alias_detect) = @_; 
    2518         my ($i, $new_detected_ref, $detected_ref, $main_entry, $isalias); 
     2515        my ($chipdriver, $datahash) = @_; 
     2516        my ($i, $new_detected_ref, $detected_ref, $main_entry); 
    25192517 
    25202518        # First determine where the hash has to be added. 
    2521         $isalias = 0; 
    25222519        for ($i = 0; $i < @chips_detected; $i++) { 
    25232520                last if ($chips_detected[$i]->{driver} eq $chipdriver); 
     
    25302527        } 
    25312528        $new_detected_ref = $chips_detected[$i]->{detected}; 
    2532  
    2533         # Now, we are looking for aliases. An alias can only be the same 
    2534         # chiptype. If it is found in the detected list, we still have to 
    2535         # check whether another chip has claimed this ISA address. So we 
    2536         # remove the old entry from the detected list and put it in datahash. 
    2537         for ($i = 0; $i < @$new_detected_ref; $i++) { 
    2538                 if (exists $new_detected_ref->[$i]->{i2c_addr} and 
    2539                     not exists $new_detected_ref->[$i]->{isa_addr} and 
    2540                     defined $alias_detect and 
    2541                     $new_detected_ref->[$i]->{chipname} eq $datahash->{chipname}) { 
    2542                         open(local *FILE, "$dev_i2c$new_detected_ref->[$i]->{i2c_devnr}") or 
    2543                                 print("Can't open $dev_i2c$new_detected_ref->[$i]->{i2c_devnr}?!?\n"), 
    2544                                 next; 
    2545                         binmode(FILE); 
    2546                         i2c_set_slave_addr(\*FILE, $new_detected_ref->[$i]->{i2c_addr}) or 
    2547                                 print("Can't set I2C address for ", 
    2548                                       "$dev_i2c$new_detected_ref->[$i]->{i2c_devnr}?!?\n"), 
    2549                                 next; 
    2550                         if (&$alias_detect($datahash->{isa_addr}, \*FILE, 
    2551                                            $new_detected_ref->[$i]->{i2c_addr})) { 
    2552                                 $new_detected_ref->[$i]->{isa_addr} = $datahash->{isa_addr}; 
    2553                                 ($datahash) = splice (@$new_detected_ref, $i, 1); 
    2554                                 $isalias = 1; 
    2555                                 last; 
    2556                         } 
    2557                 } 
    2558         } 
    25592529 
    25602530        # Find out whether our new entry should go into the detected list 
     
    25702540                                        push @$new_detected_ref, $datahash; 
    25712541                                } 
    2572                                 if ($isalias) { 
    2573                                         return $datahash; 
    2574                                 } else { 
    2575                                         return 0; 
    2576                                 } 
     2542                                return; 
    25772543                        } 
    25782544                } 
     
    25812547        # Not found? OK, put it in the detected list 
    25822548        push @$new_detected_ref, $datahash; 
    2583         if ($isalias) { 
    2584                 return $datahash; 
    2585         } else { 
    2586                 return 0; 
     2549} 
     2550 
     2551# $_[0]: reference to an array of chips which may be aliases of each other 
     2552sub find_aliases 
     2553{ 
     2554        my $detected = shift; 
     2555        my ($isa, $i2c, $dev, $alias_detect, $is_alias); 
     2556 
     2557        for ($isa = 0; $isa < @{$detected}; $isa++) { 
     2558                # Look for chips with an ISA address but no I2C address 
     2559                next unless defined $detected->[$isa]; 
     2560                next unless $detected->[$isa]->{isa_addr}; 
     2561                next if defined $detected->[$isa]->{i2c_addr}; 
     2562                # Additionally, the chip must possibly have I2C aliases 
     2563                next unless defined $detected->[$isa]->{alias_detect}; 
     2564 
     2565                for ($i2c = 0; $i2c < @{$detected}; $i2c++) { 
     2566                        # Look for chips with an I2C address but no ISA address 
     2567                        next unless defined $detected->[$i2c]; 
     2568                        next unless defined $detected->[$i2c]->{i2c_addr}; 
     2569                        next if $detected->[$i2c]->{isa_addr}; 
     2570                        # Additionally, it must have the same chip name 
     2571                        next unless $detected->[$i2c]->{chipname} eq 
     2572                                    $detected->[$isa]->{chipname}; 
     2573 
     2574                        # We have potential aliases, check if they actually are 
     2575                        $dev = $dev_i2c.$detected->[$i2c]->{i2c_devnr}; 
     2576                        open(local *FILE, $dev) or 
     2577                                print("Can't open $dev\n"), 
     2578                                next; 
     2579                        binmode(FILE); 
     2580                        i2c_set_slave_addr(\*FILE, $detected->[$i2c]->{i2c_addr}) or 
     2581                                print("Can't set I2C address for $dev\n"), 
     2582                                next; 
     2583 
     2584                        initialize_ioports(); 
     2585                        $alias_detect = $detected->[$isa]->{alias_detect}; 
     2586                        $is_alias = &$alias_detect($detected->[$isa]->{isa_addr}, 
     2587                                                   \*FILE, 
     2588                                                   $detected->[$i2c]->{i2c_addr}); 
     2589                        close(FILE); 
     2590                        close_ioports(); 
     2591 
     2592                        next unless $is_alias; 
     2593                        # This is an alias: copy the I2C data into the ISA 
     2594                        # entry, then discard the I2C entry 
     2595                        $detected->[$isa]->{i2c_devnr} = $detected->[$i2c]->{i2c_devnr}; 
     2596                        $detected->[$isa]->{i2c_addr} = $detected->[$i2c]->{i2c_addr}; 
     2597                        $detected->[$isa]->{i2c_sub_addr} = $detected->[$i2c]->{i2c_sub_addr}; 
     2598                        undef $detected->[$i2c]; 
     2599                        last; 
     2600                } 
     2601        } 
     2602 
     2603        # The loops above may have made the chip list sparse, make it 
     2604        # compact again 
     2605        for ($isa = 0; $isa < @{$detected}; ) { 
     2606                if (defined($detected->[$isa])) { 
     2607                        $isa++; 
     2608                } else { 
     2609                        splice @{$detected}, $isa, 1; 
     2610                } 
    25872611        } 
    25882612} 
     
    27772801                                isa_addr => $addr, 
    27782802                                chipname => $chip->{name}, 
     2803                                alias_detect => $chip->{alias_detect}, 
    27792804                        }; 
    2780                         $new_hash = add_isa_to_chips_detected($chip->{driver}, 
    2781                                                               $new_hash, 
    2782                                                               $chip->{alias_detect}); 
    2783                         if ($new_hash) { 
    2784                                 printf "    Alias of the chip on I2C bus `%s', address 0x%02x\n", 
    2785                                        $i2c_adapters[$new_hash->{i2c_devnr}]->{name}, 
    2786                                        $new_hash->{i2c_addr}; 
    2787                         } 
     2805                        add_isa_to_chips_detected($chip->{driver}, $new_hash); 
    27882806                } 
    27892807        } 
     
    49885006        foreach $chip (@chips_detected) { 
    49895007                next unless @{$chip->{detected}}; 
     5008                find_aliases($chip->{detected}); 
    49905009                print "\nDriver `$chip->{driver}':\n"; 
    49915010                print_chips_report($chip->{detected});