Commit d8c98618 authored by Corey Minyard's avatar Corey Minyard Committed by Linus Torvalds

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: default avatarCorey Minyard <cminyard@mvista.com>
Cc: Stian Jordet <liste@jordet.net>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent ac019151
......@@ -2380,20 +2380,9 @@ static int try_get_dev_id(struct smi_info *smi_info)
/* Otherwise, we got some data. */
resp_len = smi_info->handlers->get_result(smi_info->si_sm,
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)) {
/* That's odd, it shouldn't be able to fail. */
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);
/* Check and record info from the get device id, in case we need it. */
rv = ipmi_demangle_device_id(resp, resp_len, &smi_info->device_id);
out:
kfree(resp);
......
......@@ -148,26 +148,46 @@ struct ipmi_device_id {
/* 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
byte from the get device id response after the completion code.
The caller is responsible for making sure the length is at least
11 and the command completed without error. */
static inline void ipmi_demangle_device_id(unsigned char *data,
netfn << 2, the data should be of the format:
netfn << 2, cmd, completion code, data
as normally comes from a device interface. */
static inline int ipmi_demangle_device_id(const unsigned char *data,
unsigned int data_len,
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_revision = data[1];
id->firmware_revision_1 = data[2];
id->firmware_revision_2 = data[3];
id->ipmi_version = data[4];
id->additional_device_support = data[5];
id->manufacturer_id = data[6] | (data[7] << 8) | (data[8] << 16);
if (data_len >= 6) {
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) {
memcpy(id->aux_firmware_revision, data+11, 4);
id->aux_firmware_revision_set = 1;
} else
id->aux_firmware_revision_set = 0;
return 0;
}
/* Add a low-level interface to the IPMI driver. Note that if the
......
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