Hi Prashant and Guenter, Thank you to spend your time on look at this.
On 4/7/20 16:26, Guenter Roeck wrote: > 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 > error code gets lost. Convert all EC errors to Linux error codes to report > a more meaningful error to the caller to aid debugging. > > Cc: Yu-Hsuan Hsu <yuhs...@chromium.org> > Cc: Prashant Malani <pmal...@chromium.org> > Signed-off-by: Guenter Roeck <li...@roeck-us.net> > --- For me the patch looks good as is. Said that, I'd like to discuss a bit more (but not too much) about it :-). My "concerns" are: - It is not clear to me if some EC errors match directly to a linux kernel error codes, the importance of them, and which action should be taken in that case or if just reporting is enough. - The EC result can be obtained, either, enabling more debug traces or using the linux kernel tracing tools. So, IMO mapping _all_ the errors has very little value. Right now, the policy I followed is return -EPROTO for all EC errors and introduce/match a new error when someone (another kernel driver or userspace needs to know about it, i.e [1], where some EC drivers do different actions if -ENOTSUPP is returned). We introduced that error because we had a use case for it. The future, I'd like to maintain this policy if it makes sense to you. And introduce a new error when we have a use case for it. I.e if at some point a kernel driver needs to know when the EC is busy (-EBUSY) because the driver waits and retries again, I'll be fine to introduce this new error/match code. Otherwise, I feel that has no really value. Said that, if you still feel, that this will help you for debugging purposes, I am completely fine to pick the patch. Thoughts? Thanks, Enric [1] commit c5cd2b47b203f63682778c2a1783198e6b644294 Author: Enric Balletbo i Serra <enric.balle...@collabora.com> Date: Thu Feb 20 16:58:52 2020 +0100 platform/chrome: cros_ec_proto: Report command not supported In practice most drivers that use the EC protocol what really care is if the result was successful or not, hence, we introduced a cros_ec_cmd_xfer_status() function that converts EC errors to standard Linux error codes. On some few cases, though, we are interested on know if the command is supported or not, and in such cases, just ignore the error. To achieve this, return a -ENOTSUPP error when the command is not supported. > drivers/platform/chrome/cros_ec_proto.c | 37 +++++++++++++++++++------ > 1 file changed, 29 insertions(+), 8 deletions(-) > > diff --git a/drivers/platform/chrome/cros_ec_proto.c > b/drivers/platform/chrome/cros_ec_proto.c > index 3e745e0fe092..10aa9e483d35 100644 > --- a/drivers/platform/chrome/cros_ec_proto.c > +++ b/drivers/platform/chrome/cros_ec_proto.c > @@ -543,6 +543,29 @@ int cros_ec_cmd_xfer(struct cros_ec_device *ec_dev, > } > EXPORT_SYMBOL(cros_ec_cmd_xfer); > > +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] = -ENOTSUPP, > + [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, > +}; > + > /** > * cros_ec_cmd_xfer_status() - Send a command to the ChromeOS EC. > * @ec_dev: EC device. > @@ -555,8 +578,7 @@ EXPORT_SYMBOL(cros_ec_cmd_xfer); > * > * Return: > * >=0 - The number of bytes transferred > - * -ENOTSUPP - 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) > @@ -566,13 +588,12 @@ int cros_ec_cmd_xfer_status(struct cros_ec_device > *ec_dev, > 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 -ENOTSUPP; > } else if (msg->result != EC_RES_SUCCESS) { > - dev_dbg(ec_dev->dev, "Command result (err: %d)\n", msg->result); > - return -EPROTO; > + if (msg->result < ARRAY_SIZE(cros_ec_error_map) && > cros_ec_error_map[msg->result]) > + ret = cros_ec_error_map[msg->result]; > + else > + ret = -EPROTO; > + dev_dbg(ec_dev->dev, "Command result (err: %d [%d])\n", > msg->result, ret); > } > > return ret; >