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