aboutsummaryrefslogtreecommitdiff
path: root/drivers/platform
diff options
context:
space:
mode:
authorGuenter Roeck2020-08-22 08:08:56 -0700
committerEnric Balletbo i Serra2020-08-24 11:37:34 +0200
commit0d080459e813ce8076f183cc73a4c9b64a39a4d8 (patch)
tree628f6a316b6ee66e5ac0b0bc486b060669d52d0f /drivers/platform
parentb4e452b5e97dc70d529475168a37ad7394994b8b (diff)
platform/chrome: cros_ec_proto: Convert EC error codes to Linux error 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>
Diffstat (limited to 'drivers/platform')
-rw-r--r--drivers/platform/chrome/cros_ec_proto.c57
1 files changed, 46 insertions, 11 deletions
diff --git a/drivers/platform/chrome/cros_ec_proto.c b/drivers/platform/chrome/cros_ec_proto.c
index f4727511fb41..dda182132a6a 100644
--- a/drivers/platform/chrome/cros_ec_proto.c
+++ b/drivers/platform/chrome/cros_ec_proto.c
@@ -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)
{
@@ -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);