提交 928fa666 编写于 作者: T Tomas Winkler 提交者: 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: NTomas Winkler <tomas.winkler@intel.com>
Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
上级 03b8d341
......@@ -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,6 +320,47 @@ static inline bool mei_cl_cmp_id(const struct mei_cl *cl1,
(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.
*
......@@ -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,
struct mei_cl *cl, bool free)
{
struct mei_cl_cb *cb;
struct mei_cl_cb *next;
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(&cb->list);
list_del_init(&cb->list);
if (free)
mei_io_cb_free(cb);
}
......@@ -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_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)
__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
*
......
......@@ -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 @@ static int mei_open(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_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 @@ static ssize_t mei_read(struct file *file, char __user *ubuf,
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;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册