Messages in this thread Patch in this message | | | From | Tomas Winkler <> | Subject | [char-misc-next 3/4] mei: pxp: re-enable client on errors | Date | Wed, 11 Oct 2023 14:01:56 +0300 |
| |
From: Alexander Usyskin <alexander.usyskin@intel.com>
Disable and enable mei-pxp client on errors to clean the internal state.
Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com> Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> --- drivers/misc/mei/pxp/mei_pxp.c | 70 +++++++++++++++++++++++----------- 1 file changed, 48 insertions(+), 22 deletions(-)
diff --git a/drivers/misc/mei/pxp/mei_pxp.c b/drivers/misc/mei/pxp/mei_pxp.c index c6cdd6a47308ebcc72f34c38..9875d16445bb03efcfb31cd9 100644 --- a/drivers/misc/mei/pxp/mei_pxp.c +++ b/drivers/misc/mei/pxp/mei_pxp.c @@ -23,6 +23,24 @@ #include "mei_pxp.h" +static inline int mei_pxp_reenable(const struct device *dev, struct mei_cl_device *cldev) +{ + int ret; + + dev_warn(dev, "Trying to reset the channel...\n"); + ret = mei_cldev_disable(cldev); + if (ret < 0) + dev_warn(dev, "mei_cldev_disable failed. %d\n", ret); + /* + * Explicitly ignoring disable failure, + * enable may fix the states and succeed + */ + ret = mei_cldev_enable(cldev); + if (ret < 0) + dev_err(dev, "mei_cldev_enable failed. %d\n", ret); + return ret; +} + /** * mei_pxp_send_message() - Sends a PXP message to ME FW. * @dev: device corresponding to the mei_cl_device @@ -35,6 +53,7 @@ mei_pxp_send_message(struct device *dev, const void *message, size_t size) { struct mei_cl_device *cldev; ssize_t byte; + int ret; if (!dev || !message) return -EINVAL; @@ -44,10 +63,20 @@ mei_pxp_send_message(struct device *dev, const void *message, size_t size) byte = mei_cldev_send(cldev, message, size); if (byte < 0) { dev_dbg(dev, "mei_cldev_send failed. %zd\n", byte); - return byte; + switch (byte) { + case -ENOMEM: + fallthrough; + case -ENODEV: + fallthrough; + case -ETIME: + ret = mei_pxp_reenable(dev, cldev); + if (ret) + byte = ret; + break; + } } - return 0; + return byte; } /** @@ -63,6 +92,7 @@ mei_pxp_receive_message(struct device *dev, void *buffer, size_t size) struct mei_cl_device *cldev; ssize_t byte; bool retry = false; + int ret; if (!dev || !buffer) return -EINVAL; @@ -73,26 +103,22 @@ mei_pxp_receive_message(struct device *dev, void *buffer, size_t size) byte = mei_cldev_recv(cldev, buffer, size); if (byte < 0) { dev_dbg(dev, "mei_cldev_recv failed. %zd\n", byte); - if (byte != -ENOMEM) - return byte; - - /* Retry the read when pages are reclaimed */ - msleep(20); - if (!retry) { - retry = true; - goto retry; - } else { - dev_warn(dev, "No memory on data receive after retry, trying to reset the channel...\n"); - byte = mei_cldev_disable(cldev); - if (byte < 0) - dev_warn(dev, "mei_cldev_disable failed. %zd\n", byte); - /* - * Explicitly ignoring disable failure, - * enable may fix the states and succeed - */ - byte = mei_cldev_enable(cldev); - if (byte < 0) - dev_err(dev, "mei_cldev_enable failed. %zd\n", byte); + switch (byte) { + case -ENOMEM: + /* Retry the read when pages are reclaimed */ + msleep(20); + if (!retry) { + retry = true; + goto retry; + } + fallthrough; + case -ENODEV: + fallthrough; + case -ETIME: + ret = mei_pxp_reenable(dev, cldev); + if (ret) + byte = ret; + break; } } -- 2.41.0
| |