summaryrefslogtreecommitdiffstats
path: root/drivers/misc/mei/main.c
diff options
context:
space:
mode:
authorTomas Winkler2015-02-10 09:39:46 +0100
committerGreg Kroah-Hartman2015-03-02 04:37:00 +0100
commita9bed61053af13c0768f82c9d1c8793515dd067c (patch)
tree3beb3a01fbfc4c8cc1d73c18a220478ad5683cd8 /drivers/misc/mei/main.c
parentmei: simplify io callback disposal (diff)
downloadkernel-qcow2-linux-a9bed61053af13c0768f82c9d1c8793515dd067c.tar.gz
kernel-qcow2-linux-a9bed61053af13c0768f82c9d1c8793515dd067c.tar.xz
kernel-qcow2-linux-a9bed61053af13c0768f82c9d1c8793515dd067c.zip
mei: allow read concurrency
Replace clunky read state machine with read stack implemented as per client read list, this is important mostly for mei drivers with unsolicited reads 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.c42
1 files changed, 8 insertions, 34 deletions
diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c
index c34853be963f..d80867e0d803 100644
--- a/drivers/misc/mei/main.c
+++ b/drivers/misc/mei/main.c
@@ -112,14 +112,11 @@ static int mei_release(struct inode *inode, struct file *file)
cl_dbg(dev, cl, "disconnecting\n");
rets = mei_cl_disconnect(cl);
}
- mei_cl_flush_queues(cl);
+ mei_cl_flush_queues(cl, file);
cl_dbg(dev, cl, "removing\n");
mei_cl_unlink(cl);
- mei_io_cb_free(cl->read_cb);
- cl->read_cb = NULL;
-
file->private_data = NULL;
kfree(cl);
@@ -143,8 +140,8 @@ static ssize_t mei_read(struct file *file, char __user *ubuf,
size_t length, loff_t *offset)
{
struct mei_cl *cl = file->private_data;
- struct mei_cl_cb *cb = NULL;
struct mei_device *dev;
+ struct mei_cl_cb *cb = NULL;
int rets;
int err;
@@ -171,7 +168,7 @@ static ssize_t mei_read(struct file *file, char __user *ubuf,
goto out;
}
- cb = cl->read_cb;
+ cb = mei_cl_read_cb(cl, file);
if (cb) {
/* read what left */
if (cb->buf_idx > *offset)
@@ -196,9 +193,7 @@ static ssize_t mei_read(struct file *file, char __user *ubuf,
goto out;
}
- if (MEI_READ_COMPLETE != cl->reading_state &&
- !waitqueue_active(&cl->rx_wait)) {
-
+ if (list_empty(&cl->rd_completed) && !waitqueue_active(&cl->rx_wait)) {
if (file->f_flags & O_NONBLOCK) {
rets = -EAGAIN;
goto out;
@@ -207,7 +202,7 @@ static ssize_t mei_read(struct file *file, char __user *ubuf,
mutex_unlock(&dev->device_lock);
if (wait_event_interruptible(cl->rx_wait,
- MEI_READ_COMPLETE == cl->reading_state ||
+ (!list_empty(&cl->rd_completed)) ||
mei_cl_is_transitioning(cl))) {
if (signal_pending(current))
@@ -222,14 +217,8 @@ static ssize_t mei_read(struct file *file, char __user *ubuf,
}
}
- cb = cl->read_cb;
-
+ cb = mei_cl_read_cb(cl, file);
if (!cb) {
- rets = -ENODEV;
- goto out;
- }
-
- if (cl->reading_state != MEI_READ_COMPLETE) {
rets = 0;
goto out;
}
@@ -266,9 +255,7 @@ copy_buffer:
free:
mei_io_cb_free(cb);
- cl->read_cb = NULL;
- cl->reading_state = MEI_IDLE;
out:
dev_dbg(dev->dev, "end mei read rets= %d\n", rets);
mutex_unlock(&dev->device_lock);
@@ -335,8 +322,7 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf,
timeout = write_cb->read_time +
mei_secs_to_jiffies(MEI_IAMTHIF_READ_TIMER);
- if (time_after(jiffies, timeout) ||
- cl->reading_state == MEI_READ_COMPLETE) {
+ if (time_after(jiffies, timeout)) {
*offset = 0;
mei_io_cb_free(write_cb);
write_cb = NULL;
@@ -344,19 +330,7 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf,
}
}
- /* free entry used in read */
- if (cl->reading_state == MEI_READ_COMPLETE) {
- *offset = 0;
- write_cb = mei_cl_find_read_cb(cl);
- if (write_cb) {
- mei_io_cb_free(write_cb);
- write_cb = NULL;
- cl->read_cb = NULL;
- cl->reading_state = MEI_IDLE;
- }
- } else if (cl->reading_state == MEI_IDLE)
- *offset = 0;
-
+ *offset = 0;
write_cb = mei_cl_alloc_cb(cl, length, MEI_FOP_WRITE, file);
if (!write_cb) {
rets = -ENOMEM;