Skip to content

Commit

Permalink
platform/chrome: cros_ec_proto: Convert EC error codes to Linux error…
Browse files Browse the repository at this point in the history
… codes

The EC reports a variety of error codes. Most of those, with the exception
of EC_RES_INVALID_VERSION, are converted to -EPROTO. As result, the actual
EC error code gets lost. Introduce cros_ec_map_error() to map EC error
codes to Linux error codes, and use it in cros_ec_cmd_xfer_status() to
report more meaningful errors to the caller. With this change, callers of
cros_ec_cmd_xfer_status() can implement a more distinguished action without
having to rely on the EC error code. At the same time, debugging is improved
in situations where the Linux error code is reported to userspace and/or in
the kernel log.

Cc: Gwendal Grignou <gwendal@chromium.org>
Cc: Yu-Hsuan Hsu <yuhsuan@chromium.org>
Cc: Prashant Malani <pmalani@chromium.org>
Cc: Brian Norris <briannorris@chromium.org>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
  • Loading branch information
groeck authored and Enric Balletbo i Serra committed Aug 24, 2020
1 parent b4e452b commit 0d08045
Showing 1 changed file with 46 additions and 11 deletions.
57 changes: 46 additions & 11 deletions drivers/platform/chrome/cros_ec_proto.c
Expand Up @@ -15,6 +15,43 @@

#define EC_COMMAND_RETRIES 50

static const int cros_ec_error_map[] = {
[EC_RES_INVALID_COMMAND] = -EOPNOTSUPP,
[EC_RES_ERROR] = -EIO,
[EC_RES_INVALID_PARAM] = -EINVAL,
[EC_RES_ACCESS_DENIED] = -EACCES,
[EC_RES_INVALID_RESPONSE] = -EPROTO,
[EC_RES_INVALID_VERSION] = -ENOPROTOOPT,
[EC_RES_INVALID_CHECKSUM] = -EBADMSG,
[EC_RES_IN_PROGRESS] = -EINPROGRESS,
[EC_RES_UNAVAILABLE] = -ENODATA,
[EC_RES_TIMEOUT] = -ETIMEDOUT,
[EC_RES_OVERFLOW] = -EOVERFLOW,
[EC_RES_INVALID_HEADER] = -EBADR,
[EC_RES_REQUEST_TRUNCATED] = -EBADR,
[EC_RES_RESPONSE_TOO_BIG] = -EFBIG,
[EC_RES_BUS_ERROR] = -EFAULT,
[EC_RES_BUSY] = -EBUSY,
[EC_RES_INVALID_HEADER_VERSION] = -EBADMSG,
[EC_RES_INVALID_HEADER_CRC] = -EBADMSG,
[EC_RES_INVALID_DATA_CRC] = -EBADMSG,
[EC_RES_DUP_UNAVAILABLE] = -ENODATA,
};

static int cros_ec_map_error(uint32_t result)
{
int ret = 0;

if (result != EC_RES_SUCCESS) {
if (result < ARRAY_SIZE(cros_ec_error_map) && cros_ec_error_map[result])
ret = cros_ec_error_map[result];
else
ret = -EPROTO;
}

return ret;
}

static int prepare_packet(struct cros_ec_device *ec_dev,
struct cros_ec_command *msg)
{
Expand Down Expand Up @@ -579,26 +616,24 @@ static int cros_ec_cmd_xfer(struct cros_ec_device *ec_dev,
*
* Return:
* >=0 - The number of bytes transferred
* -ENOPROTOOPT - Operation not supported
* -EPROTO - Protocol error
* <0 - Linux error code
*/
int cros_ec_cmd_xfer_status(struct cros_ec_device *ec_dev,
struct cros_ec_command *msg)
{
int ret;
int ret, mapped;

ret = cros_ec_cmd_xfer(ec_dev, msg);
if (ret < 0) {
dev_err(ec_dev->dev, "Command xfer error (err:%d)\n", ret);
} else if (msg->result == EC_RES_INVALID_VERSION) {
dev_dbg(ec_dev->dev, "Command invalid version (err:%d)\n",
msg->result);
return -ENOPROTOOPT;
} else if (msg->result != EC_RES_SUCCESS) {
dev_dbg(ec_dev->dev, "Command result (err: %d)\n", msg->result);
return -EPROTO;
return ret;
}
mapped = cros_ec_map_error(msg->result);
if (mapped) {
dev_dbg(ec_dev->dev, "Command result (err: %d [%d])\n",
msg->result, mapped);
ret = mapped;
}

return ret;
}
EXPORT_SYMBOL(cros_ec_cmd_xfer_status);
Expand Down

0 comments on commit 0d08045

Please sign in to comment.