Commit 928fa666 authored by Tomas Winkler's avatar Tomas Winkler Committed by Greg Kroah-Hartman

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: default avatarTomas Winkler <tomas.winkler@intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 03b8d341
...@@ -196,16 +196,16 @@ int mei_amthif_read(struct mei_device *dev, struct file *file, ...@@ -196,16 +196,16 @@ int mei_amthif_read(struct mei_device *dev, struct file *file,
if (time_after(jiffies, timeout)) { if (time_after(jiffies, timeout)) {
dev_dbg(dev->dev, "amthif Time out\n"); dev_dbg(dev->dev, "amthif Time out\n");
/* 15 sec for the message has expired */ /* 15 sec for the message has expired */
list_del(&cb->list); list_del_init(&cb->list);
rets = -ETIME; rets = -ETIME;
goto free; goto free;
} }
/* if the whole message will fit remove it from the list */ /* if the whole message will fit remove it from the list */
if (cb->buf_idx >= *offset && length >= (cb->buf_idx - *offset)) 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) { else if (cb->buf_idx > 0 && cb->buf_idx <= *offset) {
/* end of the message has been reached */ /* end of the message has been reached */
list_del(&cb->list); list_del_init(&cb->list);
rets = 0; rets = 0;
goto free; goto free;
} }
...@@ -504,26 +504,22 @@ void mei_amthif_complete(struct mei_device *dev, struct mei_cl_cb *cb) ...@@ -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, static bool mei_clear_list(struct mei_device *dev,
const struct file *file, struct list_head *mei_cb_list) const struct file *file, struct list_head *mei_cb_list)
{ {
struct mei_cl_cb *cb_pos = NULL; struct mei_cl *cl = &dev->iamthif_cl;
struct mei_cl_cb *cb_next = NULL; struct mei_cl_cb *cb, *next;
bool removed = false; bool removed = false;
/* list all list member */ /* 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 */ /* check if list member associated with a file */
if (file == cb_pos->file_object) { if (file == cb->file_object) {
/* remove member from the list */
list_del(&cb_pos->list);
/* check if cb equal to current iamthif cb */ /* 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; dev->iamthif_current_cb = NULL;
/* send flow control to iamthif client */ /* send flow control to iamthif client */
mei_hbm_cl_flow_control_req(dev, mei_hbm_cl_flow_control_req(dev, cl);
&dev->iamthif_cl);
} }
/* free all allocated buffers */ /* free all allocated buffers */
mei_io_cb_free(cb_pos); mei_io_cb_free(cb);
cb_pos = NULL;
removed = true; removed = true;
} }
} }
......
...@@ -311,13 +311,13 @@ ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length) ...@@ -311,13 +311,13 @@ ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length)
mutex_lock(&dev->device_lock); mutex_lock(&dev->device_lock);
} }
cb = cl->read_cb;
if (cl->reading_state != MEI_READ_COMPLETE) { if (cl->reading_state != MEI_READ_COMPLETE) {
rets = 0; rets = 0;
goto out; goto out;
} }
cb = cl->read_cb;
if (cb->status) { if (cb->status) {
rets = cb->status; rets = cb->status;
goto free; goto free;
...@@ -329,8 +329,8 @@ ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length) ...@@ -329,8 +329,8 @@ ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length)
free: free:
mei_io_cb_free(cb); mei_io_cb_free(cb);
cl->reading_state = MEI_IDLE;
cl->read_cb = NULL; cl->read_cb = NULL;
cl->reading_state = MEI_IDLE;
out: out:
mutex_unlock(&dev->device_lock); mutex_unlock(&dev->device_lock);
...@@ -486,23 +486,7 @@ int mei_cl_disable_device(struct mei_cl_device *device) ...@@ -486,23 +486,7 @@ int mei_cl_disable_device(struct mei_cl_device *device)
/* Flush queues and remove any pending read */ /* Flush queues and remove any pending read */
mei_cl_flush_queues(cl); mei_cl_flush_queues(cl);
mei_io_cb_free(cl->read_cb);
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;
}
}
device->event_cb = NULL; device->event_cb = NULL;
......
...@@ -320,6 +320,47 @@ static inline bool mei_cl_cmp_id(const struct mei_cl *cl1, ...@@ -320,6 +320,47 @@ static inline bool mei_cl_cmp_id(const struct mei_cl *cl1,
(cl1->me_client_id == cl2->me_client_id); (cl1->me_client_id == cl2->me_client_id);
} }
/**
* mei_io_cb_free - free mei_cb_private related memory
*
* @cb: mei callback struct
*/
void mei_io_cb_free(struct mei_cl_cb *cb)
{
if (cb == NULL)
return;
list_del(&cb->list);
kfree(cb->buf.data);
kfree(cb);
}
/**
* mei_io_cb_init - allocate and initialize io callback
*
* @cl: mei client
* @type: operation type
* @fp: pointer to file structure
*
* Return: mei_cl_cb pointer or NULL;
*/
struct mei_cl_cb *mei_io_cb_init(struct mei_cl *cl, enum mei_cb_file_ops type,
struct file *fp)
{
struct mei_cl_cb *cb;
cb = kzalloc(sizeof(struct mei_cl_cb), GFP_KERNEL);
if (!cb)
return NULL;
INIT_LIST_HEAD(&cb->list);
cb->file_object = fp;
cb->cl = cl;
cb->buf_idx = 0;
cb->fop_type = type;
return cb;
}
/** /**
* __mei_io_list_flush - removes and frees cbs belonging to cl. * __mei_io_list_flush - removes and frees cbs belonging to cl.
* *
...@@ -330,13 +371,12 @@ static inline bool mei_cl_cmp_id(const struct mei_cl *cl1, ...@@ -330,13 +371,12 @@ static inline bool mei_cl_cmp_id(const struct mei_cl *cl1,
static void __mei_io_list_flush(struct mei_cl_cb *list, static void __mei_io_list_flush(struct mei_cl_cb *list,
struct mei_cl *cl, bool free) struct mei_cl *cl, bool free)
{ {
struct mei_cl_cb *cb; struct mei_cl_cb *cb, *next;
struct mei_cl_cb *next;
/* enable removing everything if no cl is specified */ /* enable removing everything if no cl is specified */
list_for_each_entry_safe(cb, next, &list->list, list) { list_for_each_entry_safe(cb, next, &list->list, list) {
if (!cl || mei_cl_cmp_id(cl, cb->cl)) { if (!cl || mei_cl_cmp_id(cl, cb->cl)) {
list_del(&cb->list); list_del_init(&cb->list);
if (free) if (free)
mei_io_cb_free(cb); mei_io_cb_free(cb);
} }
...@@ -354,7 +394,6 @@ void mei_io_list_flush(struct mei_cl_cb *list, struct mei_cl *cl) ...@@ -354,7 +394,6 @@ void mei_io_list_flush(struct mei_cl_cb *list, struct mei_cl *cl)
__mei_io_list_flush(list, cl, false); __mei_io_list_flush(list, cl, false);
} }
/** /**
* mei_io_list_free - removes cb belonging to cl and free them * mei_io_list_free - removes cb belonging to cl and free them
* *
...@@ -366,47 +405,6 @@ static inline void mei_io_list_free(struct mei_cl_cb *list, struct mei_cl *cl) ...@@ -366,47 +405,6 @@ 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_list_flush(list, cl, true);
} }
/**
* mei_io_cb_free - free mei_cb_private related memory
*
* @cb: mei callback struct
*/
void mei_io_cb_free(struct mei_cl_cb *cb)
{
if (cb == NULL)
return;
kfree(cb->buf.data);
kfree(cb);
}
/**
* mei_io_cb_init - allocate and initialize io callback
*
* @cl: mei client
* @type: operation type
* @fp: pointer to file structure
*
* Return: mei_cl_cb pointer or NULL;
*/
struct mei_cl_cb *mei_io_cb_init(struct mei_cl *cl, enum mei_cb_file_ops type,
struct file *fp)
{
struct mei_cl_cb *cb;
cb = kzalloc(sizeof(struct mei_cl_cb), GFP_KERNEL);
if (!cb)
return NULL;
mei_io_list_init(cb);
cb->file_object = fp;
cb->cl = cl;
cb->buf_idx = 0;
cb->fop_type = type;
return cb;
}
/** /**
* mei_io_cb_alloc_buf - allocate callback buffer * mei_io_cb_alloc_buf - allocate callback buffer
* *
......
...@@ -639,7 +639,7 @@ static void mei_hbm_cl_res(struct mei_device *dev, ...@@ -639,7 +639,7 @@ static void mei_hbm_cl_res(struct mei_device *dev,
continue; continue;
if (mei_hbm_cl_addr_equal(cl, rs)) { if (mei_hbm_cl_addr_equal(cl, rs)) {
list_del(&cb->list); list_del_init(&cb->list);
break; break;
} }
} }
......
...@@ -202,7 +202,6 @@ static int mei_cl_irq_disconnect_rsp(struct mei_cl *cl, struct mei_cl_cb *cb, ...@@ -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->state = MEI_FILE_DISCONNECTED;
cl->status = 0; cl->status = 0;
list_del(&cb->list);
mei_io_cb_free(cb); mei_io_cb_free(cb);
return ret; return ret;
...@@ -320,7 +319,7 @@ static int mei_cl_irq_connect(struct mei_cl *cl, struct mei_cl_cb *cb, ...@@ -320,7 +319,7 @@ static int mei_cl_irq_connect(struct mei_cl *cl, struct mei_cl_cb *cb,
if (ret) { if (ret) {
cl->status = ret; cl->status = ret;
cb->buf_idx = 0; cb->buf_idx = 0;
list_del(&cb->list); list_del_init(&cb->list);
return ret; return ret;
} }
......
...@@ -94,7 +94,6 @@ static int mei_open(struct inode *inode, struct file *file) ...@@ -94,7 +94,6 @@ static int mei_open(struct inode *inode, struct file *file)
static int mei_release(struct inode *inode, struct file *file) static int mei_release(struct inode *inode, struct file *file)
{ {
struct mei_cl *cl = file->private_data; struct mei_cl *cl = file->private_data;
struct mei_cl_cb *cb;
struct mei_device *dev; struct mei_device *dev;
int rets = 0; int rets = 0;
...@@ -118,23 +117,11 @@ static int mei_release(struct inode *inode, struct file *file) ...@@ -118,23 +117,11 @@ static int mei_release(struct inode *inode, struct file *file)
mei_cl_unlink(cl); mei_cl_unlink(cl);
mei_io_cb_free(cl->read_cb);
/* 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; cl->read_cb = NULL;
}
file->private_data = NULL; file->private_data = NULL;
mei_io_cb_free(cb);
kfree(cl); kfree(cl);
out: out:
mutex_unlock(&dev->device_lock); mutex_unlock(&dev->device_lock);
...@@ -156,7 +143,6 @@ static ssize_t mei_read(struct file *file, char __user *ubuf, ...@@ -156,7 +143,6 @@ static ssize_t mei_read(struct file *file, char __user *ubuf,
size_t length, loff_t *offset) size_t length, loff_t *offset)
{ {
struct mei_cl *cl = file->private_data; struct mei_cl *cl = file->private_data;
struct mei_cl_cb *cb_pos = NULL;
struct mei_cl_cb *cb = NULL; struct mei_cl_cb *cb = NULL;
struct mei_device *dev; struct mei_device *dev;
int rets; int rets;
...@@ -279,13 +265,10 @@ static ssize_t mei_read(struct file *file, char __user *ubuf, ...@@ -279,13 +265,10 @@ static ssize_t mei_read(struct file *file, char __user *ubuf,
goto out; goto out;
free: 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); mei_io_cb_free(cb);
cl->reading_state = MEI_IDLE;
cl->read_cb = NULL; cl->read_cb = NULL;
cl->reading_state = MEI_IDLE;
out: out:
dev_dbg(dev->dev, "end mei read rets= %d\n", rets); dev_dbg(dev->dev, "end mei read rets= %d\n", rets);
mutex_unlock(&dev->device_lock); mutex_unlock(&dev->device_lock);
...@@ -355,7 +338,6 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, ...@@ -355,7 +338,6 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf,
if (time_after(jiffies, timeout) || if (time_after(jiffies, timeout) ||
cl->reading_state == MEI_READ_COMPLETE) { cl->reading_state == MEI_READ_COMPLETE) {
*offset = 0; *offset = 0;
list_del(&write_cb->list);
mei_io_cb_free(write_cb); mei_io_cb_free(write_cb);
write_cb = NULL; write_cb = NULL;
} }
...@@ -367,11 +349,10 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, ...@@ -367,11 +349,10 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf,
*offset = 0; *offset = 0;
write_cb = mei_cl_find_read_cb(cl); write_cb = mei_cl_find_read_cb(cl);
if (write_cb) { if (write_cb) {
list_del(&write_cb->list);
mei_io_cb_free(write_cb); mei_io_cb_free(write_cb);
write_cb = NULL; write_cb = NULL;
cl->reading_state = MEI_IDLE;
cl->read_cb = NULL; cl->read_cb = NULL;
cl->reading_state = MEI_IDLE;
} }
} else if (cl->reading_state == MEI_IDLE) } else if (cl->reading_state == MEI_IDLE)
*offset = 0; *offset = 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment