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

From: Corey Minyard
Date: Wed Feb 09 2005 - 12:27:18 EST


BTW, I'm also working with the person who had the trouble with the I2C non-blocking driver updates, but we haven't figured it out yet. Hopefully soon. (Though that has nothing to do with this patch.)

Thanks,

-Corey 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 <minyard@xxxxxxx>

Index: linux-2.6.11-rc3/drivers/char/ipmi/ipmi_si_intf.c
===================================================================
--- linux-2.6.11-rc3.orig/drivers/char/ipmi/ipmi_si_intf.c
+++ linux-2.6.11-rc3/drivers/char/ipmi/ipmi_si_intf.c
@@ -1578,46 +1578,53 @@
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;