1  // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2  /*******************************************************************************
3   *
4   * Module Name: uterror - Various internal error/warning output functions
5   *
6   ******************************************************************************/
7  
8  #include <acpi/acpi.h>
9  #include "accommon.h"
10  #include "acnamesp.h"
11  
12  #define _COMPONENT          ACPI_UTILITIES
13  ACPI_MODULE_NAME("uterror")
14  
15  /*
16   * This module contains internal error functions that may
17   * be configured out.
18   */
19  #if !defined (ACPI_NO_ERROR_MESSAGES)
20  /*******************************************************************************
21   *
22   * FUNCTION:    acpi_ut_predefined_warning
23   *
24   * PARAMETERS:  module_name     - Caller's module name (for error output)
25   *              line_number     - Caller's line number (for error output)
26   *              pathname        - Full pathname to the node
27   *              node_flags      - From Namespace node for the method/object
28   *              format          - Printf format string + additional args
29   *
30   * RETURN:      None
31   *
32   * DESCRIPTION: Warnings for the predefined validation module. Messages are
33   *              only emitted the first time a problem with a particular
34   *              method/object is detected. This prevents a flood of error
35   *              messages for methods that are repeatedly evaluated.
36   *
37   ******************************************************************************/
38  void ACPI_INTERNAL_VAR_XFACE
acpi_ut_predefined_warning(const char * module_name,u32 line_number,char * pathname,u16 node_flags,const char * format,...)39  acpi_ut_predefined_warning(const char *module_name,
40  			   u32 line_number,
41  			   char *pathname,
42  			   u16 node_flags, const char *format, ...)
43  {
44  	va_list arg_list;
45  
46  	/*
47  	 * Warning messages for this method/object will be disabled after the
48  	 * first time a validation fails or an object is successfully repaired.
49  	 */
50  	if (node_flags & ANOBJ_EVALUATED) {
51  		return;
52  	}
53  
54  	acpi_os_printf(ACPI_MSG_WARNING "%s: ", pathname);
55  
56  	va_start(arg_list, format);
57  	acpi_os_vprintf(format, arg_list);
58  	ACPI_MSG_SUFFIX;
59  	va_end(arg_list);
60  }
61  
62  /*******************************************************************************
63   *
64   * FUNCTION:    acpi_ut_predefined_info
65   *
66   * PARAMETERS:  module_name     - Caller's module name (for error output)
67   *              line_number     - Caller's line number (for error output)
68   *              pathname        - Full pathname to the node
69   *              node_flags      - From Namespace node for the method/object
70   *              format          - Printf format string + additional args
71   *
72   * RETURN:      None
73   *
74   * DESCRIPTION: Info messages for the predefined validation module. Messages
75   *              are only emitted the first time a problem with a particular
76   *              method/object is detected. This prevents a flood of
77   *              messages for methods that are repeatedly evaluated.
78   *
79   ******************************************************************************/
80  
81  void ACPI_INTERNAL_VAR_XFACE
acpi_ut_predefined_info(const char * module_name,u32 line_number,char * pathname,u16 node_flags,const char * format,...)82  acpi_ut_predefined_info(const char *module_name,
83  			u32 line_number,
84  			char *pathname, u16 node_flags, const char *format, ...)
85  {
86  	va_list arg_list;
87  
88  	/*
89  	 * Warning messages for this method/object will be disabled after the
90  	 * first time a validation fails or an object is successfully repaired.
91  	 */
92  	if (node_flags & ANOBJ_EVALUATED) {
93  		return;
94  	}
95  
96  	acpi_os_printf(ACPI_MSG_INFO "%s: ", pathname);
97  
98  	va_start(arg_list, format);
99  	acpi_os_vprintf(format, arg_list);
100  	ACPI_MSG_SUFFIX;
101  	va_end(arg_list);
102  }
103  
104  /*******************************************************************************
105   *
106   * FUNCTION:    acpi_ut_predefined_bios_error
107   *
108   * PARAMETERS:  module_name     - Caller's module name (for error output)
109   *              line_number     - Caller's line number (for error output)
110   *              pathname        - Full pathname to the node
111   *              node_flags      - From Namespace node for the method/object
112   *              format          - Printf format string + additional args
113   *
114   * RETURN:      None
115   *
116   * DESCRIPTION: BIOS error message for predefined names. Messages
117   *              are only emitted the first time a problem with a particular
118   *              method/object is detected. This prevents a flood of
119   *              messages for methods that are repeatedly evaluated.
120   *
121   ******************************************************************************/
122  
123  void ACPI_INTERNAL_VAR_XFACE
acpi_ut_predefined_bios_error(const char * module_name,u32 line_number,char * pathname,u16 node_flags,const char * format,...)124  acpi_ut_predefined_bios_error(const char *module_name,
125  			      u32 line_number,
126  			      char *pathname,
127  			      u16 node_flags, const char *format, ...)
128  {
129  	va_list arg_list;
130  
131  	/*
132  	 * Warning messages for this method/object will be disabled after the
133  	 * first time a validation fails or an object is successfully repaired.
134  	 */
135  	if (node_flags & ANOBJ_EVALUATED) {
136  		return;
137  	}
138  
139  	acpi_os_printf(ACPI_MSG_BIOS_ERROR "%s: ", pathname);
140  
141  	va_start(arg_list, format);
142  	acpi_os_vprintf(format, arg_list);
143  	ACPI_MSG_SUFFIX;
144  	va_end(arg_list);
145  }
146  
147  /*******************************************************************************
148   *
149   * FUNCTION:    acpi_ut_prefixed_namespace_error
150   *
151   * PARAMETERS:  module_name         - Caller's module name (for error output)
152   *              line_number         - Caller's line number (for error output)
153   *              prefix_scope        - Scope/Path that prefixes the internal path
154   *              internal_path       - Name or path of the namespace node
155   *              lookup_status       - Exception code from NS lookup
156   *
157   * RETURN:      None
158   *
159   * DESCRIPTION: Print error message with the full pathname constructed this way:
160   *
161   *                  prefix_scope_node_full_path.externalized_internal_path
162   *
163   * NOTE:        10/2017: Treat the major ns_lookup errors as firmware errors
164   *
165   ******************************************************************************/
166  
167  void
acpi_ut_prefixed_namespace_error(const char * module_name,u32 line_number,union acpi_generic_state * prefix_scope,const char * internal_path,acpi_status lookup_status)168  acpi_ut_prefixed_namespace_error(const char *module_name,
169  				 u32 line_number,
170  				 union acpi_generic_state *prefix_scope,
171  				 const char *internal_path,
172  				 acpi_status lookup_status)
173  {
174  	char *full_path;
175  	const char *message;
176  
177  	/*
178  	 * Main cases:
179  	 * 1) Object creation, object must not already exist
180  	 * 2) Object lookup, object must exist
181  	 */
182  	switch (lookup_status) {
183  	case AE_ALREADY_EXISTS:
184  
185  		acpi_os_printf(ACPI_MSG_BIOS_ERROR);
186  		message = "Failure creating named object";
187  		break;
188  
189  	case AE_NOT_FOUND:
190  
191  		acpi_os_printf(ACPI_MSG_BIOS_ERROR);
192  		message = "Could not resolve symbol";
193  		break;
194  
195  	default:
196  
197  		acpi_os_printf(ACPI_MSG_ERROR);
198  		message = "Failure resolving symbol";
199  		break;
200  	}
201  
202  	/* Concatenate the prefix path and the internal path */
203  
204  	full_path =
205  	    acpi_ns_build_prefixed_pathname(prefix_scope, internal_path);
206  
207  	acpi_os_printf("%s [%s], %s", message,
208  		       full_path ? full_path : "Could not get pathname",
209  		       acpi_format_exception(lookup_status));
210  
211  	if (full_path) {
212  		ACPI_FREE(full_path);
213  	}
214  
215  	ACPI_MSG_SUFFIX;
216  }
217  
218  #ifdef __OBSOLETE_FUNCTION
219  /*******************************************************************************
220   *
221   * FUNCTION:    acpi_ut_namespace_error
222   *
223   * PARAMETERS:  module_name         - Caller's module name (for error output)
224   *              line_number         - Caller's line number (for error output)
225   *              internal_name       - Name or path of the namespace node
226   *              lookup_status       - Exception code from NS lookup
227   *
228   * RETURN:      None
229   *
230   * DESCRIPTION: Print error message with the full pathname for the NS node.
231   *
232   ******************************************************************************/
233  
234  void
acpi_ut_namespace_error(const char * module_name,u32 line_number,const char * internal_name,acpi_status lookup_status)235  acpi_ut_namespace_error(const char *module_name,
236  			u32 line_number,
237  			const char *internal_name, acpi_status lookup_status)
238  {
239  	acpi_status status;
240  	u32 bad_name;
241  	char *name = NULL;
242  
243  	ACPI_MSG_REDIRECT_BEGIN;
244  	acpi_os_printf(ACPI_MSG_ERROR);
245  
246  	if (lookup_status == AE_BAD_CHARACTER) {
247  
248  		/* There is a non-ascii character in the name */
249  
250  		ACPI_MOVE_32_TO_32(&bad_name,
251  				   ACPI_CAST_PTR(u32, internal_name));
252  		acpi_os_printf("[0x%.8X] (NON-ASCII)", bad_name);
253  	} else {
254  		/* Convert path to external format */
255  
256  		status =
257  		    acpi_ns_externalize_name(ACPI_UINT32_MAX, internal_name,
258  					     NULL, &name);
259  
260  		/* Print target name */
261  
262  		if (ACPI_SUCCESS(status)) {
263  			acpi_os_printf("[%s]", name);
264  		} else {
265  			acpi_os_printf("[COULD NOT EXTERNALIZE NAME]");
266  		}
267  
268  		if (name) {
269  			ACPI_FREE(name);
270  		}
271  	}
272  
273  	acpi_os_printf(" Namespace lookup failure, %s",
274  		       acpi_format_exception(lookup_status));
275  
276  	ACPI_MSG_SUFFIX;
277  	ACPI_MSG_REDIRECT_END;
278  }
279  #endif
280  
281  /*******************************************************************************
282   *
283   * FUNCTION:    acpi_ut_method_error
284   *
285   * PARAMETERS:  module_name         - Caller's module name (for error output)
286   *              line_number         - Caller's line number (for error output)
287   *              message             - Error message to use on failure
288   *              prefix_node         - Prefix relative to the path
289   *              path                - Path to the node (optional)
290   *              method_status       - Execution status
291   *
292   * RETURN:      None
293   *
294   * DESCRIPTION: Print error message with the full pathname for the method.
295   *
296   ******************************************************************************/
297  
298  void
acpi_ut_method_error(const char * module_name,u32 line_number,const char * message,struct acpi_namespace_node * prefix_node,const char * path,acpi_status method_status)299  acpi_ut_method_error(const char *module_name,
300  		     u32 line_number,
301  		     const char *message,
302  		     struct acpi_namespace_node *prefix_node,
303  		     const char *path, acpi_status method_status)
304  {
305  	acpi_status status;
306  	struct acpi_namespace_node *node = prefix_node;
307  
308  	ACPI_MSG_REDIRECT_BEGIN;
309  	acpi_os_printf(ACPI_MSG_ERROR);
310  
311  	if (path) {
312  		status = acpi_ns_get_node(prefix_node, path,
313  					  ACPI_NS_NO_UPSEARCH, &node);
314  		if (ACPI_FAILURE(status)) {
315  			acpi_os_printf("[Could not get node by pathname]");
316  		}
317  	}
318  
319  	acpi_ns_print_node_pathname(node, message);
320  	acpi_os_printf(" due to previous error (%s)",
321  		       acpi_format_exception(method_status));
322  
323  	ACPI_MSG_SUFFIX;
324  	ACPI_MSG_REDIRECT_END;
325  }
326  
327  #endif				/* ACPI_NO_ERROR_MESSAGES */
328