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

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
Loading
Loading
Loading
Loading
+15 −10
Original line number Diff line number Diff line
@@ -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 &&
	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;
}
+1 −1
Original line number Diff line number Diff line
@@ -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);

+11 −13
Original line number Diff line number Diff line
@@ -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);