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;