Commit 3c503a0f authored by Corey Minyard's avatar Corey Minyard Committed by Linus Torvalds

[PATCH] Update to IPMI driver to support old DMI spec

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: default avatarCorey Minyard <minyard@acm.org>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent e920feb5
......@@ -1564,48 +1564,54 @@ static int decode_dmi(dmi_header_t *dm, dmi_ipmi_data_t *ipmi_data)
u8 *data = (u8 *)dm;
unsigned long base_addr;
u8 reg_spacing;
u8 len = dm->length;
ipmi_data->type = data[0x04];
ipmi_data->type = data[4];
memcpy(&base_addr,&data[0x08],sizeof(unsigned long));
if (base_addr & 1) {
/* I/O */
base_addr &= 0xFFFE;
memcpy(&base_addr, data+8, sizeof(unsigned long));
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:
printk("ipmi_si: Unknown SMBIOS IPMI Base Addr"
" Modifier: 0x%x\n", reg_spacing);
return -EIO;
}
/* 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))
return 0;
return 0;
memset(ipmi_data,0,sizeof(dmi_ipmi_data_t));
memset(ipmi_data, 0, sizeof(dmi_ipmi_data_t));
return -1;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment