From: Corey Minyard The 1999 version of the DMI spec had a different configuration than the newer versions for the IPMI configuration information. This patch handles the differences between the two. Signed-off-by: Corey Minyard Signed-off-by: Andrew Morton --- 25-akpm/drivers/char/ipmi/ipmi_si_intf.c | 65 +++++++++++++++++-------------- 1 files changed, 36 insertions(+), 29 deletions(-) diff -puN drivers/char/ipmi/ipmi_si_intf.c~update-to-ipmi-driver-to-support-old-dmi-spec drivers/char/ipmi/ipmi_si_intf.c --- 25/drivers/char/ipmi/ipmi_si_intf.c~update-to-ipmi-driver-to-support-old-dmi-spec Wed Feb 9 14:51:12 2005 +++ 25-akpm/drivers/char/ipmi/ipmi_si_intf.c Wed Feb 9 14:51:12 2005 @@ -1578,46 +1578,53 @@ static int decode_dmi(dmi_header_t *dm, u8 *data = (u8 *)dm; unsigned long base_addr; u8 reg_spacing; + u8 len = dm->length; dmi_ipmi_data_t *ipmi_data = dmi_data+intf_num; ipmi_data->type = data[4]; memcpy(&base_addr, data+8, sizeof(unsigned long)); - if (base_addr & 1) { - /* I/O */ - base_addr &= 0xFFFE; + if (len >= 0x11) { + if (base_addr & 1) { + /* I/O */ + base_addr &= 0xFFFE; + ipmi_data->addr_space = IPMI_IO_ADDR_SPACE; + } + else { + /* Memory */ + ipmi_data->addr_space = IPMI_MEM_ADDR_SPACE; + } + /* If bit 4 of byte 0x10 is set, then the lsb for the address + is odd. */ + ipmi_data->base_addr = base_addr | ((data[0x10] & 0x10) >> 4); + + ipmi_data->irq = data[0x11]; + + /* The top two bits of byte 0x10 hold the register spacing. */ + reg_spacing = (data[0x10] & 0xC0) >> 6; + switch(reg_spacing){ + case 0x00: /* Byte boundaries */ + ipmi_data->offset = 1; + break; + case 0x01: /* 32-bit boundaries */ + ipmi_data->offset = 4; + break; + case 0x02: /* 16-byte boundaries */ + ipmi_data->offset = 16; + break; + default: + /* Some other interface, just ignore it. */ + return -EIO; + } + } else { + /* Old DMI spec. */ + ipmi_data->base_addr = base_addr; ipmi_data->addr_space = IPMI_IO_ADDR_SPACE; - } - else { - /* Memory */ - ipmi_data->addr_space = IPMI_MEM_ADDR_SPACE; - } - - /* The top two bits of byte 0x10 hold the register spacing. */ - reg_spacing = (data[0x10] & 0xC0) >> 6; - switch(reg_spacing){ - case 0x00: /* Byte boundaries */ ipmi_data->offset = 1; - break; - case 0x01: /* 32-bit boundaries */ - ipmi_data->offset = 4; - break; - case 0x02: /* 16-byte boundaries */ - ipmi_data->offset = 16; - break; - default: - /* Some other interface, just ignore it. */ - return -EIO; } ipmi_data->slave_addr = data[6]; - /* If bit 4 of byte 0x10 is set, then the lsb for the address - is odd. */ - ipmi_data->base_addr = base_addr | ((data[0x10] & 0x10) >> 4); - - ipmi_data->irq = data[0x11]; - if (is_new_interface(-1, ipmi_data->addr_space,ipmi_data->base_addr)) { dmi_data_entries++; return 0; _