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: 136698e535 (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>
This commit is contained in:
Alexander Usyskin 2016-12-14 17:56:52 +02:00 коммит произвёл Greg Kroah-Hartman
Родитель 5026c9cb07
Коммит e09ee853c9
1 изменённых файлов: 12 добавлений и 8 удалений

Просмотреть файл

@ -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; rets = first_chunk ? mei_cl_tx_flow_ctrl_creds(cl) : 1;
if (rets < 0) if (rets < 0)
return rets; goto err;
if (rets == 0) { if (rets == 0) {
cl_dbg(dev, cl, "No flow control credentials: not sending.\n"); 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); cb->buf.size, cb->buf_idx);
rets = mei_write_message(dev, &mei_hdr, buf->data + cb->buf_idx); rets = mei_write_message(dev, &mei_hdr, buf->data + cb->buf_idx);
if (rets) { if (rets)
cl->status = rets; goto err;
list_move_tail(&cb->list, &cmpl_list->list);
return rets;
}
cl->status = 0; cl->status = 0;
cl->writing_state = MEI_WRITING; 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; cb->completed = mei_hdr.msg_complete == 1;
if (first_chunk) { if (first_chunk) {
if (mei_cl_tx_flow_ctrl_creds_reduce(cl)) if (mei_cl_tx_flow_ctrl_creds_reduce(cl)) {
return -EIO; rets = -EIO;
goto err;
}
} }
if (mei_hdr.msg_complete) if (mei_hdr.msg_complete)
list_move_tail(&cb->list, &dev->write_waiting_list.list); list_move_tail(&cb->list, &dev->write_waiting_list.list);
return 0; return 0;
err:
cl->status = rets;
list_move_tail(&cb->list, &cmpl_list->list);
return rets;
} }
/** /**