blob: 0a3fabab0da07aec81d0a6f632a8c3acece06505 [file] [log] [blame]
Mohit Aggarwal86731ea2017-05-25 20:21:12 +05301/* Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
Sreelakshmi Gownipallicb8893d2016-10-19 16:02:34 -07002 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13#ifdef CONFIG_DEBUG_FS
14
15#include <linux/slab.h>
16#include <linux/debugfs.h>
17#include <linux/atomic.h>
18#include <linux/uaccess.h>
19#include "diagchar.h"
20#include "diagfwd.h"
21#ifdef CONFIG_DIAGFWD_BRIDGE_CODE
22#include "diagfwd_bridge.h"
23#endif
24#ifdef CONFIG_USB_QCOM_DIAG_BRIDGE
25#include "diagfwd_hsic.h"
26#include "diagfwd_smux.h"
27#endif
28#ifdef CONFIG_MSM_MHI
29#include "diagfwd_mhi.h"
30#endif
31#include "diagmem.h"
32#include "diag_dci.h"
33#include "diag_usb.h"
34#include "diagfwd_peripheral.h"
35#include "diagfwd_socket.h"
36#include "diagfwd_glink.h"
37#include "diag_debugfs.h"
38#include "diag_ipc_logging.h"
39
40#define DEBUG_BUF_SIZE 4096
41static struct dentry *diag_dbgfs_dent;
42static int diag_dbgfs_table_index;
43static int diag_dbgfs_mempool_index;
44static int diag_dbgfs_usbinfo_index;
45static int diag_dbgfs_socketinfo_index;
46static int diag_dbgfs_glinkinfo_index;
47static int diag_dbgfs_hsicinfo_index;
48static int diag_dbgfs_mhiinfo_index;
49static int diag_dbgfs_bridgeinfo_index;
50static int diag_dbgfs_finished;
51static int diag_dbgfs_dci_data_index;
52static int diag_dbgfs_dci_finished;
Sreelakshmi Gownipalli13e83672017-10-09 12:59:56 -070053static struct mutex diag_dci_dbgfs_mutex;
Sreelakshmi Gownipallicb8893d2016-10-19 16:02:34 -070054static ssize_t diag_dbgfs_read_status(struct file *file, char __user *ubuf,
55 size_t count, loff_t *ppos)
56{
57 char *buf;
58 int ret, i;
59 unsigned int buf_size;
60
61 buf = kzalloc(sizeof(char) * DEBUG_BUF_SIZE, GFP_KERNEL);
62 if (!buf)
63 return -ENOMEM;
64 buf_size = ksize(buf);
65 ret = scnprintf(buf, buf_size,
66 "CPU Tools ID: %d\n"
67 "Check Polling Response: %d\n"
68 "Polling Registered: %d\n"
69 "Uses Device Tree: %d\n"
70 "Apps Supports Separate CMDRSP: %d\n"
71 "Apps Supports HDLC Encoding: %d\n"
Manoj Prabhu B571cf422017-08-08 19:01:41 +053072 "Apps Supports Header Untagging: %d\n"
Sreelakshmi Gownipallicb8893d2016-10-19 16:02:34 -070073 "Apps Supports Sockets: %d\n"
74 "Logging Mode: %d\n"
75 "RSP Buffer is Busy: %d\n"
76 "HDLC Disabled: %d\n"
77 "Time Sync Enabled: %d\n"
78 "MD session mode: %d\n"
79 "MD session mask: %d\n"
Manoj Prabhu Bcba38ed2017-11-08 20:24:46 +053080 "Uses Time API: %d\n"
81 "Supports PD buffering: %d\n",
Sreelakshmi Gownipallicb8893d2016-10-19 16:02:34 -070082 chk_config_get_id(),
83 chk_polling_response(),
84 driver->polling_reg_flag,
85 driver->use_device_tree,
86 driver->supports_separate_cmdrsp,
87 driver->supports_apps_hdlc_encoding,
Manoj Prabhu B571cf422017-08-08 19:01:41 +053088 driver->supports_apps_header_untagging,
Sreelakshmi Gownipallicb8893d2016-10-19 16:02:34 -070089 driver->supports_sockets,
90 driver->logging_mode,
91 driver->rsp_buf_busy,
92 driver->hdlc_disabled,
93 driver->time_sync_enabled,
94 driver->md_session_mode,
95 driver->md_session_mask,
Manoj Prabhu Bcba38ed2017-11-08 20:24:46 +053096 driver->uses_time_api,
97 driver->supports_pd_buffering);
Sreelakshmi Gownipallicb8893d2016-10-19 16:02:34 -070098
99 for (i = 0; i < NUM_PERIPHERALS; i++) {
100 ret += scnprintf(buf+ret, buf_size-ret,
Manoj Prabhu Bcba38ed2017-11-08 20:24:46 +0530101 "p: %s Feature: %02x %02x |%c%c%c%c%c%c%c%c%c%c|\n",
Sreelakshmi Gownipallicb8893d2016-10-19 16:02:34 -0700102 PERIPHERAL_STRING(i),
103 driver->feature[i].feature_mask[0],
104 driver->feature[i].feature_mask[1],
105 driver->feature[i].rcvd_feature_mask ? 'F':'f',
106 driver->feature[i].separate_cmd_rsp ? 'C':'c',
107 driver->feature[i].encode_hdlc ? 'H':'h',
108 driver->feature[i].peripheral_buffering ? 'B':'b',
109 driver->feature[i].mask_centralization ? 'M':'m',
Manoj Prabhu Bcba38ed2017-11-08 20:24:46 +0530110 driver->feature[i].pd_buffering ? 'P':'p',
Sreelakshmi Gownipallicb8893d2016-10-19 16:02:34 -0700111 driver->feature[i].stm_support ? 'Q':'q',
112 driver->feature[i].sockets_enabled ? 'S':'s',
Manoj Prabhu B571cf422017-08-08 19:01:41 +0530113 driver->feature[i].sent_feature_mask ? 'T':'t',
114 driver->feature[i].untag_header ? 'U':'u');
Sreelakshmi Gownipallicb8893d2016-10-19 16:02:34 -0700115 }
116
117#ifdef CONFIG_DIAG_OVER_USB
118 ret += scnprintf(buf+ret, buf_size-ret,
119 "USB Connected: %d\n",
120 driver->usb_connected);
121#endif
122
123 for (i = 0; i < DIAG_NUM_PROC; i++) {
124 ret += scnprintf(buf+ret, buf_size-ret,
125 "Real Time Mode: %d: %d\n", i,
126 driver->real_time_mode[i]);
127 }
128
129 ret = simple_read_from_buffer(ubuf, count, ppos, buf, ret);
130
131 kfree(buf);
132 return ret;
133}
134
135static ssize_t diag_dbgfs_read_dcistats(struct file *file,
136 char __user *ubuf, size_t count, loff_t *ppos)
137{
138 char *buf = NULL;
139 unsigned int bytes_remaining, bytes_written = 0;
140 unsigned int bytes_in_buf = 0, i = 0;
141 struct diag_dci_data_info *temp_data = dci_traffic;
142 unsigned int buf_size;
143
144 buf_size = (count > DEBUG_BUF_SIZE) ? DEBUG_BUF_SIZE : count;
145
146 if (diag_dbgfs_dci_finished) {
147 diag_dbgfs_dci_finished = 0;
148 return 0;
149 }
150
151 buf = kcalloc(buf_size, sizeof(char), GFP_KERNEL);
152 if (ZERO_OR_NULL_PTR(buf))
153 return -ENOMEM;
154
155 buf_size = ksize(buf);
156 bytes_remaining = buf_size;
157
Sreelakshmi Gownipalli13e83672017-10-09 12:59:56 -0700158 mutex_lock(&diag_dci_dbgfs_mutex);
Sreelakshmi Gownipallicb8893d2016-10-19 16:02:34 -0700159 if (diag_dbgfs_dci_data_index == 0) {
160 bytes_written =
161 scnprintf(buf, buf_size,
162 "number of clients: %d\n"
163 "dci proc active: %d\n"
164 "dci real time vote: %d\n",
165 driver->num_dci_client,
166 (driver->proc_active_mask & DIAG_PROC_DCI) ? 1 : 0,
167 (driver->proc_rt_vote_mask[DIAG_LOCAL_PROC] &
168 DIAG_PROC_DCI) ? 1 : 0);
169 bytes_in_buf += bytes_written;
170 bytes_remaining -= bytes_written;
171#ifdef CONFIG_DIAG_OVER_USB
172 bytes_written = scnprintf(buf+bytes_in_buf, bytes_remaining,
173 "usb_connected: %d\n",
174 driver->usb_connected);
175 bytes_in_buf += bytes_written;
176 bytes_remaining -= bytes_written;
177#endif
178 bytes_written = scnprintf(buf+bytes_in_buf,
179 bytes_remaining,
180 "dci power: active, relax: %lu, %lu\n",
181 driver->diag_dev->power.wakeup->
182 active_count,
183 driver->diag_dev->
184 power.wakeup->relax_count);
185 bytes_in_buf += bytes_written;
186 bytes_remaining -= bytes_written;
187
188 }
189 temp_data += diag_dbgfs_dci_data_index;
190 for (i = diag_dbgfs_dci_data_index; i < DIAG_DCI_DEBUG_CNT; i++) {
191 if (temp_data->iteration != 0) {
192 bytes_written = scnprintf(
193 buf + bytes_in_buf, bytes_remaining,
194 "i %-5ld\t"
195 "s %-5d\t"
196 "p %-5d\t"
197 "r %-5d\t"
198 "c %-5d\t"
199 "t %-15s\n",
200 temp_data->iteration,
201 temp_data->data_size,
202 temp_data->peripheral,
203 temp_data->proc,
204 temp_data->ch_type,
205 temp_data->time_stamp);
206 bytes_in_buf += bytes_written;
207 bytes_remaining -= bytes_written;
208 /* Check if there is room for another entry */
209 if (bytes_remaining < bytes_written)
210 break;
211 }
212 temp_data++;
213 }
Sreelakshmi Gownipallicb8893d2016-10-19 16:02:34 -0700214 diag_dbgfs_dci_data_index = (i >= DIAG_DCI_DEBUG_CNT) ? 0 : i + 1;
Sreelakshmi Gownipalli13e83672017-10-09 12:59:56 -0700215 mutex_unlock(&diag_dci_dbgfs_mutex);
Sreelakshmi Gownipallicb8893d2016-10-19 16:02:34 -0700216 bytes_written = simple_read_from_buffer(ubuf, count, ppos, buf,
217 bytes_in_buf);
218 kfree(buf);
219 diag_dbgfs_dci_finished = 1;
220 return bytes_written;
221}
222
223static ssize_t diag_dbgfs_read_power(struct file *file, char __user *ubuf,
224 size_t count, loff_t *ppos)
225{
226 char *buf;
227 int ret;
228 unsigned int buf_size;
229
230 buf = kzalloc(sizeof(char) * DEBUG_BUF_SIZE, GFP_KERNEL);
231 if (!buf)
232 return -ENOMEM;
233
234 buf_size = ksize(buf);
235 ret = scnprintf(buf, buf_size,
236 "DCI reference count: %d\n"
237 "DCI copy count: %d\n"
238 "DCI Client Count: %d\n\n"
239 "Memory Device reference count: %d\n"
240 "Memory Device copy count: %d\n"
241 "Logging mode: %d\n\n"
242 "Wakeup source active count: %lu\n"
243 "Wakeup source relax count: %lu\n\n",
244 driver->dci_ws.ref_count,
245 driver->dci_ws.copy_count,
246 driver->num_dci_client,
247 driver->md_ws.ref_count,
248 driver->md_ws.copy_count,
249 driver->logging_mode,
250 driver->diag_dev->power.wakeup->active_count,
251 driver->diag_dev->power.wakeup->relax_count);
252
253 ret = simple_read_from_buffer(ubuf, count, ppos, buf, ret);
254
255 kfree(buf);
256 return ret;
257}
258
259static ssize_t diag_dbgfs_read_table(struct file *file, char __user *ubuf,
260 size_t count, loff_t *ppos)
261{
262 char *buf;
263 int ret = 0;
264 int i = 0;
265 int is_polling = 0;
266 unsigned int bytes_remaining;
267 unsigned int bytes_in_buffer = 0;
268 unsigned int bytes_written;
269 unsigned int buf_size;
270 struct list_head *start;
271 struct list_head *temp;
272 struct diag_cmd_reg_t *item = NULL;
273
Mohit Aggarwal86731ea2017-05-25 20:21:12 +0530274 mutex_lock(&driver->cmd_reg_mutex);
Sreelakshmi Gownipallicb8893d2016-10-19 16:02:34 -0700275 if (diag_dbgfs_table_index == driver->cmd_reg_count) {
276 diag_dbgfs_table_index = 0;
Mohit Aggarwal86731ea2017-05-25 20:21:12 +0530277 mutex_unlock(&driver->cmd_reg_mutex);
Sreelakshmi Gownipallicb8893d2016-10-19 16:02:34 -0700278 return 0;
279 }
280
281 buf_size = (count > DEBUG_BUF_SIZE) ? DEBUG_BUF_SIZE : count;
282
283 buf = kcalloc(buf_size, sizeof(char), GFP_KERNEL);
284 if (ZERO_OR_NULL_PTR(buf)) {
285 pr_err("diag: %s, Error allocating memory\n", __func__);
Mohit Aggarwal86731ea2017-05-25 20:21:12 +0530286 mutex_unlock(&driver->cmd_reg_mutex);
Sreelakshmi Gownipallicb8893d2016-10-19 16:02:34 -0700287 return -ENOMEM;
288 }
289 buf_size = ksize(buf);
290 bytes_remaining = buf_size;
291
292 if (diag_dbgfs_table_index == 0) {
293 bytes_written = scnprintf(buf+bytes_in_buffer, bytes_remaining,
294 "Client ids: Modem: %d, LPASS: %d, WCNSS: %d, SLPI: %d, APPS: %d\n",
295 PERIPHERAL_MODEM, PERIPHERAL_LPASS,
296 PERIPHERAL_WCNSS, PERIPHERAL_SENSORS,
297 APPS_DATA);
298 bytes_in_buffer += bytes_written;
299 bytes_remaining -= bytes_written;
300 }
301
302 list_for_each_safe(start, temp, &driver->cmd_reg_list) {
303 item = list_entry(start, struct diag_cmd_reg_t, link);
304 if (i < diag_dbgfs_table_index) {
305 i++;
306 continue;
307 }
308
309 is_polling = diag_cmd_chk_polling(&item->entry);
310 bytes_written = scnprintf(buf+bytes_in_buffer, bytes_remaining,
311 "i: %3d, cmd_code: %4x, subsys_id: %4x, cmd_code_lo: %4x, cmd_code_hi: %4x, proc: %d, process_id: %5d %s\n",
312 i++,
313 item->entry.cmd_code,
314 item->entry.subsys_id,
315 item->entry.cmd_code_lo,
316 item->entry.cmd_code_hi,
317 item->proc,
318 item->pid,
319 (is_polling == DIAG_CMD_POLLING) ?
320 "<-- Polling Cmd" : "");
321
322 bytes_in_buffer += bytes_written;
323
324 /* Check if there is room to add another table entry */
325 bytes_remaining = buf_size - bytes_in_buffer;
326
327 if (bytes_remaining < bytes_written)
328 break;
329 }
330 diag_dbgfs_table_index = i;
Mohit Aggarwal86731ea2017-05-25 20:21:12 +0530331 mutex_unlock(&driver->cmd_reg_mutex);
Sreelakshmi Gownipallicb8893d2016-10-19 16:02:34 -0700332
333 *ppos = 0;
334 ret = simple_read_from_buffer(ubuf, count, ppos, buf, bytes_in_buffer);
335
336 kfree(buf);
337 return ret;
338}
339
340static ssize_t diag_dbgfs_read_mempool(struct file *file, char __user *ubuf,
341 size_t count, loff_t *ppos)
342{
343 char *buf = NULL;
344 int ret = 0;
345 int i = 0;
346 unsigned int buf_size;
347 unsigned int bytes_remaining = 0;
348 unsigned int bytes_written = 0;
349 unsigned int bytes_in_buffer = 0;
350 struct diag_mempool_t *mempool = NULL;
351
352 if (diag_dbgfs_mempool_index >= NUM_MEMORY_POOLS) {
353 /* Done. Reset to prepare for future requests */
354 diag_dbgfs_mempool_index = 0;
355 return 0;
356 }
357
358 buf = kzalloc(sizeof(char) * DEBUG_BUF_SIZE, GFP_KERNEL);
359 if (ZERO_OR_NULL_PTR(buf)) {
360 pr_err("diag: %s, Error allocating memory\n", __func__);
361 return -ENOMEM;
362 }
363
364 buf_size = ksize(buf);
365 bytes_remaining = buf_size;
366 bytes_written = scnprintf(buf+bytes_in_buffer, bytes_remaining,
367 "%-24s\t"
368 "%-10s\t"
369 "%-5s\t"
370 "%-5s\t"
371 "%-5s\n",
372 "POOL", "HANDLE", "COUNT", "SIZE", "ITEMSIZE");
373 bytes_in_buffer += bytes_written;
374 bytes_remaining = buf_size - bytes_in_buffer;
375
376 for (i = diag_dbgfs_mempool_index; i < NUM_MEMORY_POOLS; i++) {
377 mempool = &diag_mempools[i];
378 bytes_written = scnprintf(buf+bytes_in_buffer, bytes_remaining,
379 "%-24s\t"
380 "%-10p\t"
381 "%-5d\t"
382 "%-5d\t"
383 "%-5d\n",
384 mempool->name,
385 mempool->pool,
386 mempool->count,
387 mempool->poolsize,
388 mempool->itemsize);
389 bytes_in_buffer += bytes_written;
390
391 /* Check if there is room to add another table entry */
392 bytes_remaining = buf_size - bytes_in_buffer;
393
394 if (bytes_remaining < bytes_written)
395 break;
396 }
397 diag_dbgfs_mempool_index = i+1;
398 *ppos = 0;
399 ret = simple_read_from_buffer(ubuf, count, ppos, buf, bytes_in_buffer);
400
401 kfree(buf);
402 return ret;
403}
404
405static ssize_t diag_dbgfs_read_usbinfo(struct file *file, char __user *ubuf,
406 size_t count, loff_t *ppos)
407{
408 char *buf = NULL;
409 int ret = 0;
410 int i = 0;
411 unsigned int buf_size;
412 unsigned int bytes_remaining = 0;
413 unsigned int bytes_written = 0;
414 unsigned int bytes_in_buffer = 0;
415 struct diag_usb_info *usb_info = NULL;
416
417 if (diag_dbgfs_usbinfo_index >= NUM_DIAG_USB_DEV) {
418 /* Done. Reset to prepare for future requests */
419 diag_dbgfs_usbinfo_index = 0;
420 return 0;
421 }
422
423 buf = kzalloc(sizeof(char) * DEBUG_BUF_SIZE, GFP_KERNEL);
424 if (ZERO_OR_NULL_PTR(buf)) {
425 pr_err("diag: %s, Error allocating memory\n", __func__);
426 return -ENOMEM;
427 }
428
429 buf_size = ksize(buf);
430 bytes_remaining = buf_size;
431 for (i = diag_dbgfs_usbinfo_index; i < NUM_DIAG_USB_DEV; i++) {
432 usb_info = &diag_usb[i];
433 if (!usb_info->enabled)
434 continue;
435 bytes_written = scnprintf(buf+bytes_in_buffer, bytes_remaining,
436 "id: %d\n"
437 "name: %s\n"
438 "hdl: %pK\n"
439 "connected: %d\n"
440 "diag state: %d\n"
441 "enabled: %d\n"
442 "mempool: %s\n"
443 "read pending: %d\n"
444 "read count: %lu\n"
445 "write count: %lu\n"
446 "read work pending: %d\n"
447 "read done work pending: %d\n"
448 "connect work pending: %d\n"
449 "disconnect work pending: %d\n"
450 "max size supported: %d\n\n",
451 usb_info->id,
452 usb_info->name,
453 usb_info->hdl,
454 atomic_read(&usb_info->connected),
455 atomic_read(&usb_info->diag_state),
456 usb_info->enabled,
457 DIAG_MEMPOOL_GET_NAME(usb_info->mempool),
458 atomic_read(&usb_info->read_pending),
459 usb_info->read_cnt,
460 usb_info->write_cnt,
461 work_pending(&usb_info->read_work),
462 work_pending(&usb_info->read_done_work),
463 work_pending(&usb_info->connect_work),
464 work_pending(&usb_info->disconnect_work),
465 usb_info->max_size);
466 bytes_in_buffer += bytes_written;
467
468 /* Check if there is room to add another table entry */
469 bytes_remaining = buf_size - bytes_in_buffer;
470
471 if (bytes_remaining < bytes_written)
472 break;
473 }
474 diag_dbgfs_usbinfo_index = i+1;
475 *ppos = 0;
476 ret = simple_read_from_buffer(ubuf, count, ppos, buf, bytes_in_buffer);
477
478 kfree(buf);
479 return ret;
480}
481
482static ssize_t diag_dbgfs_read_socketinfo(struct file *file, char __user *ubuf,
483 size_t count, loff_t *ppos)
484{
485 char *buf = NULL;
486 int ret = 0;
487 int i = 0;
488 int j = 0;
489 unsigned int buf_size;
490 unsigned int bytes_remaining = 0;
491 unsigned int bytes_written = 0;
492 unsigned int bytes_in_buffer = 0;
493 struct diag_socket_info *info = NULL;
494 struct diagfwd_info *fwd_ctxt = NULL;
495
496 if (diag_dbgfs_socketinfo_index >= NUM_PERIPHERALS) {
497 /* Done. Reset to prepare for future requests */
498 diag_dbgfs_socketinfo_index = 0;
499 return 0;
500 }
501
502 buf = kzalloc(sizeof(char) * DEBUG_BUF_SIZE, GFP_KERNEL);
503 if (ZERO_OR_NULL_PTR(buf)) {
504 pr_err("diag: %s, Error allocating memory\n", __func__);
505 return -ENOMEM;
506 }
507
508 buf_size = ksize(buf);
509 bytes_remaining = buf_size;
510 for (i = 0; i < NUM_TYPES; i++) {
511 for (j = 0; j < NUM_PERIPHERALS; j++) {
512 switch (i) {
513 case TYPE_DATA:
514 info = &socket_data[j];
515 break;
516 case TYPE_CNTL:
517 info = &socket_cntl[j];
518 break;
519 case TYPE_DCI:
520 info = &socket_dci[j];
521 break;
522 case TYPE_CMD:
523 info = &socket_cmd[j];
524 break;
525 case TYPE_DCI_CMD:
526 info = &socket_dci_cmd[j];
527 break;
528 default:
529 return -EINVAL;
530 }
531
532 fwd_ctxt = (struct diagfwd_info *)(info->fwd_ctxt);
533
534 bytes_written = scnprintf(buf+bytes_in_buffer,
535 bytes_remaining,
536 "name\t\t:\t%s\n"
537 "hdl\t\t:\t%pK\n"
538 "inited\t\t:\t%d\n"
539 "opened\t\t:\t%d\n"
540 "diag_state\t:\t%d\n"
541 "buf_1 busy\t:\t%d\n"
542 "buf_2 busy\t:\t%d\n"
543 "flow ctrl count\t:\t%d\n"
544 "data_ready\t:\t%d\n"
545 "init pending\t:\t%d\n"
546 "read pending\t:\t%d\n"
547 "bytes read\t:\t%lu\n"
548 "bytes written\t:\t%lu\n"
549 "fwd inited\t:\t%d\n"
550 "fwd opened\t:\t%d\n"
551 "fwd ch_open\t:\t%d\n\n",
552 info->name,
553 info->hdl,
554 info->inited,
555 atomic_read(&info->opened),
556 atomic_read(&info->diag_state),
557 (fwd_ctxt && fwd_ctxt->buf_1) ?
558 atomic_read(&fwd_ctxt->buf_1->in_busy) : -1,
559 (fwd_ctxt && fwd_ctxt->buf_2) ?
560 atomic_read(&fwd_ctxt->buf_2->in_busy) : -1,
561 atomic_read(&info->flow_cnt),
562 info->data_ready,
563 work_pending(&info->init_work),
564 work_pending(&info->read_work),
565 (fwd_ctxt) ? fwd_ctxt->read_bytes : 0,
566 (fwd_ctxt) ? fwd_ctxt->write_bytes : 0,
567 (fwd_ctxt) ? fwd_ctxt->inited : -1,
568 (fwd_ctxt) ?
569 atomic_read(&fwd_ctxt->opened) : -1,
570 (fwd_ctxt) ? fwd_ctxt->ch_open : -1);
571 bytes_in_buffer += bytes_written;
572
573 /* Check if there is room to add another table entry */
574 bytes_remaining = buf_size - bytes_in_buffer;
575
576 if (bytes_remaining < bytes_written)
577 break;
578 }
579 }
580 diag_dbgfs_socketinfo_index = i+1;
581 *ppos = 0;
582 ret = simple_read_from_buffer(ubuf, count, ppos, buf, bytes_in_buffer);
583
584 kfree(buf);
585 return ret;
586}
587
588static ssize_t diag_dbgfs_read_glinkinfo(struct file *file, char __user *ubuf,
589 size_t count, loff_t *ppos)
590{
591 char *buf = NULL;
592 int ret = 0;
593 int i = 0;
594 int j = 0;
595 unsigned int buf_size;
596 unsigned int bytes_remaining = 0;
597 unsigned int bytes_written = 0;
598 unsigned int bytes_in_buffer = 0;
599 struct diag_glink_info *info = NULL;
600 struct diagfwd_info *fwd_ctxt = NULL;
601
602 if (diag_dbgfs_glinkinfo_index >= NUM_PERIPHERALS) {
603 /* Done. Reset to prepare for future requests */
604 diag_dbgfs_socketinfo_index = 0;
605 return 0;
606 }
607
608 buf = kzalloc(sizeof(char) * DEBUG_BUF_SIZE, GFP_KERNEL);
609 if (!buf)
610 return -ENOMEM;
611
612 buf_size = ksize(buf);
613 bytes_remaining = buf_size;
614 for (i = 0; i < NUM_TYPES; i++) {
615 for (j = 0; j < NUM_PERIPHERALS; j++) {
616 switch (i) {
617 case TYPE_DATA:
618 info = &glink_data[j];
619 break;
620 case TYPE_CNTL:
621 info = &glink_cntl[j];
622 break;
623 case TYPE_DCI:
624 info = &glink_dci[j];
625 break;
626 case TYPE_CMD:
627 info = &glink_cmd[j];
628 break;
629 case TYPE_DCI_CMD:
630 info = &glink_dci_cmd[j];
631 break;
632 default:
633 return -EINVAL;
634 }
635
636 fwd_ctxt = (struct diagfwd_info *)(info->fwd_ctxt);
637
638 bytes_written = scnprintf(buf+bytes_in_buffer,
639 bytes_remaining,
640 "name\t\t:\t%s\n"
641 "hdl\t\t:\t%pK\n"
642 "inited\t\t:\t%d\n"
643 "opened\t\t:\t%d\n"
644 "diag_state\t:\t%d\n"
645 "buf_1 busy\t:\t%d\n"
646 "buf_2 busy\t:\t%d\n"
647 "tx_intent_ready\t:\t%d\n"
648 "open pending\t:\t%d\n"
649 "close pending\t:\t%d\n"
650 "read pending\t:\t%d\n"
651 "bytes read\t:\t%lu\n"
652 "bytes written\t:\t%lu\n"
653 "fwd inited\t:\t%d\n"
654 "fwd opened\t:\t%d\n"
655 "fwd ch_open\t:\t%d\n\n",
656 info->name,
657 info->hdl,
658 info->inited,
659 atomic_read(&info->opened),
660 atomic_read(&info->diag_state),
661 (fwd_ctxt && fwd_ctxt->buf_1) ?
662 atomic_read(&fwd_ctxt->buf_1->in_busy) : -1,
663 (fwd_ctxt && fwd_ctxt->buf_2) ?
664 atomic_read(&fwd_ctxt->buf_2->in_busy) : -1,
665 atomic_read(&info->tx_intent_ready),
666 work_pending(&info->open_work),
667 work_pending(&info->close_work),
668 work_pending(&info->read_work),
669 (fwd_ctxt) ? fwd_ctxt->read_bytes : 0,
670 (fwd_ctxt) ? fwd_ctxt->write_bytes : 0,
671 (fwd_ctxt) ? fwd_ctxt->inited : -1,
672 (fwd_ctxt) ?
673 atomic_read(&fwd_ctxt->opened) : -1,
674 (fwd_ctxt) ? fwd_ctxt->ch_open : -1);
675 bytes_in_buffer += bytes_written;
676
677 /* Check if there is room to add another table entry */
678 bytes_remaining = buf_size - bytes_in_buffer;
679
680 if (bytes_remaining < bytes_written)
681 break;
682 }
683 }
684 diag_dbgfs_glinkinfo_index = i+1;
685 *ppos = 0;
686 ret = simple_read_from_buffer(ubuf, count, ppos, buf, bytes_in_buffer);
687
688 kfree(buf);
689 return ret;
690}
691
692static ssize_t diag_dbgfs_write_debug(struct file *fp, const char __user *buf,
693 size_t count, loff_t *ppos)
694{
695 const int size = 10;
696 unsigned char cmd[size];
697 long value = 0;
698 int len = 0;
699
700 if (count < 1)
701 return -EINVAL;
702
703 len = (count < (size - 1)) ? count : size - 1;
704 if (copy_from_user(cmd, buf, len))
705 return -EFAULT;
706
707 cmd[len] = 0;
708 if (cmd[len-1] == '\n') {
709 cmd[len-1] = 0;
710 len--;
711 }
712
713 if (kstrtol(cmd, 10, &value))
714 return -EINVAL;
715
716 if (value < 0)
717 return -EINVAL;
718
719 diag_debug_mask = (uint16_t)value;
720 return count;
721}
722
723#ifdef CONFIG_DIAGFWD_BRIDGE_CODE
724#ifdef CONFIG_USB_QCOM_DIAG_BRIDGE
725static ssize_t diag_dbgfs_read_hsicinfo(struct file *file, char __user *ubuf,
726 size_t count, loff_t *ppos)
727{
728 char *buf = NULL;
729 int ret = 0;
730 int i = 0;
731 unsigned int buf_size;
732 unsigned int bytes_remaining = 0;
733 unsigned int bytes_written = 0;
734 unsigned int bytes_in_buffer = 0;
735 struct diag_hsic_info *hsic_info = NULL;
736
737 if (diag_dbgfs_hsicinfo_index >= NUM_DIAG_USB_DEV) {
738 /* Done. Reset to prepare for future requests */
739 diag_dbgfs_hsicinfo_index = 0;
740 return 0;
741 }
742
743 buf = kzalloc(sizeof(char) * DEBUG_BUF_SIZE, GFP_KERNEL);
744 if (ZERO_OR_NULL_PTR(buf)) {
745 pr_err("diag: %s, Error allocating memory\n", __func__);
746 return -ENOMEM;
747 }
748
749 buf_size = ksize(buf);
750 bytes_remaining = buf_size;
751 for (i = diag_dbgfs_hsicinfo_index; i < NUM_HSIC_DEV; i++) {
752 hsic_info = &diag_hsic[i];
753 if (!hsic_info->enabled)
754 continue;
755 bytes_written = scnprintf(buf+bytes_in_buffer, bytes_remaining,
756 "id: %d\n"
757 "name: %s\n"
758 "bridge index: %s\n"
759 "opened: %d\n"
760 "enabled: %d\n"
761 "suspended: %d\n"
762 "mempool: %s\n"
763 "read work pending: %d\n"
764 "open work pending: %d\n"
765 "close work pending: %d\n\n",
766 hsic_info->id,
767 hsic_info->name,
768 DIAG_BRIDGE_GET_NAME(hsic_info->dev_id),
769 hsic_info->opened,
770 hsic_info->enabled,
771 hsic_info->suspended,
772 DIAG_MEMPOOL_GET_NAME(hsic_info->mempool),
773 work_pending(&hsic_info->read_work),
774 work_pending(&hsic_info->open_work),
775 work_pending(&hsic_info->close_work));
776 bytes_in_buffer += bytes_written;
777
778 /* Check if there is room to add another table entry */
779 bytes_remaining = buf_size - bytes_in_buffer;
780
781 if (bytes_remaining < bytes_written)
782 break;
783 }
784 diag_dbgfs_hsicinfo_index = i+1;
785 *ppos = 0;
786 ret = simple_read_from_buffer(ubuf, count, ppos, buf, bytes_in_buffer);
787
788 kfree(buf);
789 return ret;
790}
791
792const struct file_operations diag_dbgfs_hsicinfo_ops = {
793 .read = diag_dbgfs_read_hsicinfo,
794};
795#endif
796#ifdef CONFIG_MSM_MHI
797static ssize_t diag_dbgfs_read_mhiinfo(struct file *file, char __user *ubuf,
798 size_t count, loff_t *ppos)
799{
800 char *buf = NULL;
801 int ret = 0;
802 int i = 0;
803 unsigned int buf_size;
804 unsigned int bytes_remaining = 0;
805 unsigned int bytes_written = 0;
806 unsigned int bytes_in_buffer = 0;
807 struct diag_mhi_info *mhi_info = NULL;
808
809 if (diag_dbgfs_mhiinfo_index >= NUM_MHI_DEV) {
810 /* Done. Reset to prepare for future requests */
811 diag_dbgfs_mhiinfo_index = 0;
812 return 0;
813 }
814
815 buf = kzalloc(sizeof(char) * DEBUG_BUF_SIZE, GFP_KERNEL);
816 if (ZERO_OR_NULL_PTR(buf)) {
817 pr_err("diag: %s, Error allocating memory\n", __func__);
818 return -ENOMEM;
819 }
820
821 buf_size = ksize(buf);
822 bytes_remaining = buf_size;
823 for (i = diag_dbgfs_mhiinfo_index; i < NUM_MHI_DEV; i++) {
824 mhi_info = &diag_mhi[i];
825 bytes_written = scnprintf(buf+bytes_in_buffer, bytes_remaining,
826 "id: %d\n"
827 "name: %s\n"
828 "bridge index: %s\n"
829 "mempool: %s\n"
830 "read ch opened: %d\n"
831 "read ch hdl: %pK\n"
832 "write ch opened: %d\n"
833 "write ch hdl: %pK\n"
834 "read work pending: %d\n"
835 "read done work pending: %d\n"
836 "open work pending: %d\n"
837 "close work pending: %d\n\n",
838 mhi_info->id,
839 mhi_info->name,
840 DIAG_BRIDGE_GET_NAME(mhi_info->dev_id),
841 DIAG_MEMPOOL_GET_NAME(mhi_info->mempool),
842 atomic_read(&mhi_info->read_ch.opened),
843 mhi_info->read_ch.hdl,
844 atomic_read(&mhi_info->write_ch.opened),
845 mhi_info->write_ch.hdl,
846 work_pending(&mhi_info->read_work),
847 work_pending(&mhi_info->read_done_work),
848 work_pending(&mhi_info->open_work),
849 work_pending(&mhi_info->close_work));
850 bytes_in_buffer += bytes_written;
851
852 /* Check if there is room to add another table entry */
853 bytes_remaining = buf_size - bytes_in_buffer;
854
855 if (bytes_remaining < bytes_written)
856 break;
857 }
858 diag_dbgfs_mhiinfo_index = i+1;
859 *ppos = 0;
860 ret = simple_read_from_buffer(ubuf, count, ppos, buf, bytes_in_buffer);
861
862 kfree(buf);
863 return ret;
864}
865
866
867const struct file_operations diag_dbgfs_mhiinfo_ops = {
868 .read = diag_dbgfs_read_mhiinfo,
869};
870
871#endif
872static ssize_t diag_dbgfs_read_bridge(struct file *file, char __user *ubuf,
873 size_t count, loff_t *ppos)
874{
875 char *buf = NULL;
876 int ret = 0;
877 int i = 0;
878 unsigned int buf_size;
879 unsigned int bytes_remaining = 0;
880 unsigned int bytes_written = 0;
881 unsigned int bytes_in_buffer = 0;
882 struct diagfwd_bridge_info *info = NULL;
883
884 if (diag_dbgfs_bridgeinfo_index >= NUM_DIAG_USB_DEV) {
885 /* Done. Reset to prepare for future requests */
886 diag_dbgfs_bridgeinfo_index = 0;
887 return 0;
888 }
889
890 buf = kzalloc(sizeof(char) * DEBUG_BUF_SIZE, GFP_KERNEL);
891 if (ZERO_OR_NULL_PTR(buf)) {
892 pr_err("diag: %s, Error allocating memory\n", __func__);
893 return -ENOMEM;
894 }
895
896 buf_size = ksize(buf);
897 bytes_remaining = buf_size;
898 for (i = diag_dbgfs_bridgeinfo_index; i < NUM_REMOTE_DEV; i++) {
899 info = &bridge_info[i];
900 if (!info->inited)
901 continue;
902 bytes_written = scnprintf(buf+bytes_in_buffer, bytes_remaining,
903 "id: %d\n"
904 "name: %s\n"
905 "type: %d\n"
906 "inited: %d\n"
907 "ctxt: %d\n"
908 "dev_ops: %pK\n"
909 "dci_read_buf: %pK\n"
910 "dci_read_ptr: %pK\n"
911 "dci_read_len: %d\n\n",
912 info->id,
913 info->name,
914 info->type,
915 info->inited,
916 info->ctxt,
917 info->dev_ops,
918 info->dci_read_buf,
919 info->dci_read_ptr,
920 info->dci_read_len);
921 bytes_in_buffer += bytes_written;
922
923 /* Check if there is room to add another table entry */
924 bytes_remaining = buf_size - bytes_in_buffer;
925
926 if (bytes_remaining < bytes_written)
927 break;
928 }
929 diag_dbgfs_bridgeinfo_index = i+1;
930 *ppos = 0;
931 ret = simple_read_from_buffer(ubuf, count, ppos, buf, bytes_in_buffer);
932
933 kfree(buf);
934 return ret;
935}
936
937const struct file_operations diag_dbgfs_bridge_ops = {
938 .read = diag_dbgfs_read_bridge,
939};
940
941#endif
942
943const struct file_operations diag_dbgfs_status_ops = {
944 .read = diag_dbgfs_read_status,
945};
946
947const struct file_operations diag_dbgfs_socketinfo_ops = {
948 .read = diag_dbgfs_read_socketinfo,
949};
950
951const struct file_operations diag_dbgfs_glinkinfo_ops = {
952 .read = diag_dbgfs_read_glinkinfo,
953};
954
955const struct file_operations diag_dbgfs_table_ops = {
956 .read = diag_dbgfs_read_table,
957};
958
959const struct file_operations diag_dbgfs_mempool_ops = {
960 .read = diag_dbgfs_read_mempool,
961};
962
963const struct file_operations diag_dbgfs_usbinfo_ops = {
964 .read = diag_dbgfs_read_usbinfo,
965};
966
967const struct file_operations diag_dbgfs_dcistats_ops = {
968 .read = diag_dbgfs_read_dcistats,
969};
970
971const struct file_operations diag_dbgfs_power_ops = {
972 .read = diag_dbgfs_read_power,
973};
974
975const struct file_operations diag_dbgfs_debug_ops = {
976 .write = diag_dbgfs_write_debug
977};
978
979int diag_debugfs_init(void)
980{
981 struct dentry *entry = NULL;
982
983 diag_dbgfs_dent = debugfs_create_dir("diag", 0);
984 if (IS_ERR(diag_dbgfs_dent))
985 return -ENOMEM;
986
987 entry = debugfs_create_file("status", 0444, diag_dbgfs_dent, 0,
988 &diag_dbgfs_status_ops);
989 if (!entry)
990 goto err;
991
992 entry = debugfs_create_file("socketinfo", 0444, diag_dbgfs_dent, 0,
993 &diag_dbgfs_socketinfo_ops);
994 if (!entry)
995 goto err;
996
997 entry = debugfs_create_file("glinkinfo", 0444, diag_dbgfs_dent, 0,
998 &diag_dbgfs_glinkinfo_ops);
999 if (!entry)
1000 goto err;
1001
1002 entry = debugfs_create_file("table", 0444, diag_dbgfs_dent, 0,
1003 &diag_dbgfs_table_ops);
1004 if (!entry)
1005 goto err;
1006
1007 entry = debugfs_create_file("mempool", 0444, diag_dbgfs_dent, 0,
1008 &diag_dbgfs_mempool_ops);
1009 if (!entry)
1010 goto err;
1011
1012 entry = debugfs_create_file("usbinfo", 0444, diag_dbgfs_dent, 0,
1013 &diag_dbgfs_usbinfo_ops);
1014 if (!entry)
1015 goto err;
1016
1017 entry = debugfs_create_file("dci_stats", 0444, diag_dbgfs_dent, 0,
1018 &diag_dbgfs_dcistats_ops);
1019 if (!entry)
1020 goto err;
1021
1022 entry = debugfs_create_file("power", 0444, diag_dbgfs_dent, 0,
1023 &diag_dbgfs_power_ops);
1024 if (!entry)
1025 goto err;
1026
1027 entry = debugfs_create_file("debug", 0444, diag_dbgfs_dent, 0,
1028 &diag_dbgfs_debug_ops);
1029 if (!entry)
1030 goto err;
1031
1032#ifdef CONFIG_DIAGFWD_BRIDGE_CODE
1033 entry = debugfs_create_file("bridge", 0444, diag_dbgfs_dent, 0,
1034 &diag_dbgfs_bridge_ops);
1035 if (!entry)
1036 goto err;
1037#ifdef CONFIG_USB_QCOM_DIAG_BRIDGE
1038 entry = debugfs_create_file("hsicinfo", 0444, diag_dbgfs_dent, 0,
1039 &diag_dbgfs_hsicinfo_ops);
1040 if (!entry)
1041 goto err;
1042#endif
1043#ifdef CONFIG_MSM_MHI
1044 entry = debugfs_create_file("mhiinfo", 0444, diag_dbgfs_dent, 0,
1045 &diag_dbgfs_mhiinfo_ops);
1046 if (!entry)
1047 goto err;
1048#endif
1049#endif
1050 diag_dbgfs_table_index = 0;
1051 diag_dbgfs_mempool_index = 0;
1052 diag_dbgfs_usbinfo_index = 0;
1053 diag_dbgfs_socketinfo_index = 0;
1054 diag_dbgfs_hsicinfo_index = 0;
1055 diag_dbgfs_bridgeinfo_index = 0;
1056 diag_dbgfs_mhiinfo_index = 0;
1057 diag_dbgfs_finished = 0;
1058 diag_dbgfs_dci_data_index = 0;
1059 diag_dbgfs_dci_finished = 0;
1060
1061 /* DCI related structures */
1062 dci_traffic = kzalloc(sizeof(struct diag_dci_data_info) *
1063 DIAG_DCI_DEBUG_CNT, GFP_KERNEL);
1064 if (ZERO_OR_NULL_PTR(dci_traffic))
1065 pr_warn("diag: could not allocate memory for dci debug info\n");
1066
1067 mutex_init(&dci_stat_mutex);
Sreelakshmi Gownipalli13e83672017-10-09 12:59:56 -07001068 mutex_init(&diag_dci_dbgfs_mutex);
Sreelakshmi Gownipallicb8893d2016-10-19 16:02:34 -07001069 return 0;
1070err:
1071 kfree(dci_traffic);
1072 debugfs_remove_recursive(diag_dbgfs_dent);
1073 return -ENOMEM;
1074}
1075
1076void diag_debugfs_cleanup(void)
1077{
1078 debugfs_remove_recursive(diag_dbgfs_dent);
1079 diag_dbgfs_dent = NULL;
1080 kfree(dci_traffic);
1081 mutex_destroy(&dci_stat_mutex);
Sreelakshmi Gownipalli13e83672017-10-09 12:59:56 -07001082 mutex_destroy(&diag_dci_dbgfs_mutex);
Sreelakshmi Gownipallicb8893d2016-10-19 16:02:34 -07001083}
1084#else
1085int diag_debugfs_init(void) { return 0; }
1086void diag_debugfs_cleanup(void) { }
1087#endif