diag: Assign dci_client_id properly while client registration

Currently while doing dci client registration dci_client_id is
assigned by incremeting previous id. Starting dci clients
multiple times can make id equal to error types and dci client
registratin can fail. The patch assign dci_client_id properly
and un-assign it while deinit of client.

Change-Id: Idd13166f5edb680f8c97c538a76ce613af3a1e8e
Signed-off-by: Hardik Arya <harya@codeaurora.org>
diff --git a/drivers/char/diag/diag_dci.c b/drivers/char/diag/diag_dci.c
index 0937b2f..5a1afd0 100644
--- a/drivers/char/diag/diag_dci.c
+++ b/drivers/char/diag/diag_dci.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -2757,10 +2757,11 @@
 
 int diag_dci_init(void)
 {
-	int ret = 0;
+	int ret = 0, i;
 
 	driver->dci_tag = 0;
-	driver->dci_client_id = 0;
+	for (i = 0; i < MAX_DCI_CLIENTS; i++)
+		driver->dci_client_id[i] = 0;
 	driver->num_dci_client = 0;
 	mutex_init(&driver->dci_mutex);
 	mutex_init(&dci_log_mask_mutex);
@@ -2956,8 +2957,8 @@
 	mutex_init(&new_entry->write_buf_mutex);
 	new_entry->dci_log_mask =  vzalloc(DCI_LOG_MASK_SIZE);
 	if (!new_entry->dci_log_mask) {
-		pr_err("diag: Unable to create log mask for client, %d",
-							driver->dci_client_id);
+		pr_err("diag: Unable to create log mask for DCI client, tgid: %d\n",
+			current->tgid);
 		goto fail_alloc;
 	}
 	create_dci_log_mask_tbl(new_entry->dci_log_mask, DCI_LOG_MASK_CLEAN);
@@ -3006,17 +3007,24 @@
 		proc_buf->buf_curr = proc_buf->buf_primary;
 	}
 
-	list_add_tail(&new_entry->track, &driver->dci_client_list);
-	driver->dci_client_id++;
-	new_entry->client_info.client_id = driver->dci_client_id;
-	reg_entry->client_id = driver->dci_client_id;
+	for (i = 0; i < MAX_DCI_CLIENTS; i++) {
+		if (driver->dci_client_id[i] == 0)
+			break;
+	}
+
+	if (i == MAX_DCI_CLIENTS)
+		goto fail_alloc;
+	driver->dci_client_id[i] = 1;
+	new_entry->client_info.client_id = i+1;
+	reg_entry->client_id = i+1;
 	driver->num_dci_client++;
+	list_add_tail(&new_entry->track, &driver->dci_client_list);
 	if (driver->num_dci_client == 1)
 		diag_update_proc_vote(DIAG_PROC_DCI, VOTE_UP, reg_entry->token);
 	queue_work(driver->diag_real_time_wq, &driver->diag_real_time_work);
 	mutex_unlock(&driver->dci_mutex);
 
-	return driver->dci_client_id;
+	return reg_entry->client_id;
 
 fail_alloc:
 	if (new_entry) {
@@ -3075,7 +3083,11 @@
 	 */
 	if (!list_empty(&entry->track))
 		list_del(&entry->track);
+
+	if (entry->client_info.client_id > MAX_DCI_CLIENTS)
+		return DIAG_DCI_NO_REG;
 	driver->num_dci_client--;
+	driver->dci_client_id[entry->client_info.client_id - 1] = 0;
 	/*
 	 * Clear the client's log and event masks, update the cumulative
 	 * masks and send the masks to peripherals
diff --git a/drivers/char/diag/diag_dci.h b/drivers/char/diag/diag_dci.h
index 2fb0e3f..835c0c1 100644
--- a/drivers/char/diag/diag_dci.h
+++ b/drivers/char/diag/diag_dci.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2016, 2018 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2016, 2018-2019 The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -12,7 +12,6 @@
 #ifndef DIAG_DCI_H
 #define DIAG_DCI_H
 
-#define MAX_DCI_CLIENTS		10
 #define DCI_PKT_RSP_CODE	0x93
 #define DCI_DELAYED_RSP_CODE	0x94
 #define DCI_CONTROL_PKT_CODE	0x9A
diff --git a/drivers/char/diag/diagchar.h b/drivers/char/diag/diagchar.h
index 2e87d51..9419c58 100644
--- a/drivers/char/diag/diagchar.h
+++ b/drivers/char/diag/diagchar.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2008-2019, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -288,6 +288,7 @@
 #define DIAG_CNTL_TYPE		2
 #define DIAG_DCI_TYPE		3
 
+#define MAX_DCI_CLIENTS		10
 /*
  * List of diag ids
  * 0 is reserved for unknown diag id, 1 for apps, diag ids
@@ -582,7 +583,7 @@
 	struct list_head dci_req_list;
 	struct list_head dci_client_list;
 	int dci_tag;
-	int dci_client_id;
+	int dci_client_id[MAX_DCI_CLIENTS];
 	struct mutex dci_mutex;
 	int num_dci_client;
 	unsigned char *apps_dci_buf;