Changeset 1583

Show
Ignore:
Timestamp:
11/07/02 16:24:20 (6 years ago)
Author:
khali
Message:

Upgrade dmidecode to version 1.8

Files:

Legend:

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

    r1582 r1583  
    4141  Module w83781d: Fix in0/in1 initialization 
    4242  Module smartbatt: New 
    43   Program dmidecode: Fix read bug 
     43  Program dmidecode: Fix read bug; upgrade to version 1.8 
    4444  Program doc-insmod: Complete rewrite; fix author output 
    4545  Program doc-features: Complete rewrite; handle missing sysctl entries; 
  • lm-sensors/trunk/prog/detect/dmidecode.c

    r1557 r1583  
    11/* 
    2  *     DMI decode rev 1.4 
    3  * 
    4  *      (C) 2000,2001 Alan Cox <alan@redhat.com> 
     2 * DMI decode rev 1.8 
     3 * 
     4 *      (C) 2000-2002 Alan Cox <alan@redhat.com> 
    55 * 
    66 *      2-July-2001 Matt Domsch <Matt_Domsch@dell.com> 
     
    3434 *      Commented out code removed 
    3535 *      DMI 0.0 case handled 
    36  *      Fix return value in dmi_port_type and dmi_port_connector_type 
    37  * 
    38  *      Licensed under the GNU Public license. If you want to use it in with 
    39  *      another license just ask. 
     36 *      Fix return value of dmi_port_type and dmi_port_connector_type 
     37 * 
     38 *      23-August-2002 Alan Cox <alan@redhat.com> 
     39 *      Make the code pass -Wall -pedantic by fixing a few harmless sign of 
     40 *        pointer mismatches 
     41 *      Correct main prototype 
     42 *      Check for compilers with wrong type sizes 
     43 * 
     44 *      17-Sep-2002 Larry Lile <llile@dreamworks.com> 
     45 *      Type 16 & 17 structures displayed per SMBIOS 2.3.1 spec 
     46 * 
     47 *      20-September-2002 Dave Johnson <ddj@cascv.brown.edu> 
     48 *      Fix comparisons in dmi_bus_name 
     49 *      Fix comparison in dmi_processor_type 
     50 *      Fix bitmasking in dmi_onboard_type 
     51 *      Fix return value of dmi_temp_loc 
     52 * 
     53 *      28-September-2002 Jean Delvare <khali@linux-fr.org> 
     54 *      Fix missing coma in dmi_bus_name 
     55 *      Remove unwanted bitmaskings in dmi_mgmt_dev_type, dmi_mgmt_addr_type, 
     56 *        dmi_fan_type, dmi_volt_loc, dmi_temp_loc and dmi_status 
     57 *      Fix DMI table read bug ("dmi: read: Success") 
     58 *      Make the code pass -W again 
     59 *      Fix return value of dmi_card_size 
     60 * 
     61 *      05-October-2002 Jean Delvare <khali@linux-fr.org> 
     62 *      More ACPI decoded 
     63 *      More PNP decoded 
     64 *      More SYSID decoded 
     65 *      PCI Interrupt Routing decoded 
     66 *      BIOS32 Service Directory decoded 
     67 *      Sony system detection (unconfirmed) 
     68 *      Checksums verified whenever possible 
     69 *      Better checks on file read and close 
     70 *      Define VERSION and display version at beginning 
     71 *      More secure decoding (won't run off the table in any case) 
     72 *      Do not try to decode more structures than announced 
     73 *      Fix an off-by-one error that caused the last address being 
     74 *        scanned to be 0x100000, not 0xFFFF0 as it should 
     75 * 
     76 *      10-October-2002 Jean Delvare <khali@linux-fr.org> 
     77 *      Remove extra semicolon at the end of dmi_memory_array_use 
     78 *      Fix compilation warnings 
     79 *      Add missing backslash in DMI case 37 
     80 *      Fix BIOS ROM size (DMI case 0) 
     81 * 
     82 *      12-October-2002 Jean Delvare <khali@linux-fr.org> 
     83 *      Fix maximum cache size and installed size being inverted 
     84 *      Fix typos in port types 
     85 * 
     86 *      14-October-2002 Jean Delvare <khali@linux-fr.org> 
     87 *      Fix typo in dmi_memory_array_location 
     88 *      Replace Kbyte by kB in DMI case 16 
     89 *      Add DDR entry in dmi_memory_device_type 
     90 *      Fix extra s in SYSIS 
     91 * 
     92 *      15-October-2002 Jean Delvare <khali@linux-fr.org> 
     93 *      Fix bad index in DMI case 27 (cooling device) 
     94 * 
     95 * Licensed under the GNU Public license. If you want to use it in with 
     96 * another license just ask. 
     97 * 
     98 * This program is free software; you can redistribute it and/or modify 
     99 * it under the terms of the GNU General Public License as published by 
     100 * the Free Software Foundation; either version 2 of the License, or 
     101 * (at your option) any later version. 
     102 * 
     103 * This program is distributed in the hope that it will be useful, 
     104 * but WITHOUT ANY WARRANTY; without even the implied warranty of 
     105 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
     106 * GNU General Public License for more details. 
     107 * 
     108 * You should have received a copy of the GNU General Public License 
     109 * along with this program; if not, write to the Free Software 
     110 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
     111 * 
     112 * For the avoidance of doubt the "preferred form" of this code is one which 
     113 * is in an open unpatent encumbered format. Where cryptographic key signing 
     114 * forms part of the process of creating an executable the information  
     115 * including keys needed to generate an equivalently functional executable 
     116 * are deemed to be part of the source code. 
     117 *              [In the light of TCPA and Palladium the author urges 
     118 *               other open source authors to add such a clarification] 
    40119 */ 
    41120 
     
    46125#include <stdlib.h> 
    47126 
     127#define VERSION "1.8" 
     128 
    48129typedef unsigned char u8; 
    49130typedef unsigned short u16; 
     
    53134dump_raw_data(void *data, unsigned int length) 
    54135{ 
    55         unsigned char buffer1[80], buffer2[80], *b1, *b2, c; 
     136        char buffer1[80], buffer2[80], *b1, *b2, c; 
    56137        unsigned char *p = data; 
    57138        unsigned long column=0; 
     
    92173}; 
    93174 
    94 static char *dmi_string(struct dmi_header *dm, u8 s) 
    95 
    96         u8 *bp=(u8 *)dm; 
    97         if (!s) return NULL; 
     175static const char *dmi_string(struct dmi_header *dm, u8 s) 
     176
     177        char *bp=(char *)dm; 
     178        if(s==0) 
     179                return ""; 
    98180         
    99181        bp+=dm->length; 
    100         while(s>1
     182        while(s>1 && *bp
    101183        { 
    102184                bp+=strlen(bp); 
     
    104186                s--; 
    105187        } 
     188        if(!*bp) 
     189                return "<bad index>"; 
    106190        return bp; 
    107191} 
     
    169253                "EISA ", 
    170254                "PCI ", 
    171                 "PCMCIA " 
     255                "PCMCIA ", 
    172256                "VLB ", 
    173257                "Proprietary ", 
     
    189273        }; 
    190274         
    191         if(num<=0x12
     275        if(num<=0x11
    192276                return bus[num]; 
    193         if(num>=0xA0 && num<0xA5
     277        if(num>=0xA0 && num<=0xA4
    194278                return jpbus[num - 0xA0]; 
    195279        return ""; 
     
    215299const char *dmi_card_size(u8 v) 
    216300{ 
    217         if(v==2
     301        if(v==3
    218302                return("Short "); 
    219         if(v==3
     303        if(v==4
    220304                return("Long "); 
    221305        return ""; 
     
    335419} 
    336420 
     421static const char *dmi_memory_array_location(u8 num) 
     422{ 
     423        static const char *memory_array_location[]={ 
     424                "", 
     425                "Other", 
     426                "Unknown", 
     427                "System board or motherboard", 
     428                "ISA add-on card", 
     429                "EISA add-on card", 
     430                "PCI add-on card", 
     431                "MCA add-on card", 
     432                "PCMCIA add-on card", 
     433                "Proprietary add-on card", 
     434                "NuBus", 
     435        }; 
     436        static const char *jp_memory_array_location[]={ 
     437                "PC-98/C20 add-on card", 
     438                "PC-98/C24 add-on card", 
     439                "PC-98/E add-on card", 
     440                "PC-98/Local bus add-on card", 
     441        }; 
     442        if(num<=0x0A) 
     443                return memory_array_location[num]; 
     444        if(num>=0xA0 && num<0xA3) 
     445                return jp_memory_array_location[num]; 
     446        return ""; 
     447} 
     448 
     449static const char *dmi_memory_array_use(u8 num) 
     450{ 
     451        static const char *memory_array_use[]={ 
     452                "", 
     453                "Other", 
     454                "Unknown", 
     455                "System memory", 
     456                "Video memory", 
     457                "Flash memory", 
     458                "Non-volatile RAM", 
     459                "Cache memory", 
     460        }; 
     461        if (num > 0x07) 
     462                return ""; 
     463        return memory_array_use[num]; 
     464} 
     465 
     466static const char *dmi_memory_array_error_correction_type(u8 num) 
     467{ 
     468        static const char *memory_array_error_correction_type[]={ 
     469                "", 
     470                "Other", 
     471                "Unknown", 
     472                "None", 
     473                "Parity", 
     474                "Single-bit ECC", 
     475                "Multi-bit ECC", 
     476                "CRC", 
     477        }; 
     478        if (num > 0x07) 
     479                return ""; 
     480        return memory_array_error_correction_type[num]; 
     481} 
     482 
     483static const char *dmi_memory_device_form_factor(u8 num) 
     484{ 
     485        static const char *memory_device_form_factor[]={ 
     486                "", 
     487                "Other", 
     488                "Unknown", 
     489                "SIMM", 
     490                "SIP", 
     491                "Chip", 
     492                "DIP", 
     493                "ZIP", 
     494                "Proprietary Card", 
     495                "DIMM", 
     496                "TSOP", 
     497                "Row of chips", 
     498                "RIMM", 
     499                "SODIMM", 
     500                "SRIMM", 
     501        }; 
     502        if (num > 0x0E) 
     503                return ""; 
     504        return memory_device_form_factor[num]; 
     505} 
     506 
     507static const char *dmi_memory_device_type(u8 num) 
     508{ 
     509        static const char *memory_device_type[]={ 
     510                "", 
     511                "Other", 
     512                "Unknown", 
     513                "DRAM", 
     514                "EDRAM", 
     515                "VRAM", 
     516                "SRAM", 
     517                "RAM", 
     518                "ROM", 
     519                "FLASH", 
     520                "EEPROM", 
     521                "FEPROM", 
     522                "EPROM", 
     523                "CDRAM", 
     524                "3DRAM", 
     525                "SDRAM", 
     526                "SGRAM", 
     527                "RDRAM", 
     528                "DDR" 
     529        }; 
     530        if (num > 0x12) 
     531                return ""; 
     532        return memory_device_type[num]; 
     533} 
     534 
     535static void dmi_memory_device_detail(u8 v) 
     536{ 
     537        printf("\t\tType Detail: "); 
     538        if (v&(1<<1)) 
     539                printf("Other "); 
     540        if (v&(1<<2)) 
     541                printf("Unknown "); 
     542        if (v&(1<<3)) 
     543                printf("Fast-paged "); 
     544        if (v&(1<<4)) 
     545                printf("Static column "); 
     546        if (v&(1<<5)) 
     547                printf("Pseudo-static "); 
     548        if (v&(1<<6)) 
     549                printf("RAMBUS "); 
     550        if (v&(1<<7)) 
     551                printf("Synchronous "); 
     552        if (v&(1<<8)) 
     553                printf("CMOS "); 
     554        if (v&(1<<9)) 
     555                printf("EDO "); 
     556        if (v&(1<<10)) 
     557                printf("Window DRAM "); 
     558        if (v&(1<<11)) 
     559                printf("Cache DRAM "); 
     560        if (v&(1<<12)) 
     561                printf("Non-volatile "); 
     562        printf("\n"); 
     563} 
    337564 
    338565const char *dmi_port_type(u8 code) 
     
    347574                "Serial Port XT/AT Compatible", 
    348575                "Serial Port 16450 Compatible", 
    349                 "Serial Port 16650 Compatible", 
    350                 "Serial Port 16650A Compatible", 
     576                "Serial Port 16550 Compatible", 
     577                "Serial Port 16550A Compatible", 
    351578                "SCSI Port", 
    352579                "MIDI Port", 
     
    402629                return "Other"; 
    403630         
    404         if (code > 0xA1
     631        if (code > 6
    405632                return ""; 
    406633        return processor_type[code]; 
     
    459686                "Sound", 
    460687        }; 
    461         code &= 0x80; 
     688        code &= ~0x80; 
    462689        if (code > 7) 
    463690                return ""; 
     
    483710                "HT82H791", 
    484711        }; 
    485         code &= 0x80; 
     712         
    486713        if (code > 0x0d) 
    487714                return ""; 
     
    499726                "SMBus", 
    500727        }; 
    501         code &= 0x80; 
     728         
    502729        if (code > 5) 
    503730                return ""; 
     
    527754                "Passive Cooling", 
    528755        }; 
    529         code &= 0x80; 
     756         
    530757        if (code > 0x11) 
    531758                return ""; 
     
    549776                "Add-in Card", 
    550777        }; 
    551         code &= 0x80; 
     778         
    552779        if (code > 0x0b) 
    553780                return ""; 
     
    563790                "Drive Back Plane", 
    564791        }; 
    565         code &= 0x80; 
     792         
    566793        if (code <= 0x0b) 
    567794                return dmi_volt_loc(code); 
    568         return type[code - 0x0c]; 
     795        if (code <= 0x0f) 
     796                return type[code - 0x0c]; 
     797        return ""; 
    569798} 
    570799 
     
    580809                "Non-recoverable", 
    581810        }; 
    582         code &= 0x80; 
     811         
    583812        if (code > 6) 
    584813                return ""; 
     
    641870static void dmi_table(int fd, u32 base, int len, int num) 
    642871{ 
    643         char *buf=malloc(len); 
     872        unsigned char *buf=malloc(len); 
    644873        struct dmi_header *dm; 
    645         u8 *data
     874        u8 *data, *next
    646875        int i=0; 
    647876        int r=0, r2=0; 
     
    663892                return; 
    664893        } 
    665         while(r2!=len && (r=read(fd, buf+r2, len-r2))!=0
     894        while(r2!=len && (r=read(fd, buf+r2, len-r2))!=0 && r!=-1
    666895                r2+=r; 
    667         if(r==0
     896        if(r==-1
    668897        { 
    669898                perror("dmi: read"); 
    670899                return; 
    671900        } 
     901        if(r==0) 
     902        { 
     903                fputs("dmi: read: Unexpected end of file\n", stderr); 
     904                return; 
     905        } 
    672906        data = buf; 
    673         while(data+sizeof(struct dmi_header)<=(u8*)buf+len) 
     907        while(i<num && data+sizeof(struct dmi_header)<=(u8*)buf+len) 
    674908        { 
    675909                u32 u, u2; 
     
    680914                 
    681915                /* we won't read beyond allocated memory */ 
    682                 if(data+dm->length>(u8*)buf+len) 
     916                next=data+dm->length; 
     917                while(next-buf+1<len && (next[0]!=0 || next[1]!=0)) 
     918                        next++; 
     919                next+=2; 
     920                if(next-buf>len) 
    683921                { 
    684922                        printf("\tIncomplete structure, abort decoding.\n"); 
     
    699937                                        data[7]<<8|data[6]); 
    700938                        printf("\t\tROM size: %dK\n", 
    701                                         64*data[9]); 
     939                                        64*(data[9]+1)); 
    702940                                printf("\t\tCapabilities:\n"); 
    703941                                u=data[13]<<24|data[12]<<16|data[11]<<8|data[10];                
     
    8541092                                        printf("disabled\n"); 
    8551093                                printf("\t\tL%d Cache Size: ", 1+(u&7)); 
     1094                                dmi_cache_size(data[9]|data[10]<<8); 
     1095                                printf("\t\tL%d Cache Maximum: ", 1+(u&7)); 
    8561096                                dmi_cache_size(data[7]|data[8]<<8); 
    857                                 printf("\t\tL%d Cache Maximum: ", 1+(u&7)); 
    858                                 dmi_cache_size(data[9]|data[10]<<8); 
    8591097                                printf("\t\tL%d Cache Type: ", 1+(u&7)); 
    8601098                                dmi_decode_cache(data[13]); 
     
    9601198                case 16: 
    9611199                        printf("\tPhysical Memory Array\n"); 
     1200                        printf("\t\tLocation: %s\n", 
     1201                                dmi_memory_array_location(data[4])); 
     1202                        printf("\t\tUse: %s\n", 
     1203                                dmi_memory_array_use(data[5])); 
     1204                        printf("\t\tError Correction Type: %s\n", 
     1205                                dmi_memory_array_error_correction_type(data[6])); 
     1206                        u2 = data[10]<<24|data[9]<<16|data[8]<<8|data[7]; 
     1207                        printf("\t\tMaximum Capacity: "); 
     1208                        if (u2 == 0x80000000) 
     1209                                printf("Unknown\n"); 
     1210                        else 
     1211                                printf("%u kB\n", u2); 
     1212                        printf("\t\tError Information Handle: "); 
     1213                        u = data[12]<<8|data[11]; 
     1214                        if (u == 0xffff) { 
     1215                                printf("None\n"); 
     1216                        } else if (u == 0xfffe) { 
     1217                                printf("Not Provided\n"); 
     1218                        } else { 
     1219                                printf("0x%04X\n", u); 
     1220                        } 
     1221                        printf("\t\tNumber of Devices: %u\n", data[14]<<8|data[13]); 
    9621222                        break; 
    9631223                case 17: 
    9641224                        printf("\tMemory Device\n"); 
     1225                        printf("\t\tArray Handle: 0x%04X\n", data[5]<<8|data[4]); 
     1226                        printf("\t\tError Information Handle: "); 
     1227                        u = data[7]<<8|data[6]; 
     1228                        if (u == 0xffff) { 
     1229                                printf("None\n"); 
     1230                        } else if (u == 0xfffe) { 
     1231                                printf("Not Provided\n"); 
     1232                        } else { 
     1233                                printf("0x%04X\n", u); 
     1234                        } 
     1235                        u = data[9]<<8|data[8]; 
     1236                        printf("\t\tTotal Width: "); 
     1237                        if (u == 0xffff) 
     1238                                printf("Unknown\n"); 
     1239                        else 
     1240                                printf("%u bits\n", u); 
     1241                        u = data[11]<<8|data[10]; 
     1242                        printf("\t\tData Width: "); 
     1243                        if (u == 0xffff) 
     1244                                printf("Unknown\n"); 
     1245                        else 
     1246                                printf("%u bits\n", u); 
     1247                        u = data[13]<<8|data[12]; 
     1248                        printf("\t\tSize: "); 
     1249                        if (u == 0xffff) 
     1250                                printf("Unknown\n"); 
     1251                        else 
     1252                                printf("%u %sbyte\n", (u&0x7fff), (u&0x8000) ? "K" : "M"); 
     1253                        printf("\t\tForm Factor: %s\n", 
     1254                                dmi_memory_device_form_factor(data[14])); 
     1255                        if (data[15] != 0) { 
     1256                                printf("\t\tSet: "); 
     1257                                if (data[15] == 0xff) 
     1258                                        printf("Unknown\n"); 
     1259                                else 
     1260                                        printf("0x%02X\n", data[15]); 
     1261                        } 
     1262                        printf("\t\tLocator: %s\n", 
     1263                                dmi_string(dm, data[16])); 
     1264                        printf("\t\tBank Locator: %s\n", 
     1265                                dmi_string(dm, data[17])); 
     1266                        printf("\t\tType: %s\n", 
     1267                                dmi_memory_device_type(data[18])); 
     1268                        u = data[20]<<8|data[19]; 
     1269                        if (u&0x1ffe) 
     1270                                dmi_memory_device_detail(u); 
     1271                        if (dm->length > 21) { 
     1272                                u = data[22]<<8|data[21]; 
     1273                                printf("\t\tSpeed: "); 
     1274                                if (u == 0) 
     1275                                        printf("Unknown\n"); 
     1276                                else 
     1277                                        printf("%u MHz (%.1f ns)\n", u, (1000.0/u)); 
     1278                        } 
     1279                        if (dm->length > 23) 
     1280                                printf("\t\tManufacturer: %s\n", 
     1281                                        dmi_string(dm, data[23])); 
     1282                        if (dm->length > 24) 
     1283                                printf("\t\tSerial Number: %s\n", 
     1284                                        dmi_string(dm, data[24])); 
     1285                        if (dm->length > 25) 
     1286                                printf("\t\tAsset Tag: %s\n", 
     1287                                        dmi_string(dm, data[25])); 
     1288                        if (dm->length > 26) 
     1289                                printf("\t\tPart Number: %s\n", 
     1290                                        dmi_string(dm, data[26])); 
    9651291                        break; 
    9661292                case 18: 
     
    10241350                        printf("\tCooling Device\n"); 
    10251351                        printf("\t\tDevice Type: %s\n", 
    1026                                dmi_fan_type(data[5] & 0x1f)); 
     1352                               dmi_fan_type(data[6] & 0x1f)); 
    10271353                        printf("\t\tDevice Status: %s\n", 
    1028                                dmi_status(data[5] >> 5)); 
     1354                               dmi_status(data[6] >> 5)); 
    10291355                        if(dm->length > 0x0c) 
    10301356                                printf("\t\tNominal Speed: %s\n", 
     
    11131439                        break; 
    11141440                case 37: 
    1115                         printf("\tMemory Channeln"); 
     1441                        printf("\tMemory Channel\n"); 
    11161442                        break; 
    11171443                case 38: 
     
    11411467                         
    11421468                } 
    1143                 data+=dm->length; 
    1144                 while(*data || data[1]) 
    1145                         data++; 
    1146                 data+=2; 
     1469                data=next; 
    11471470                i++; 
    11481471        } 
    11491472        if(i!=num) 
    11501473        { 
    1151                 printf("Wrong DMI structures count: %d announced, %d decoded.\n", num, i); 
     1474                printf("Wrong DMI structures count: %d announced, only %d decoded.\n", 
     1475                        num, i); 
    11521476        } 
    11531477        if(data-(u8*)buf!=len) 
    11541478        { 
    1155                 printf("Wrong DMI structures length: %d bytes announced, %d bytes decoded.\n", len, data-(u8*)buf); 
     1479                printf("Wrong DMI structures length: %d bytes announced, %d bytes decoded.\n", 
     1480                        len, data-(u8*)buf); 
    11561481        } 
    11571482        free(buf); 
     
    11591484 
    11601485 
    1161 int main(void) 
    1162 
    1163         unsigned char buf[20]; 
     1486static const char *acpi_version(u8 code) 
     1487
     1488        static const char *version[]={ 
     1489                " 1.0", 
     1490                "", 
     1491                " 2.0" 
     1492        }; 
     1493         
     1494        if(code<=2) 
     1495                return version[code]; 
     1496        return ""; 
     1497
     1498 
     1499 
     1500static const char *pnp_event_notification(u8 code) 
     1501
     1502        static const char *notification[]={ 
     1503                "Not Supported", 
     1504                "Polling", 
     1505                "Asynchronous" 
     1506        }; 
     1507         
     1508        if(code<=2) 
     1509                return notification[code]; 
     1510        return ""; 
     1511
     1512 
     1513 
     1514static void pir_exclusive_irqs(u16 code) 
     1515
     1516        if(code==0) 
     1517                printf(" None"); 
     1518        else 
     1519        { 
     1520                u8 a; 
     1521                for(a=0; a<16; a++) 
     1522                        if(code&(1<<a)) 
     1523                                printf(" %u", a); 
     1524        } 
     1525
     1526 
     1527 
     1528static __inline__ int checksum(u8 *buf, int len) 
     1529
     1530        u8 sum=0; 
     1531        int a; 
     1532         
     1533        for(a=0; a<len; a++) 
     1534                sum+=buf[a]; 
     1535        return (sum==0); 
     1536
     1537 
     1538int main(__attribute__ ((unused)) int argc, const char *argv[]) 
     1539
     1540        u8 buf[48]; 
    11641541        int fd=open("/dev/mem", O_RDONLY); 
    11651542        long fp=0xE0000L; 
    11661543        u8 smmajver=0, smminver=0; 
     1544         
     1545        if(sizeof(u8)!=1 || sizeof(u16)!=2 || sizeof(u32)!=4 || '\0'!=0) 
     1546        { 
     1547                fprintf(stderr,"%s: compiler incompatibility.\n", argv[0]); 
     1548                exit(255); 
     1549        } 
     1550        printf("# dmidecode %s\n", VERSION); 
    11671551        if(fd==-1) 
    11681552        { 
     
    11761560        } 
    11771561                 
    1178  
    1179         fp -= 16; 
    1180          
    11811562        while( fp < 0xFFFFF) 
    11821563        { 
    1183                 fp+=16; 
    1184                 if(read(fd, buf, 16)!=16) 
     1564                ssize_t r=0, r2=0; 
     1565                 
     1566                while(r2!=16 && (r=read(fd, buf+r2, 16-r2))!=0 && r!=-1) 
     1567                        r2+=r; 
     1568                if(r==-1) 
     1569                { 
    11851570                        perror("read"); 
    1186                 else if(memcmp(buf, "_SM_", 4)==0) 
     1571                        exit(1); 
     1572                } 
     1573                if(r==0) 
     1574                { 
     1575                        fputs("read: Unexpected end of file\n", stderr); 
     1576                        exit(1); 
     1577                } 
     1578                 
     1579                if(memcmp(buf, "_SM_", 4)==0) 
    11871580                        printf("SMBIOS %d.%d present.\n", smmajver=buf[6], smminver=buf[7]); 
    11881581                else if(memcmp(buf, "_SYSID_", 7)==0) 
    1189                         printf("SYSID present.\n"); 
    1190                 else if(memcmp(buf, "_DMI_", 5)==0) 
     1582                { 
     1583                        /* complete buffer, compute checksum */ 
     1584                        read(fd, buf+16, 16); /* arbitrary, at least 1 */ 
     1585                        if(*(u16 *)(buf+8)<=32 && checksum(buf, *(u16 *)(buf+8))) 
     1586                        { 
     1587                                fp+=16; 
     1588                                printf("SYSID present.\n"); 
     1589                                printf("\tRevision: %u\n", 
     1590                                        buf[16]); 
     1591                                printf("%d structure%s.\n", 
     1592                                        *(u16 *)(buf+14), *(u16 *)(buf+14)>1?"s":""); 
     1593                                printf("SYSID table at 0x%08X.\n", 
     1594                                        *(u32 *)(buf+10)); 
     1595                        } 
     1596                        else 
     1597                                lseek(fd, -16, SEEK_CUR); 
     1598                } 
     1599                else if(memcmp(buf, "_DMI_", 5)==0 && checksum(buf, 15)) 
    11911600                { 
    11921601                        u16 num=buf[13]<<8|buf[12]; 
     
    11941603                        u32 base=buf[11]<<24|buf[10]<<16|buf[9]<<8|buf[8]; 
    11951604 
     1605                        /* if version is 0.0, the real version is taken from _SM_ above */ 
    11961606                        printf("DMI %d.%d present.\n", 
    11971607                                buf[14]?buf[14]>>4:smmajver, buf[14]?buf[14]&0x0F:smminver); 
     
    12061616                } 
    12071617                else if(memcmp(buf, "$PnP", 4)==0) 
    1208                         printf("PNP BIOS present.\n"); 
     1618                { 
     1619                        /* complete buffer, compute checksum */ 
     1620                        read(fd, buf+16, 32); /* arbitrary, at least 1 */ 
     1621                        if(buf[5]<=48 && checksum(buf, buf[5])) 
     1622                        { 
     1623                                fp+=32; 
     1624                                printf("PNP %u.%u present.\n", 
     1625                                        buf[4]>>4, buf[4]&0x0F); 
     1626                                printf("\tEvent Notification: %s\n", 
     1627                                        pnp_event_notification((*(u16 *)(buf+6))&0x03)); 
     1628                                if(((*(u16 *)(buf+6))&0x03)==1) 
     1629                                        printf("\tEvent Notification Flag Address: 0x%08X\n", 
     1630                                                *(u32 *)(buf+9)); 
     1631                                printf("\tReal Mode Code Address: %04X:%04X\n", 
     1632                                        *(u16 *)(buf+0x0F), *(u16 *)(buf+0x0D)); 
     1633                                printf("\tReal Mode Data Address: %04X:0000\n", 
     1634                                        *(u16 *)(buf+0x1B)); 
     1635                                printf("\tProtected Mode Code Address: 0x%08X\n", 
     1636                                        *(u32 *)(buf+0x13)+*(u16 *)(buf+0x11)); 
     1637                                printf("\tProtected Mode Data Address: 0x%08X\n", 
     1638                                        *(u32 *)(buf+0x1D)); 
     1639                                if(*(u32 *)(buf+0x17)!=0) 
     1640                                        printf("\tOEM Device Identifier: 0x%08X\n", 
     1641                                                *(u32 *)(buf+0x17)); 
     1642                        } 
     1643                        else 
     1644                                lseek(fd, -32, SEEK_CUR); 
     1645                } 
    12091646                else if(memcmp(buf, "RSD PTR ", 8)==0) 
    12101647                { 
    1211                         int a; 
    1212                         unsigned char sum=0; 
    1213                         printf("RSD PTR found at 0x%lX.\n", fp); 
    1214  
    1215                         if(buf[15]!=0) 
     1648                        /* complete buffer, compute checksum */ 
     1649                        read(fd, buf+16, 4); 
     1650                        if(checksum(buf, 20)) 
    12161651                        { 
    1217                                 printf("Reserved check failed.\n"); 
     1652                                lseek(fd, 12, SEEK_CUR); 
     1653                                fp+=16; 
     1654                                printf("ACPI%s present.\n", 
     1655                                        acpi_version(buf[15])); 
     1656                                printf("\tOEM ID: "); 
     1657                                fwrite(buf+9, 6, 1, stdout); 
     1658                                printf("\n"); 
     1659                                printf("RSD table at 0x%08X.\n", 
     1660                                        *(u32 *)(buf+16)); 
    12181661                        } 
    1219                         printf("OEM "); 
    1220                         fwrite(buf+9, 6, 1, stdout); 
    1221                         printf("\n"); 
    1222                         read(fd,buf+16,4); 
    1223                         lseek(fd, -4, SEEK_CUR); 
    1224                         for(a=0;a<20;a++) 
    1225                                 sum+=buf[a]; 
    1226                         if(sum!=0) 
    1227                                 printf("Bad checksum.\n"); 
     1662                        else 
     1663                                lseek(fd, -4, SEEK_CUR); 
    12281664                } 
     1665                else if(memcmp(buf, "$SNY", 4)==0) 
     1666                { 
     1667                        /* complete buffer, compute checksum */ 
     1668                        read(fd, buf+16, 16); 
     1669                        if(buf[5]<=32 && checksum(buf, buf[5])) 
     1670                        { 
     1671                                fp+=16; 
     1672                                printf("Sony system detected (?).\n"); 
     1673                        } 
     1674                        else 
     1675                                lseek(fd, -16, SEEK_CUR); 
     1676                } 
     1677                else if(memcmp(buf, "_32_", 4)==0) 
     1678                { 
     1679                        /* complete buffer, reposition file, compute checksum */ 
     1680                        read(fd, buf+16, 32); 
     1681                        lseek(fd, -32, SEEK_CUR); 
     1682                        if(buf[9]>=1 && buf[9]<=3 && checksum(buf, buf[9]<<4)) 
     1683                        { 
     1684                                printf("BIOS32 Service Directory present.\n"); 
     1685                                printf("\tCalling Interface Address: 0x%08X\n", 
     1686                                        *(u32 *)(buf+4)); 
     1687                                lseek(fd, (buf[9]-1)<<4, SEEK_CUR); 
     1688                                fp+=(buf[9]-1)<<4; 
     1689                        } 
     1690                } 
     1691                else if(memcmp(buf, "$PIR", 4)==0) 
     1692                { 
     1693                        /* complete buffer, reposition file */ 
     1694                        read(fd, buf+16, 16); 
     1695                        lseek(fd, -16, SEEK_CUR); 
     1696                        if(buf[5]!=0 && buf[30]==0) 
     1697                        { 
     1698                                printf("PCI Interrupt Routing %u.%u present.\n", 
     1699                                        buf[5], buf[4]); 
     1700                                printf("\tTable Size: %u bytes\n", 
     1701                                        *(u16 *)(buf+6)); 
     1702                                printf("\tRouter ID: %02x:%02x.%1x\n", 
     1703                                        buf[8], buf[9]>>3, buf[9]&0x07); 
     1704                                printf("\tExclusive IRQs:"); 
     1705                                pir_exclusive_irqs(*(u16 *)(buf+10)); 
     1706                                printf("\n"); 
     1707                                if(*(u32 *)(buf+12)!=0) 
     1708                                        printf("\tCompatible Router: %04x:%04x\n", 
     1709                                                *(u16 *)(buf+12), *(u16 *)(buf+14)); 
     1710                                if(*(u32 *)(buf+16)!=0) 
     1711                                        printf("\tMiniport Data: 0x%08X\n", 
     1712                                          &n