PageRenderTime 41ms CodeModel.GetById 9ms app.highlight 25ms RepoModel.GetById 1ms app.codeStats 1ms

/drivers/acpi/executer/exnames.c

https://bitbucket.org/evzijst/gittest
C | 427 lines | 201 code | 99 blank | 127 comment | 47 complexity | 30de35d536e058fdbbcc8ef23cd3913b MD5 | raw file
  1
  2/******************************************************************************
  3 *
  4 * Module Name: exnames - interpreter/scanner name load/execute
  5 *
  6 *****************************************************************************/
  7
  8/*
  9 * Copyright (C) 2000 - 2005, R. Byron Moore
 10 * All rights reserved.
 11 *
 12 * Redistribution and use in source and binary forms, with or without
 13 * modification, are permitted provided that the following conditions
 14 * are met:
 15 * 1. Redistributions of source code must retain the above copyright
 16 *    notice, this list of conditions, and the following disclaimer,
 17 *    without modification.
 18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
 19 *    substantially similar to the "NO WARRANTY" disclaimer below
 20 *    ("Disclaimer") and any redistribution must be conditioned upon
 21 *    including a substantially similar Disclaimer requirement for further
 22 *    binary redistribution.
 23 * 3. Neither the names of the above-listed copyright holders nor the names
 24 *    of any contributors may be used to endorse or promote products derived
 25 *    from this software without specific prior written permission.
 26 *
 27 * Alternatively, this software may be distributed under the terms of the
 28 * GNU General Public License ("GPL") version 2 as published by the Free
 29 * Software Foundation.
 30 *
 31 * NO WARRANTY
 32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
 35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 42 * POSSIBILITY OF SUCH DAMAGES.
 43 */
 44
 45
 46#include <acpi/acpi.h>
 47#include <acpi/acinterp.h>
 48#include <acpi/amlcode.h>
 49
 50#define _COMPONENT          ACPI_EXECUTER
 51	 ACPI_MODULE_NAME    ("exnames")
 52
 53
 54/* AML Package Length encodings */
 55
 56#define ACPI_AML_PACKAGE_TYPE1   0x40
 57#define ACPI_AML_PACKAGE_TYPE2   0x4000
 58#define ACPI_AML_PACKAGE_TYPE3   0x400000
 59#define ACPI_AML_PACKAGE_TYPE4   0x40000000
 60
 61
 62/*******************************************************************************
 63 *
 64 * FUNCTION:    acpi_ex_allocate_name_string
 65 *
 66 * PARAMETERS:  prefix_count        - Count of parent levels. Special cases:
 67 *                                    (-1) = root,  0 = none
 68 *              num_name_segs       - count of 4-character name segments
 69 *
 70 * RETURN:      A pointer to the allocated string segment.  This segment must
 71 *              be deleted by the caller.
 72 *
 73 * DESCRIPTION: Allocate a buffer for a name string. Ensure allocated name
 74 *              string is long enough, and set up prefix if any.
 75 *
 76 ******************************************************************************/
 77
 78char *
 79acpi_ex_allocate_name_string (
 80	u32                             prefix_count,
 81	u32                             num_name_segs)
 82{
 83	char                            *temp_ptr;
 84	char                            *name_string;
 85	u32                              size_needed;
 86
 87	ACPI_FUNCTION_TRACE ("ex_allocate_name_string");
 88
 89
 90	/*
 91	 * Allow room for all \ and ^ prefixes, all segments, and a multi_name_prefix.
 92	 * Also, one byte for the null terminator.
 93	 * This may actually be somewhat longer than needed.
 94	 */
 95	if (prefix_count == ACPI_UINT32_MAX) {
 96		/* Special case for root */
 97
 98		size_needed = 1 + (ACPI_NAME_SIZE * num_name_segs) + 2 + 1;
 99	}
100	else {
101		size_needed = prefix_count + (ACPI_NAME_SIZE * num_name_segs) + 2 + 1;
102	}
103
104	/*
105	 * Allocate a buffer for the name.
106	 * This buffer must be deleted by the caller!
107	 */
108	name_string = ACPI_MEM_ALLOCATE (size_needed);
109	if (!name_string) {
110		ACPI_REPORT_ERROR (("ex_allocate_name_string: Could not allocate size %d\n", size_needed));
111		return_PTR (NULL);
112	}
113
114	temp_ptr = name_string;
115
116	/* Set up Root or Parent prefixes if needed */
117
118	if (prefix_count == ACPI_UINT32_MAX) {
119		*temp_ptr++ = AML_ROOT_PREFIX;
120	}
121	else {
122		while (prefix_count--) {
123			*temp_ptr++ = AML_PARENT_PREFIX;
124		}
125	}
126
127
128	/* Set up Dual or Multi prefixes if needed */
129
130	if (num_name_segs > 2) {
131		/* Set up multi prefixes   */
132
133		*temp_ptr++ = AML_MULTI_NAME_PREFIX_OP;
134		*temp_ptr++ = (char) num_name_segs;
135	}
136	else if (2 == num_name_segs) {
137		/* Set up dual prefixes */
138
139		*temp_ptr++ = AML_DUAL_NAME_PREFIX;
140	}
141
142	/*
143	 * Terminate string following prefixes. acpi_ex_name_segment() will
144	 * append the segment(s)
145	 */
146	*temp_ptr = 0;
147
148	return_PTR (name_string);
149}
150
151/*******************************************************************************
152 *
153 * FUNCTION:    acpi_ex_name_segment
154 *
155 * PARAMETERS:  interpreter_mode    - Current running mode (load1/Load2/Exec)
156 *
157 * RETURN:      Status
158 *
159 * DESCRIPTION: Execute a name segment (4 bytes)
160 *
161 ******************************************************************************/
162
163acpi_status
164acpi_ex_name_segment (
165	u8                              **in_aml_address,
166	char                            *name_string)
167{
168	char                            *aml_address = (void *) *in_aml_address;
169	acpi_status                     status = AE_OK;
170	u32                             index;
171	char                            char_buf[5];
172
173
174	ACPI_FUNCTION_TRACE ("ex_name_segment");
175
176
177	/*
178	 * If first character is a digit, then we know that we aren't looking at a
179	 * valid name segment
180	 */
181	char_buf[0] = *aml_address;
182
183	if ('0' <= char_buf[0] && char_buf[0] <= '9') {
184		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "leading digit: %c\n", char_buf[0]));
185		return_ACPI_STATUS (AE_CTRL_PENDING);
186	}
187
188	ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "Bytes from stream:\n"));
189
190	for (index = 0;
191		(index < ACPI_NAME_SIZE) && (acpi_ut_valid_acpi_character (*aml_address));
192		index++) {
193		char_buf[index] = *aml_address++;
194		ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "%c\n", char_buf[index]));
195	}
196
197
198	/* Valid name segment  */
199
200	if (index == 4) {
201		/* Found 4 valid characters */
202
203		char_buf[4] = '\0';
204
205		if (name_string) {
206			ACPI_STRCAT (name_string, char_buf);
207			ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
208				"Appended to - %s \n", name_string));
209		}
210		else {
211			ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
212				"No Name string - %s \n", char_buf));
213		}
214	}
215	else if (index == 0) {
216		/*
217		 * First character was not a valid name character,
218		 * so we are looking at something other than a name.
219		 */
220		ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
221			"Leading character is not alpha: %02Xh (not a name)\n",
222			char_buf[0]));
223		status = AE_CTRL_PENDING;
224	}
225	else {
226		/* Segment started with one or more valid characters, but fewer than 4 */
227
228		status = AE_AML_BAD_NAME;
229		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Bad character %02x in name, at %p\n",
230			*aml_address, aml_address));
231	}
232
233	*in_aml_address = (u8 *) aml_address;
234	return_ACPI_STATUS (status);
235}
236
237
238/*******************************************************************************
239 *
240 * FUNCTION:    acpi_ex_get_name_string
241 *
242 * PARAMETERS:  data_type           - Data type to be associated with this name
243 *
244 * RETURN:      Status
245 *
246 * DESCRIPTION: Get a name, including any prefixes.
247 *
248 ******************************************************************************/
249
250acpi_status
251acpi_ex_get_name_string (
252	acpi_object_type                data_type,
253	u8                              *in_aml_address,
254	char                            **out_name_string,
255	u32                             *out_name_length)
256{
257	acpi_status                     status = AE_OK;
258	u8                              *aml_address = in_aml_address;
259	char                            *name_string = NULL;
260	u32                             num_segments;
261	u32                             prefix_count = 0;
262	u8                              has_prefix = FALSE;
263
264
265	ACPI_FUNCTION_TRACE_PTR ("ex_get_name_string", aml_address);
266
267
268	if (ACPI_TYPE_LOCAL_REGION_FIELD == data_type  ||
269		ACPI_TYPE_LOCAL_BANK_FIELD == data_type    ||
270		ACPI_TYPE_LOCAL_INDEX_FIELD == data_type) {
271		/* Disallow prefixes for types associated with field_unit names */
272
273		name_string = acpi_ex_allocate_name_string (0, 1);
274		if (!name_string) {
275			status = AE_NO_MEMORY;
276		}
277		else {
278			status = acpi_ex_name_segment (&aml_address, name_string);
279		}
280	}
281	else {
282		/*
283		 * data_type is not a field name.
284		 * Examine first character of name for root or parent prefix operators
285		 */
286		switch (*aml_address) {
287		case AML_ROOT_PREFIX:
288
289			ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "root_prefix(\\) at %p\n", aml_address));
290
291			/*
292			 * Remember that we have a root_prefix --
293			 * see comment in acpi_ex_allocate_name_string()
294			 */
295			aml_address++;
296			prefix_count = ACPI_UINT32_MAX;
297			has_prefix = TRUE;
298			break;
299
300
301		case AML_PARENT_PREFIX:
302
303			/* Increment past possibly multiple parent prefixes */
304
305			do {
306				ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "parent_prefix (^) at %p\n", aml_address));
307
308				aml_address++;
309				prefix_count++;
310
311			} while (*aml_address == AML_PARENT_PREFIX);
312
313			has_prefix = TRUE;
314			break;
315
316
317		default:
318
319			/* Not a prefix character */
320
321			break;
322		}
323
324
325		/* Examine first character of name for name segment prefix operator */
326
327		switch (*aml_address) {
328		case AML_DUAL_NAME_PREFIX:
329
330			ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "dual_name_prefix at %p\n", aml_address));
331
332			aml_address++;
333			name_string = acpi_ex_allocate_name_string (prefix_count, 2);
334			if (!name_string) {
335				status = AE_NO_MEMORY;
336				break;
337			}
338
339			/* Indicate that we processed a prefix */
340
341			has_prefix = TRUE;
342
343			status = acpi_ex_name_segment (&aml_address, name_string);
344			if (ACPI_SUCCESS (status)) {
345				status = acpi_ex_name_segment (&aml_address, name_string);
346			}
347			break;
348
349
350		case AML_MULTI_NAME_PREFIX_OP:
351
352			ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "multi_name_prefix at %p\n", aml_address));
353
354			/* Fetch count of segments remaining in name path */
355
356			aml_address++;
357			num_segments = *aml_address;
358
359			name_string = acpi_ex_allocate_name_string (prefix_count, num_segments);
360			if (!name_string) {
361				status = AE_NO_MEMORY;
362				break;
363			}
364
365			/* Indicate that we processed a prefix */
366
367			aml_address++;
368			has_prefix = TRUE;
369
370			while (num_segments &&
371					(status = acpi_ex_name_segment (&aml_address, name_string)) == AE_OK) {
372				num_segments--;
373			}
374
375			break;
376
377
378		case 0:
379
380			/* null_name valid as of 8-12-98 ASL/AML Grammar Update */
381
382			if (prefix_count == ACPI_UINT32_MAX) {
383				ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "name_seg is \"\\\" followed by NULL\n"));
384			}
385
386			/* Consume the NULL byte */
387
388			aml_address++;
389			name_string = acpi_ex_allocate_name_string (prefix_count, 0);
390			if (!name_string) {
391				status = AE_NO_MEMORY;
392				break;
393			}
394
395			break;
396
397
398		default:
399
400			/* Name segment string */
401
402			name_string = acpi_ex_allocate_name_string (prefix_count, 1);
403			if (!name_string) {
404				status = AE_NO_MEMORY;
405				break;
406			}
407
408			status = acpi_ex_name_segment (&aml_address, name_string);
409			break;
410		}
411	}
412
413	if (AE_CTRL_PENDING == status && has_prefix) {
414		/* Ran out of segments after processing a prefix */
415
416		ACPI_REPORT_ERROR (
417			("ex_do_name: Malformed Name at %p\n", name_string));
418		status = AE_AML_BAD_NAME;
419	}
420
421	*out_name_string = name_string;
422	*out_name_length = (u32) (aml_address - in_aml_address);
423
424	return_ACPI_STATUS (status);
425}
426
427