mei: simplify io callback disposal
Simplify disposal of io callback by removing the callback implicitly from its lookup list inside mei_io_cb_free Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
03b8d3419f
commit
928fa6664b
|
@ -196,16 +196,16 @@ int mei_amthif_read(struct mei_device *dev, struct file *file,
|
|||
if (time_after(jiffies, timeout)) {
|
||||
dev_dbg(dev->dev, "amthif Time out\n");
|
||||
/* 15 sec for the message has expired */
|
||||
list_del(&cb->list);
|
||||
list_del_init(&cb->list);
|
||||
rets = -ETIME;
|
||||
goto free;
|
||||
}
|
||||
/* if the whole message will fit remove it from the list */
|
||||
if (cb->buf_idx >= *offset && length >= (cb->buf_idx - *offset))
|
||||
list_del(&cb->list);
|
||||
list_del_init(&cb->list);
|
||||
else if (cb->buf_idx > 0 && cb->buf_idx <= *offset) {
|
||||
/* end of the message has been reached */
|
||||
list_del(&cb->list);
|
||||
list_del_init(&cb->list);
|
||||
rets = 0;
|
||||
goto free;
|
||||
}
|
||||
|
@ -504,26 +504,22 @@ void mei_amthif_complete(struct mei_device *dev, struct mei_cl_cb *cb)
|
|||
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;
|
||||
struct mei_cl *cl = &dev->iamthif_cl;
|
||||
struct mei_cl_cb *cb, *next;
|
||||
bool removed = false;
|
||||
|
||||
/* list all list member */
|
||||
list_for_each_entry_safe(cb_pos, cb_next, mei_cb_list, list) {
|
||||
list_for_each_entry_safe(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);
|
||||
if (file == cb->file_object) {
|
||||
/* check if cb equal to current iamthif cb */
|
||||
if (dev->iamthif_current_cb == cb_pos) {
|
||||
if (dev->iamthif_current_cb == cb) {
|
||||
dev->iamthif_current_cb = NULL;
|
||||
/* send flow control to iamthif client */
|
||||
mei_hbm_cl_flow_control_req(dev,
|
||||
&dev->iamthif_cl);
|
||||
mei_hbm_cl_flow_control_req(dev, cl);
|
||||
}
|
||||
/* free all allocated buffers */
|
||||
mei_io_cb_free(cb_pos);
|
||||
cb_pos = NULL;
|
||||
mei_io_cb_free(cb);
|
||||
removed = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -311,13 +311,13 @@ ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length)
|
|||
mutex_lock(&dev->device_lock);
|
||||
}
|
||||
|
||||
cb = cl->read_cb;
|
||||
|
||||
if (cl->reading_state != MEI_READ_COMPLETE) {
|
||||
rets = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
cb = cl->read_cb;
|
||||
if (cb->status) {
|
||||
rets = cb->status;
|
||||
goto free;
|
||||
|
@ -329,8 +329,8 @@ ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length)
|
|||
|
||||
free:
|
||||
mei_io_cb_free(cb);
|
||||
cl->reading_state = MEI_IDLE;
|
||||
cl->read_cb = NULL;
|
||||
cl->reading_state = MEI_IDLE;
|
||||
|
||||
out:
|
||||
mutex_unlock(&dev->device_lock);
|
||||
|
@ -486,23 +486,7 @@ int mei_cl_disable_device(struct mei_cl_device *device)
|
|||
|
||||
/* Flush queues and remove any pending read */
|
||||
mei_cl_flush_queues(cl);
|
||||
|
||||
if (cl->read_cb) {
|
||||
struct mei_cl_cb *cb = NULL;
|
||||
|
||||
cb = mei_cl_find_read_cb(cl);
|
||||
/* Remove entry from read list */
|
||||
if (cb)
|
||||
list_del(&cb->list);
|
||||
|
||||
cb = cl->read_cb;
|
||||
cl->read_cb = NULL;
|
||||
|
||||
if (cb) {
|
||||
mei_io_cb_free(cb);
|
||||
cb = NULL;
|
||||
}
|
||||
}
|
||||
mei_io_cb_free(cl->read_cb);
|
||||
|
||||
device->event_cb = NULL;
|
||||
|
||||
|
|
|
@ -320,52 +320,6 @@ static inline bool mei_cl_cmp_id(const struct mei_cl *cl1,
|
|||
(cl1->me_client_id == cl2->me_client_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* __mei_io_list_flush - removes and frees cbs belonging to cl.
|
||||
*
|
||||
* @list: an instance of our list structure
|
||||
* @cl: host client, can be NULL for flushing the whole list
|
||||
* @free: whether to free the cbs
|
||||
*/
|
||||
static void __mei_io_list_flush(struct mei_cl_cb *list,
|
||||
struct mei_cl *cl, bool free)
|
||||
{
|
||||
struct mei_cl_cb *cb;
|
||||
struct mei_cl_cb *next;
|
||||
|
||||
/* enable removing everything if no cl is specified */
|
||||
list_for_each_entry_safe(cb, next, &list->list, list) {
|
||||
if (!cl || mei_cl_cmp_id(cl, cb->cl)) {
|
||||
list_del(&cb->list);
|
||||
if (free)
|
||||
mei_io_cb_free(cb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* mei_io_list_flush - removes list entry belonging to cl.
|
||||
*
|
||||
* @list: An instance of our list structure
|
||||
* @cl: host client
|
||||
*/
|
||||
void mei_io_list_flush(struct mei_cl_cb *list, struct mei_cl *cl)
|
||||
{
|
||||
__mei_io_list_flush(list, cl, false);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* mei_io_list_free - removes cb belonging to cl and free them
|
||||
*
|
||||
* @list: An instance of our list structure
|
||||
* @cl: host client
|
||||
*/
|
||||
static inline void mei_io_list_free(struct mei_cl_cb *list, struct mei_cl *cl)
|
||||
{
|
||||
__mei_io_list_flush(list, cl, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* mei_io_cb_free - free mei_cb_private related memory
|
||||
*
|
||||
|
@ -376,6 +330,7 @@ void mei_io_cb_free(struct mei_cl_cb *cb)
|
|||
if (cb == NULL)
|
||||
return;
|
||||
|
||||
list_del(&cb->list);
|
||||
kfree(cb->buf.data);
|
||||
kfree(cb);
|
||||
}
|
||||
|
@ -398,8 +353,7 @@ struct mei_cl_cb *mei_io_cb_init(struct mei_cl *cl, enum mei_cb_file_ops type,
|
|||
if (!cb)
|
||||
return NULL;
|
||||
|
||||
mei_io_list_init(cb);
|
||||
|
||||
INIT_LIST_HEAD(&cb->list);
|
||||
cb->file_object = fp;
|
||||
cb->cl = cl;
|
||||
cb->buf_idx = 0;
|
||||
|
@ -407,6 +361,50 @@ struct mei_cl_cb *mei_io_cb_init(struct mei_cl *cl, enum mei_cb_file_ops type,
|
|||
return cb;
|
||||
}
|
||||
|
||||
/**
|
||||
* __mei_io_list_flush - removes and frees cbs belonging to cl.
|
||||
*
|
||||
* @list: an instance of our list structure
|
||||
* @cl: host client, can be NULL for flushing the whole list
|
||||
* @free: whether to free the cbs
|
||||
*/
|
||||
static void __mei_io_list_flush(struct mei_cl_cb *list,
|
||||
struct mei_cl *cl, bool free)
|
||||
{
|
||||
struct mei_cl_cb *cb, *next;
|
||||
|
||||
/* enable removing everything if no cl is specified */
|
||||
list_for_each_entry_safe(cb, next, &list->list, list) {
|
||||
if (!cl || mei_cl_cmp_id(cl, cb->cl)) {
|
||||
list_del_init(&cb->list);
|
||||
if (free)
|
||||
mei_io_cb_free(cb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* mei_io_list_flush - removes list entry belonging to cl.
|
||||
*
|
||||
* @list: An instance of our list structure
|
||||
* @cl: host client
|
||||
*/
|
||||
void mei_io_list_flush(struct mei_cl_cb *list, struct mei_cl *cl)
|
||||
{
|
||||
__mei_io_list_flush(list, cl, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* mei_io_list_free - removes cb belonging to cl and free them
|
||||
*
|
||||
* @list: An instance of our list structure
|
||||
* @cl: host client
|
||||
*/
|
||||
static inline void mei_io_list_free(struct mei_cl_cb *list, struct mei_cl *cl)
|
||||
{
|
||||
__mei_io_list_flush(list, cl, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* mei_io_cb_alloc_buf - allocate callback buffer
|
||||
*
|
||||
|
|
|
@ -639,7 +639,7 @@ static void mei_hbm_cl_res(struct mei_device *dev,
|
|||
continue;
|
||||
|
||||
if (mei_hbm_cl_addr_equal(cl, rs)) {
|
||||
list_del(&cb->list);
|
||||
list_del_init(&cb->list);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -202,7 +202,6 @@ static int mei_cl_irq_disconnect_rsp(struct mei_cl *cl, struct mei_cl_cb *cb,
|
|||
|
||||
cl->state = MEI_FILE_DISCONNECTED;
|
||||
cl->status = 0;
|
||||
list_del(&cb->list);
|
||||
mei_io_cb_free(cb);
|
||||
|
||||
return ret;
|
||||
|
@ -320,7 +319,7 @@ static int mei_cl_irq_connect(struct mei_cl *cl, struct mei_cl_cb *cb,
|
|||
if (ret) {
|
||||
cl->status = ret;
|
||||
cb->buf_idx = 0;
|
||||
list_del(&cb->list);
|
||||
list_del_init(&cb->list);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -94,7 +94,6 @@ err_unlock:
|
|||
static int mei_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct mei_cl *cl = file->private_data;
|
||||
struct mei_cl_cb *cb;
|
||||
struct mei_device *dev;
|
||||
int rets = 0;
|
||||
|
||||
|
@ -118,23 +117,11 @@ static int mei_release(struct inode *inode, struct file *file)
|
|||
|
||||
mei_cl_unlink(cl);
|
||||
|
||||
|
||||
/* free read cb */
|
||||
cb = NULL;
|
||||
if (cl->read_cb) {
|
||||
cb = mei_cl_find_read_cb(cl);
|
||||
/* Remove entry from read list */
|
||||
if (cb)
|
||||
list_del(&cb->list);
|
||||
|
||||
cb = cl->read_cb;
|
||||
cl->read_cb = NULL;
|
||||
}
|
||||
mei_io_cb_free(cl->read_cb);
|
||||
cl->read_cb = NULL;
|
||||
|
||||
file->private_data = NULL;
|
||||
|
||||
mei_io_cb_free(cb);
|
||||
|
||||
kfree(cl);
|
||||
out:
|
||||
mutex_unlock(&dev->device_lock);
|
||||
|
@ -156,7 +143,6 @@ static ssize_t mei_read(struct file *file, char __user *ubuf,
|
|||
size_t length, loff_t *offset)
|
||||
{
|
||||
struct mei_cl *cl = file->private_data;
|
||||
struct mei_cl_cb *cb_pos = NULL;
|
||||
struct mei_cl_cb *cb = NULL;
|
||||
struct mei_device *dev;
|
||||
int rets;
|
||||
|
@ -279,13 +265,10 @@ copy_buffer:
|
|||
goto out;
|
||||
|
||||
free:
|
||||
cb_pos = mei_cl_find_read_cb(cl);
|
||||
/* Remove entry from read list */
|
||||
if (cb_pos)
|
||||
list_del(&cb_pos->list);
|
||||
mei_io_cb_free(cb);
|
||||
cl->reading_state = MEI_IDLE;
|
||||
cl->read_cb = NULL;
|
||||
|
||||
cl->reading_state = MEI_IDLE;
|
||||
out:
|
||||
dev_dbg(dev->dev, "end mei read rets= %d\n", rets);
|
||||
mutex_unlock(&dev->device_lock);
|
||||
|
@ -355,7 +338,6 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf,
|
|||
if (time_after(jiffies, timeout) ||
|
||||
cl->reading_state == MEI_READ_COMPLETE) {
|
||||
*offset = 0;
|
||||
list_del(&write_cb->list);
|
||||
mei_io_cb_free(write_cb);
|
||||
write_cb = NULL;
|
||||
}
|
||||
|
@ -367,11 +349,10 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf,
|
|||
*offset = 0;
|
||||
write_cb = mei_cl_find_read_cb(cl);
|
||||
if (write_cb) {
|
||||
list_del(&write_cb->list);
|
||||
mei_io_cb_free(write_cb);
|
||||
write_cb = NULL;
|
||||
cl->reading_state = MEI_IDLE;
|
||||
cl->read_cb = NULL;
|
||||
cl->reading_state = MEI_IDLE;
|
||||
}
|
||||
} else if (cl->reading_state == MEI_IDLE)
|
||||
*offset = 0;
|
||||
|
|
Loading…
Reference in New Issue