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}
v4.6
  1/******************************************************************************
  2 *
  3 * Module Name: nsrepair - Repair for objects returned by predefined methods
  4 *
  5 *****************************************************************************/
  6
  7/*
  8 * Copyright (C) 2000 - 2016, 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#include "amlresrc.h"
 50
 51#define _COMPONENT          ACPI_NAMESPACE
 52ACPI_MODULE_NAME("nsrepair")
 53
 54/*******************************************************************************
 55 *
 56 * This module attempts to repair or convert objects returned by the
 57 * predefined methods to an object type that is expected, as per the ACPI
 58 * specification. The need for this code is dictated by the many machines that
 59 * return incorrect types for the standard predefined methods. Performing these
 60 * conversions here, in one place, eliminates the need for individual ACPI
 61 * device drivers to do the same. Note: Most of these conversions are different
 62 * than the internal object conversion routines used for implicit object
 63 * conversion.
 64 *
 65 * The following conversions can be performed as necessary:
 66 *
 67 * Integer -> String
 68 * Integer -> Buffer
 69 * String  -> Integer
 70 * String  -> Buffer
 71 * Buffer  -> Integer
 72 * Buffer  -> String
 73 * Buffer  -> Package of Integers
 74 * Package -> Package of one Package
 75 *
 76 * Additional conversions that are available:
 77 *  Convert a null return or zero return value to an end_tag descriptor
 78 *  Convert an ASCII string to a Unicode buffer
 79 *
 80 * An incorrect standalone object is wrapped with required outer package
 81 *
 82 * Additional possible repairs:
 83 * Required package elements that are NULL replaced by Integer/String/Buffer
 
 84 *
 85 ******************************************************************************/
 86/* Local prototypes */
 87static const struct acpi_simple_repair_info *acpi_ns_match_simple_repair(struct
 88									 acpi_namespace_node
 89									 *node,
 90									 u32
 91									 return_btype,
 92									 u32
 93									 package_index);
 94
 95/*
 96 * Special but simple repairs for some names.
 97 *
 98 * 2nd argument: Unexpected types that can be repaired
 99 */
100static const struct acpi_simple_repair_info acpi_object_repair_info[] = {
101	/* Resource descriptor conversions */
102
103	{"_CRS",
104	 ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING | ACPI_RTYPE_BUFFER |
105	 ACPI_RTYPE_NONE,
106	 ACPI_NOT_PACKAGE_ELEMENT,
107	 acpi_ns_convert_to_resource},
108	{"_DMA",
109	 ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING | ACPI_RTYPE_BUFFER |
110	 ACPI_RTYPE_NONE,
111	 ACPI_NOT_PACKAGE_ELEMENT,
112	 acpi_ns_convert_to_resource},
113	{"_PRS",
114	 ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING | ACPI_RTYPE_BUFFER |
115	 ACPI_RTYPE_NONE,
116	 ACPI_NOT_PACKAGE_ELEMENT,
117	 acpi_ns_convert_to_resource},
118
119	/* Object reference conversions */
120
121	{"_DEP", ACPI_RTYPE_STRING, ACPI_ALL_PACKAGE_ELEMENTS,
122	 acpi_ns_convert_to_reference},
123
124	/* Unicode conversions */
125
126	{"_MLS", ACPI_RTYPE_STRING, 1,
127	 acpi_ns_convert_to_unicode},
128	{"_STR", ACPI_RTYPE_STRING | ACPI_RTYPE_BUFFER,
129	 ACPI_NOT_PACKAGE_ELEMENT,
130	 acpi_ns_convert_to_unicode},
131	{{0, 0, 0, 0}, 0, 0, NULL}	/* Table terminator */
132};
133
134/*******************************************************************************
135 *
136 * FUNCTION:    acpi_ns_simple_repair
137 *
138 * PARAMETERS:  info                - Method execution information block
139 *              expected_btypes     - Object types expected
140 *              package_index       - Index of object within parent package (if
141 *                                    applicable - ACPI_NOT_PACKAGE_ELEMENT
142 *                                    otherwise)
143 *              return_object_ptr   - Pointer to the object returned from the
144 *                                    evaluation of a method or object
145 *
146 * RETURN:      Status. AE_OK if repair was successful.
147 *
148 * DESCRIPTION: Attempt to repair/convert a return object of a type that was
149 *              not expected.
150 *
151 ******************************************************************************/
152
153acpi_status
154acpi_ns_simple_repair(struct acpi_evaluate_info *info,
155		      u32 expected_btypes,
156		      u32 package_index,
157		      union acpi_operand_object **return_object_ptr)
158{
159	union acpi_operand_object *return_object = *return_object_ptr;
160	union acpi_operand_object *new_object = NULL;
161	acpi_status status;
162	const struct acpi_simple_repair_info *predefined;
163
164	ACPI_FUNCTION_NAME(ns_simple_repair);
165
166	/*
167	 * Special repairs for certain names that are in the repair table.
168	 * Check if this name is in the list of repairable names.
169	 */
170	predefined = acpi_ns_match_simple_repair(info->node,
171						 info->return_btype,
172						 package_index);
173	if (predefined) {
174		if (!return_object) {
175			ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
176					      ACPI_WARN_ALWAYS,
177					      "Missing expected return value"));
178		}
179
180		status = predefined->object_converter(info->node, return_object,
181						      &new_object);
182		if (ACPI_FAILURE(status)) {
183
184			/* A fatal error occurred during a conversion */
185
186			ACPI_EXCEPTION((AE_INFO, status,
187					"During return object analysis"));
188			return (status);
189		}
190		if (new_object) {
191			goto object_repaired;
192		}
193	}
194
195	/*
196	 * Do not perform simple object repair unless the return type is not
197	 * expected.
198	 */
199	if (info->return_btype & expected_btypes) {
200		return (AE_OK);
201	}
202
203	/*
204	 * At this point, we know that the type of the returned object was not
205	 * one of the expected types for this predefined name. Attempt to
206	 * repair the object by converting it to one of the expected object
207	 * types for this predefined name.
208	 */
209
210	/*
211	 * If there is no return value, check if we require a return value for
212	 * this predefined name. Either one return value is expected, or none,
213	 * for both methods and other objects.
214	 *
215	 * Try to fix if there was no return object. Warning if failed to fix.
216	 */
217	if (!return_object) {
218		if (expected_btypes && (!(expected_btypes & ACPI_RTYPE_NONE))) {
219			if (package_index != ACPI_NOT_PACKAGE_ELEMENT) {
220				ACPI_WARN_PREDEFINED((AE_INFO,
221						      info->full_pathname,
222						      ACPI_WARN_ALWAYS,
223						      "Found unexpected NULL package element"));
224
225				status =
226				    acpi_ns_repair_null_element(info,
227								expected_btypes,
228								package_index,
229								return_object_ptr);
230				if (ACPI_SUCCESS(status)) {
231					return (AE_OK);	/* Repair was successful */
232				}
233			} else {
234				ACPI_WARN_PREDEFINED((AE_INFO,
235						      info->full_pathname,
236						      ACPI_WARN_ALWAYS,
237						      "Missing expected return value"));
238			}
239
240			return (AE_AML_NO_RETURN_VALUE);
241		}
242	}
243
244	if (expected_btypes & ACPI_RTYPE_INTEGER) {
245		status = acpi_ns_convert_to_integer(return_object, &new_object);
246		if (ACPI_SUCCESS(status)) {
247			goto object_repaired;
248		}
249	}
250	if (expected_btypes & ACPI_RTYPE_STRING) {
251		status = acpi_ns_convert_to_string(return_object, &new_object);
252		if (ACPI_SUCCESS(status)) {
253			goto object_repaired;
254		}
255	}
256	if (expected_btypes & ACPI_RTYPE_BUFFER) {
257		status = acpi_ns_convert_to_buffer(return_object, &new_object);
258		if (ACPI_SUCCESS(status)) {
259			goto object_repaired;
260		}
261	}
262	if (expected_btypes & ACPI_RTYPE_PACKAGE) {
263		/*
264		 * A package is expected. We will wrap the existing object with a
265		 * new package object. It is often the case that if a variable-length
266		 * package is required, but there is only a single object needed, the
267		 * BIOS will return that object instead of wrapping it with a Package
268		 * object. Note: after the wrapping, the package will be validated
269		 * for correct contents (expected object type or types).
270		 */
271		status =
272		    acpi_ns_wrap_with_package(info, return_object, &new_object);
273		if (ACPI_SUCCESS(status)) {
274			/*
275			 * The original object just had its reference count
276			 * incremented for being inserted into the new package.
277			 */
278			*return_object_ptr = new_object;	/* New Package object */
279			info->return_flags |= ACPI_OBJECT_REPAIRED;
280			return (AE_OK);
281		}
282	}
283
284	/* We cannot repair this object */
285
286	return (AE_AML_OPERAND_TYPE);
287
288object_repaired:
289
290	/* Object was successfully repaired */
291
 
 
 
 
 
 
292	if (package_index != ACPI_NOT_PACKAGE_ELEMENT) {
293		/*
294		 * The original object is a package element. We need to
295		 * decrement the reference count of the original object,
296		 * for removing it from the package.
297		 *
298		 * However, if the original object was just wrapped with a
299		 * package object as part of the repair, we don't need to
300		 * change the reference count.
301		 */
302		if (!(info->return_flags & ACPI_OBJECT_WRAPPED)) {
303			new_object->common.reference_count =
304			    return_object->common.reference_count;
305
306			if (return_object->common.reference_count > 1) {
307				return_object->common.reference_count--;
308			}
309		}
310
311		ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
312				  "%s: Converted %s to expected %s at Package index %u\n",
313				  info->full_pathname,
314				  acpi_ut_get_object_type_name(return_object),
315				  acpi_ut_get_object_type_name(new_object),
316				  package_index));
317	} else {
318		ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
319				  "%s: Converted %s to expected %s\n",
320				  info->full_pathname,
321				  acpi_ut_get_object_type_name(return_object),
322				  acpi_ut_get_object_type_name(new_object)));
323	}
324
325	/* Delete old object, install the new return object */
326
327	acpi_ut_remove_reference(return_object);
328	*return_object_ptr = new_object;
329	info->return_flags |= ACPI_OBJECT_REPAIRED;
330	return (AE_OK);
331}
332
333/******************************************************************************
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
334 *
335 * FUNCTION:    acpi_ns_match_simple_repair
336 *
337 * PARAMETERS:  node                - Namespace node for the method/object
338 *              return_btype        - Object type that was returned
339 *              package_index       - Index of object within parent package (if
340 *                                    applicable - ACPI_NOT_PACKAGE_ELEMENT
341 *                                    otherwise)
342 *
343 * RETURN:      Pointer to entry in repair table. NULL indicates not found.
344 *
345 * DESCRIPTION: Check an object name against the repairable object list.
346 *
347 *****************************************************************************/
348
349static const struct acpi_simple_repair_info *acpi_ns_match_simple_repair(struct
350									 acpi_namespace_node
351									 *node,
352									 u32
353									 return_btype,
354									 u32
355									 package_index)
356{
357	const struct acpi_simple_repair_info *this_name;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
358
359	/* Search info table for a repairable predefined method/object name */
 
 
 
 
 
 
 
 
 
 
360
361	this_name = acpi_object_repair_info;
362	while (this_name->object_converter) {
363		if (ACPI_COMPARE_NAME(node->name.ascii, this_name->name)) {
364
365			/* Check if we can actually repair this name/type combination */
 
366
367			if ((return_btype & this_name->unexpected_btypes) &&
368			    (this_name->package_index ==
369			     ACPI_ALL_PACKAGE_ELEMENTS
370			     || package_index == this_name->package_index)) {
371				return (this_name);
372			}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
373
374			return (NULL);
 
 
 
 
 
 
 
 
 
 
 
375		}
 
376
377		this_name++;
 
378	}
379
380	return (NULL);		/* Name was not found in the repair table */
 
381}
382
383/*******************************************************************************
384 *
385 * FUNCTION:    acpi_ns_repair_null_element
386 *
387 * PARAMETERS:  info                - Method execution information block
388 *              expected_btypes     - Object types expected
389 *              package_index       - Index of object within parent package (if
390 *                                    applicable - ACPI_NOT_PACKAGE_ELEMENT
391 *                                    otherwise)
392 *              return_object_ptr   - Pointer to the object returned from the
393 *                                    evaluation of a method or object
394 *
395 * RETURN:      Status. AE_OK if repair was successful.
396 *
397 * DESCRIPTION: Attempt to repair a NULL element of a returned Package object.
398 *
399 ******************************************************************************/
400
401acpi_status
402acpi_ns_repair_null_element(struct acpi_evaluate_info * info,
403			    u32 expected_btypes,
404			    u32 package_index,
405			    union acpi_operand_object **return_object_ptr)
406{
407	union acpi_operand_object *return_object = *return_object_ptr;
408	union acpi_operand_object *new_object;
409
410	ACPI_FUNCTION_NAME(ns_repair_null_element);
411
412	/* No repair needed if return object is non-NULL */
413
414	if (return_object) {
415		return (AE_OK);
416	}
417
418	/*
419	 * Attempt to repair a NULL element of a Package object. This applies to
420	 * predefined names that return a fixed-length package and each element
421	 * is required. It does not apply to variable-length packages where NULL
422	 * elements are allowed, especially at the end of the package.
423	 */
424	if (expected_btypes & ACPI_RTYPE_INTEGER) {
425
426		/* Need an integer - create a zero-value integer */
427
428		new_object = acpi_ut_create_integer_object((u64)0);
429	} else if (expected_btypes & ACPI_RTYPE_STRING) {
430
431		/* Need a string - create a NULL string */
432
433		new_object = acpi_ut_create_string_object(0);
434	} else if (expected_btypes & ACPI_RTYPE_BUFFER) {
435
436		/* Need a buffer - create a zero-length buffer */
437
438		new_object = acpi_ut_create_buffer_object(0);
439	} else {
440		/* Error for all other expected types */
441
442		return (AE_AML_OPERAND_TYPE);
443	}
444
445	if (!new_object) {
446		return (AE_NO_MEMORY);
447	}
448
449	/* Set the reference count according to the parent Package object */
450
451	new_object->common.reference_count =
452	    info->parent_package->common.reference_count;
453
454	ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
455			  "%s: Converted NULL package element to expected %s at index %u\n",
456			  info->full_pathname,
457			  acpi_ut_get_object_type_name(new_object),
458			  package_index));
459
460	*return_object_ptr = new_object;
461	info->return_flags |= ACPI_OBJECT_REPAIRED;
462	return (AE_OK);
463}
464
465/******************************************************************************
466 *
467 * FUNCTION:    acpi_ns_remove_null_elements
468 *
469 * PARAMETERS:  info                - Method execution information block
470 *              package_type        - An acpi_return_package_types value
471 *              obj_desc            - A Package object
472 *
473 * RETURN:      None.
474 *
475 * DESCRIPTION: Remove all NULL package elements from packages that contain
476 *              a variable number of subpackages. For these types of
477 *              packages, NULL elements can be safely removed.
478 *
479 *****************************************************************************/
480
481void
482acpi_ns_remove_null_elements(struct acpi_evaluate_info *info,
483			     u8 package_type,
484			     union acpi_operand_object *obj_desc)
485{
486	union acpi_operand_object **source;
487	union acpi_operand_object **dest;
488	u32 count;
489	u32 new_count;
490	u32 i;
491
492	ACPI_FUNCTION_NAME(ns_remove_null_elements);
493
494	/*
495	 * We can safely remove all NULL elements from these package types:
496	 * PTYPE1_VAR packages contain a variable number of simple data types.
497	 * PTYPE2 packages contain a variable number of subpackages.
498	 */
499	switch (package_type) {
500	case ACPI_PTYPE1_VAR:
501	case ACPI_PTYPE2:
502	case ACPI_PTYPE2_COUNT:
503	case ACPI_PTYPE2_PKG_COUNT:
504	case ACPI_PTYPE2_FIXED:
505	case ACPI_PTYPE2_MIN:
506	case ACPI_PTYPE2_REV_FIXED:
507	case ACPI_PTYPE2_FIX_VAR:
508		break;
509
510	default:
511	case ACPI_PTYPE2_VAR_VAR:
512	case ACPI_PTYPE1_FIXED:
513	case ACPI_PTYPE1_OPTION:
514		return;
515	}
516
517	count = obj_desc->package.count;
518	new_count = count;
519
520	source = obj_desc->package.elements;
521	dest = source;
522
523	/* Examine all elements of the package object, remove nulls */
524
525	for (i = 0; i < count; i++) {
526		if (!*source) {
527			new_count--;
528		} else {
529			*dest = *source;
530			dest++;
531		}
532
533		source++;
534	}
535
536	/* Update parent package if any null elements were removed */
537
538	if (new_count < count) {
539		ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
540				  "%s: Found and removed %u NULL elements\n",
541				  info->full_pathname, (count - new_count)));
542
543		/* NULL terminate list and update the package count */
544
545		*dest = NULL;
546		obj_desc->package.count = new_count;
547	}
548}
549
550/*******************************************************************************
551 *
552 * FUNCTION:    acpi_ns_wrap_with_package
553 *
554 * PARAMETERS:  info                - Method execution information block
555 *              original_object     - Pointer to the object to repair.
556 *              obj_desc_ptr        - The new package object is returned here
 
557 *
558 * RETURN:      Status, new object in *obj_desc_ptr
559 *
560 * DESCRIPTION: Repair a common problem with objects that are defined to
561 *              return a variable-length Package of sub-objects. If there is
562 *              only one sub-object, some BIOS code mistakenly simply declares
563 *              the single object instead of a Package with one sub-object.
564 *              This function attempts to repair this error by wrapping a
565 *              Package object around the original object, creating the
566 *              correct and expected Package with one sub-object.
567 *
568 *              Names that can be repaired in this manner include:
569 *              _ALR, _CSD, _HPX, _MLS, _PLD, _PRT, _PSS, _TRT, _TSS,
570 *              _BCL, _DOD, _FIX, _Sx
571 *
572 ******************************************************************************/
573
574acpi_status
575acpi_ns_wrap_with_package(struct acpi_evaluate_info *info,
576			  union acpi_operand_object *original_object,
577			  union acpi_operand_object **obj_desc_ptr)
578{
579	union acpi_operand_object *pkg_obj_desc;
580
581	ACPI_FUNCTION_NAME(ns_wrap_with_package);
582
583	/*
584	 * Create the new outer package and populate it. The new
585	 * package will have a single element, the lone sub-object.
586	 */
587	pkg_obj_desc = acpi_ut_create_package_object(1);
588	if (!pkg_obj_desc) {
589		return (AE_NO_MEMORY);
590	}
591
592	pkg_obj_desc->package.elements[0] = original_object;
593
594	ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
595			  "%s: Wrapped %s with expected Package object\n",
596			  info->full_pathname,
597			  acpi_ut_get_object_type_name(original_object)));
598
599	/* Return the new object in the object pointer */
600
601	*obj_desc_ptr = pkg_obj_desc;
602	info->return_flags |= ACPI_OBJECT_REPAIRED | ACPI_OBJECT_WRAPPED;
 
 
 
 
 
603	return (AE_OK);
604}