1 /*
2 * Copyright (C) 2018 Knowles Electronics
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <stdio.h>
18 #include <errno.h>
19 #include <stdlib.h>
20 #include <sys/types.h>
21 #include <sys/stat.h>
22 #include <fcntl.h>
23 #include <string.h>
24 #include <getopt.h>
25 #include <stdbool.h>
26 #include <arpa/inet.h>
27 #include <limits.h>
28 #include <unistd.h>
29 #include <linux/mfd/adnc/iaxxx-debug-intf.h>
30
31 #define LOG_TAG "ia_dump_registers"
32
33 #include <log/log.h>
34
35 #define DEBUG_DEV "/dev/debug0"
36 #define GETOPT_HELP_CHAR (CHAR_MIN - 2)
37 #define REG_ADDR "Register Address"
38 #define REG_VAL "Register Value"
39 #define SRB_REG "SRB Registers"
40 #define ARB_REG "ARB Registers"
41 #define REG_OUT_FILE "/data/data/reg_dump.txt"
42 #define CIRC_OUT_FILE_CM4 "/data/data/circular_buf_cm4.bin"
43 #define CIRC_OUT_FILE_DMX "/data/data/circular_buf_dmx.bin"
44 #define CIRC_OUT_FILE_HMD "/data/data/circular_buf_hmd.bin"
45
46 //#define ENABLE_DEBUG_PRINTS
47
48 static struct option const long_options[] = {
49 {"stdout", no_argument, NULL, 'o'},
50 {"regdump", no_argument, NULL, 'r'},
51 {"circbuf", no_argument, NULL, 'c'},
52 {"help", no_argument, NULL, GETOPT_HELP_CHAR},
53 {NULL, 0, NULL, 0}
54 };
55
usage(void)56 void usage(void)
57 {
58 fputs("\
59 USAGE -\n\
60 -------\n\
61 1) dump_debug_info -c\n\
62 2) dump_debug_info -r\n\
63 3) dump_debug_info -l <module id> <log level>\n\
64 4) dump_debug_info -l <module id>\n\
65 5) dump_debug_info -m <processor id> <mode>\n\
66 6) dump_debug_info -m <processor id>\n\
67 7) dump_debug_info -t <tunnel id>\n\
68 8) dump_debug_info -n <channel id>\n\
69 9) dump_debug_info -s <stream id>\n\
70 \n\
71 In the first form, it dumps the circular buffer logging for Rome, the output is\n\
72 dumped to the file /data/data/circular_buf_(cm4/dmx/hmd).bin\n\
73 In the second form, it dumps all the SRB and ARB registers, the output is\n\
74 dumped to the file /data/data/reg_dump.txt\n\
75 In the third form, it sets the log level to a particular module id\n\
76 In the fourth form, it gets the log level for the requested modele id\n\
77 In the fifth form, it sets the mode to a particular processor id\n\
78 In the sixth form, it gets the mode for the requested processor id\n\
79 In the seventh form, it gets the tunnel information for the requested tunnel id [0, 31]\n\
80 In the eighth form, it gets the channel information for the requested channel id [0, 31]\n\
81 In the ninth form, it gets the stream information for the requested stream id [0, 15]\n\
82 ", stdout);
83
84 fputs("\
85 Options -\n\
86 ---------\n\
87 -c Dump the circular buffer\n\
88 -r Dump all SRB and ARB registers\n\
89 -o Dump to stdout (Works only with -r option)\n\
90 -l Set/Get the log level for a particular module\n\
91 -m Set/Get the mode for a particular processor id\n\
92 -t Dump the tunnel information for a particular tunnel id [0, 31]\n\
93 -n Dump the channel information for a particular channel id [0, 31]\n\
94 -s Dump the stream information for a particular stream id [0, 15]\n\
95 \n\
96 Module ids -\n\
97 -----------\n\
98 enum iaxxx_debug_module_ids {\n\
99 IAXXX_DBG_MODULE_ID_ASSERT_LOG = 0,\n\
100 IAXXX_DBG_MODULE_ID_ACCDETMGR_LOG = 1,\n\
101 IAXXX_DBG_MODULE_ID_BATTERYMGR_LOG = 2,\n\
102 IAXXX_DBG_MODULE_ID_BLUETOOTHMGR_LOG = 3,\n\
103 IAXXX_DBG_MODULE_ID_BUTTONMGR_LOG = 4,\n\
104 IAXXX_DBG_MODULE_ID_CODECMGR_LOG = 5,\n\
105 IAXXX_DBG_MODULE_ID_CTRLMGR_LOG = 6,\n\
106 IAXXX_DBG_MODULE_ID_DMAMGR_LOG = 7,\n\
107 IAXXX_DBG_MODULE_ID_EVTMGR_LOG = 8,\n\
108 IAXXX_DBG_MODULE_ID_FLASHMGR_LOG = 9,\n\
109 IAXXX_DBG_MODULE_ID_LEDMGR_LOG = 10,\n\
110 IAXXX_DBG_MODULE_ID_POWERMGR_LOG = 11,\n\
111 IAXXX_DBG_MODULE_ID_STREAMMGR_LOG = 12,\n\
112 IAXXX_DBG_MODULE_ID_SENSORMGR_LOG = 13,\n\
113 IAXXX_DBG_MODULE_ID_TUNNELMGR_LOG = 14,\n\
114 IAXXX_DBG_MODULE_ID_USBMGR_LOG = 15,\n\
115 IAXXX_DBG_MODULE_ID_PLUGINMGR_LOG = 16,\n\
116 IAXXX_DBG_MODULE_ID_PLUGINVM_LOG = 17,\n\
117 IAXXX_DBG_MODULE_ID_PACKAGEUTILS_LOG = 18,\n\
118 IAXXX_DBG_MODULE_ID_ENDPOINT_LOG = 19,\n\
119 IAXXX_DBG_MODULE_ID_PUTMSG_LOG = 20,\n\
120 IAXXX_DBG_MODULE_ID_CONTROLLER_LOG = 21,\n\
121 IAXXX_DBG_MODULE_ID_MIPSPROFILER_LOG = 22,\n\
122 IAXXX_DBG_MODULE_ID_DEBUGMONITOR_LOG = 23,\n\
123 IAXXX_DBG_MODULE_ID_SSPDRV_LOG = 24,\n\
124 IAXXX_DBG_MODULE_ID_AFDRV_LOG = 25,\n\
125 IAXXX_DBG_MODULE_ID_SPIDRV_LOG = 26,\n\
126 IAXXX_DBG_MODULE_ID_I2CDRV_LOG = 27,\n\
127 IAXXX_DBG_MODULE_ID_A400DRV_LOG = 28,\n\
128 IAXXX_DBG_MODULE_ID_ADAU1361DRV_LOG = 29,\n\
129 IAXXX_DBG_MODULE_ID_MAX98090DRV_LOG = 30,\n\
130 IAXXX_DBG_MODULE_ID_BQ27425DRV_LOG = 31,\n\
131 IAXXX_DBG_MODULE_ID_USBDRV_LOG = 32,\n\
132 IAXXX_DBG_MODULE_ID_CSR8811_LOG = 33,\n\
133 IAXXX_DBG_MODULE_ID_CYW20707DRV_LOG = 34,\n\
134 IAXXX_DBG_MODULE_ID_BUTTONDRV_LOG = 35,\n\
135 IAXXX_DBG_MODULE_ID_LEDDRV_LOG = 36,\n\
136 IAXXX_DBG_MODULE_ID_TIMERDRV_LOG = 37,\n\
137 IAXXX_DBG_MODULE_ID_UARTDRV_LOG = 38,\n\
138 IAXXX_DBG_MODULE_ID_FLASHDRV_LOG = 39,\n\
139 IAXXX_DBG_MODULE_ID_DMADRV_LOG = 40,\n\
140 IAXXX_DBG_MODULE_ID_GPIODRV_LOG = 41,\n\
141 IAXXX_DBG_MODULE_ID_MACDRV_LOG = 42,\n\
142 IAXXX_DBG_MODULE_ID_STMRDRV_LOG = 43,\n\
143 IAXXX_DBG_MODULE_ID_STMRPTDRV_LOG = 44,\n\
144 IAXXX_DBG_MODULE_ID_SLIMBUSDRV_LOG = 45,\n\
145 IAXXX_DBG_MODULE_ID_SSENSORDRV_LOG = 46,\n\
146 IAXXX_DBG_MODULE_ID_STRMDRV_LOG = 47,\n\
147 IAXXX_DBG_MODULE_ID_CPUSTRMDRV_LOG = 48,\n\
148 IAXXX_DBG_MODULE_ID_CLKTREEUTILS_LOG = 49,\n\
149 IAXXX_DBG_MODULE_ID_SCRIPTMGR_LOG = 50,\n\
150 };\n\
151 \n\
152 Log Levels -\n\
153 ------------\n\
154 enum iaxxx_fw_debug_log_level {\n\
155 IAXXX_DBG_LOG_LVL_OFF = 0,\n\
156 IAXXX_DBG_LOG_LVL_CUSTOM = 1,\n\
157 IAXXX_DBG_LOG_LVL_FATAL = 2,\n\
158 IAXXX_DBG_LOG_LVL_ERROR = 3,\n\
159 IAXXX_DBG_LOG_LVL_WARN = 4,\n\
160 IAXXX_DBG_LOG_LVL_INFO = 5,\n\
161 IAXXX_DBG_LOG_LVL_DEBUG = 6,\n\
162 IAXXX_DBG_LOG_LVL_TRACE = 7,\n\
163 };\n\
164 \n\
165 Modes -\n\
166 -------\n\
167 enum iaxxx_fw_debug_log_mode {\n\
168 IAXXX_FROM_MEMORY = 0,\n\
169 IAXXX_FROM_ENDPOINT = 1,\n\
170 };\n\
171 \n\
172 Processor ids -\n\
173 ---------------\n\
174 enum iaxxx_proc_id_e {\n\
175 IAXXX_NO_PROC = 0,\n\
176 IAXXX_BOSS_ID = 1,\n\
177 IAXXX_SSP_ID = 2,\n\
178 IAXXX_CM4_ID = 3,\n\
179 IAXXX_HMD_ID = 4,\n\
180 IAXXX_DMX_ID = 5,\n\
181 };\n\
182 ", stdout);
183
184 exit(EXIT_FAILURE);
185 }
186
log_lvl(int fd,int module_id,int log_level)187 void log_lvl(int fd, int module_id, int log_level) {
188 int err = 0;
189 struct iaxxx_log_level_info log_level_info;
190
191 log_level_info.module_id = module_id;
192
193 if (log_level == -1) {
194 // We need to get the log level for the module id
195 log_level_info.log_level = 0;
196 err = ioctl(fd, IAXXX_GET_DBG_LOG_LEVEL,
197 (unsigned long) &log_level_info);
198 if (err == -1) {
199 ALOGE("%s: ERROR: IAXXX_GET_DBG_LOG_LEVEL failed %d(%s)", __func__,
200 errno, strerror(errno));
201 return;
202 }
203
204 ALOGD("%s: Module level %d Log level %u", __func__, module_id,
205 log_level_info.log_level);
206 } else {
207 // We need to set the Log level for the module id
208 log_level_info.log_level = log_level;
209 err = ioctl(fd, IAXXX_SET_DBG_LOG_LEVEL,
210 (unsigned long) &log_level_info);
211 if (err == -1) {
212 ALOGE("%s: ERROR: IAXXX_SET_DBG_LOG_LEVEL failed %d(%s)", __func__,
213 errno, strerror(errno));
214 return;
215 }
216 }
217 }
218
pmode(int fd,int proc_id,int mode)219 void pmode(int fd, int proc_id, int mode) {
220 int err = 0;
221 struct iaxxx_log_mode_info log_mode_info;
222
223 log_mode_info.proc_id = proc_id;
224
225 if (mode == -1) {
226 // We need to get the mode for the processor id
227 log_mode_info.mode = 0;
228 err = ioctl(fd, IAXXX_GET_DBG_LOG_MODE,
229 (unsigned long) &log_mode_info);
230 if (err == -1) {
231 ALOGE("%s: ERROR: IAXXX_GET_DBG_LOG_MODE failed %d(%s)", __func__,
232 errno, strerror(errno));
233 return;
234 }
235
236 ALOGD("%s: Processor ID %d Mode %u", __func__, proc_id,
237 log_mode_info.mode);
238 } else {
239 // We need to set the mode for the processor id
240 log_mode_info.mode = mode;
241 err = ioctl(fd, IAXXX_SET_DBG_LOG_MODE,
242 (unsigned long) &log_mode_info);
243 if (err == -1) {
244 ALOGE("%s: ERROR: IAXXX_SET_DBG_LOG_MODE failed %d(%s)", __func__,
245 errno, strerror(errno));
246 return;
247 }
248 }
249 }
250
dump_all_regs(const struct iaxxx_registers_dump * info,bool use_stdout)251 void dump_all_regs(const struct iaxxx_registers_dump *info, bool use_stdout)
252 {
253 uint32_t addr;
254 int i, j;
255 FILE *out_fp = NULL;
256 const struct iaxxx_srb_info *srb_info = &info->srb_info;
257 const struct iaxxx_arb_info *arb_info = &info->arb_info;
258
259 if (use_stdout) {
260 out_fp = stdout;
261 } else {
262 out_fp = fopen(REG_OUT_FILE, "w");
263 if (NULL == out_fp) {
264 ALOGE("Couldn't open the file %s for writing", REG_OUT_FILE);
265 return;
266 }
267 }
268
269 /* SRB */
270 #ifdef ENABLE_DEBUG_PRINTS
271 ALOGD("%s", SRB_REG);
272 ALOGD("%s\t%s", REG_ADDR, REG_VAL);
273 #endif
274 fprintf(out_fp, "%s\n", SRB_REG);
275 fprintf(out_fp, "%s\t%s\n", REG_ADDR, REG_VAL);
276
277 addr = srb_info->reg_start_addr;
278 for (i = 0; i < srb_info->reg_num; ++i) {
279 uint32_t val = srb_info->reg_vals[i];
280
281 #ifdef ENABLE_DEBUG_PRINTS
282 ALOGD("0x%X\t\t\t0x%08X", addr, val);
283 #endif
284 fprintf(out_fp, "0x%X\t\t\t0x%08X\n", addr, val);
285
286 addr += sizeof(uint32_t);
287 }
288
289 /* ARB */
290 addr = arb_info->reg_start_addr;
291 /* Dump all the ARB start address and the size at the beginning
292 * before dumping all the ARB information
293 */
294 for (i = 0, j = 0; i < arb_info->reg_num; i += 2, j++) {
295 uint32_t arb_phy_addr = arb_info->reg_vals[i];
296 uint32_t arb_sz = arb_info->reg_vals[i + 1];
297
298 #ifdef ENABLE_DEBUG_PRINTS
299 ALOGD("0x%X\t\t\t0x%08X", addr, arb_phy_addr);
300 ALOGD("0x%X\t\t\t0x%08X", (addr + 4), arb_sz);
301 #endif
302 fprintf(out_fp, "0x%X\t\t\t0x%08X\n", addr, arb_phy_addr);
303 fprintf(out_fp, "0x%X\t\t\t0x%08X\n", (addr + sizeof(uint32_t)), arb_sz);
304 addr += (sizeof(uint32_t) * 2);
305 }
306
307 addr = arb_info->reg_start_addr;
308 for (i = 0, j = 0; i < arb_info->reg_num; i += 2, j++) {
309 const struct iaxxx_arb_block *block = &arb_info->blocks[j];
310 uint32_t k;
311 uint32_t temp_arb_addr;
312 #ifdef ENABLE_DEBUG_PRINTS
313 uint32_t arb_phy_addr = arb_info->reg_vals[i];
314 uint32_t arb_sz = arb_info->reg_vals[i + 1];
315
316 ALOGD("0x%X \t\t arb phy addr 0x%08X arb size 0x%08X", addr, arb_phy_addr, arb_sz);
317 ALOGD("%s %d", ARB_REG, j);
318 ALOGD("%s\t%s", REG_ADDR, REG_VAL);
319 #endif
320 addr += (sizeof(uint32_t) * 2);
321
322 fprintf(out_fp, "%s %d\n", ARB_REG, j);
323 fprintf(out_fp, "%s\t%s\n", REG_ADDR, REG_VAL);
324
325 if (0 == block->reg_start_addr || 0 == block->reg_num) {
326 ALOGD("------------- NA -------------");
327 fprintf(out_fp, "------------- NA -------------\n");
328 continue;
329 }
330
331 temp_arb_addr = block->reg_start_addr;
332 for (k = 0; k < block->reg_num; k++) {
333 uint32_t temp_val = block->reg_vals[k];
334 #ifdef ENABLE_DEBUG_PRINTS
335 ALOGD("0x%X\t\t\t0x%08X", temp_arb_addr, temp_val);
336 #endif
337 fprintf(out_fp, "0x%X\t\t\t0x%08X\n", temp_arb_addr, temp_val);
338
339 temp_arb_addr += sizeof(uint32_t);
340 }
341 }
342
343 fflush(out_fp);
344 if (!use_stdout)
345 fclose(out_fp);
346 }
347
348 /*
349 * Register Information -
350 * All circular buffers start address and size is stored in ARB10
351 * ARB10 - physical address in SRB is 0x580001bc
352 * Start Address location Size location
353 * CM4 ARB10 + 0 ARB10 + 4
354 * HMD ARB10 + 8 ARB10 + C
355 * DMX ARB10 + 10 ARB10 + 14
356 */
dump_circ_buf(const struct iaxxx_circ_buffer_info * circ_buffer_info)357 void dump_circ_buf(const struct iaxxx_circ_buffer_info *circ_buffer_info)
358 {
359 uint32_t i = 0, j = 0;
360 const char *out_file_names[IAXXX_MAX_CIRC_BUFS] = {CIRC_OUT_FILE_CM4, CIRC_OUT_FILE_HMD, CIRC_OUT_FILE_DMX};
361
362 if (circ_buffer_info->buf_num > IAXXX_MAX_CIRC_BUFS) {
363 ALOGE("Too large buf_num: %d", circ_buffer_info->buf_num);
364 return;
365 }
366
367 for (i = 0, j = 0; j < circ_buffer_info->buf_num; i += 2, j++) {
368 const struct iaxxx_circ_buffer *buf = &circ_buffer_info->bufs[j];
369 FILE *fp = NULL;
370 uint32_t k = 0;
371
372 // Get the physical address and size for each of the circular buffers
373 if (0 == buf->reg_start_addr || 0 == buf->reg_num) {
374 ALOGE("Couldn't find physical address and size");
375 ALOGE("phy_addr 0x%X size 0x%X", buf->reg_start_addr, buf->reg_num);
376 continue;
377 }
378
379 fp = fopen(out_file_names[j], "wb");
380 if (NULL == fp) {
381 ALOGE("Couldn't open the file for writing");
382 continue;
383 }
384
385 for (k = 0; k < buf->reg_num; k++)
386 fwrite(buf->reg_vals + k, sizeof(uint32_t), 1, fp);
387
388 fflush(fp);
389 fclose(fp);
390 }
391 }
392
dump_tunnel(int fd,int tunnel_id)393 static int dump_tunnel(int fd, int tunnel_id)
394 {
395 int ret;
396 struct iaxxx_tunnel_info_dump dump = {
397 .id = tunnel_id
398 };
399
400 if ((ret = ioctl(fd, IAXXX_IOCTL_GET_TUNNEL_INFO_DUMP, &dump)) != 0) {
401 ALOGE("Failed to ioctl %s IAXXX_IOCTL_GET_TUNNEL_INFO_DUMP, ret=%d", DEBUG_DEV, ret);
402 ret = errno;
403 return ret;
404 }
405
406 fprintf(stdout, "header.en=0x%08x\n"
407 "header.st=0x%08x\n"
408 "header.out_buf_size=%u\n"
409 "header.out_buf_addr=0x%08x\n"
410 "header.out_buf_head=%u\n"
411 "header.out_buf_tail=%u\n"
412 "header.out_buf_threshold=%u\n"
413 "tunnel%u.nframe_drops=%u\n"
414 "tunnel%u.nsent_to_host=%u\n"
415 "tunnel%u.nsent=%u\n"
416 "tunnel%u.nrecvd=%u\n"
417 "tunnel%u.ctrl=%u\n"
418 "tunnel%u.format=%u\n",
419 dump.en,
420 dump.st,
421 dump.out_buf_size,
422 dump.out_buf_addr,
423 dump.out_buf_head,
424 dump.out_buf_tail,
425 dump.out_buf_threshold,
426 dump.id, dump.nframe_drops,
427 dump.id, dump.nsent_to_host,
428 dump.id, dump.nsent,
429 dump.id, dump.nrecvd,
430 dump.id, dump.ctrl,
431 dump.id, dump.format);
432
433 return ret;
434 }
435
dump_channel(int fd,int channel_id)436 static int dump_channel(int fd, int channel_id)
437 {
438 int ret;
439 struct iaxxx_channel_info_dump dump = {
440 .id = channel_id
441 };
442
443 if ((ret = ioctl(fd, IAXXX_IOCTL_GET_CHANNEL_INFO_DUMP, &dump)) != 0) {
444 ALOGE("Failed to ioctl %s IAXXX_IOCTL_GET_CHANNEL_INFO_DUMP, ret=%d", DEBUG_DEV, ret);
445 ret = errno;
446 return ret;
447 }
448
449 fprintf(stdout, "header.st=0x%08x\n"
450 "header.direction=%u\n"
451 "header.gain=%u\n"
452 "channel%u.nsent=%u\n"
453 "channel%u.nrecvd=%u\n"
454 "channel%u.endpoint_state=%u\n"
455 "channel%u.intr_cnt=%u\n"
456 "channel%u.drop_cnt=%u\n"
457 "channel%u.gain_ctrl=%u\n"
458 "channel%u.gain_status=%u\n"
459 "channel%u.""%s""=%u\n",
460 dump.st,
461 dump.direction,
462 dump.gain,
463 dump.id, dump.nsent,
464 dump.id, dump.nrecvd,
465 dump.id, dump.endpoint_state,
466 dump.id, dump.intr_cnt,
467 dump.id, dump.drop_cnt,
468 dump.id, dump.gain_ctrl,
469 dump.id, dump.gain_status,
470 dump.id, (dump.id >= 0 && dump.id < 16)
471 ? "out_fmt" : "in_connect", dump.in_connect);
472
473 return ret;
474 }
475
dump_stream(int fd,int stream_id)476 static int dump_stream(int fd, int stream_id)
477 {
478 int ret;
479 struct iaxxx_stream_info_dump dump = {
480 .id = stream_id
481 };
482
483 if ((ret = ioctl(fd, IAXXX_IOCTL_GET_STREAM_INFO_DUMP, &dump)) != 0) {
484 ALOGE("Failed to ioctl %s IAXXX_IOCTL_GET_STREAM_INFO_DUMP, ret=%d", DEBUG_DEV, ret);
485 ret = errno;
486 return ret;
487 }
488
489 fprintf(stdout, "header.en=0x%08x\n"
490 "header.st=0x%08x\n"
491 "stream%u.af_error_afs_fifo_overflow_cnt=%u\n"
492 "stream%u.af_error_afs_fifo_underflow_cnt=%u\n"
493 "stream%u.af_error_tus_fifo_overflow_cnt=%u\n"
494 "stream%u.af_error_tus_fifo_underflow_cnt=%u\n"
495 "stream%u.af_error_tus_fifo_coherency_cnt=%u\n"
496 "stream%u.af_error_deadline_cnt=%u\n"
497 "stream%u.af_error_phy_cnt=%u\n"
498 "stream%u.af_error_timeout_cnt=%u\n"
499 "stream%u.af_error_access_cnt=%u\n"
500 "stream%u.ctrl=%u\n"
501 "stream%u.status=%u\n"
502 "stream%u.format=%u\n"
503 "stream%u.port=%u\n"
504 "stream%u.channel=%u\n"
505 "stream%u.sync=%u\n",
506 dump.en,
507 dump.st,
508 dump.id, dump.af_error_afs_fifo_overflow_cnt,
509 dump.id, dump.af_error_afs_fifo_underflow_cnt,
510 dump.id, dump.af_error_tus_fifo_overflow_cnt,
511 dump.id, dump.af_error_tus_fifo_underflow_cnt,
512 dump.id, dump.af_error_tus_fifo_coherency_cnt,
513 dump.id, dump.af_error_deadline_cnt,
514 dump.id, dump.af_error_phy_cnt,
515 dump.id, dump.af_error_timeout_cnt,
516 dump.id, dump.af_error_access_cnt,
517 dump.id, dump.ctrl,
518 dump.id, dump.status,
519 dump.id, dump.format,
520 dump.id, dump.port,
521 dump.id, dump.channel,
522 dump.id, dump.sync);
523
524 return ret;
525 }
526
main(int argc,char * argv[])527 int main(int argc, char *argv[])
528 {
529 int fd = 0, ret = 0;
530 int c;
531 bool dump_all_registers = false;
532 bool dump_circ_buffer = false;
533 bool dump_tunnel_info = false;
534 bool dump_channel_info = false;
535 bool dump_stream_info = false;
536 bool log_mode = false;
537 bool use_stdout = false;
538 bool proc_mode = false;
539 // Log level set will require 2 arguments while get needs one
540 const int log_lvl_req_arg_get = 1;
541 const int log_lvl_req_arg_set = 2;
542 // Mode level set will required 2 arguments while set needs one
543 const int mode_req_arg_get = 1;
544 const int mode_req_arg_set = 2;
545 int module_id = 0, log_level = -1;
546 int proc_id = 0, mode = -1;
547 int tunnel_id = -1, channel_id = -1, stream_id = -1;
548
549 if (argc <= 1) {
550 usage();
551 return 0;
552 }
553
554 while ((c = getopt_long(argc, argv, "rcot:n:s:l:m:", long_options, NULL)) != -1) {
555 switch (c) {
556 case 'r':
557 dump_all_registers = true;
558 break;
559 case 'c':
560 dump_circ_buffer = true;
561 break;
562 case 'o':
563 use_stdout = true;
564 break;
565 case 't':
566 dump_tunnel_info = true;
567 tunnel_id = atoi(optarg);
568 break;
569 case 'n':
570 dump_channel_info = true;
571 channel_id = atoi(optarg);
572 break;
573 case 's':
574 dump_stream_info = true;
575 stream_id = atoi(optarg);
576 break;
577 case 'l':
578 log_mode = true;
579 // reset optind by 1
580 --optind;
581 if ((optind + log_lvl_req_arg_get) != argc &&
582 (optind + log_lvl_req_arg_set) != argc) {
583 usage();
584 }
585
586 module_id = strtol(argv[optind], NULL, 0);
587
588 if ((optind + log_lvl_req_arg_set) == argc) {
589 // Move to the next before fetching the value
590 optind++;
591 log_level = strtol(argv[optind], NULL, 0);
592 optind++;
593 }
594 break;
595 case 'm':
596 proc_mode = true;
597 // reset optind by 1
598 --optind;
599 if ((optind + mode_req_arg_get) != argc &&
600 (optind + mode_req_arg_set) != argc) {
601 usage();
602 }
603
604 proc_id = strtol(argv[optind], NULL, 0);
605
606 if ((optind + mode_req_arg_set) == argc) {
607 // Move to the next before fetching the value
608 optind++;
609 mode = strtol(argv[optind], NULL, 0);
610 optind++;
611 }
612 break;
613 default:
614 // Do nothing
615 break;
616 }
617 }
618
619 fd = open(DEBUG_DEV, O_RDONLY);
620 if (-1 == fd) {
621 fprintf(stderr, "Failed to open %s", DEBUG_DEV);
622 ret = errno;
623 goto exit;
624 }
625
626 if(log_mode == true) {
627 log_lvl(fd, module_id, log_level);
628 }
629
630 if (proc_mode == true) {
631 pmode(fd, proc_id, mode);
632 }
633
634
635 if (dump_all_registers || dump_circ_buffer) {
636 static struct iaxxx_registers_dump dump;
637
638 if ((ret = ioctl(fd, IAXXX_IOCTL_GET_REGISTERS_DUMP, &dump)) != 0) {
639 fprintf(stderr, "Failed to ioctl %s IAXXX_IOCTL_GET_REGISTERS_DUMP, ret=%d", DEBUG_DEV, ret);
640 ret = errno;
641 } else {
642 if (dump_all_registers)
643 dump_all_regs(&dump, use_stdout);
644
645 if (dump_circ_buffer)
646 dump_circ_buf(&dump.circ_buffer_info);
647 }
648 }
649
650 if (dump_tunnel_info) {
651 if (tunnel_id >= 0 && tunnel_id < IAXXX_TUNNEL_MAX) {
652 ret = dump_tunnel(fd, tunnel_id);
653 if (ret) {
654 fprintf(stderr, "Failed to dump_tunnel(), ret=%d", ret);
655 }
656 } else {
657 fprintf(stderr, "Invalid tunnel_id %d\n", tunnel_id);
658 }
659 }
660
661 if (dump_channel_info) {
662 if (channel_id >= 0 && channel_id < IAXXX_CHANNEL_MAX) {
663 ret = dump_channel(fd, channel_id);
664 if (ret) {
665 fprintf(stderr, "Failed to dump_channel(), ret=%d", ret);
666 }
667 } else {
668 fprintf(stderr, "Invalid channel_id %d\n", channel_id);
669 }
670 }
671
672 if (dump_stream_info) {
673 if (stream_id >= 0 && stream_id < IAXXX_STREAM_MAX) {
674 ret = dump_stream(fd, stream_id);
675 if (ret) {
676 fprintf(stderr, "Failed to dump_stream(), ret=%d", ret);
677 }
678 } else {
679 fprintf(stderr, "Invalid stream_id %d\n", stream_id);
680 }
681 }
682
683 exit:
684 if (-1 != fd)
685 close(fd);
686
687 return ret;
688 }
689