blob: 8badc55e4d85498b0c5401ec53396df3bf6adfb8 [file] [log] [blame]
Dixon Petersond6a20a92012-09-27 15:58:50 -07001/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
2 *
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 "diagchar.h"
18#include "diagfwd.h"
Shalabh Jain737fca72012-11-14 21:53:43 -080019#include "diagfwd_bridge.h"
Dixon Petersond6a20a92012-09-27 15:58:50 -070020
21#define DEBUG_BUF_SIZE 4096
22static struct dentry *diag_dbgfs_dent;
23static int diag_dbgfs_table_index;
24
25static ssize_t diag_dbgfs_read_status(struct file *file, char __user *ubuf,
26 size_t count, loff_t *ppos)
27{
28 char *buf;
29 int ret;
30
31 buf = kzalloc(sizeof(char) * DEBUG_BUF_SIZE, GFP_KERNEL);
32 if (!buf) {
33 pr_err("diag: %s, Error allocating memory\n", __func__);
34 return -ENOMEM;
35 }
36
37 ret = scnprintf(buf, DEBUG_BUF_SIZE,
38 "modem ch: 0x%x\n"
39 "lpass ch: 0x%x\n"
40 "riva ch: 0x%x\n"
41 "dci ch: 0x%x\n"
42 "modem cntl_ch: 0x%x\n"
43 "lpass cntl_ch: 0x%x\n"
44 "riva cntl_ch: 0x%x\n"
45 "CPU Tools id: %d\n"
46 "Apps only: %d\n"
47 "Apps master: %d\n"
48 "Check Polling Response: %d\n"
49 "polling_reg_flag: %d\n"
50 "uses device tree: %d\n"
Dixon Peterson66fb11b2012-12-04 20:30:54 -080051 "Modem in_busy_1: %d\n"
52 "Modem in_busy_2: %d\n"
53 "LPASS in_busy_1: %d\n"
54 "LPASS in_busy_2: %d\n"
55 "RIVA in_busy_1: %d\n"
56 "RIVA in_busy_2: %d\n"
57 "DCI Modem in_busy_1: %d\n"
Dixon Petersond6a20a92012-09-27 15:58:50 -070058 "logging_mode: %d\n",
Dixon Peterson66fb11b2012-12-04 20:30:54 -080059 (unsigned int)driver->smd_data[SMD_MODEM_INDEX].ch,
60 (unsigned int)driver->smd_data[SMD_LPASS_INDEX].ch,
61 (unsigned int)driver->smd_data[SMD_WCNSS_INDEX].ch,
62 (unsigned int)driver->smd_dci[SMD_MODEM_INDEX].ch,
63 (unsigned int)driver->smd_cntl[SMD_MODEM_INDEX].ch,
64 (unsigned int)driver->smd_cntl[SMD_LPASS_INDEX].ch,
65 (unsigned int)driver->smd_cntl[SMD_WCNSS_INDEX].ch,
Dixon Petersond6a20a92012-09-27 15:58:50 -070066 chk_config_get_id(),
67 chk_apps_only(),
68 chk_apps_master(),
69 chk_polling_response(),
70 driver->polling_reg_flag,
71 driver->use_device_tree,
Dixon Peterson66fb11b2012-12-04 20:30:54 -080072 driver->smd_data[SMD_MODEM_INDEX].in_busy_1,
73 driver->smd_data[SMD_MODEM_INDEX].in_busy_2,
74 driver->smd_data[SMD_LPASS_INDEX].in_busy_1,
75 driver->smd_data[SMD_LPASS_INDEX].in_busy_2,
76 driver->smd_data[SMD_WCNSS_INDEX].in_busy_1,
77 driver->smd_data[SMD_WCNSS_INDEX].in_busy_2,
78 driver->smd_dci[SMD_MODEM_INDEX].in_busy_1,
Dixon Petersond6a20a92012-09-27 15:58:50 -070079 driver->logging_mode);
80
81#ifdef CONFIG_DIAG_OVER_USB
82 ret += scnprintf(buf+ret, DEBUG_BUF_SIZE,
83 "usb_connected: %d\n",
84 driver->usb_connected);
85#endif
86 ret = simple_read_from_buffer(ubuf, count, ppos, buf, ret);
87
88 kfree(buf);
89 return ret;
90}
91
92static ssize_t diag_dbgfs_read_workpending(struct file *file,
93 char __user *ubuf, size_t count, loff_t *ppos)
94{
95 char *buf;
96 int ret;
97
98 buf = kzalloc(sizeof(char) * DEBUG_BUF_SIZE, GFP_KERNEL);
99 if (!buf) {
100 pr_err("diag: %s, Error allocating memory\n", __func__);
101 return -ENOMEM;
102 }
103
104 ret = scnprintf(buf, DEBUG_BUF_SIZE,
105 "Pending status for work_stucts:\n"
106 "diag_drain_work: %d\n"
Dixon Peterson66fb11b2012-12-04 20:30:54 -0800107 "Modem data diag_read_smd_work: %d\n"
108 "LPASS data diag_read_smd_work: %d\n"
109 "RIVA data diag_read_smd_work: %d\n"
110 "Modem cntl diag_read_smd_work: %d\n"
111 "LPASS cntl diag_read_smd_work: %d\n"
112 "RIVA cntl diag_read_smd_work: %d\n"
113 "Modem dci diag_read_smd_work: %d\n"
114 "Modem data diag_notify_update_smd_work: %d\n"
115 "LPASS data diag_notify_update_smd_work: %d\n"
116 "RIVA data diag_notify_update_smd_work: %d\n"
117 "Modem cntl diag_notify_update_smd_work: %d\n"
118 "LPASS cntl diag_notify_update_smd_work: %d\n"
119 "RIVA cntl diag_notify_update_smd_work: %d\n"
120 "Modem dci diag_notify_update_smd_work: %d\n",
Dixon Petersond6a20a92012-09-27 15:58:50 -0700121 work_pending(&(driver->diag_drain_work)),
Dixon Peterson66fb11b2012-12-04 20:30:54 -0800122 work_pending(&(driver->smd_data[SMD_MODEM_INDEX].
123 diag_read_smd_work)),
124 work_pending(&(driver->smd_data[SMD_LPASS_INDEX].
125 diag_read_smd_work)),
126 work_pending(&(driver->smd_data[SMD_WCNSS_INDEX].
127 diag_read_smd_work)),
128 work_pending(&(driver->smd_cntl[SMD_MODEM_INDEX].
129 diag_read_smd_work)),
130 work_pending(&(driver->smd_cntl[SMD_LPASS_INDEX].
131 diag_read_smd_work)),
132 work_pending(&(driver->smd_cntl[SMD_WCNSS_INDEX].
133 diag_read_smd_work)),
134 work_pending(&(driver->smd_dci[SMD_MODEM_INDEX].
135 diag_read_smd_work)),
136 work_pending(&(driver->smd_data[SMD_MODEM_INDEX].
137 diag_notify_update_smd_work)),
138 work_pending(&(driver->smd_data[SMD_LPASS_INDEX].
139 diag_notify_update_smd_work)),
140 work_pending(&(driver->smd_data[SMD_WCNSS_INDEX].
141 diag_notify_update_smd_work)),
142 work_pending(&(driver->smd_cntl[SMD_MODEM_INDEX].
143 diag_notify_update_smd_work)),
144 work_pending(&(driver->smd_cntl[SMD_LPASS_INDEX].
145 diag_notify_update_smd_work)),
146 work_pending(&(driver->smd_cntl[SMD_WCNSS_INDEX].
147 diag_notify_update_smd_work)),
148 work_pending(&(driver->smd_dci[SMD_MODEM_INDEX].
149 diag_notify_update_smd_work)));
Dixon Petersond6a20a92012-09-27 15:58:50 -0700150
151#ifdef CONFIG_DIAG_OVER_USB
152 ret += scnprintf(buf+ret, DEBUG_BUF_SIZE,
153 "diag_proc_hdlc_work: %d\n"
154 "diag_read_work: %d\n",
155 work_pending(&(driver->diag_proc_hdlc_work)),
156 work_pending(&(driver->diag_read_work)));
157#endif
158 ret = simple_read_from_buffer(ubuf, count, ppos, buf, ret);
159
160 kfree(buf);
161 return ret;
162}
163
164static ssize_t diag_dbgfs_read_table(struct file *file, char __user *ubuf,
165 size_t count, loff_t *ppos)
166{
167 char *buf;
168 int ret = 0;
169 int i;
170 int bytes_remaining;
171 int bytes_in_buffer = 0;
172 int bytes_written;
173 int buf_size = (DEBUG_BUF_SIZE < count) ? DEBUG_BUF_SIZE : count;
174
175 if (diag_dbgfs_table_index >= diag_max_reg) {
176 /* Done. Reset to prepare for future requests */
177 diag_dbgfs_table_index = 0;
178 return 0;
179 }
180
181 buf = kzalloc(sizeof(char) * buf_size, GFP_KERNEL);
182 if (!buf) {
183 pr_err("diag: %s, Error allocating memory\n", __func__);
184 return -ENOMEM;
185 }
186
187 bytes_remaining = buf_size;
188 for (i = diag_dbgfs_table_index; i < diag_max_reg; i++) {
189 /* Do not process empty entries in the table */
190 if (driver->table[i].process_id == 0)
191 continue;
192
193 bytes_written = scnprintf(buf+bytes_in_buffer, bytes_remaining,
194 "i: %3d, cmd_code: %4x, subsys_id: %4x, "
195 "client: %2d, cmd_code_lo: %4x, "
196 "cmd_code_hi: %4x, process_id: %5d\n",
197 i,
198 driver->table[i].cmd_code,
199 driver->table[i].subsys_id,
200 driver->table[i].client_id,
201 driver->table[i].cmd_code_lo,
202 driver->table[i].cmd_code_hi,
203 driver->table[i].process_id);
204
205 bytes_in_buffer += bytes_written;
206
207 /* Check if there is room to add another table entry */
208 bytes_remaining = buf_size - bytes_in_buffer;
209 if (bytes_remaining < bytes_written)
210 break;
211 }
Dixon Peterson66fb11b2012-12-04 20:30:54 -0800212 diag_dbgfs_table_index = i+1;
Dixon Petersond6a20a92012-09-27 15:58:50 -0700213
214 *ppos = 0;
215 ret = simple_read_from_buffer(ubuf, count, ppos, buf, bytes_in_buffer);
216
217 kfree(buf);
218 return ret;
219}
220
Shalabh Jain737fca72012-11-14 21:53:43 -0800221#ifdef CONFIG_DIAGFWD_BRIDGE_CODE
222static ssize_t diag_dbgfs_read_bridge(struct file *file, char __user *ubuf,
Dixon Petersond6a20a92012-09-27 15:58:50 -0700223 size_t count, loff_t *ppos)
224{
225 char *buf;
226 int ret;
227
228 buf = kzalloc(sizeof(char) * DEBUG_BUF_SIZE, GFP_KERNEL);
229 if (!buf) {
230 pr_err("diag: %s, Error allocating memory\n", __func__);
231 return -ENOMEM;
232 }
233
234 ret = scnprintf(buf, DEBUG_BUF_SIZE,
235 "hsic ch: %d\n"
236 "hsic_inited: %d\n"
237 "hsic enabled: %d\n"
238 "hsic_opened: %d\n"
239 "hsic_suspend: %d\n"
240 "in_busy_hsic_read_on_device: %d\n"
241 "in_busy_hsic_write: %d\n"
242 "count_hsic_pool: %d\n"
243 "count_hsic_write_pool: %d\n"
244 "diag_hsic_pool: %x\n"
245 "diag_hsic_write_pool: %x\n"
Shalabh Jain737fca72012-11-14 21:53:43 -0800246 "HSIC write_len: %d\n"
Dixon Petersond6a20a92012-09-27 15:58:50 -0700247 "num_hsic_buf_tbl_entries: %d\n"
Shalabh Jain737fca72012-11-14 21:53:43 -0800248 "HSIC usb_connected: %d\n"
249 "HSIC diag_read_work: %d\n"
Dixon Petersond6a20a92012-09-27 15:58:50 -0700250 "diag_read_hsic_work: %d\n"
251 "diag_disconnect_work: %d\n"
Shalabh Jain737fca72012-11-14 21:53:43 -0800252 "diag_usb_read_complete_work: %d\n"
Dixon Peterson66fb11b2012-12-04 20:30:54 -0800253 "smux ch: %d\n"
254 "smux enabled %d\n"
255 "smux in busy %d\n"
256 "smux connected %d\n",
Dixon Petersond6a20a92012-09-27 15:58:50 -0700257 driver->hsic_ch,
258 driver->hsic_inited,
259 driver->hsic_device_enabled,
260 driver->hsic_device_opened,
261 driver->hsic_suspend,
262 driver->in_busy_hsic_read_on_device,
263 driver->in_busy_hsic_write,
264 driver->count_hsic_pool,
265 driver->count_hsic_write_pool,
266 (unsigned int)driver->diag_hsic_pool,
267 (unsigned int)driver->diag_hsic_write_pool,
Shalabh Jain737fca72012-11-14 21:53:43 -0800268 diag_bridge[HSIC].write_len,
Dixon Petersond6a20a92012-09-27 15:58:50 -0700269 driver->num_hsic_buf_tbl_entries,
Shalabh Jain737fca72012-11-14 21:53:43 -0800270 diag_bridge[HSIC].usb_connected,
271 work_pending(&(diag_bridge[HSIC].diag_read_work)),
Dixon Petersond6a20a92012-09-27 15:58:50 -0700272 work_pending(&(driver->diag_read_hsic_work)),
273 work_pending(&(driver->diag_disconnect_work)),
Shalabh Jain737fca72012-11-14 21:53:43 -0800274 work_pending(&(diag_bridge[HSIC].usb_read_complete_work)),
275 driver->lcid,
276 driver->diag_smux_enabled,
277 driver->in_busy_smux,
278 driver->smux_connected);
Dixon Petersond6a20a92012-09-27 15:58:50 -0700279
280 ret = simple_read_from_buffer(ubuf, count, ppos, buf, ret);
281
282 kfree(buf);
283 return ret;
284}
285
Shalabh Jain737fca72012-11-14 21:53:43 -0800286const struct file_operations diag_dbgfs_bridge_ops = {
287 .read = diag_dbgfs_read_bridge,
Dixon Petersond6a20a92012-09-27 15:58:50 -0700288};
289#endif
290
291const struct file_operations diag_dbgfs_status_ops = {
292 .read = diag_dbgfs_read_status,
293};
294
295const struct file_operations diag_dbgfs_table_ops = {
296 .read = diag_dbgfs_read_table,
297};
298
299const struct file_operations diag_dbgfs_workpending_ops = {
300 .read = diag_dbgfs_read_workpending,
301};
302
303void diag_debugfs_init(void)
304{
305 diag_dbgfs_dent = debugfs_create_dir("diag", 0);
306 if (IS_ERR(diag_dbgfs_dent))
307 return;
308
309 debugfs_create_file("status", 0444, diag_dbgfs_dent, 0,
310 &diag_dbgfs_status_ops);
311
312 debugfs_create_file("table", 0444, diag_dbgfs_dent, 0,
313 &diag_dbgfs_table_ops);
314
315 debugfs_create_file("work_pending", 0444, diag_dbgfs_dent, 0,
316 &diag_dbgfs_workpending_ops);
317
Shalabh Jain737fca72012-11-14 21:53:43 -0800318#ifdef CONFIG_DIAGFWD_BRIDGE_CODE
319 debugfs_create_file("bridge", 0444, diag_dbgfs_dent, 0,
320 &diag_dbgfs_bridge_ops);
Dixon Petersond6a20a92012-09-27 15:58:50 -0700321#endif
322
323 diag_dbgfs_table_index = 0;
324}
325
326void diag_debugfs_cleanup(void)
327{
328 if (diag_dbgfs_dent) {
329 debugfs_remove_recursive(diag_dbgfs_dent);
330 diag_dbgfs_dent = NULL;
331 }
332}
333#else
334void diag_debugfs_init(void) { }
335void diag_debugfs_cleanup(void) { }
336#endif