summaryrefslogtreecommitdiffstats
path: root/drivers/misc/mei/main.c
diff options
context:
space:
mode:
authorTomas Winkler <tomas.winkler@intel.com>2015-02-10 10:39:36 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-03-01 19:36:59 -0800
commit3d33ff2457355a9dd3c3178b04ab6669882b306c (patch)
tree692168d2c6df72783349246c879995212d3f7dd3 /drivers/misc/mei/main.c
parent3908be6f9aa5517bc717f8ffdaaafd89a1b78471 (diff)
downloadlinux-3d33ff2457355a9dd3c3178b04ab6669882b306c.tar.gz
linux-3d33ff2457355a9dd3c3178b04ab6669882b306c.tar.bz2
linux-3d33ff2457355a9dd3c3178b04ab6669882b306c.zip
mei: fix device reset on mei_cl_irq_read_msg allocation failure
On memory allocation failure mei_cl_irq_read_msg will return with error that will cause device reset. Instead we should propagate error to caller and just clean the read queues. Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/misc/mei/main.c')
-rw-r--r--drivers/misc/mei/main.c17
1 files changed, 13 insertions, 4 deletions
diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c
index 3c019c0e60eb..cbdbf4af2bf7 100644
--- a/drivers/misc/mei/main.c
+++ b/drivers/misc/mei/main.c
@@ -192,8 +192,8 @@ static ssize_t mei_read(struct file *file, char __user *ubuf,
goto out;
}
- if (cl->read_cb) {
- cb = cl->read_cb;
+ cb = cl->read_cb;
+ if (cb) {
/* read what left */
if (cb->buf_idx > *offset)
goto copy_buffer;
@@ -218,7 +218,8 @@ static ssize_t mei_read(struct file *file, char __user *ubuf,
}
if (MEI_READ_COMPLETE != cl->reading_state &&
- !waitqueue_active(&cl->rx_wait)) {
+ !waitqueue_active(&cl->rx_wait)) {
+
if (file->f_flags & O_NONBLOCK) {
rets = -EAGAIN;
goto out;
@@ -248,12 +249,20 @@ static ssize_t mei_read(struct file *file, char __user *ubuf,
rets = -ENODEV;
goto out;
}
+
if (cl->reading_state != MEI_READ_COMPLETE) {
rets = 0;
goto out;
}
- /* now copy the data to user space */
+
copy_buffer:
+ /* now copy the data to user space */
+ if (cb->status) {
+ rets = cb->status;
+ dev_dbg(dev->dev, "read operation failed %d\n", rets);
+ goto free;
+ }
+
dev_dbg(dev->dev, "buf.size = %d buf.idx= %ld\n",
cb->response_buffer.size, cb->buf_idx);
if (length == 0 || ubuf == NULL || *offset > cb->buf_idx) {