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>
This commit is contained in:
parent
4b8960b492
commit
a562d5c25a
@ -596,4 +596,118 @@ void mei_amthif_complete(struct mei_device *dev, struct mei_cl_cb *cb)
|
||||
wake_up_interruptible(&dev->iamthif_cl.wait);
|
||||
}
|
||||
|
||||
/**
|
||||
* mei_clear_list - removes all callbacks associated with file
|
||||
* from mei_cb_list
|
||||
*
|
||||
* @dev: device structure.
|
||||
* @file: file structure
|
||||
* @mei_cb_list: callbacks list
|
||||
*
|
||||
* mei_clear_list is called to clear resources associated with file
|
||||
* when application calls close function or Ctrl-C was pressed
|
||||
*
|
||||
* returns true if callback removed from the list, false otherwise
|
||||
*/
|
||||
static bool mei_clear_list(struct mei_device *dev,
|
||||
const struct file *file, struct list_head *mei_cb_list)
|
||||
{
|
||||
struct mei_cl_cb *cb_pos = NULL;
|
||||
struct mei_cl_cb *cb_next = NULL;
|
||||
bool removed = false;
|
||||
|
||||
/* list all list member */
|
||||
list_for_each_entry_safe(cb_pos, cb_next, mei_cb_list, list) {
|
||||
/* check if list member associated with a file */
|
||||
if (file == cb_pos->file_object) {
|
||||
/* remove member from the list */
|
||||
list_del(&cb_pos->list);
|
||||
/* check if cb equal to current iamthif cb */
|
||||
if (dev->iamthif_current_cb == cb_pos) {
|
||||
dev->iamthif_current_cb = NULL;
|
||||
/* send flow control to iamthif client */
|
||||
mei_send_flow_control(dev, &dev->iamthif_cl);
|
||||
}
|
||||
/* free all allocated buffers */
|
||||
mei_io_cb_free(cb_pos);
|
||||
cb_pos = NULL;
|
||||
removed = true;
|
||||
}
|
||||
}
|
||||
return removed;
|
||||
}
|
||||
|
||||
/**
|
||||
* mei_clear_lists - removes all callbacks associated with file
|
||||
*
|
||||
* @dev: device structure
|
||||
* @file: file structure
|
||||
*
|
||||
* mei_clear_lists is called to clear resources associated with file
|
||||
* when application calls close function or Ctrl-C was pressed
|
||||
*
|
||||
* returns true if callback removed from the list, false otherwise
|
||||
*/
|
||||
static bool mei_clear_lists(struct mei_device *dev, struct file *file)
|
||||
{
|
||||
bool removed = false;
|
||||
|
||||
/* remove callbacks associated with a file */
|
||||
mei_clear_list(dev, file, &dev->amthif_cmd_list.list);
|
||||
if (mei_clear_list(dev, file, &dev->amthif_rd_complete_list.list))
|
||||
removed = true;
|
||||
|
||||
mei_clear_list(dev, file, &dev->ctrl_rd_list.list);
|
||||
|
||||
if (mei_clear_list(dev, file, &dev->ctrl_wr_list.list))
|
||||
removed = true;
|
||||
|
||||
if (mei_clear_list(dev, file, &dev->write_waiting_list.list))
|
||||
removed = true;
|
||||
|
||||
if (mei_clear_list(dev, file, &dev->write_list.list))
|
||||
removed = true;
|
||||
|
||||
/* check if iamthif_current_cb not NULL */
|
||||
if (dev->iamthif_current_cb && !removed) {
|
||||
/* check file and iamthif current cb association */
|
||||
if (dev->iamthif_current_cb->file_object == file) {
|
||||
/* remove cb */
|
||||
mei_io_cb_free(dev->iamthif_current_cb);
|
||||
dev->iamthif_current_cb = NULL;
|
||||
removed = true;
|
||||
}
|
||||
}
|
||||
return removed;
|
||||
}
|
||||
|
||||
/**
|
||||
* mei_amthif_release - the release function
|
||||
*
|
||||
* @inode: pointer to inode structure
|
||||
* @file: pointer to file structure
|
||||
*
|
||||
* returns 0 on success, <0 on error
|
||||
*/
|
||||
int mei_amthif_release(struct mei_device *dev, struct file *file)
|
||||
{
|
||||
if (dev->open_handle_count > 0)
|
||||
dev->open_handle_count--;
|
||||
|
||||
if (dev->iamthif_file_object == file &&
|
||||
dev->iamthif_state != MEI_IAMTHIF_IDLE) {
|
||||
|
||||
dev_dbg(&dev->pdev->dev, "amthi canceled iamthif state %d\n",
|
||||
dev->iamthif_state);
|
||||
dev->iamthif_canceled = true;
|
||||
if (dev->iamthif_state == MEI_IAMTHIF_READ_COMPLETE) {
|
||||
dev_dbg(&dev->pdev->dev, "run next amthi iamthif cb\n");
|
||||
mei_amthif_run_next_cmd(dev);
|
||||
}
|
||||
}
|
||||
|
||||
if (mei_clear_lists(dev, file))
|
||||
dev->iamthif_state = MEI_IAMTHIF_IDLE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -89,90 +89,6 @@ MODULE_DEVICE_TABLE(pci, mei_pci_tbl);
|
||||
static DEFINE_MUTEX(mei_mutex);
|
||||
|
||||
|
||||
/**
|
||||
* mei_clear_list - removes all callbacks associated with file
|
||||
* from mei_cb_list
|
||||
*
|
||||
* @dev: device structure.
|
||||
* @file: file structure
|
||||
* @mei_cb_list: callbacks list
|
||||
*
|
||||
* mei_clear_list is called to clear resources associated with file
|
||||
* when application calls close function or Ctrl-C was pressed
|
||||
*
|
||||
* returns true if callback removed from the list, false otherwise
|
||||
*/
|
||||
static bool mei_clear_list(struct mei_device *dev,
|
||||
const struct file *file, struct list_head *mei_cb_list)
|
||||
{
|
||||
struct mei_cl_cb *cb_pos = NULL;
|
||||
struct mei_cl_cb *cb_next = NULL;
|
||||
bool removed = false;
|
||||
|
||||
/* list all list member */
|
||||
list_for_each_entry_safe(cb_pos, cb_next, mei_cb_list, list) {
|
||||
/* check if list member associated with a file */
|
||||
if (file == cb_pos->file_object) {
|
||||
/* remove member from the list */
|
||||
list_del(&cb_pos->list);
|
||||
/* check if cb equal to current iamthif cb */
|
||||
if (dev->iamthif_current_cb == cb_pos) {
|
||||
dev->iamthif_current_cb = NULL;
|
||||
/* send flow control to iamthif client */
|
||||
mei_send_flow_control(dev, &dev->iamthif_cl);
|
||||
}
|
||||
/* free all allocated buffers */
|
||||
mei_io_cb_free(cb_pos);
|
||||
cb_pos = NULL;
|
||||
removed = true;
|
||||
}
|
||||
}
|
||||
return removed;
|
||||
}
|
||||
|
||||
/**
|
||||
* mei_clear_lists - removes all callbacks associated with file
|
||||
*
|
||||
* @dev: device structure
|
||||
* @file: file structure
|
||||
*
|
||||
* mei_clear_lists is called to clear resources associated with file
|
||||
* when application calls close function or Ctrl-C was pressed
|
||||
*
|
||||
* returns true if callback removed from the list, false otherwise
|
||||
*/
|
||||
static bool mei_clear_lists(struct mei_device *dev, struct file *file)
|
||||
{
|
||||
bool removed = false;
|
||||
|
||||
/* remove callbacks associated with a file */
|
||||
mei_clear_list(dev, file, &dev->amthif_cmd_list.list);
|
||||
if (mei_clear_list(dev, file, &dev->amthif_rd_complete_list.list))
|
||||
removed = true;
|
||||
|
||||
mei_clear_list(dev, file, &dev->ctrl_rd_list.list);
|
||||
|
||||
if (mei_clear_list(dev, file, &dev->ctrl_wr_list.list))
|
||||
removed = true;
|
||||
|
||||
if (mei_clear_list(dev, file, &dev->write_waiting_list.list))
|
||||
removed = true;
|
||||
|
||||
if (mei_clear_list(dev, file, &dev->write_list.list))
|
||||
removed = true;
|
||||
|
||||
/* check if iamthif_current_cb not NULL */
|
||||
if (dev->iamthif_current_cb && !removed) {
|
||||
/* check file and iamthif current cb association */
|
||||
if (dev->iamthif_current_cb->file_object == file) {
|
||||
/* remove cb */
|
||||
mei_io_cb_free(dev->iamthif_current_cb);
|
||||
dev->iamthif_current_cb = NULL;
|
||||
removed = true;
|
||||
}
|
||||
}
|
||||
return removed;
|
||||
}
|
||||
/**
|
||||
* find_read_list_entry - find read list entry
|
||||
*
|
||||
@ -289,67 +205,51 @@ static int mei_release(struct inode *inode, struct file *file)
|
||||
dev = cl->dev;
|
||||
|
||||
mutex_lock(&dev->device_lock);
|
||||
if (cl != &dev->iamthif_cl) {
|
||||
if (cl->state == MEI_FILE_CONNECTED) {
|
||||
cl->state = MEI_FILE_DISCONNECTING;
|
||||
dev_dbg(&dev->pdev->dev,
|
||||
"disconnecting client host client = %d, "
|
||||
"ME client = %d\n",
|
||||
cl->host_client_id,
|
||||
cl->me_client_id);
|
||||
rets = mei_disconnect_host_client(dev, cl);
|
||||
}
|
||||
mei_cl_flush_queues(cl);
|
||||
dev_dbg(&dev->pdev->dev, "remove client host client = %d, ME client = %d\n",
|
||||
if (cl == &dev->iamthif_cl) {
|
||||
rets = mei_amthif_release(dev, file);
|
||||
goto out;
|
||||
}
|
||||
if (cl->state == MEI_FILE_CONNECTED) {
|
||||
cl->state = MEI_FILE_DISCONNECTING;
|
||||
dev_dbg(&dev->pdev->dev,
|
||||
"disconnecting client host client = %d, "
|
||||
"ME client = %d\n",
|
||||
cl->host_client_id,
|
||||
cl->me_client_id);
|
||||
|
||||
if (dev->open_handle_count > 0) {
|
||||
clear_bit(cl->host_client_id, dev->host_clients_map);
|
||||
dev->open_handle_count--;
|
||||
}
|
||||
mei_remove_client_from_file_list(dev, cl->host_client_id);
|
||||
|
||||
/* free read cb */
|
||||
cb = NULL;
|
||||
if (cl->read_cb) {
|
||||
cb = find_read_list_entry(dev, cl);
|
||||
/* Remove entry from read list */
|
||||
if (cb)
|
||||
list_del(&cb->list);
|
||||
|
||||
cb = cl->read_cb;
|
||||
cl->read_cb = NULL;
|
||||
}
|
||||
|
||||
file->private_data = NULL;
|
||||
|
||||
if (cb) {
|
||||
mei_io_cb_free(cb);
|
||||
cb = NULL;
|
||||
}
|
||||
|
||||
kfree(cl);
|
||||
} else {
|
||||
if (dev->open_handle_count > 0)
|
||||
dev->open_handle_count--;
|
||||
|
||||
if (dev->iamthif_file_object == file &&
|
||||
dev->iamthif_state != MEI_IAMTHIF_IDLE) {
|
||||
|
||||
dev_dbg(&dev->pdev->dev, "amthi canceled iamthif state %d\n",
|
||||
dev->iamthif_state);
|
||||
dev->iamthif_canceled = true;
|
||||
if (dev->iamthif_state == MEI_IAMTHIF_READ_COMPLETE) {
|
||||
dev_dbg(&dev->pdev->dev, "run next amthi iamthif cb\n");
|
||||
mei_amthif_run_next_cmd(dev);
|
||||
}
|
||||
}
|
||||
|
||||
if (mei_clear_lists(dev, file))
|
||||
dev->iamthif_state = MEI_IAMTHIF_IDLE;
|
||||
|
||||
rets = mei_disconnect_host_client(dev, cl);
|
||||
}
|
||||
mei_cl_flush_queues(cl);
|
||||
dev_dbg(&dev->pdev->dev, "remove client host client = %d, ME client = %d\n",
|
||||
cl->host_client_id,
|
||||
cl->me_client_id);
|
||||
|
||||
if (dev->open_handle_count > 0) {
|
||||
clear_bit(cl->host_client_id, dev->host_clients_map);
|
||||
dev->open_handle_count--;
|
||||
}
|
||||
mei_remove_client_from_file_list(dev, cl->host_client_id);
|
||||
|
||||
/* free read cb */
|
||||
cb = NULL;
|
||||
if (cl->read_cb) {
|
||||
cb = find_read_list_entry(dev, cl);
|
||||
/* Remove entry from read list */
|
||||
if (cb)
|
||||
list_del(&cb->list);
|
||||
|
||||
cb = cl->read_cb;
|
||||
cl->read_cb = NULL;
|
||||
}
|
||||
|
||||
file->private_data = NULL;
|
||||
|
||||
if (cb) {
|
||||
mei_io_cb_free(cb);
|
||||
cb = NULL;
|
||||
}
|
||||
|
||||
kfree(cl);
|
||||
out:
|
||||
mutex_unlock(&dev->device_lock);
|
||||
return rets;
|
||||
}
|
||||
|
@ -389,6 +389,8 @@ int mei_amthif_write(struct mei_device *dev, struct mei_cl_cb *priv_cb);
|
||||
int mei_amthif_read(struct mei_device *dev, struct file *file,
|
||||
char __user *ubuf, size_t length, loff_t *offset);
|
||||
|
||||
int mei_amthif_release(struct mei_device *dev, struct file *file);
|
||||
|
||||
struct mei_cl_cb *mei_amthif_find_read_list_entry(struct mei_device *dev,
|
||||
struct file *file);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user