root/i2c-tools/trunk/eeprom/decode-vaio @ 5164

Revision 5164, 7.3 KB (checked in by khali, 5 years ago)

Update the FSF address.

  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
Line 
1#!/usr/bin/perl -w
2#
3# Copyright (C) 2002-2007 Jean Delvare <khali@linux-fr.org>
4#
5#    This program is free software; you can redistribute it and/or modify
6#    it under the terms of the GNU General Public License as published by
7#    the Free Software Foundation; either version 2 of the License, or
8#    (at your option) any later version.
9#
10#    This program is distributed in the hope that it will be useful,
11#    but WITHOUT ANY WARRANTY; without even the implied warranty of
12#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13#    GNU General Public License for more details.
14#
15#    You should have received a copy of the GNU General Public License
16#    along with this program; if not, write to the Free Software
17#    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18#    MA 02110-1301 USA.
19#
20# Version 0.1  2002-02-06  Jean Delvare <khali@linux-fr.org>
21# Version 0.2  2002-02-16  Jean Delvare <khali@linux-fr.org>
22#  Fixed to work with the new, simplified /proc interface names of the eeprom
23#    driver (lm_sensors 2.6.3 and greater).
24#  Shifted data display by 4 columns left.
25# Version 0.3  2002-02-17  Jean Delvare <khali@linux-fr.org>
26#  Added UUID field at 0x10 (added decode_uuid).
27#  Merged decode_string and decode_string32.
28#  Added unknown field at 0x20.
29#  Moved header and footer to BEGIN and END, respectively.
30#  Reformated history to match those of the other decode scripts.
31#  Deleted decode_char (made useless by decode_string).
32#  Reordered field display, changed some labels.
33#  Added old /proc interface check.
34# Version 1.0  2002-11-15  Jean Delvare <khali@linux-fr.org>
35#  Gave the label "OEM Data" to the field at 0x20.
36#  Gave the label "Timestamp" to the field at 0xE0.
37#  Renamed "Model Number" to "Model Name".
38#  Added some documentation.
39# Version 1.1  2004-01-17  Jean Delvare <khali@linux-fr.org>
40#  Added support for Linux 2.5/2.6 (i.e. sysfs).
41# Version 1.2  2004-11-28  Jean Delvare <khali@linux-fr.org>
42#  Support bus number 0 to 4 instead of only 0.
43# Version 1.3  2005-01-18  Jean Delvare <khali@linux-fr.org>
44#  Revision might be a Service Tag.
45# Version 1.4  2006-09-20  Jean Delvare <khali@linux-fr.org>
46#  Detect and skip false positives (e.g. EDID EEPROMs).
47# Version 1.5  2007-11-19  Jean Delvare <khali@linux-fr.org>
48#  UUID and serial number might be hidden
49#  The model name is actually the first half of the asset tag
50#  The timestamp is only 18-byte long
51#
52# EEPROM data decoding for Sony Vaio laptops.
53#
54# The eeprom driver must be loaded. For kernels older than 2.6.0, the
55# eeprom driver can be found in the lm-sensors package.
56#
57# Please note that this is a guess-only work.  Sony support refused to help
58# me, so if someone can provide information, please contact me.
59# My knowledge is summarized on this page:
60# http://khali.linux-fr.org/vaio/eeprom.html
61#
62# It seems that if present, the EEPROM is always at 0x57.
63#
64# Models tested so far:
65#   PCG-F403     : No EEPROM
66#   PCG-F707     : No EEPROM
67#   PCG-GR114EK  : OK
68#   PCG-GR114SK  : OK
69#   PCG-GR214EP  : OK
70#   PCG-GRT955MP : OK
71#   PCG-GRX316G  : OK
72#   PCG-GRX570   : OK
73#   PCG-GRX600K  : OK
74#   PCG-U1       : OK
75#   PCG-Z600LEK  : No EEPROM
76#   PCG-Z600NE   : No EEPROM
77#   VGN-S260     : OK
78#   VGN-S4M/S    : OK
79#   VGN-TZ11MN/N : OK
80# Any feedback appreciated anyway.
81#
82# Thanks to Werner Heuser, Carsten Blume, Christian Gennerat, Joe Wreschnig,
83# Xavier Roche, Sebastien Lefevre, Lars Heer, Steve Dobson, Kent Hunt,
84# Timo Hoenig and others for their precious help.
85
86
87use strict;
88use Fcntl qw(:DEFAULT :seek);
89use vars qw($sysfs $found);
90
91use constant ONLYROOT   => "Readable only by root";
92
93sub print_item
94{
95        my ($label,$value) = @_;
96       
97        printf("\%16s : \%s\n",$label,$value);
98}
99
100# Abstract reads so that other functions don't have to care wether
101# we need to use procfs or sysfs
102sub read_eeprom_bytes
103{
104        my ($bus, $addr, $offset, $length) = @_;
105        my $filename;
106       
107        if ($sysfs)
108        {
109                $filename = "/sys/bus/i2c/devices/$bus-00$addr/eeprom";
110                sysopen(FH, $filename, O_RDONLY)
111                        or die "Can't open $filename";
112                sysseek(FH, $offset, SEEK_SET)
113                        or die "Can't seek in $filename";
114
115                my ($r, $bytes);
116                $bytes = '';
117                $offset = 0;
118                while($length)
119                {
120                        $r = sysread(FH, $bytes, $length, $offset);
121                        die "Can't read $filename"
122                                unless defined($r);
123                        die "Unexpected EOF in $filename"
124                                unless $r;
125                        $offset += $r;
126                        $length -= $r;
127                }
128                close(FH);
129               
130                return $bytes;
131        }
132        else
133        {
134                my $base = $offset & 0xf0;
135                $offset -= $base;
136                my $values = '';
137                my $remains = $length + $offset;
138               
139                # Get all lines in a single string
140                while ($remains > 0)
141                {
142                        $filename = "/proc/sys/dev/sensors/eeprom-i2c-$bus-$addr/"
143                                  . sprintf('%02x', $base);
144                        open(FH, $filename)
145                                or die "Can't open $filename";
146                        $values .= <FH>;
147                        close(FH);
148                        $remains -= 16;
149                        $base += 16;
150                }
151               
152                # Store the useful part in an array
153                my @bytes = split(/[ \n]/, $values);
154                @bytes = @bytes[$offset..$offset+$length-1];
155
156                # Back to a binary string
157                return pack('C*', @bytes);
158        }
159}
160
161sub decode_string
162{
163        my ($bus, $addr, $offset, $length) = @_;
164
165        my $string = read_eeprom_bytes($bus, $addr, $offset, $length);
166        $string =~ s/\x00.*$//;
167       
168        return($string);
169}
170
171sub decode_hexa
172{
173        my ($bus, $addr, $offset, $length) = @_;
174
175        my @bytes = unpack('C*', read_eeprom_bytes($bus, $addr, $offset, $length));
176        my $string='';
177
178        for(my $i=0;$i<$length;$i++)
179        {
180                $string.=sprintf('%02X', shift(@bytes));
181        }
182
183        return($string);
184}
185
186sub decode_uuid
187{
188        my ($bus,$addr,$base) = @_;
189
190        my @bytes = unpack('C16', read_eeprom_bytes($bus, $addr, $base, 16));
191        my $string='';
192
193        for(my $i=0;$i<16;$i++)
194        {
195                $string.=sprintf('%02x',shift(@bytes));
196                if(($i==3)||($i==5)||($i==7)||($i==9))
197                {
198                        $string.='-';
199                }
200        }
201
202        if ($string eq '00000000-0000-0000-0000-000000000000')
203        {
204                return(ONLYROOT);
205        }
206        else
207        {
208                return($string);
209        }
210}
211
212sub vaio_decode
213{
214        my ($bus,$addr) = @_;
215       
216        my $name = decode_string($bus, $addr, 128, 32);
217        # Simple heuristic to skip false positives
218        return 0 unless $name =~ m/^[A-Z-]{4}/;
219
220        print_item('Machine Name', $name);
221        my $serial = decode_string($bus, $addr, 192, 32);
222        print_item('Serial Number', $serial ? $serial : ONLYROOT);
223        print_item('UUID', decode_uuid($bus, $addr, 16));
224        my $revision = decode_string($bus, $addr, 160, 10);
225        print_item(length($revision) > 2 ? 'Service Tag' : 'Revision',
226                   $revision);
227        print_item('Asset Tag', decode_string($bus, $addr, 170, 4).
228                                decode_hexa($bus, $addr, 174, 12));
229        print_item('OEM Data', decode_string($bus, $addr, 32, 16));
230        print_item('Timestamp', decode_string($bus, $addr, 224, 18));
231        return 1;
232}
233
234BEGIN
235{
236        print("Sony Vaio EEPROM Decoder\n");
237        print("Copyright (C) 2002-2007  Jean Delvare\n");
238        print("Version 1.5\n\n");
239}
240
241END
242{
243        print("\n");
244}
245
246for (my $i = 0, $found=0; $i <= 4 && !$found; $i++)
247{
248        if (-r "/sys/bus/i2c/devices/$i-0057/eeprom")
249        {
250                $sysfs = 1;
251                $found += vaio_decode($i, '57');
252        }
253        elsif (-r "/proc/sys/dev/sensors/eeprom-i2c-$i-57")
254        {
255                if (-r "/proc/sys/dev/sensors/eeprom-i2c-$i-57/data0-15")
256                {
257                        print("Deprecated old interface found.  Please upgrade to lm_sensors 2.6.3 or greater.");
258                        exit;
259                }
260                else
261                {
262                        $sysfs = 0;
263                        $found += vaio_decode($i, '57');
264                }
265        }
266}
267
268if (!$found)
269{
270        print("Vaio EEPROM not found.  Please make sure that the eeprom module is loaded.\n");
271        print("If you believe this is an error, please contact me <khali\@linux-fr.org>\n");
272        print("so that we may see how to fix the problem.\n");
273}
Note: See TracBrowser for help on using the browser.