Commit c468f911 authored by Jeremy Kerr's avatar Jeremy Kerr Committed by Corey Minyard

ipmi: Make ipmi_demangle_device_id more generic

Currently, ipmi_demagle_device_id requires a full response buffer in its
data argument. This means we can't use it to parse a response in a
struct ipmi_recv_msg, which has the netfn and cmd as separate bytes.

This change alters the definition and users of ipmi_demangle_device_id
to use a split netfn, cmd and data buffer, so it can be used with
non-sequential responses.
Signed-off-by: default avatarJeremy Kerr <jk@ozlabs.org>

Fixed the ipmi_ssif.c and ipmi_si_intf.c changes to use data from the
response, not the data from the message, when passing info to the
ipmi_demangle_device_id() function.
Signed-off-by: default avatarCorey Minyard <cminyard@mvista.com>
parent a9137c3d
...@@ -2926,7 +2926,8 @@ static int try_get_dev_id(struct smi_info *smi_info) ...@@ -2926,7 +2926,8 @@ static int try_get_dev_id(struct smi_info *smi_info)
resp, IPMI_MAX_MSG_LENGTH); resp, IPMI_MAX_MSG_LENGTH);
/* Check and record info from the get device id, in case we need it. */ /* 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); rv = ipmi_demangle_device_id(resp[0] >> 2, resp[1],
resp + 2, resp_len - 2, &smi_info->device_id);
out: out:
kfree(resp); kfree(resp);
......
...@@ -1491,7 +1491,8 @@ static int ssif_probe(struct i2c_client *client, const struct i2c_device_id *id) ...@@ -1491,7 +1491,8 @@ static int ssif_probe(struct i2c_client *client, const struct i2c_device_id *id)
if (rv) if (rv)
goto out; goto out;
rv = ipmi_demangle_device_id(resp, len, &ssif_info->device_id); rv = ipmi_demangle_device_id(resp[0] >> 2, resp[1],
resp + 2, len - 2, &ssif_info->device_id);
if (rv) if (rv)
goto out; goto out;
......
...@@ -162,27 +162,27 @@ struct ipmi_device_id { ...@@ -162,27 +162,27 @@ struct ipmi_device_id {
#define ipmi_version_major(v) ((v)->ipmi_version & 0xf) #define ipmi_version_major(v) ((v)->ipmi_version & 0xf)
#define ipmi_version_minor(v) ((v)->ipmi_version >> 4) #define ipmi_version_minor(v) ((v)->ipmi_version >> 4)
/* Take a pointer to a raw data buffer and a length and extract device /* Take a pointer to an IPMI response and extract device id information from
id information from it. The first byte of data must point to the * it. @netfn is in the IPMI_NETFN_ format, so may need to be shifted from
netfn << 2, the data should be of the format: * a SI response.
netfn << 2, cmd, completion code, data */
as normally comes from a device interface. */ static inline int ipmi_demangle_device_id(uint8_t netfn, uint8_t cmd,
static inline int ipmi_demangle_device_id(const unsigned char *data, 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) if (data_len < 7)
return -EINVAL; return -EINVAL;
if (data[0] != IPMI_NETFN_APP_RESPONSE << 2 || if (netfn != IPMI_NETFN_APP_RESPONSE || cmd != IPMI_GET_DEVICE_ID_CMD)
data[1] != IPMI_GET_DEVICE_ID_CMD)
/* Strange, didn't get the response we expected. */ /* Strange, didn't get the response we expected. */
return -EINVAL; return -EINVAL;
if (data[2] != 0) if (data[0] != 0)
/* That's odd, it shouldn't be able to fail. */ /* That's odd, it shouldn't be able to fail. */
return -EINVAL; return -EINVAL;
data += 3; data++;
data_len -= 3; data_len--;
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];
......
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