summaryrefslogtreecommitdiffstats
path: root/drivers/misc/mei/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc/mei/main.c')
-rw-r--r--drivers/misc/mei/main.c50
1 files changed, 27 insertions, 23 deletions
diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c
index e1bf54481fd6..bf816449cd40 100644
--- a/drivers/misc/mei/main.c
+++ b/drivers/misc/mei/main.c
@@ -26,7 +26,7 @@
#include <linux/init.h>
#include <linux/ioctl.h>
#include <linux/cdev.h>
-#include <linux/sched.h>
+#include <linux/sched/signal.h>
#include <linux/uuid.h>
#include <linux/compat.h>
#include <linux/jiffies.h>
@@ -182,32 +182,36 @@ static ssize_t mei_read(struct file *file, char __user *ubuf,
goto out;
}
- if (rets == -EBUSY &&
- !mei_cl_enqueue_ctrl_wr_cb(cl, length, MEI_FOP_READ, file)) {
- rets = -ENOMEM;
- goto out;
- }
- do {
- mutex_unlock(&dev->device_lock);
-
- if (wait_event_interruptible(cl->rx_wait,
- (!list_empty(&cl->rd_completed)) ||
- (!mei_cl_is_connected(cl)))) {
+again:
+ mutex_unlock(&dev->device_lock);
+ if (wait_event_interruptible(cl->rx_wait,
+ !list_empty(&cl->rd_completed) ||
+ !mei_cl_is_connected(cl))) {
+ if (signal_pending(current))
+ return -EINTR;
+ return -ERESTARTSYS;
+ }
+ mutex_lock(&dev->device_lock);
- if (signal_pending(current))
- return -EINTR;
- return -ERESTARTSYS;
- }
+ if (!mei_cl_is_connected(cl)) {
+ rets = -ENODEV;
+ goto out;
+ }
- mutex_lock(&dev->device_lock);
- if (!mei_cl_is_connected(cl)) {
- rets = -ENODEV;
- goto out;
- }
+ cb = mei_cl_read_cb(cl, file);
+ if (!cb) {
+ /*
+ * For amthif all the waiters are woken up,
+ * but only fp with matching cb->fp get the cb,
+ * the others have to return to wait on read.
+ */
+ if (cl == &dev->iamthif_cl)
+ goto again;
- cb = mei_cl_read_cb(cl, file);
- } while (!cb);
+ rets = 0;
+ goto out;
+ }
copy_buffer:
/* now copy the data to user space */