diff options
author | Tomas Winkler <tomas.winkler@intel.com> | 2015-03-26 18:27:57 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2015-04-03 10:18:56 -0400 |
commit | 1d9013f09203c694e2cba478b05afc6484d55180 (patch) | |
tree | 5121a805e981d630719641d0872c893a6c64feb7 /drivers/misc | |
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>
Diffstat (limited to 'drivers/misc')
-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) | |||
362 | return mei_amthif_run_next_cmd(dev); | 362 | return mei_amthif_run_next_cmd(dev); |
363 | } | 363 | } |
364 | 364 | ||
365 | /** | ||
366 | * mei_amthif_poll - the amthif poll function | ||
367 | * | ||
368 | * @dev: the device structure | ||
369 | * @file: pointer to file structure | ||
370 | * @wait: pointer to poll_table structure | ||
371 | * | ||
372 | * Return: poll mask | ||
373 | * | ||
374 | * Locking: called under "dev->device_lock" lock | ||
375 | */ | ||
376 | |||
365 | unsigned int mei_amthif_poll(struct mei_device *dev, | 377 | unsigned int mei_amthif_poll(struct mei_device *dev, |
366 | struct file *file, poll_table *wait) | 378 | struct file *file, poll_table *wait) |
367 | { | 379 | { |
@@ -369,19 +381,12 @@ unsigned int mei_amthif_poll(struct mei_device *dev, | |||
369 | 381 | ||
370 | poll_wait(file, &dev->iamthif_cl.wait, wait); | 382 | poll_wait(file, &dev->iamthif_cl.wait, wait); |
371 | 383 | ||
372 | mutex_lock(&dev->device_lock); | 384 | if (dev->iamthif_state == MEI_IAMTHIF_READ_COMPLETE && |
373 | if (!mei_cl_is_connected(&dev->iamthif_cl)) { | 385 | dev->iamthif_file_object == file) { |
374 | |||
375 | mask = POLLERR; | ||
376 | |||
377 | } else if (dev->iamthif_state == MEI_IAMTHIF_READ_COMPLETE && | ||
378 | dev->iamthif_file_object == file) { | ||
379 | 386 | ||
380 | mask |= (POLLIN | POLLRDNORM); | 387 | mask |= POLLIN | POLLRDNORM; |
381 | dev_dbg(dev->dev, "run next amthif cb\n"); | ||
382 | mei_amthif_run_next_cmd(dev); | 388 | mei_amthif_run_next_cmd(dev); |
383 | } | 389 | } |
384 | mutex_unlock(&dev->device_lock); | ||
385 | 390 | ||
386 | return mask; | 391 | return mask; |
387 | } | 392 | } |
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) | |||
1299 | } else if (cb->fop_type == MEI_FOP_READ) { | 1299 | } else if (cb->fop_type == MEI_FOP_READ) { |
1300 | list_add_tail(&cb->list, &cl->rd_completed); | 1300 | list_add_tail(&cb->list, &cl->rd_completed); |
1301 | if (waitqueue_active(&cl->rx_wait)) | 1301 | if (waitqueue_active(&cl->rx_wait)) |
1302 | wake_up_interruptible(&cl->rx_wait); | 1302 | wake_up_interruptible_all(&cl->rx_wait); |
1303 | else | 1303 | else |
1304 | mei_cl_bus_rx_event(cl); | 1304 | mei_cl_bus_rx_event(cl); |
1305 | 1305 | ||
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, | |||
542 | */ | 542 | */ |
543 | static unsigned int mei_poll(struct file *file, poll_table *wait) | 543 | static unsigned int mei_poll(struct file *file, poll_table *wait) |
544 | { | 544 | { |
545 | unsigned long req_events = poll_requested_events(wait); | ||
545 | struct mei_cl *cl = file->private_data; | 546 | struct mei_cl *cl = file->private_data; |
546 | struct mei_device *dev; | 547 | struct mei_device *dev; |
547 | unsigned int mask = 0; | 548 | unsigned int mask = 0; |
@@ -558,22 +559,19 @@ static unsigned int mei_poll(struct file *file, poll_table *wait) | |||
558 | goto out; | 559 | goto out; |
559 | } | 560 | } |
560 | 561 | ||
561 | mutex_unlock(&dev->device_lock); | 562 | if (cl == &dev->iamthif_cl) { |
562 | 563 | mask = mei_amthif_poll(dev, file, wait); | |
563 | |||
564 | if (cl == &dev->iamthif_cl) | ||
565 | return mei_amthif_poll(dev, file, wait); | ||
566 | |||
567 | poll_wait(file, &cl->tx_wait, wait); | ||
568 | |||
569 | mutex_lock(&dev->device_lock); | ||
570 | |||
571 | if (!mei_cl_is_connected(cl)) { | ||
572 | mask = POLLERR; | ||
573 | goto out; | 564 | goto out; |
574 | } | 565 | } |
575 | 566 | ||
576 | mask |= (POLLIN | POLLRDNORM); | 567 | if (req_events & (POLLIN | POLLRDNORM)) { |
568 | poll_wait(file, &cl->rx_wait, wait); | ||
569 | |||
570 | if (!list_empty(&cl->rd_completed)) | ||
571 | mask |= POLLIN | POLLRDNORM; | ||
572 | else | ||
573 | mei_cl_read_start(cl, 0, file); | ||
574 | } | ||
577 | 575 | ||
578 | out: | 576 | out: |
579 | mutex_unlock(&dev->device_lock); | 577 | mutex_unlock(&dev->device_lock); |