aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/mei/amthif.c
diff options
context:
space:
mode:
authorTomas Winkler <tomas.winkler@intel.com>2012-11-11 10:38:01 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-11-15 18:34:18 -0500
commita562d5c25aa48c23774ab8d60bfd3bbcbca4bf1d (patch)
treea9a990d28b42502b2a6fe7e5ab56128707b42f86 /drivers/misc/mei/amthif.c
parent4b8960b492360c115f8214ec116f469338ac2734 (diff)
mei: move amthif specific release code to amithif
Move amthif code part into separate function mei_amthif_release. Also helper functions mei_clear_list and mei_clear_lists are moved along Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/misc/mei/amthif.c')
-rw-r--r--drivers/misc/mei/amthif.c114
1 files changed, 114 insertions, 0 deletions
diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c
index 34d37a9c31a1..8f4373aa9e24 100644
--- a/drivers/misc/mei/amthif.c
+++ b/drivers/misc/mei/amthif.c
@@ -596,4 +596,118 @@ void mei_amthif_complete(struct mei_device *dev, struct mei_cl_cb *cb)
596 wake_up_interruptible(&dev->iamthif_cl.wait); 596 wake_up_interruptible(&dev->iamthif_cl.wait);
597} 597}
598 598
599/**
600 * mei_clear_list - removes all callbacks associated with file
601 * from mei_cb_list
602 *
603 * @dev: device structure.
604 * @file: file structure
605 * @mei_cb_list: callbacks list
606 *
607 * mei_clear_list is called to clear resources associated with file
608 * when application calls close function or Ctrl-C was pressed
609 *
610 * returns true if callback removed from the list, false otherwise
611 */
612static bool mei_clear_list(struct mei_device *dev,
613 const struct file *file, struct list_head *mei_cb_list)
614{
615 struct mei_cl_cb *cb_pos = NULL;
616 struct mei_cl_cb *cb_next = NULL;
617 bool removed = false;
618
619 /* list all list member */
620 list_for_each_entry_safe(cb_pos, cb_next, mei_cb_list, list) {
621 /* check if list member associated with a file */
622 if (file == cb_pos->file_object) {
623 /* remove member from the list */
624 list_del(&cb_pos->list);
625 /* check if cb equal to current iamthif cb */
626 if (dev->iamthif_current_cb == cb_pos) {
627 dev->iamthif_current_cb = NULL;
628 /* send flow control to iamthif client */
629 mei_send_flow_control(dev, &dev->iamthif_cl);
630 }
631 /* free all allocated buffers */
632 mei_io_cb_free(cb_pos);
633 cb_pos = NULL;
634 removed = true;
635 }
636 }
637 return removed;
638}
639
640/**
641 * mei_clear_lists - removes all callbacks associated with file
642 *
643 * @dev: device structure
644 * @file: file structure
645 *
646 * mei_clear_lists is called to clear resources associated with file
647 * when application calls close function or Ctrl-C was pressed
648 *
649 * returns true if callback removed from the list, false otherwise
650 */
651static bool mei_clear_lists(struct mei_device *dev, struct file *file)
652{
653 bool removed = false;
654
655 /* remove callbacks associated with a file */
656 mei_clear_list(dev, file, &dev->amthif_cmd_list.list);
657 if (mei_clear_list(dev, file, &dev->amthif_rd_complete_list.list))
658 removed = true;
599 659
660 mei_clear_list(dev, file, &dev->ctrl_rd_list.list);
661
662 if (mei_clear_list(dev, file, &dev->ctrl_wr_list.list))
663 removed = true;
664
665 if (mei_clear_list(dev, file, &dev->write_waiting_list.list))
666 removed = true;
667
668 if (mei_clear_list(dev, file, &dev->write_list.list))
669 removed = true;
670
671 /* check if iamthif_current_cb not NULL */
672 if (dev->iamthif_current_cb && !removed) {
673 /* check file and iamthif current cb association */
674 if (dev->iamthif_current_cb->file_object == file) {
675 /* remove cb */
676 mei_io_cb_free(dev->iamthif_current_cb);
677 dev->iamthif_current_cb = NULL;
678 removed = true;
679 }
680 }
681 return removed;
682}
683
684/**
685* mei_amthif_release - the release function
686*
687* @inode: pointer to inode structure
688* @file: pointer to file structure
689*
690* returns 0 on success, <0 on error
691*/
692int mei_amthif_release(struct mei_device *dev, struct file *file)
693{
694 if (dev->open_handle_count > 0)
695 dev->open_handle_count--;
696
697 if (dev->iamthif_file_object == file &&
698 dev->iamthif_state != MEI_IAMTHIF_IDLE) {
699
700 dev_dbg(&dev->pdev->dev, "amthi canceled iamthif state %d\n",
701 dev->iamthif_state);
702 dev->iamthif_canceled = true;
703 if (dev->iamthif_state == MEI_IAMTHIF_READ_COMPLETE) {
704 dev_dbg(&dev->pdev->dev, "run next amthi iamthif cb\n");
705 mei_amthif_run_next_cmd(dev);
706 }
707 }
708
709 if (mei_clear_lists(dev, file))
710 dev->iamthif_state = MEI_IAMTHIF_IDLE;
711
712 return 0;
713}