Commit 1d9013f0 authored by Tomas Winkler's avatar Tomas Winkler Committed by Greg Kroah-Hartman

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: default avatarTomas Winkler <tomas.winkler@intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent e1c0d82d
...@@ -362,6 +362,18 @@ int mei_amthif_write(struct mei_cl *cl, struct mei_cl_cb *cb) ...@@ -362,6 +362,18 @@ int mei_amthif_write(struct mei_cl *cl, struct mei_cl_cb *cb)
return mei_amthif_run_next_cmd(dev); 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, unsigned int mei_amthif_poll(struct mei_device *dev,
struct file *file, poll_table *wait) struct file *file, poll_table *wait)
{ {
...@@ -369,19 +381,12 @@ unsigned int mei_amthif_poll(struct mei_device *dev, ...@@ -369,19 +381,12 @@ unsigned int mei_amthif_poll(struct mei_device *dev,
poll_wait(file, &dev->iamthif_cl.wait, wait); poll_wait(file, &dev->iamthif_cl.wait, wait);
mutex_lock(&dev->device_lock); if (dev->iamthif_state == MEI_IAMTHIF_READ_COMPLETE &&
if (!mei_cl_is_connected(&dev->iamthif_cl)) {
mask = POLLERR;
} else if (dev->iamthif_state == MEI_IAMTHIF_READ_COMPLETE &&
dev->iamthif_file_object == file) { dev->iamthif_file_object == file) {
mask |= (POLLIN | POLLRDNORM); mask |= POLLIN | POLLRDNORM;
dev_dbg(dev->dev, "run next amthif cb\n");
mei_amthif_run_next_cmd(dev); mei_amthif_run_next_cmd(dev);
} }
mutex_unlock(&dev->device_lock);
return mask; return mask;
} }
......
...@@ -1299,7 +1299,7 @@ void mei_cl_complete(struct mei_cl *cl, struct mei_cl_cb *cb) ...@@ -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) { } else if (cb->fop_type == MEI_FOP_READ) {
list_add_tail(&cb->list, &cl->rd_completed); list_add_tail(&cb->list, &cl->rd_completed);
if (waitqueue_active(&cl->rx_wait)) if (waitqueue_active(&cl->rx_wait))
wake_up_interruptible(&cl->rx_wait); wake_up_interruptible_all(&cl->rx_wait);
else else
mei_cl_bus_rx_event(cl); mei_cl_bus_rx_event(cl);
......
...@@ -542,6 +542,7 @@ static long mei_compat_ioctl(struct file *file, ...@@ -542,6 +542,7 @@ static long mei_compat_ioctl(struct file *file,
*/ */
static unsigned int mei_poll(struct file *file, poll_table *wait) 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_cl *cl = file->private_data;
struct mei_device *dev; struct mei_device *dev;
unsigned int mask = 0; unsigned int mask = 0;
...@@ -558,22 +559,19 @@ static unsigned int mei_poll(struct file *file, poll_table *wait) ...@@ -558,22 +559,19 @@ static unsigned int mei_poll(struct file *file, poll_table *wait)
goto out; goto out;
} }
mutex_unlock(&dev->device_lock); if (cl == &dev->iamthif_cl) {
mask = mei_amthif_poll(dev, file, wait);
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;
goto out; 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: out:
mutex_unlock(&dev->device_lock); mutex_unlock(&dev->device_lock);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment