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,10 +1564,12 @@ static int decode_dmi(dmi_header_t *dm, dmi_ipmi_data_t *ipmi_data) ...@@ -1564,10 +1564,12 @@ static int decode_dmi(dmi_header_t *dm, dmi_ipmi_data_t *ipmi_data)
u8 *data = (u8 *)dm; u8 *data = (u8 *)dm;
unsigned long base_addr; unsigned long base_addr;
u8 reg_spacing; 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)); memcpy(&base_addr, data+8, sizeof(unsigned long));
if (len >= 0x11) {
if (base_addr & 1) { if (base_addr & 1) {
/* I/O */ /* I/O */
base_addr &= 0xFFFE; base_addr &= 0xFFFE;
...@@ -1577,6 +1579,11 @@ static int decode_dmi(dmi_header_t *dm, dmi_ipmi_data_t *ipmi_data) ...@@ -1577,6 +1579,11 @@ static int decode_dmi(dmi_header_t *dm, dmi_ipmi_data_t *ipmi_data)
/* Memory */ /* Memory */
ipmi_data->addr_space = IPMI_MEM_ADDR_SPACE; 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. */ /* The top two bits of byte 0x10 hold the register spacing. */
reg_spacing = (data[0x10] & 0xC0) >> 6; reg_spacing = (data[0x10] & 0xC0) >> 6;
...@@ -1591,21 +1598,20 @@ static int decode_dmi(dmi_header_t *dm, dmi_ipmi_data_t *ipmi_data) ...@@ -1591,21 +1598,20 @@ static int decode_dmi(dmi_header_t *dm, dmi_ipmi_data_t *ipmi_data)
ipmi_data->offset = 16; ipmi_data->offset = 16;
break; break;
default: default:
printk("ipmi_si: Unknown SMBIOS IPMI Base Addr" /* Some other interface, just ignore it. */
" Modifier: 0x%x\n", reg_spacing);
return -EIO; return -EIO;
} }
} else {
/* If bit 4 of byte 0x10 is set, then the lsb for the address /* Old DMI spec. */
is odd. */ ipmi_data->base_addr = base_addr;
ipmi_data->base_addr = base_addr | ((data[0x10] & 0x10) >> 4); ipmi_data->addr_space = IPMI_IO_ADDR_SPACE;
ipmi_data->offset = 1;
ipmi_data->irq = data[0x11]; }
if (is_new_interface(-1, ipmi_data->addr_space,ipmi_data->base_addr)) 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; 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