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>
diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c
index 3fdd223..7b6ed0b 100644
--- a/drivers/misc/mei/amthif.c
+++ b/drivers/misc/mei/amthif.c
@@ -196,16 +196,16 @@
 	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 @@
 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;
 		}
 	}
diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c
index 3e6ffed..b538537 100644
--- a/drivers/misc/mei/bus.c
+++ b/drivers/misc/mei/bus.c
@@ -311,13 +311,13 @@
 		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 @@
 
 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 @@
 
 	/* 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;
 
diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c
index e263c07..624bf01 100644
--- a/drivers/misc/mei/client.c
+++ b/drivers/misc/mei/client.c
@@ -321,52 +321,6 @@
 }
 
 /**
- * __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
  *
  * @cb: mei callback struct
@@ -376,6 +330,7 @@
 	if (cb == NULL)
 		return;
 
+	list_del(&cb->list);
 	kfree(cb->buf.data);
 	kfree(cb);
 }
@@ -398,8 +353,7 @@
 	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;
@@ -408,6 +362,50 @@
 }
 
 /**
+ * __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
  *
  * @cb: io callback structure
diff --git a/drivers/misc/mei/hbm.c b/drivers/misc/mei/hbm.c
index 2c581dc..58da925 100644
--- a/drivers/misc/mei/hbm.c
+++ b/drivers/misc/mei/hbm.c
@@ -639,7 +639,7 @@
 			continue;
 
 		if (mei_hbm_cl_addr_equal(cl, rs)) {
-			list_del(&cb->list);
+			list_del_init(&cb->list);
 			break;
 		}
 	}
diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c
index 60469a0..1e2f3c7 100644
--- a/drivers/misc/mei/interrupt.c
+++ b/drivers/misc/mei/interrupt.c
@@ -202,7 +202,6 @@
 
 	cl->state = MEI_FILE_DISCONNECTED;
 	cl->status = 0;
-	list_del(&cb->list);
 	mei_io_cb_free(cb);
 
 	return ret;
@@ -320,7 +319,7 @@
 	if (ret) {
 		cl->status = ret;
 		cb->buf_idx = 0;
-		list_del(&cb->list);
+		list_del_init(&cb->list);
 		return ret;
 	}
 
diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c
index 10fc3a6a..c34853b 100644
--- a/drivers/misc/mei/main.c
+++ b/drivers/misc/mei/main.c
@@ -94,7 +94,6 @@
 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 @@
 
 	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 @@
 			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 @@
 		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 @@
 			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 @@
 		*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;