Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+10 −14
Original line number Diff line number Diff line
@@ -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;
		}
	}
+3 −19
Original line number Diff line number Diff line
@@ -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;

+43 −45
Original line number Diff line number Diff line
@@ -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
 *
+1 −1
Original line number Diff line number Diff line
@@ -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;
		}
	}
+1 −2
Original line number Diff line number Diff line
@@ -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;
	}

Loading