Changeset 5247

Show
Ignore:
Timestamp:
05/11/08 19:14:29 (4 months ago)
Author:
khali
Message:

Try to detect 1-register-only devices, which are designed to be
accessed with SMBus receive byte and SMBus send byte transactions
(i.e. short reads and short writes) and treat SMBus read byte as a
real write followed by a read. The device detection routines would
write random values to the chip with possibly very nasty results for
the hardware. So when we detect such a chip, we skip all probing for
this address.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • lm-sensors/trunk/CHANGES

    r5244 r5247  
    1919                          Don't probe I2C addresses 0x40-0x47 
    2020                          Fix the parsing of I2C addresses not to scan 
     21                          Detect and skip 1-register-only I2C devices 
    2122 
    22232.10.6 "Welcome Home Lina" (20080306) 
  • lm-sensors/trunk/prog/detect/sensors-detect

    r5244 r5247  
    27622762} 
    27632763 
     2764# $_[0]: Reference to an opened file handle 
     2765# Returns: 1 if the device is safe to access, 0 else. 
     2766# This function is meant to prevent access to 1-register-only devices, 
     2767# which are designed to be accessed with SMBus receive byte and SMBus send 
     2768# byte transactions (i.e. short reads and short writes) and treat SMBus 
     2769# read byte as a real write followed by a read. The device detection 
     2770# routines would write random values to the chip with possibly very nasty 
     2771# results for the hardware. Note that this function won't catch all such 
     2772# chips, as it assumes that reads and writes relate to the same register, 
     2773# but that's the best we can do. 
     2774sub i2c_safety_check 
     2775{ 
     2776  my ($file) = @_; 
     2777  my $data; 
     2778 
     2779  # First we receive a byte from the chip, and remember it. 
     2780  $data = i2c_smbus_read_byte($file); 
     2781  return 1 if ($data < 0); 
     2782 
     2783  # We receive a byte again; very likely to be the same for 
     2784  # 1-register-only devices. 
     2785  return 1 if (i2c_smbus_read_byte($file) != $data); 
     2786 
     2787  # Then we try a standard byte read, with a register offset equal to 
     2788  # the byte we received; we should receive the same byte value in return. 
     2789  return 1 if (i2c_smbus_read_byte_data($file, $data) != $data); 
     2790 
     2791  # Then we try a standard byte read, with a slightly different register 
     2792  # offset; we should again receive the same byte value in return. 
     2793  return 1 if (i2c_smbus_read_byte_data($file, $data ^ 1) != ($data ^ 1)); 
     2794 
     2795  # Apprently this is a 1-register-only device, restore the original register 
     2796  # value and leave it alone. 
     2797  i2c_smbus_read_byte_data($file, $data); 
     2798  return 0; 
     2799} 
     2800 
    27642801#################### 
    27652802# ADAPTER SCANNING # 
     
    31083145    next unless i2c_probe(\*FILE, $addr, $funcs); 
    31093146    printf "Client found at address 0x%02x\n",$addr; 
     3147    if (!i2c_safety_check(\*FILE)) { 
     3148      print "Seems to be a 1-register-only device, skipping.\n"; 
     3149      next; 
     3150    } 
    31103151 
    31113152    $| = 1;