mei: iamthif: fix device reset on mei_amthif_irq_read_msg
On failure mei_amthif_irq_read_msg returns an error that will cause device reset but the issue is software one so instead we should propagate error to caller and just clean the read queues. As a side effect also removes useless BUG_ONs Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
3d33ff2457
commit
db4756fd2f
@ -195,23 +195,26 @@ int mei_amthif_read(struct mei_device *dev, struct file *file,
|
||||
dev_dbg(dev->dev, "woke up from sleep\n");
|
||||
}
|
||||
|
||||
if (cb->status) {
|
||||
rets = cb->status;
|
||||
dev_dbg(dev->dev, "read operation failed %d\n", rets);
|
||||
goto free;
|
||||
}
|
||||
|
||||
dev_dbg(dev->dev, "Got amthif data\n");
|
||||
dev->iamthif_timer = 0;
|
||||
|
||||
if (cb) {
|
||||
timeout = cb->read_time +
|
||||
mei_secs_to_jiffies(MEI_IAMTHIF_READ_TIMER);
|
||||
dev_dbg(dev->dev, "amthif timeout = %lud\n",
|
||||
timeout);
|
||||
timeout = cb->read_time +
|
||||
mei_secs_to_jiffies(MEI_IAMTHIF_READ_TIMER);
|
||||
dev_dbg(dev->dev, "amthif timeout = %lud\n",
|
||||
timeout);
|
||||
|
||||
if (time_after(jiffies, timeout)) {
|
||||
dev_dbg(dev->dev, "amthif Time out\n");
|
||||
/* 15 sec for the message has expired */
|
||||
list_del(&cb->list);
|
||||
rets = -ETIME;
|
||||
goto free;
|
||||
}
|
||||
if (time_after(jiffies, timeout)) {
|
||||
dev_dbg(dev->dev, "amthif Time out\n");
|
||||
/* 15 sec for the message has expired */
|
||||
list_del(&cb->list);
|
||||
rets = -ETIME;
|
||||
goto free;
|
||||
}
|
||||
/* if the whole message will fit remove it from the list */
|
||||
if (cb->buf_idx >= *offset && length >= (cb->buf_idx - *offset))
|
||||
@ -501,25 +504,42 @@ int mei_amthif_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb,
|
||||
* mei_amthif_irq_read_msg - read routine after ISR to
|
||||
* handle the read amthif message
|
||||
*
|
||||
* @dev: the device structure
|
||||
* @cl: mei client
|
||||
* @mei_hdr: header of amthif message
|
||||
* @complete_list: An instance of our list structure
|
||||
* @complete_list: completed callbacks list
|
||||
*
|
||||
* Return: 0 on success, <0 on failure.
|
||||
* Return: -ENODEV if cb is NULL 0 otherwise; error message is in cb->status
|
||||
*/
|
||||
int mei_amthif_irq_read_msg(struct mei_device *dev,
|
||||
int mei_amthif_irq_read_msg(struct mei_cl *cl,
|
||||
struct mei_msg_hdr *mei_hdr,
|
||||
struct mei_cl_cb *complete_list)
|
||||
{
|
||||
struct mei_device *dev;
|
||||
struct mei_cl_cb *cb;
|
||||
unsigned char *buffer;
|
||||
int ret = 0;
|
||||
|
||||
BUG_ON(mei_hdr->me_addr != dev->iamthif_cl.me_client_id);
|
||||
BUG_ON(dev->iamthif_state != MEI_IAMTHIF_READING);
|
||||
dev = cl->dev;
|
||||
|
||||
if (cl->state != MEI_FILE_CONNECTED)
|
||||
goto err;
|
||||
|
||||
if (dev->iamthif_state != MEI_IAMTHIF_READING)
|
||||
goto err;
|
||||
|
||||
cb = dev->iamthif_current_cb;
|
||||
|
||||
if (!cb) {
|
||||
ret = -ENODEV;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (dev->iamthif_mtu < dev->iamthif_msg_buf_index + mei_hdr->length) {
|
||||
cb->status = -ERANGE;
|
||||
goto err;
|
||||
}
|
||||
|
||||
buffer = dev->iamthif_msg_buf + dev->iamthif_msg_buf_index;
|
||||
BUG_ON(dev->iamthif_mtu < dev->iamthif_msg_buf_index + mei_hdr->length);
|
||||
|
||||
mei_read_slots(dev, buffer, mei_hdr->length);
|
||||
|
||||
dev->iamthif_msg_buf_index += mei_hdr->length;
|
||||
@ -527,14 +547,8 @@ int mei_amthif_irq_read_msg(struct mei_device *dev,
|
||||
if (!mei_hdr->msg_complete)
|
||||
return 0;
|
||||
|
||||
dev_dbg(dev->dev, "amthif_message_buffer_index =%d\n",
|
||||
mei_hdr->length);
|
||||
|
||||
dev_dbg(dev->dev, "completed amthif read.\n ");
|
||||
if (!dev->iamthif_current_cb)
|
||||
return -ENODEV;
|
||||
|
||||
cb = dev->iamthif_current_cb;
|
||||
dev->iamthif_current_cb = NULL;
|
||||
|
||||
dev->iamthif_stall_timer = 0;
|
||||
@ -543,10 +557,16 @@ int mei_amthif_irq_read_msg(struct mei_device *dev,
|
||||
if (dev->iamthif_ioctl) {
|
||||
/* found the iamthif cb */
|
||||
dev_dbg(dev->dev, "complete the amthif read cb.\n ");
|
||||
dev_dbg(dev->dev, "add the amthif read cb to complete.\n ");
|
||||
list_add_tail(&cb->list, &complete_list->list);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
mei_read_slots(dev, dev->rd_msg_buf, mei_hdr->length);
|
||||
dev_dbg(dev->dev, "discarding message " MEI_HDR_FMT "\n",
|
||||
MEI_HDR_PRM(mei_hdr));
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -384,11 +384,8 @@ int mei_irq_read_handler(struct mei_device *dev,
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (mei_hdr->host_addr == dev->iamthif_cl.host_client_id &&
|
||||
MEI_FILE_CONNECTED == dev->iamthif_cl.state &&
|
||||
dev->iamthif_state == MEI_IAMTHIF_READING) {
|
||||
|
||||
ret = mei_amthif_irq_read_msg(dev, mei_hdr, cmpl_list);
|
||||
if (cl == &dev->iamthif_cl) {
|
||||
ret = mei_amthif_irq_read_msg(cl, mei_hdr, cmpl_list);
|
||||
if (ret) {
|
||||
dev_err(dev->dev, "mei_amthif_irq_read_msg failed = %d\n",
|
||||
ret);
|
||||
|
@ -685,7 +685,7 @@ int mei_amthif_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb,
|
||||
struct mei_cl_cb *cmpl_list);
|
||||
|
||||
void mei_amthif_complete(struct mei_device *dev, struct mei_cl_cb *cb);
|
||||
int mei_amthif_irq_read_msg(struct mei_device *dev,
|
||||
int mei_amthif_irq_read_msg(struct mei_cl *cl,
|
||||
struct mei_msg_hdr *mei_hdr,
|
||||
struct mei_cl_cb *complete_list);
|
||||
int mei_amthif_irq_read(struct mei_device *dev, s32 *slots);
|
||||
|
Loading…
Reference in New Issue
Block a user