diff options
author | Alexander Usyskin <alexander.usyskin@intel.com> | 2016-12-14 17:56:52 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-01-04 18:22:44 +0100 |
commit | e09ee853c92011860a4bd2fbdf6126f60fc16bd3 (patch) | |
tree | 580aa5b27803e95e08bdf7acebe4fedbd0f5b623 /drivers/misc/mei | |
parent | 5026c9cb0744a9cd40242743ca91a5d712f468c6 (diff) | |
download | linux-stable-e09ee853c92011860a4bd2fbdf6126f60fc16bd3.tar.gz linux-stable-e09ee853c92011860a4bd2fbdf6126f60fc16bd3.tar.bz2 linux-stable-e09ee853c92011860a4bd2fbdf6126f60fc16bd3.zip |
mei: move write cb to completion on credentials failures
The credentials handling was pushed to the write handlers
but error handling wasn't done properly.
Move write callbacks to completion queue to destroy them
and to notify a blocked writer about the failure
Fixes: 136698e535cd1 (mei: push credentials inside the irq write handler)
Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/misc/mei')
-rw-r--r-- | drivers/misc/mei/client.c | 20 |
1 files changed, 12 insertions, 8 deletions
diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index 391936c1aa04..b0395601c6ae 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c @@ -1541,7 +1541,7 @@ int mei_cl_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb, rets = first_chunk ? mei_cl_tx_flow_ctrl_creds(cl) : 1; if (rets < 0) - return rets; + goto err; if (rets == 0) { cl_dbg(dev, cl, "No flow control credentials: not sending.\n"); @@ -1575,11 +1575,8 @@ int mei_cl_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb, cb->buf.size, cb->buf_idx); rets = mei_write_message(dev, &mei_hdr, buf->data + cb->buf_idx); - if (rets) { - cl->status = rets; - list_move_tail(&cb->list, &cmpl_list->list); - return rets; - } + if (rets) + goto err; cl->status = 0; cl->writing_state = MEI_WRITING; @@ -1587,14 +1584,21 @@ int mei_cl_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb, cb->completed = mei_hdr.msg_complete == 1; if (first_chunk) { - if (mei_cl_tx_flow_ctrl_creds_reduce(cl)) - return -EIO; + if (mei_cl_tx_flow_ctrl_creds_reduce(cl)) { + rets = -EIO; + goto err; + } } if (mei_hdr.msg_complete) list_move_tail(&cb->list, &dev->write_waiting_list.list); return 0; + +err: + cl->status = rets; + list_move_tail(&cb->list, &cmpl_list->list); + return rets; } /** |