diff options
author | Tomas Winkler <tomas.winkler@intel.com> | 2015-03-27 00:27:57 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2015-04-03 16:18:56 +0200 |
commit | 1d9013f09203c694e2cba478b05afc6484d55180 (patch) | |
tree | 5121a805e981d630719641d0872c893a6c64feb7 | |
parent | e1c0d82dab4a4605d3bd1968436f030dfed4a829 (diff) |
mei: fix mei_poll operation
mei_poll returned with POLLIN w/o checking whether the operation
has really completed.
remove redundant check and locking in amthif specific handler
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/misc/mei/amthif.c | 25 | ||||
-rw-r--r-- | drivers/misc/mei/client.c | 2 | ||||
-rw-r--r-- | drivers/misc/mei/main.c | 24 |
3 files changed, 27 insertions, 24 deletions
diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c index 7b6ed0bbfc9c..3c1fd87ee10b 100644 --- a/drivers/misc/mei/amthif.c +++ b/drivers/misc/mei/amthif.c @@ -362,6 +362,18 @@ int mei_amthif_write(struct mei_cl *cl, struct mei_cl_cb *cb) return mei_amthif_run_next_cmd(dev); } +/** + * mei_amthif_poll - the amthif poll function + * + * @dev: the device structure + * @file: pointer to file structure + * @wait: pointer to poll_table structure + * + * Return: poll mask + * + * Locking: called under "dev->device_lock" lock + */ + unsigned int mei_amthif_poll(struct mei_device *dev, struct file *file, poll_table *wait) { @@ -369,19 +381,12 @@ unsigned int mei_amthif_poll(struct mei_device *dev, poll_wait(file, &dev->iamthif_cl.wait, wait); - mutex_lock(&dev->device_lock); - if (!mei_cl_is_connected(&dev->iamthif_cl)) { - - mask = POLLERR; - - } else if (dev->iamthif_state == MEI_IAMTHIF_READ_COMPLETE && - dev->iamthif_file_object == file) { + if (dev->iamthif_state == MEI_IAMTHIF_READ_COMPLETE && + dev->iamthif_file_object == file) { - mask |= (POLLIN | POLLRDNORM); - dev_dbg(dev->dev, "run next amthif cb\n"); + mask |= POLLIN | POLLRDNORM; mei_amthif_run_next_cmd(dev); } - mutex_unlock(&dev->device_lock); return mask; } diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index b6fec4d15307..e5aeb6fd1ba4 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c @@ -1299,7 +1299,7 @@ void mei_cl_complete(struct mei_cl *cl, struct mei_cl_cb *cb) } else if (cb->fop_type == MEI_FOP_READ) { list_add_tail(&cb->list, &cl->rd_completed); if (waitqueue_active(&cl->rx_wait)) - wake_up_interruptible(&cl->rx_wait); + wake_up_interruptible_all(&cl->rx_wait); else mei_cl_bus_rx_event(cl); diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index d80867e0d803..a1ec45054988 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -542,6 +542,7 @@ static long mei_compat_ioctl(struct file *file, */ static unsigned int mei_poll(struct file *file, poll_table *wait) { + unsigned long req_events = poll_requested_events(wait); struct mei_cl *cl = file->private_data; struct mei_device *dev; unsigned int mask = 0; @@ -558,22 +559,19 @@ static unsigned int mei_poll(struct file *file, poll_table *wait) goto out; } - mutex_unlock(&dev->device_lock); - - - if (cl == &dev->iamthif_cl) - return mei_amthif_poll(dev, file, wait); - - poll_wait(file, &cl->tx_wait, wait); - - mutex_lock(&dev->device_lock); - - if (!mei_cl_is_connected(cl)) { - mask = POLLERR; + if (cl == &dev->iamthif_cl) { + mask = mei_amthif_poll(dev, file, wait); goto out; } - mask |= (POLLIN | POLLRDNORM); + if (req_events & (POLLIN | POLLRDNORM)) { + poll_wait(file, &cl->rx_wait, wait); + + if (!list_empty(&cl->rd_completed)) + mask |= POLLIN | POLLRDNORM; + else + mei_cl_read_start(cl, 0, file); + } out: mutex_unlock(&dev->device_lock); |