IPMI: add 0.9 support

Add support for IPMI 0.9 systems to the IPMI driver.  Just handle a shorter
get device ID command with less information.

Signed-off-by: Corey Minyard <cminyard@mvista.com>
Cc: Stian Jordet <liste@jordet.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Corey Minyard 2007-10-18 03:07:11 -07:00 committed by Linus Torvalds
parent ac0191517c
commit d8c98618f4
2 changed files with 30 additions and 21 deletions

View file

@ -2380,20 +2380,9 @@ static int try_get_dev_id(struct smi_info *smi_info)
/* Otherwise, we got some data. */ /* Otherwise, we got some data. */
resp_len = smi_info->handlers->get_result(smi_info->si_sm, resp_len = smi_info->handlers->get_result(smi_info->si_sm,
resp, IPMI_MAX_MSG_LENGTH); resp, IPMI_MAX_MSG_LENGTH);
if (resp_len < 14) {
/* That's odd, it should be longer. */
rv = -EINVAL;
goto out;
}
if ((resp[1] != IPMI_GET_DEVICE_ID_CMD) || (resp[2] != 0)) { /* Check and record info from the get device id, in case we need it. */
/* That's odd, it shouldn't be able to fail. */ rv = ipmi_demangle_device_id(resp, resp_len, &smi_info->device_id);
rv = -EINVAL;
goto out;
}
/* Record info from the get device id, in case we need it. */
ipmi_demangle_device_id(resp+3, resp_len-3, &smi_info->device_id);
out: out:
kfree(resp); kfree(resp);

View file

@ -148,26 +148,46 @@ struct ipmi_device_id {
/* Take a pointer to a raw data buffer and a length and extract device /* Take a pointer to a raw data buffer and a length and extract device
id information from it. The first byte of data must point to the id information from it. The first byte of data must point to the
byte from the get device id response after the completion code. netfn << 2, the data should be of the format:
The caller is responsible for making sure the length is at least netfn << 2, cmd, completion code, data
11 and the command completed without error. */ as normally comes from a device interface. */
static inline void ipmi_demangle_device_id(unsigned char *data, static inline int ipmi_demangle_device_id(const unsigned char *data,
unsigned int data_len, unsigned int data_len,
struct ipmi_device_id *id) struct ipmi_device_id *id)
{ {
if (data_len < 9)
return -EINVAL;
if (data[0] != IPMI_NETFN_APP_RESPONSE << 2 ||
data[1] != IPMI_GET_DEVICE_ID_CMD)
/* Strange, didn't get the response we expected. */
return -EINVAL;
if (data[2] != 0)
/* That's odd, it shouldn't be able to fail. */
return -EINVAL;
data += 3;
data_len -= 3;
id->device_id = data[0]; id->device_id = data[0];
id->device_revision = data[1]; id->device_revision = data[1];
id->firmware_revision_1 = data[2]; id->firmware_revision_1 = data[2];
id->firmware_revision_2 = data[3]; id->firmware_revision_2 = data[3];
id->ipmi_version = data[4]; id->ipmi_version = data[4];
id->additional_device_support = data[5]; id->additional_device_support = data[5];
id->manufacturer_id = data[6] | (data[7] << 8) | (data[8] << 16); if (data_len >= 6) {
id->product_id = data[9] | (data[10] << 8); id->manufacturer_id = (data[6] | (data[7] << 8) |
(data[8] << 16));
id->product_id = data[9] | (data[10] << 8);
} else {
id->manufacturer_id = 0;
id->product_id = 0;
}
if (data_len >= 15) { if (data_len >= 15) {
memcpy(id->aux_firmware_revision, data+11, 4); memcpy(id->aux_firmware_revision, data+11, 4);
id->aux_firmware_revision_set = 1; id->aux_firmware_revision_set = 1;
} else } else
id->aux_firmware_revision_set = 0; id->aux_firmware_revision_set = 0;
return 0;
} }
/* Add a low-level interface to the IPMI driver. Note that if the /* Add a low-level interface to the IPMI driver. Note that if the