Linux Audio

Check our new training course

Loading...
v3.1
 
  1/******************************************************************************
  2 *
  3 * Module Name: nsrepair - Repair for objects returned by predefined methods
  4 *
  5 *****************************************************************************/
  6
  7/*
  8 * Copyright (C) 2000 - 2011, Intel Corp.
  9 * All rights reserved.
 10 *
 11 * Redistribution and use in source and binary forms, with or without
 12 * modification, are permitted provided that the following conditions
 13 * are met:
 14 * 1. Redistributions of source code must retain the above copyright
 15 *    notice, this list of conditions, and the following disclaimer,
 16 *    without modification.
 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
 18 *    substantially similar to the "NO WARRANTY" disclaimer below
 19 *    ("Disclaimer") and any redistribution must be conditioned upon
 20 *    including a substantially similar Disclaimer requirement for further
 21 *    binary redistribution.
 22 * 3. Neither the names of the above-listed copyright holders nor the names
 23 *    of any contributors may be used to endorse or promote products derived
 24 *    from this software without specific prior written permission.
 25 *
 26 * Alternatively, this software may be distributed under the terms of the
 27 * GNU General Public License ("GPL") version 2 as published by the Free
 28 * Software Foundation.
 29 *
 30 * NO WARRANTY
 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 41 * POSSIBILITY OF SUCH DAMAGES.
 42 */
 43
 44#include <acpi/acpi.h>
 45#include "accommon.h"
 46#include "acnamesp.h"
 47#include "acinterp.h"
 48#include "acpredef.h"
 
 49
 50#define _COMPONENT          ACPI_NAMESPACE
 51ACPI_MODULE_NAME("nsrepair")
 52
 53/*******************************************************************************
 54 *
 55 * This module attempts to repair or convert objects returned by the
 56 * predefined methods to an object type that is expected, as per the ACPI
 57 * specification. The need for this code is dictated by the many machines that
 58 * return incorrect types for the standard predefined methods. Performing these
 59 * conversions here, in one place, eliminates the need for individual ACPI
 60 * device drivers to do the same. Note: Most of these conversions are different
 61 * than the internal object conversion routines used for implicit object
 62 * conversion.
 63 *
 64 * The following conversions can be performed as necessary:
 65 *
 66 * Integer -> String
 67 * Integer -> Buffer
 68 * String  -> Integer
 69 * String  -> Buffer
 70 * Buffer  -> Integer
 71 * Buffer  -> String
 72 * Buffer  -> Package of Integers
 73 * Package -> Package of one Package
 74 *
 75 * Additional possible repairs:
 
 
 
 
 76 *
 
 77 * Required package elements that are NULL replaced by Integer/String/Buffer
 78 * Incorrect standalone package wrapped with required outer package
 79 *
 80 ******************************************************************************/
 81/* Local prototypes */
 82static acpi_status
 83acpi_ns_convert_to_integer(union acpi_operand_object *original_object,
 84			   union acpi_operand_object **return_object);
 85
 86static acpi_status
 87acpi_ns_convert_to_string(union acpi_operand_object *original_object,
 88			  union acpi_operand_object **return_object);
 89
 90static acpi_status
 91acpi_ns_convert_to_buffer(union acpi_operand_object *original_object,
 92			  union acpi_operand_object **return_object);
 93
 94static acpi_status
 95acpi_ns_convert_to_package(union acpi_operand_object *original_object,
 96			   union acpi_operand_object **return_object);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 97
 98/*******************************************************************************
 99 *
100 * FUNCTION:    acpi_ns_repair_object
101 *
102 * PARAMETERS:  Data                - Pointer to validation data structure
103 *              expected_btypes     - Object types expected
104 *              package_index       - Index of object within parent package (if
105 *                                    applicable - ACPI_NOT_PACKAGE_ELEMENT
106 *                                    otherwise)
107 *              return_object_ptr   - Pointer to the object returned from the
108 *                                    evaluation of a method or object
109 *
110 * RETURN:      Status. AE_OK if repair was successful.
111 *
112 * DESCRIPTION: Attempt to repair/convert a return object of a type that was
113 *              not expected.
114 *
115 ******************************************************************************/
116
117acpi_status
118acpi_ns_repair_object(struct acpi_predefined_data *data,
119		      u32 expected_btypes,
120		      u32 package_index,
121		      union acpi_operand_object **return_object_ptr)
122{
123	union acpi_operand_object *return_object = *return_object_ptr;
124	union acpi_operand_object *new_object;
125	acpi_status status;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
126
127	ACPI_FUNCTION_NAME(ns_repair_object);
 
 
 
 
 
 
128
129	/*
130	 * At this point, we know that the type of the returned object was not
131	 * one of the expected types for this predefined name. Attempt to
132	 * repair the object by converting it to one of the expected object
133	 * types for this predefined name.
134	 */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
135	if (expected_btypes & ACPI_RTYPE_INTEGER) {
136		status = acpi_ns_convert_to_integer(return_object, &new_object);
137		if (ACPI_SUCCESS(status)) {
138			goto object_repaired;
139		}
140	}
141	if (expected_btypes & ACPI_RTYPE_STRING) {
142		status = acpi_ns_convert_to_string(return_object, &new_object);
143		if (ACPI_SUCCESS(status)) {
144			goto object_repaired;
145		}
146	}
147	if (expected_btypes & ACPI_RTYPE_BUFFER) {
148		status = acpi_ns_convert_to_buffer(return_object, &new_object);
149		if (ACPI_SUCCESS(status)) {
150			goto object_repaired;
151		}
152	}
153	if (expected_btypes & ACPI_RTYPE_PACKAGE) {
154		status = acpi_ns_convert_to_package(return_object, &new_object);
 
 
 
 
 
 
 
 
 
155		if (ACPI_SUCCESS(status)) {
156			goto object_repaired;
 
 
 
 
 
 
157		}
158	}
159
160	/* We cannot repair this object */
161
162	return (AE_AML_OPERAND_TYPE);
163
164      object_repaired:
165
166	/* Object was successfully repaired */
167
168	/*
169	 * If the original object is a package element, we need to:
170	 * 1. Set the reference count of the new object to match the
171	 *    reference count of the old object.
172	 * 2. Decrement the reference count of the original object.
173	 */
174	if (package_index != ACPI_NOT_PACKAGE_ELEMENT) {
175		new_object->common.reference_count =
176		    return_object->common.reference_count;
177
178		if (return_object->common.reference_count > 1) {
179			return_object->common.reference_count--;
 
 
 
180		}
181
182		ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
183				  "%s: Converted %s to expected %s at index %u\n",
184				  data->pathname,
185				  acpi_ut_get_object_type_name(return_object),
186				  acpi_ut_get_object_type_name(new_object),
187				  package_index));
188	} else {
189		ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
190				  "%s: Converted %s to expected %s\n",
191				  data->pathname,
192				  acpi_ut_get_object_type_name(return_object),
193				  acpi_ut_get_object_type_name(new_object)));
194	}
195
196	/* Delete old object, install the new return object */
197
198	acpi_ut_remove_reference(return_object);
199	*return_object_ptr = new_object;
200	data->flags |= ACPI_OBJECT_REPAIRED;
201	return (AE_OK);
202}
203
204/*******************************************************************************
205 *
206 * FUNCTION:    acpi_ns_convert_to_integer
207 *
208 * PARAMETERS:  original_object     - Object to be converted
209 *              return_object       - Where the new converted object is returned
210 *
211 * RETURN:      Status. AE_OK if conversion was successful.
212 *
213 * DESCRIPTION: Attempt to convert a String/Buffer object to an Integer.
214 *
215 ******************************************************************************/
216
217static acpi_status
218acpi_ns_convert_to_integer(union acpi_operand_object *original_object,
219			   union acpi_operand_object **return_object)
220{
221	union acpi_operand_object *new_object;
222	acpi_status status;
223	u64 value = 0;
224	u32 i;
225
226	switch (original_object->common.type) {
227	case ACPI_TYPE_STRING:
228
229		/* String-to-Integer conversion */
230
231		status = acpi_ut_strtoul64(original_object->string.pointer,
232					   ACPI_ANY_BASE, &value);
233		if (ACPI_FAILURE(status)) {
234			return (status);
235		}
236		break;
237
238	case ACPI_TYPE_BUFFER:
239
240		/* Buffer-to-Integer conversion. Max buffer size is 64 bits. */
241
242		if (original_object->buffer.length > 8) {
243			return (AE_AML_OPERAND_TYPE);
244		}
245
246		/* Extract each buffer byte to create the integer */
247
248		for (i = 0; i < original_object->buffer.length; i++) {
249			value |=
250			    ((u64) original_object->buffer.
251			     pointer[i] << (i * 8));
252		}
253		break;
254
255	default:
256		return (AE_AML_OPERAND_TYPE);
257	}
258
259	new_object = acpi_ut_create_integer_object(value);
260	if (!new_object) {
261		return (AE_NO_MEMORY);
262	}
263
264	*return_object = new_object;
265	return (AE_OK);
266}
267
268/*******************************************************************************
269 *
270 * FUNCTION:    acpi_ns_convert_to_string
271 *
272 * PARAMETERS:  original_object     - Object to be converted
273 *              return_object       - Where the new converted object is returned
274 *
275 * RETURN:      Status. AE_OK if conversion was successful.
276 *
277 * DESCRIPTION: Attempt to convert a Integer/Buffer object to a String.
278 *
279 ******************************************************************************/
280
281static acpi_status
282acpi_ns_convert_to_string(union acpi_operand_object *original_object,
283			  union acpi_operand_object **return_object)
284{
285	union acpi_operand_object *new_object;
286	acpi_size length;
287	acpi_status status;
288
289	switch (original_object->common.type) {
290	case ACPI_TYPE_INTEGER:
291		/*
292		 * Integer-to-String conversion. Commonly, convert
293		 * an integer of value 0 to a NULL string. The last element of
294		 * _BIF and _BIX packages occasionally need this fix.
295		 */
296		if (original_object->integer.value == 0) {
297
298			/* Allocate a new NULL string object */
299
300			new_object = acpi_ut_create_string_object(0);
301			if (!new_object) {
302				return (AE_NO_MEMORY);
303			}
304		} else {
305			status =
306			    acpi_ex_convert_to_string(original_object,
307						      &new_object,
308						      ACPI_IMPLICIT_CONVERT_HEX);
309			if (ACPI_FAILURE(status)) {
310				return (status);
311			}
312		}
313		break;
314
315	case ACPI_TYPE_BUFFER:
316		/*
317		 * Buffer-to-String conversion. Use a to_string
318		 * conversion, no transform performed on the buffer data. The best
319		 * example of this is the _BIF method, where the string data from
320		 * the battery is often (incorrectly) returned as buffer object(s).
321		 */
322		length = 0;
323		while ((length < original_object->buffer.length) &&
324		       (original_object->buffer.pointer[length])) {
325			length++;
326		}
327
328		/* Allocate a new string object */
329
330		new_object = acpi_ut_create_string_object(length);
331		if (!new_object) {
332			return (AE_NO_MEMORY);
333		}
334
335		/*
336		 * Copy the raw buffer data with no transform. String is already NULL
337		 * terminated at Length+1.
338		 */
339		ACPI_MEMCPY(new_object->string.pointer,
340			    original_object->buffer.pointer, length);
341		break;
342
343	default:
344		return (AE_AML_OPERAND_TYPE);
345	}
346
347	*return_object = new_object;
348	return (AE_OK);
349}
350
351/*******************************************************************************
352 *
353 * FUNCTION:    acpi_ns_convert_to_buffer
354 *
355 * PARAMETERS:  original_object     - Object to be converted
356 *              return_object       - Where the new converted object is returned
 
 
 
357 *
358 * RETURN:      Status. AE_OK if conversion was successful.
359 *
360 * DESCRIPTION: Attempt to convert a Integer/String/Package object to a Buffer.
361 *
362 ******************************************************************************/
363
364static acpi_status
365acpi_ns_convert_to_buffer(union acpi_operand_object *original_object,
366			  union acpi_operand_object **return_object)
 
 
 
 
367{
368	union acpi_operand_object *new_object;
369	acpi_status status;
370	union acpi_operand_object **elements;
371	u32 *dword_buffer;
372	u32 count;
373	u32 i;
374
375	switch (original_object->common.type) {
376	case ACPI_TYPE_INTEGER:
377		/*
378		 * Integer-to-Buffer conversion.
379		 * Convert the Integer to a packed-byte buffer. _MAT and other
380		 * objects need this sometimes, if a read has been performed on a
381		 * Field object that is less than or equal to the global integer
382		 * size (32 or 64 bits).
383		 */
384		status =
385		    acpi_ex_convert_to_buffer(original_object, &new_object);
386		if (ACPI_FAILURE(status)) {
387			return (status);
388		}
389		break;
390
391	case ACPI_TYPE_STRING:
392
393		/* String-to-Buffer conversion. Simple data copy */
394
395		new_object =
396		    acpi_ut_create_buffer_object(original_object->string.
397						 length);
398		if (!new_object) {
399			return (AE_NO_MEMORY);
400		}
401
402		ACPI_MEMCPY(new_object->buffer.pointer,
403			    original_object->string.pointer,
404			    original_object->string.length);
405		break;
406
407	case ACPI_TYPE_PACKAGE:
408		/*
409		 * This case is often seen for predefined names that must return a
410		 * Buffer object with multiple DWORD integers within. For example,
411		 * _FDE and _GTM. The Package can be converted to a Buffer.
412		 */
413
414		/* All elements of the Package must be integers */
415
416		elements = original_object->package.elements;
417		count = original_object->package.count;
418
419		for (i = 0; i < count; i++) {
420			if ((!*elements) ||
421			    ((*elements)->common.type != ACPI_TYPE_INTEGER)) {
422				return (AE_AML_OPERAND_TYPE);
423			}
424			elements++;
425		}
426
427		/* Create the new buffer object to replace the Package */
428
429		new_object = acpi_ut_create_buffer_object(ACPI_MUL_4(count));
430		if (!new_object) {
431			return (AE_NO_MEMORY);
432		}
433
434		/* Copy the package elements (integers) to the buffer as DWORDs */
435
436		elements = original_object->package.elements;
437		dword_buffer = ACPI_CAST_PTR(u32, new_object->buffer.pointer);
438
439		for (i = 0; i < count; i++) {
440			*dword_buffer = (u32) (*elements)->integer.value;
441			dword_buffer++;
442			elements++;
443		}
444		break;
445
446	default:
447		return (AE_AML_OPERAND_TYPE);
448	}
449
450	*return_object = new_object;
451	return (AE_OK);
452}
453
454/*******************************************************************************
455 *
456 * FUNCTION:    acpi_ns_convert_to_package
457 *
458 * PARAMETERS:  original_object     - Object to be converted
459 *              return_object       - Where the new converted object is returned
460 *
461 * RETURN:      Status. AE_OK if conversion was successful.
462 *
463 * DESCRIPTION: Attempt to convert a Buffer object to a Package. Each byte of
464 *              the buffer is converted to a single integer package element.
465 *
466 ******************************************************************************/
467
468static acpi_status
469acpi_ns_convert_to_package(union acpi_operand_object *original_object,
470			   union acpi_operand_object **return_object)
471{
472	union acpi_operand_object *new_object;
473	union acpi_operand_object **elements;
474	u32 length;
475	u8 *buffer;
476
477	switch (original_object->common.type) {
478	case ACPI_TYPE_BUFFER:
479
480		/* Buffer-to-Package conversion */
481
482		length = original_object->buffer.length;
483		new_object = acpi_ut_create_package_object(length);
484		if (!new_object) {
485			return (AE_NO_MEMORY);
486		}
487
488		/* Convert each buffer byte to an integer package element */
489
490		elements = new_object->package.elements;
491		buffer = original_object->buffer.pointer;
492
493		while (length--) {
494			*elements =
495			    acpi_ut_create_integer_object((u64) *buffer);
496			if (!*elements) {
497				acpi_ut_remove_reference(new_object);
498				return (AE_NO_MEMORY);
499			}
500			elements++;
501			buffer++;
502		}
503		break;
504
505	default:
506		return (AE_AML_OPERAND_TYPE);
507	}
508
509	*return_object = new_object;
510	return (AE_OK);
511}
512
513/*******************************************************************************
514 *
515 * FUNCTION:    acpi_ns_repair_null_element
516 *
517 * PARAMETERS:  Data                - Pointer to validation data structure
518 *              expected_btypes     - Object types expected
519 *              package_index       - Index of object within parent package (if
520 *                                    applicable - ACPI_NOT_PACKAGE_ELEMENT
521 *                                    otherwise)
522 *              return_object_ptr   - Pointer to the object returned from the
523 *                                    evaluation of a method or object
524 *
525 * RETURN:      Status. AE_OK if repair was successful.
526 *
527 * DESCRIPTION: Attempt to repair a NULL element of a returned Package object.
528 *
529 ******************************************************************************/
530
531acpi_status
532acpi_ns_repair_null_element(struct acpi_predefined_data *data,
533			    u32 expected_btypes,
534			    u32 package_index,
535			    union acpi_operand_object **return_object_ptr)
536{
537	union acpi_operand_object *return_object = *return_object_ptr;
538	union acpi_operand_object *new_object;
539
540	ACPI_FUNCTION_NAME(ns_repair_null_element);
541
542	/* No repair needed if return object is non-NULL */
543
544	if (return_object) {
545		return (AE_OK);
546	}
547
548	/*
549	 * Attempt to repair a NULL element of a Package object. This applies to
550	 * predefined names that return a fixed-length package and each element
551	 * is required. It does not apply to variable-length packages where NULL
552	 * elements are allowed, especially at the end of the package.
553	 */
554	if (expected_btypes & ACPI_RTYPE_INTEGER) {
555
556		/* Need an Integer - create a zero-value integer */
557
558		new_object = acpi_ut_create_integer_object((u64)0);
559	} else if (expected_btypes & ACPI_RTYPE_STRING) {
560
561		/* Need a String - create a NULL string */
562
563		new_object = acpi_ut_create_string_object(0);
564	} else if (expected_btypes & ACPI_RTYPE_BUFFER) {
565
566		/* Need a Buffer - create a zero-length buffer */
567
568		new_object = acpi_ut_create_buffer_object(0);
569	} else {
570		/* Error for all other expected types */
571
572		return (AE_AML_OPERAND_TYPE);
573	}
574
575	if (!new_object) {
576		return (AE_NO_MEMORY);
577	}
578
579	/* Set the reference count according to the parent Package object */
580
581	new_object->common.reference_count =
582	    data->parent_package->common.reference_count;
583
584	ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
585			  "%s: Converted NULL package element to expected %s at index %u\n",
586			  data->pathname,
587			  acpi_ut_get_object_type_name(new_object),
588			  package_index));
589
590	*return_object_ptr = new_object;
591	data->flags |= ACPI_OBJECT_REPAIRED;
592	return (AE_OK);
593}
594
595/******************************************************************************
596 *
597 * FUNCTION:    acpi_ns_remove_null_elements
598 *
599 * PARAMETERS:  Data                - Pointer to validation data structure
600 *              package_type        - An acpi_return_package_types value
601 *              obj_desc            - A Package object
602 *
603 * RETURN:      None.
604 *
605 * DESCRIPTION: Remove all NULL package elements from packages that contain
606 *              a variable number of sub-packages. For these types of
607 *              packages, NULL elements can be safely removed.
608 *
609 *****************************************************************************/
610
611void
612acpi_ns_remove_null_elements(struct acpi_predefined_data *data,
613			     u8 package_type,
614			     union acpi_operand_object *obj_desc)
615{
616	union acpi_operand_object **source;
617	union acpi_operand_object **dest;
618	u32 count;
619	u32 new_count;
620	u32 i;
621
622	ACPI_FUNCTION_NAME(ns_remove_null_elements);
623
624	/*
625	 * We can safely remove all NULL elements from these package types:
626	 * PTYPE1_VAR packages contain a variable number of simple data types.
627	 * PTYPE2 packages contain a variable number of sub-packages.
628	 */
629	switch (package_type) {
630	case ACPI_PTYPE1_VAR:
631	case ACPI_PTYPE2:
632	case ACPI_PTYPE2_COUNT:
633	case ACPI_PTYPE2_PKG_COUNT:
634	case ACPI_PTYPE2_FIXED:
635	case ACPI_PTYPE2_MIN:
636	case ACPI_PTYPE2_REV_FIXED:
 
637		break;
638
639	default:
 
640	case ACPI_PTYPE1_FIXED:
641	case ACPI_PTYPE1_OPTION:
642		return;
643	}
644
645	count = obj_desc->package.count;
646	new_count = count;
647
648	source = obj_desc->package.elements;
649	dest = source;
650
651	/* Examine all elements of the package object, remove nulls */
652
653	for (i = 0; i < count; i++) {
654		if (!*source) {
655			new_count--;
656		} else {
657			*dest = *source;
658			dest++;
659		}
 
660		source++;
661	}
662
663	/* Update parent package if any null elements were removed */
664
665	if (new_count < count) {
666		ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
667				  "%s: Found and removed %u NULL elements\n",
668				  data->pathname, (count - new_count)));
669
670		/* NULL terminate list and update the package count */
671
672		*dest = NULL;
673		obj_desc->package.count = new_count;
674	}
675}
676
677/*******************************************************************************
678 *
679 * FUNCTION:    acpi_ns_repair_package_list
680 *
681 * PARAMETERS:  Data                - Pointer to validation data structure
682 *              obj_desc_ptr        - Pointer to the object to repair. The new
683 *                                    package object is returned here,
684 *                                    overwriting the old object.
685 *
686 * RETURN:      Status, new object in *obj_desc_ptr
687 *
688 * DESCRIPTION: Repair a common problem with objects that are defined to return
689 *              a variable-length Package of Packages. If the variable-length
690 *              is one, some BIOS code mistakenly simply declares a single
691 *              Package instead of a Package with one sub-Package. This
692 *              function attempts to repair this error by wrapping a Package
693 *              object around the original Package, creating the correct
694 *              Package with one sub-Package.
695 *
696 *              Names that can be repaired in this manner include:
697 *              _ALR, _CSD, _HPX, _MLS, _PRT, _PSS, _TRT, TSS
 
698 *
699 ******************************************************************************/
700
701acpi_status
702acpi_ns_repair_package_list(struct acpi_predefined_data *data,
703			    union acpi_operand_object **obj_desc_ptr)
 
704{
705	union acpi_operand_object *pkg_obj_desc;
706
707	ACPI_FUNCTION_NAME(ns_repair_package_list);
708
709	/*
710	 * Create the new outer package and populate it. The new package will
711	 * have a single element, the lone subpackage.
712	 */
713	pkg_obj_desc = acpi_ut_create_package_object(1);
714	if (!pkg_obj_desc) {
715		return (AE_NO_MEMORY);
716	}
717
718	pkg_obj_desc->package.elements[0] = *obj_desc_ptr;
 
 
 
 
 
719
720	/* Return the new object in the object pointer */
721
722	*obj_desc_ptr = pkg_obj_desc;
723	data->flags |= ACPI_OBJECT_REPAIRED;
724
725	ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
726			  "%s: Repaired incorrectly formed Package\n",
727			  data->pathname));
728
729	return (AE_OK);
730}
v5.9
  1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
  2/******************************************************************************
  3 *
  4 * Module Name: nsrepair - Repair for objects returned by predefined methods
  5 *
  6 * Copyright (C) 2000 - 2020, Intel Corp.
 
 
 
 
  7 *
  8 *****************************************************************************/
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
  9
 10#include <acpi/acpi.h>
 11#include "accommon.h"
 12#include "acnamesp.h"
 13#include "acinterp.h"
 14#include "acpredef.h"
 15#include "amlresrc.h"
 16
 17#define _COMPONENT          ACPI_NAMESPACE
 18ACPI_MODULE_NAME("nsrepair")
 19
 20/*******************************************************************************
 21 *
 22 * This module attempts to repair or convert objects returned by the
 23 * predefined methods to an object type that is expected, as per the ACPI
 24 * specification. The need for this code is dictated by the many machines that
 25 * return incorrect types for the standard predefined methods. Performing these
 26 * conversions here, in one place, eliminates the need for individual ACPI
 27 * device drivers to do the same. Note: Most of these conversions are different
 28 * than the internal object conversion routines used for implicit object
 29 * conversion.
 30 *
 31 * The following conversions can be performed as necessary:
 32 *
 33 * Integer -> String
 34 * Integer -> Buffer
 35 * String  -> Integer
 36 * String  -> Buffer
 37 * Buffer  -> Integer
 38 * Buffer  -> String
 39 * Buffer  -> Package of Integers
 40 * Package -> Package of one Package
 41 *
 42 * Additional conversions that are available:
 43 *  Convert a null return or zero return value to an end_tag descriptor
 44 *  Convert an ASCII string to a Unicode buffer
 45 *
 46 * An incorrect standalone object is wrapped with required outer package
 47 *
 48 * Additional possible repairs:
 49 * Required package elements that are NULL replaced by Integer/String/Buffer
 
 50 *
 51 ******************************************************************************/
 52/* Local prototypes */
 53static const struct acpi_simple_repair_info *acpi_ns_match_simple_repair(struct
 54									 acpi_namespace_node
 55									 *node,
 56									 u32
 57									 return_btype,
 58									 u32
 59									 package_index);
 60
 61/*
 62 * Special but simple repairs for some names.
 63 *
 64 * 2nd argument: Unexpected types that can be repaired
 65 */
 66static const struct acpi_simple_repair_info acpi_object_repair_info[] = {
 67	/* Resource descriptor conversions */
 68
 69	{"_CRS",
 70	 ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING | ACPI_RTYPE_BUFFER |
 71	 ACPI_RTYPE_NONE,
 72	 ACPI_NOT_PACKAGE_ELEMENT,
 73	 acpi_ns_convert_to_resource},
 74	{"_DMA",
 75	 ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING | ACPI_RTYPE_BUFFER |
 76	 ACPI_RTYPE_NONE,
 77	 ACPI_NOT_PACKAGE_ELEMENT,
 78	 acpi_ns_convert_to_resource},
 79	{"_PRS",
 80	 ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING | ACPI_RTYPE_BUFFER |
 81	 ACPI_RTYPE_NONE,
 82	 ACPI_NOT_PACKAGE_ELEMENT,
 83	 acpi_ns_convert_to_resource},
 84
 85	/* Object reference conversions */
 86
 87	{"_DEP", ACPI_RTYPE_STRING, ACPI_ALL_PACKAGE_ELEMENTS,
 88	 acpi_ns_convert_to_reference},
 89
 90	/* Unicode conversions */
 91
 92	{"_MLS", ACPI_RTYPE_STRING, 1,
 93	 acpi_ns_convert_to_unicode},
 94	{"_STR", ACPI_RTYPE_STRING | ACPI_RTYPE_BUFFER,
 95	 ACPI_NOT_PACKAGE_ELEMENT,
 96	 acpi_ns_convert_to_unicode},
 97	{{0, 0, 0, 0}, 0, 0, NULL}	/* Table terminator */
 98};
 99
100/*******************************************************************************
101 *
102 * FUNCTION:    acpi_ns_simple_repair
103 *
104 * PARAMETERS:  info                - Method execution information block
105 *              expected_btypes     - Object types expected
106 *              package_index       - Index of object within parent package (if
107 *                                    applicable - ACPI_NOT_PACKAGE_ELEMENT
108 *                                    otherwise)
109 *              return_object_ptr   - Pointer to the object returned from the
110 *                                    evaluation of a method or object
111 *
112 * RETURN:      Status. AE_OK if repair was successful.
113 *
114 * DESCRIPTION: Attempt to repair/convert a return object of a type that was
115 *              not expected.
116 *
117 ******************************************************************************/
118
119acpi_status
120acpi_ns_simple_repair(struct acpi_evaluate_info *info,
121		      u32 expected_btypes,
122		      u32 package_index,
123		      union acpi_operand_object **return_object_ptr)
124{
125	union acpi_operand_object *return_object = *return_object_ptr;
126	union acpi_operand_object *new_object = NULL;
127	acpi_status status;
128	const struct acpi_simple_repair_info *predefined;
129
130	ACPI_FUNCTION_NAME(ns_simple_repair);
131
132	/*
133	 * Special repairs for certain names that are in the repair table.
134	 * Check if this name is in the list of repairable names.
135	 */
136	predefined = acpi_ns_match_simple_repair(info->node,
137						 info->return_btype,
138						 package_index);
139	if (predefined) {
140		if (!return_object) {
141			ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
142					      ACPI_WARN_ALWAYS,
143					      "Missing expected return value"));
144		}
145
146		status = predefined->object_converter(info->node, return_object,
147						      &new_object);
148		if (ACPI_FAILURE(status)) {
149
150			/* A fatal error occurred during a conversion */
151
152			ACPI_EXCEPTION((AE_INFO, status,
153					"During return object analysis"));
154			return (status);
155		}
156		if (new_object) {
157			goto object_repaired;
158		}
159	}
160
161	/*
162	 * Do not perform simple object repair unless the return type is not
163	 * expected.
164	 */
165	if (info->return_btype & expected_btypes) {
166		return (AE_OK);
167	}
168
169	/*
170	 * At this point, we know that the type of the returned object was not
171	 * one of the expected types for this predefined name. Attempt to
172	 * repair the object by converting it to one of the expected object
173	 * types for this predefined name.
174	 */
175
176	/*
177	 * If there is no return value, check if we require a return value for
178	 * this predefined name. Either one return value is expected, or none,
179	 * for both methods and other objects.
180	 *
181	 * Try to fix if there was no return object. Warning if failed to fix.
182	 */
183	if (!return_object) {
184		if (expected_btypes && (!(expected_btypes & ACPI_RTYPE_NONE))) {
185			if (package_index != ACPI_NOT_PACKAGE_ELEMENT) {
186				ACPI_WARN_PREDEFINED((AE_INFO,
187						      info->full_pathname,
188						      ACPI_WARN_ALWAYS,
189						      "Found unexpected NULL package element"));
190
191				status =
192				    acpi_ns_repair_null_element(info,
193								expected_btypes,
194								package_index,
195								return_object_ptr);
196				if (ACPI_SUCCESS(status)) {
197					return (AE_OK);	/* Repair was successful */
198				}
199			} else {
200				ACPI_WARN_PREDEFINED((AE_INFO,
201						      info->full_pathname,
202						      ACPI_WARN_ALWAYS,
203						      "Missing expected return value"));
204			}
205
206			return (AE_AML_NO_RETURN_VALUE);
207		}
208	}
209
210	if (expected_btypes & ACPI_RTYPE_INTEGER) {
211		status = acpi_ns_convert_to_integer(return_object, &new_object);
212		if (ACPI_SUCCESS(status)) {
213			goto object_repaired;
214		}
215	}
216	if (expected_btypes & ACPI_RTYPE_STRING) {
217		status = acpi_ns_convert_to_string(return_object, &new_object);
218		if (ACPI_SUCCESS(status)) {
219			goto object_repaired;
220		}
221	}
222	if (expected_btypes & ACPI_RTYPE_BUFFER) {
223		status = acpi_ns_convert_to_buffer(return_object, &new_object);
224		if (ACPI_SUCCESS(status)) {
225			goto object_repaired;
226		}
227	}
228	if (expected_btypes & ACPI_RTYPE_PACKAGE) {
229		/*
230		 * A package is expected. We will wrap the existing object with a
231		 * new package object. It is often the case that if a variable-length
232		 * package is required, but there is only a single object needed, the
233		 * BIOS will return that object instead of wrapping it with a Package
234		 * object. Note: after the wrapping, the package will be validated
235		 * for correct contents (expected object type or types).
236		 */
237		status =
238		    acpi_ns_wrap_with_package(info, return_object, &new_object);
239		if (ACPI_SUCCESS(status)) {
240			/*
241			 * The original object just had its reference count
242			 * incremented for being inserted into the new package.
243			 */
244			*return_object_ptr = new_object;	/* New Package object */
245			info->return_flags |= ACPI_OBJECT_REPAIRED;
246			return (AE_OK);
247		}
248	}
249
250	/* We cannot repair this object */
251
252	return (AE_AML_OPERAND_TYPE);
253
254object_repaired:
255
256	/* Object was successfully repaired */
257
 
 
 
 
 
 
258	if (package_index != ACPI_NOT_PACKAGE_ELEMENT) {
 
 
259
260		/* Update reference count of new object */
261
262		if (!(info->return_flags & ACPI_OBJECT_WRAPPED)) {
263			new_object->common.reference_count =
264			    return_object->common.reference_count;
265		}
266
267		ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
268				  "%s: Converted %s to expected %s at Package index %u\n",
269				  info->full_pathname,
270				  acpi_ut_get_object_type_name(return_object),
271				  acpi_ut_get_object_type_name(new_object),
272				  package_index));
273	} else {
274		ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
275				  "%s: Converted %s to expected %s\n",
276				  info->full_pathname,
277				  acpi_ut_get_object_type_name(return_object),
278				  acpi_ut_get_object_type_name(new_object)));
279	}
280
281	/* Delete old object, install the new return object */
282
283	acpi_ut_remove_reference(return_object);
284	*return_object_ptr = new_object;
285	info->return_flags |= ACPI_OBJECT_REPAIRED;
286	return (AE_OK);
287}
288
289/******************************************************************************
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
290 *
291 * FUNCTION:    acpi_ns_match_simple_repair
292 *
293 * PARAMETERS:  node                - Namespace node for the method/object
294 *              return_btype        - Object type that was returned
295 *              package_index       - Index of object within parent package (if
296 *                                    applicable - ACPI_NOT_PACKAGE_ELEMENT
297 *                                    otherwise)
298 *
299 * RETURN:      Pointer to entry in repair table. NULL indicates not found.
300 *
301 * DESCRIPTION: Check an object name against the repairable object list.
302 *
303 *****************************************************************************/
304
305static const struct acpi_simple_repair_info *acpi_ns_match_simple_repair(struct
306									 acpi_namespace_node
307									 *node,
308									 u32
309									 return_btype,
310									 u32
311									 package_index)
312{
313	const struct acpi_simple_repair_info *this_name;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
314
315	/* Search info table for a repairable predefined method/object name */
 
 
 
316
317	this_name = acpi_object_repair_info;
318	while (this_name->object_converter) {
319		if (ACPI_COMPARE_NAMESEG(node->name.ascii, this_name->name)) {
 
 
 
320
321			/* Check if we can actually repair this name/type combination */
322
323			if ((return_btype & this_name->unexpected_btypes) &&
324			    (this_name->package_index ==
325			     ACPI_ALL_PACKAGE_ELEMENTS
326			     || package_index == this_name->package_index)) {
327				return (this_name);
 
 
328			}
 
 
 
 
329
330			return (NULL);
 
 
331		}
332
333		this_name++;
 
 
 
 
 
 
 
 
 
 
 
 
 
334	}
335
336	return (NULL);		/* Name was not found in the repair table */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
337}
338
339/*******************************************************************************
340 *
341 * FUNCTION:    acpi_ns_repair_null_element
342 *
343 * PARAMETERS:  info                - Method execution information block
344 *              expected_btypes     - Object types expected
345 *              package_index       - Index of object within parent package (if
346 *                                    applicable - ACPI_NOT_PACKAGE_ELEMENT
347 *                                    otherwise)
348 *              return_object_ptr   - Pointer to the object returned from the
349 *                                    evaluation of a method or object
350 *
351 * RETURN:      Status. AE_OK if repair was successful.
352 *
353 * DESCRIPTION: Attempt to repair a NULL element of a returned Package object.
354 *
355 ******************************************************************************/
356
357acpi_status
358acpi_ns_repair_null_element(struct acpi_evaluate_info *info,
359			    u32 expected_btypes,
360			    u32 package_index,
361			    union acpi_operand_object **return_object_ptr)
362{
363	union acpi_operand_object *return_object = *return_object_ptr;
364	union acpi_operand_object *new_object;
365
366	ACPI_FUNCTION_NAME(ns_repair_null_element);
367
368	/* No repair needed if return object is non-NULL */
369
370	if (return_object) {
371		return (AE_OK);
372	}
373
374	/*
375	 * Attempt to repair a NULL element of a Package object. This applies to
376	 * predefined names that return a fixed-length package and each element
377	 * is required. It does not apply to variable-length packages where NULL
378	 * elements are allowed, especially at the end of the package.
379	 */
380	if (expected_btypes & ACPI_RTYPE_INTEGER) {
381
382		/* Need an integer - create a zero-value integer */
383
384		new_object = acpi_ut_create_integer_object((u64)0);
385	} else if (expected_btypes & ACPI_RTYPE_STRING) {
386
387		/* Need a string - create a NULL string */
388
389		new_object = acpi_ut_create_string_object(0);
390	} else if (expected_btypes & ACPI_RTYPE_BUFFER) {
391
392		/* Need a buffer - create a zero-length buffer */
393
394		new_object = acpi_ut_create_buffer_object(0);
395	} else {
396		/* Error for all other expected types */
397
398		return (AE_AML_OPERAND_TYPE);
399	}
400
401	if (!new_object) {
402		return (AE_NO_MEMORY);
403	}
404
405	/* Set the reference count according to the parent Package object */
406
407	new_object->common.reference_count =
408	    info->parent_package->common.reference_count;
409
410	ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
411			  "%s: Converted NULL package element to expected %s at index %u\n",
412			  info->full_pathname,
413			  acpi_ut_get_object_type_name(new_object),
414			  package_index));
415
416	*return_object_ptr = new_object;
417	info->return_flags |= ACPI_OBJECT_REPAIRED;
418	return (AE_OK);
419}
420
421/******************************************************************************
422 *
423 * FUNCTION:    acpi_ns_remove_null_elements
424 *
425 * PARAMETERS:  info                - Method execution information block
426 *              package_type        - An acpi_return_package_types value
427 *              obj_desc            - A Package object
428 *
429 * RETURN:      None.
430 *
431 * DESCRIPTION: Remove all NULL package elements from packages that contain
432 *              a variable number of subpackages. For these types of
433 *              packages, NULL elements can be safely removed.
434 *
435 *****************************************************************************/
436
437void
438acpi_ns_remove_null_elements(struct acpi_evaluate_info *info,
439			     u8 package_type,
440			     union acpi_operand_object *obj_desc)
441{
442	union acpi_operand_object **source;
443	union acpi_operand_object **dest;
444	u32 count;
445	u32 new_count;
446	u32 i;
447
448	ACPI_FUNCTION_NAME(ns_remove_null_elements);
449
450	/*
451	 * We can safely remove all NULL elements from these package types:
452	 * PTYPE1_VAR packages contain a variable number of simple data types.
453	 * PTYPE2 packages contain a variable number of subpackages.
454	 */
455	switch (package_type) {
456	case ACPI_PTYPE1_VAR:
457	case ACPI_PTYPE2:
458	case ACPI_PTYPE2_COUNT:
459	case ACPI_PTYPE2_PKG_COUNT:
460	case ACPI_PTYPE2_FIXED:
461	case ACPI_PTYPE2_MIN:
462	case ACPI_PTYPE2_REV_FIXED:
463	case ACPI_PTYPE2_FIX_VAR:
464		break;
465
466	default:
467	case ACPI_PTYPE2_VAR_VAR:
468	case ACPI_PTYPE1_FIXED:
469	case ACPI_PTYPE1_OPTION:
470		return;
471	}
472
473	count = obj_desc->package.count;
474	new_count = count;
475
476	source = obj_desc->package.elements;
477	dest = source;
478
479	/* Examine all elements of the package object, remove nulls */
480
481	for (i = 0; i < count; i++) {
482		if (!*source) {
483			new_count--;
484		} else {
485			*dest = *source;
486			dest++;
487		}
488
489		source++;
490	}
491
492	/* Update parent package if any null elements were removed */
493
494	if (new_count < count) {
495		ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
496				  "%s: Found and removed %u NULL elements\n",
497				  info->full_pathname, (count - new_count)));
498
499		/* NULL terminate list and update the package count */
500
501		*dest = NULL;
502		obj_desc->package.count = new_count;
503	}
504}
505
506/*******************************************************************************
507 *
508 * FUNCTION:    acpi_ns_wrap_with_package
509 *
510 * PARAMETERS:  info                - Method execution information block
511 *              original_object     - Pointer to the object to repair.
512 *              obj_desc_ptr        - The new package object is returned here
 
513 *
514 * RETURN:      Status, new object in *obj_desc_ptr
515 *
516 * DESCRIPTION: Repair a common problem with objects that are defined to
517 *              return a variable-length Package of sub-objects. If there is
518 *              only one sub-object, some BIOS code mistakenly simply declares
519 *              the single object instead of a Package with one sub-object.
520 *              This function attempts to repair this error by wrapping a
521 *              Package object around the original object, creating the
522 *              correct and expected Package with one sub-object.
523 *
524 *              Names that can be repaired in this manner include:
525 *              _ALR, _CSD, _HPX, _MLS, _PLD, _PRT, _PSS, _TRT, _TSS,
526 *              _BCL, _DOD, _FIX, _Sx
527 *
528 ******************************************************************************/
529
530acpi_status
531acpi_ns_wrap_with_package(struct acpi_evaluate_info *info,
532			  union acpi_operand_object *original_object,
533			  union acpi_operand_object **obj_desc_ptr)
534{
535	union acpi_operand_object *pkg_obj_desc;
536
537	ACPI_FUNCTION_NAME(ns_wrap_with_package);
538
539	/*
540	 * Create the new outer package and populate it. The new
541	 * package will have a single element, the lone sub-object.
542	 */
543	pkg_obj_desc = acpi_ut_create_package_object(1);
544	if (!pkg_obj_desc) {
545		return (AE_NO_MEMORY);
546	}
547
548	pkg_obj_desc->package.elements[0] = original_object;
549
550	ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
551			  "%s: Wrapped %s with expected Package object\n",
552			  info->full_pathname,
553			  acpi_ut_get_object_type_name(original_object)));
554
555	/* Return the new object in the object pointer */
556
557	*obj_desc_ptr = pkg_obj_desc;
558	info->return_flags |= ACPI_OBJECT_REPAIRED | ACPI_OBJECT_WRAPPED;
 
 
 
 
 
559	return (AE_OK);
560}