Dixon Peterson | d6a20a9 | 2012-09-27 15:58:50 -0700 | [diff] [blame] | 1 | /* 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 Jain | 737fca7 | 2012-11-14 21:53:43 -0800 | [diff] [blame] | 19 | #include "diagfwd_bridge.h" |
Dixon Peterson | d6a20a9 | 2012-09-27 15:58:50 -0700 | [diff] [blame] | 20 | |
| 21 | #define DEBUG_BUF_SIZE 4096 |
| 22 | static struct dentry *diag_dbgfs_dent; |
| 23 | static int diag_dbgfs_table_index; |
| 24 | |
| 25 | static 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 Peterson | 66fb11b | 2012-12-04 20:30:54 -0800 | [diff] [blame^] | 51 | "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 Peterson | d6a20a9 | 2012-09-27 15:58:50 -0700 | [diff] [blame] | 58 | "logging_mode: %d\n", |
Dixon Peterson | 66fb11b | 2012-12-04 20:30:54 -0800 | [diff] [blame^] | 59 | (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 Peterson | d6a20a9 | 2012-09-27 15:58:50 -0700 | [diff] [blame] | 66 | 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 Peterson | 66fb11b | 2012-12-04 20:30:54 -0800 | [diff] [blame^] | 72 | 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 Peterson | d6a20a9 | 2012-09-27 15:58:50 -0700 | [diff] [blame] | 79 | 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 | |
| 92 | static 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 Peterson | 66fb11b | 2012-12-04 20:30:54 -0800 | [diff] [blame^] | 107 | "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 Peterson | d6a20a9 | 2012-09-27 15:58:50 -0700 | [diff] [blame] | 121 | work_pending(&(driver->diag_drain_work)), |
Dixon Peterson | 66fb11b | 2012-12-04 20:30:54 -0800 | [diff] [blame^] | 122 | 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 Peterson | d6a20a9 | 2012-09-27 15:58:50 -0700 | [diff] [blame] | 150 | |
| 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 | |
| 164 | static 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 Peterson | 66fb11b | 2012-12-04 20:30:54 -0800 | [diff] [blame^] | 212 | diag_dbgfs_table_index = i+1; |
Dixon Peterson | d6a20a9 | 2012-09-27 15:58:50 -0700 | [diff] [blame] | 213 | |
| 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 Jain | 737fca7 | 2012-11-14 21:53:43 -0800 | [diff] [blame] | 221 | #ifdef CONFIG_DIAGFWD_BRIDGE_CODE |
| 222 | static ssize_t diag_dbgfs_read_bridge(struct file *file, char __user *ubuf, |
Dixon Peterson | d6a20a9 | 2012-09-27 15:58:50 -0700 | [diff] [blame] | 223 | 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 Jain | 737fca7 | 2012-11-14 21:53:43 -0800 | [diff] [blame] | 246 | "HSIC write_len: %d\n" |
Dixon Peterson | d6a20a9 | 2012-09-27 15:58:50 -0700 | [diff] [blame] | 247 | "num_hsic_buf_tbl_entries: %d\n" |
Shalabh Jain | 737fca7 | 2012-11-14 21:53:43 -0800 | [diff] [blame] | 248 | "HSIC usb_connected: %d\n" |
| 249 | "HSIC diag_read_work: %d\n" |
Dixon Peterson | d6a20a9 | 2012-09-27 15:58:50 -0700 | [diff] [blame] | 250 | "diag_read_hsic_work: %d\n" |
| 251 | "diag_disconnect_work: %d\n" |
Shalabh Jain | 737fca7 | 2012-11-14 21:53:43 -0800 | [diff] [blame] | 252 | "diag_usb_read_complete_work: %d\n" |
Dixon Peterson | 66fb11b | 2012-12-04 20:30:54 -0800 | [diff] [blame^] | 253 | "smux ch: %d\n" |
| 254 | "smux enabled %d\n" |
| 255 | "smux in busy %d\n" |
| 256 | "smux connected %d\n", |
Dixon Peterson | d6a20a9 | 2012-09-27 15:58:50 -0700 | [diff] [blame] | 257 | 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 Jain | 737fca7 | 2012-11-14 21:53:43 -0800 | [diff] [blame] | 268 | diag_bridge[HSIC].write_len, |
Dixon Peterson | d6a20a9 | 2012-09-27 15:58:50 -0700 | [diff] [blame] | 269 | driver->num_hsic_buf_tbl_entries, |
Shalabh Jain | 737fca7 | 2012-11-14 21:53:43 -0800 | [diff] [blame] | 270 | diag_bridge[HSIC].usb_connected, |
| 271 | work_pending(&(diag_bridge[HSIC].diag_read_work)), |
Dixon Peterson | d6a20a9 | 2012-09-27 15:58:50 -0700 | [diff] [blame] | 272 | work_pending(&(driver->diag_read_hsic_work)), |
| 273 | work_pending(&(driver->diag_disconnect_work)), |
Shalabh Jain | 737fca7 | 2012-11-14 21:53:43 -0800 | [diff] [blame] | 274 | 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 Peterson | d6a20a9 | 2012-09-27 15:58:50 -0700 | [diff] [blame] | 279 | |
| 280 | ret = simple_read_from_buffer(ubuf, count, ppos, buf, ret); |
| 281 | |
| 282 | kfree(buf); |
| 283 | return ret; |
| 284 | } |
| 285 | |
Shalabh Jain | 737fca7 | 2012-11-14 21:53:43 -0800 | [diff] [blame] | 286 | const struct file_operations diag_dbgfs_bridge_ops = { |
| 287 | .read = diag_dbgfs_read_bridge, |
Dixon Peterson | d6a20a9 | 2012-09-27 15:58:50 -0700 | [diff] [blame] | 288 | }; |
| 289 | #endif |
| 290 | |
| 291 | const struct file_operations diag_dbgfs_status_ops = { |
| 292 | .read = diag_dbgfs_read_status, |
| 293 | }; |
| 294 | |
| 295 | const struct file_operations diag_dbgfs_table_ops = { |
| 296 | .read = diag_dbgfs_read_table, |
| 297 | }; |
| 298 | |
| 299 | const struct file_operations diag_dbgfs_workpending_ops = { |
| 300 | .read = diag_dbgfs_read_workpending, |
| 301 | }; |
| 302 | |
| 303 | void 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 Jain | 737fca7 | 2012-11-14 21:53:43 -0800 | [diff] [blame] | 318 | #ifdef CONFIG_DIAGFWD_BRIDGE_CODE |
| 319 | debugfs_create_file("bridge", 0444, diag_dbgfs_dent, 0, |
| 320 | &diag_dbgfs_bridge_ops); |
Dixon Peterson | d6a20a9 | 2012-09-27 15:58:50 -0700 | [diff] [blame] | 321 | #endif |
| 322 | |
| 323 | diag_dbgfs_table_index = 0; |
| 324 | } |
| 325 | |
| 326 | void 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 |
| 334 | void diag_debugfs_init(void) { } |
| 335 | void diag_debugfs_cleanup(void) { } |
| 336 | #endif |