xref: /linux/drivers/acpi/acpica/dbhistry.c (revision 96ac6d435100450f0565708d9b885ea2a7400e0a)
1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2 /******************************************************************************
3  *
4  * Module Name: dbhistry - debugger HISTORY command
5  *
6  * Copyright (C) 2000 - 2019, Intel Corp.
7  *
8  *****************************************************************************/
9 
10 #include <acpi/acpi.h>
11 #include "accommon.h"
12 #include "acdebug.h"
13 
14 #define _COMPONENT          ACPI_CA_DEBUGGER
15 ACPI_MODULE_NAME("dbhistry")
16 
17 #define HI_NO_HISTORY       0
18 #define HI_RECORD_HISTORY   1
19 #define HISTORY_SIZE        40
20 typedef struct history_info {
21 	char *command;
22 	u32 cmd_num;
23 
24 } HISTORY_INFO;
25 
26 static HISTORY_INFO acpi_gbl_history_buffer[HISTORY_SIZE];
27 static u16 acpi_gbl_lo_history = 0;
28 static u16 acpi_gbl_num_history = 0;
29 static u16 acpi_gbl_next_history_index = 0;
30 u32 acpi_gbl_next_cmd_num = 1;
31 
32 /*******************************************************************************
33  *
34  * FUNCTION:    acpi_db_add_to_history
35  *
36  * PARAMETERS:  command_line    - Command to add
37  *
38  * RETURN:      None
39  *
40  * DESCRIPTION: Add a command line to the history buffer.
41  *
42  ******************************************************************************/
43 
44 void acpi_db_add_to_history(char *command_line)
45 {
46 	u16 cmd_len;
47 	u16 buffer_len;
48 
49 	/* Put command into the next available slot */
50 
51 	cmd_len = (u16)strlen(command_line);
52 	if (!cmd_len) {
53 		return;
54 	}
55 
56 	if (acpi_gbl_history_buffer[acpi_gbl_next_history_index].command !=
57 	    NULL) {
58 		buffer_len =
59 		    (u16)
60 		    strlen(acpi_gbl_history_buffer[acpi_gbl_next_history_index].
61 			   command);
62 
63 		if (cmd_len > buffer_len) {
64 			acpi_os_free(acpi_gbl_history_buffer
65 				     [acpi_gbl_next_history_index].command);
66 			acpi_gbl_history_buffer[acpi_gbl_next_history_index].
67 			    command = acpi_os_allocate(cmd_len + 1);
68 		}
69 	} else {
70 		acpi_gbl_history_buffer[acpi_gbl_next_history_index].command =
71 		    acpi_os_allocate(cmd_len + 1);
72 	}
73 
74 	strcpy(acpi_gbl_history_buffer[acpi_gbl_next_history_index].command,
75 	       command_line);
76 
77 	acpi_gbl_history_buffer[acpi_gbl_next_history_index].cmd_num =
78 	    acpi_gbl_next_cmd_num;
79 
80 	/* Adjust indexes */
81 
82 	if ((acpi_gbl_num_history == HISTORY_SIZE) &&
83 	    (acpi_gbl_next_history_index == acpi_gbl_lo_history)) {
84 		acpi_gbl_lo_history++;
85 		if (acpi_gbl_lo_history >= HISTORY_SIZE) {
86 			acpi_gbl_lo_history = 0;
87 		}
88 	}
89 
90 	acpi_gbl_next_history_index++;
91 	if (acpi_gbl_next_history_index >= HISTORY_SIZE) {
92 		acpi_gbl_next_history_index = 0;
93 	}
94 
95 	acpi_gbl_next_cmd_num++;
96 	if (acpi_gbl_num_history < HISTORY_SIZE) {
97 		acpi_gbl_num_history++;
98 	}
99 }
100 
101 /*******************************************************************************
102  *
103  * FUNCTION:    acpi_db_display_history
104  *
105  * PARAMETERS:  None
106  *
107  * RETURN:      None
108  *
109  * DESCRIPTION: Display the contents of the history buffer
110  *
111  ******************************************************************************/
112 
113 void acpi_db_display_history(void)
114 {
115 	u32 i;
116 	u16 history_index;
117 
118 	history_index = acpi_gbl_lo_history;
119 
120 	/* Dump entire history buffer */
121 
122 	for (i = 0; i < acpi_gbl_num_history; i++) {
123 		if (acpi_gbl_history_buffer[history_index].command) {
124 			acpi_os_printf("%3ld %s\n",
125 				       acpi_gbl_history_buffer[history_index].
126 				       cmd_num,
127 				       acpi_gbl_history_buffer[history_index].
128 				       command);
129 		}
130 
131 		history_index++;
132 		if (history_index >= HISTORY_SIZE) {
133 			history_index = 0;
134 		}
135 	}
136 }
137 
138 /*******************************************************************************
139  *
140  * FUNCTION:    acpi_db_get_from_history
141  *
142  * PARAMETERS:  command_num_arg         - String containing the number of the
143  *                                        command to be retrieved
144  *
145  * RETURN:      Pointer to the retrieved command. Null on error.
146  *
147  * DESCRIPTION: Get a command from the history buffer
148  *
149  ******************************************************************************/
150 
151 char *acpi_db_get_from_history(char *command_num_arg)
152 {
153 	u32 cmd_num;
154 
155 	if (command_num_arg == NULL) {
156 		cmd_num = acpi_gbl_next_cmd_num - 1;
157 	}
158 
159 	else {
160 		cmd_num = strtoul(command_num_arg, NULL, 0);
161 	}
162 
163 	return (acpi_db_get_history_by_index(cmd_num));
164 }
165 
166 /*******************************************************************************
167  *
168  * FUNCTION:    acpi_db_get_history_by_index
169  *
170  * PARAMETERS:  cmd_num             - Index of the desired history entry.
171  *                                    Values are 0...(acpi_gbl_next_cmd_num - 1)
172  *
173  * RETURN:      Pointer to the retrieved command. Null on error.
174  *
175  * DESCRIPTION: Get a command from the history buffer
176  *
177  ******************************************************************************/
178 
179 char *acpi_db_get_history_by_index(u32 cmd_num)
180 {
181 	u32 i;
182 	u16 history_index;
183 
184 	/* Search history buffer */
185 
186 	history_index = acpi_gbl_lo_history;
187 	for (i = 0; i < acpi_gbl_num_history; i++) {
188 		if (acpi_gbl_history_buffer[history_index].cmd_num == cmd_num) {
189 
190 			/* Found the command, return it */
191 
192 			return (acpi_gbl_history_buffer[history_index].command);
193 		}
194 
195 		/* History buffer is circular */
196 
197 		history_index++;
198 		if (history_index >= HISTORY_SIZE) {
199 			history_index = 0;
200 		}
201 	}
202 
203 	acpi_os_printf("Invalid history number: %u\n", history_index);
204 	return (NULL);
205 }
206