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}
v3.5.6
  1/******************************************************************************
  2 *
  3 * Module Name: nsrepair - Repair for objects returned by predefined methods
  4 *
  5 *****************************************************************************/
  6
  7/*
  8 * Copyright (C) 2000 - 2012, 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 * An incorrect standalone object is wrapped with required outer package
 75 *
 76 * Additional possible repairs:
 
 77 * Required package elements that are NULL replaced by Integer/String/Buffer
 
 78 *
 79 ******************************************************************************/
 80/* Local prototypes */
 81static acpi_status
 82acpi_ns_convert_to_integer(union acpi_operand_object *original_object,
 83			   union acpi_operand_object **return_object);
 84
 85static acpi_status
 86acpi_ns_convert_to_string(union acpi_operand_object *original_object,
 87			  union acpi_operand_object **return_object);
 88
 89static acpi_status
 90acpi_ns_convert_to_buffer(union acpi_operand_object *original_object,
 91			  union acpi_operand_object **return_object);
 92
 
 
 
 
 93/*******************************************************************************
 94 *
 95 * FUNCTION:    acpi_ns_repair_object
 96 *
 97 * PARAMETERS:  Data                - Pointer to validation data structure
 98 *              expected_btypes     - Object types expected
 99 *              package_index       - Index of object within parent package (if
100 *                                    applicable - ACPI_NOT_PACKAGE_ELEMENT
101 *                                    otherwise)
102 *              return_object_ptr   - Pointer to the object returned from the
103 *                                    evaluation of a method or object
104 *
105 * RETURN:      Status. AE_OK if repair was successful.
106 *
107 * DESCRIPTION: Attempt to repair/convert a return object of a type that was
108 *              not expected.
109 *
110 ******************************************************************************/
111
112acpi_status
113acpi_ns_repair_object(struct acpi_predefined_data *data,
114		      u32 expected_btypes,
115		      u32 package_index,
116		      union acpi_operand_object **return_object_ptr)
117{
118	union acpi_operand_object *return_object = *return_object_ptr;
119	union acpi_operand_object *new_object;
120	acpi_status status;
121
122	ACPI_FUNCTION_NAME(ns_repair_object);
123
124	/*
125	 * At this point, we know that the type of the returned object was not
126	 * one of the expected types for this predefined name. Attempt to
127	 * repair the object by converting it to one of the expected object
128	 * types for this predefined name.
129	 */
130	if (expected_btypes & ACPI_RTYPE_INTEGER) {
131		status = acpi_ns_convert_to_integer(return_object, &new_object);
132		if (ACPI_SUCCESS(status)) {
133			goto object_repaired;
134		}
135	}
136	if (expected_btypes & ACPI_RTYPE_STRING) {
137		status = acpi_ns_convert_to_string(return_object, &new_object);
138		if (ACPI_SUCCESS(status)) {
139			goto object_repaired;
140		}
141	}
142	if (expected_btypes & ACPI_RTYPE_BUFFER) {
143		status = acpi_ns_convert_to_buffer(return_object, &new_object);
144		if (ACPI_SUCCESS(status)) {
145			goto object_repaired;
146		}
147	}
148	if (expected_btypes & ACPI_RTYPE_PACKAGE) {
149		/*
150		 * A package is expected. We will wrap the existing object with a
151		 * new package object. It is often the case that if a variable-length
152		 * package is required, but there is only a single object needed, the
153		 * BIOS will return that object instead of wrapping it with a Package
154		 * object. Note: after the wrapping, the package will be validated
155		 * for correct contents (expected object type or types).
156		 */
157		status =
158		    acpi_ns_wrap_with_package(data, return_object, &new_object);
159		if (ACPI_SUCCESS(status)) {
160			/*
161			 * The original object just had its reference count
162			 * incremented for being inserted into the new package.
163			 */
164			*return_object_ptr = new_object;	/* New Package object */
165			data->flags |= ACPI_OBJECT_REPAIRED;
166			return (AE_OK);
167		}
168	}
169
170	/* We cannot repair this object */
171
172	return (AE_AML_OPERAND_TYPE);
173
174      object_repaired:
175
176	/* Object was successfully repaired */
177
 
 
 
 
 
 
178	if (package_index != ACPI_NOT_PACKAGE_ELEMENT) {
179		/*
180		 * The original object is a package element. We need to
181		 * decrement the reference count of the original object,
182		 * for removing it from the package.
183		 *
184		 * However, if the original object was just wrapped with a
185		 * package object as part of the repair, we don't need to
186		 * change the reference count.
187		 */
188		if (!(data->flags & ACPI_OBJECT_WRAPPED)) {
189			new_object->common.reference_count =
190			    return_object->common.reference_count;
191
192			if (return_object->common.reference_count > 1) {
193				return_object->common.reference_count--;
194			}
195		}
196
197		ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
198				  "%s: Converted %s to expected %s at Package index %u\n",
199				  data->pathname,
200				  acpi_ut_get_object_type_name(return_object),
201				  acpi_ut_get_object_type_name(new_object),
202				  package_index));
203	} else {
204		ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
205				  "%s: Converted %s to expected %s\n",
206				  data->pathname,
207				  acpi_ut_get_object_type_name(return_object),
208				  acpi_ut_get_object_type_name(new_object)));
209	}
210
211	/* Delete old object, install the new return object */
212
213	acpi_ut_remove_reference(return_object);
214	*return_object_ptr = new_object;
215	data->flags |= ACPI_OBJECT_REPAIRED;
216	return (AE_OK);
217}
218
219/*******************************************************************************
220 *
221 * FUNCTION:    acpi_ns_convert_to_integer
222 *
223 * PARAMETERS:  original_object     - Object to be converted
224 *              return_object       - Where the new converted object is returned
225 *
226 * RETURN:      Status. AE_OK if conversion was successful.
227 *
228 * DESCRIPTION: Attempt to convert a String/Buffer object to an Integer.
229 *
230 ******************************************************************************/
231
232static acpi_status
233acpi_ns_convert_to_integer(union acpi_operand_object *original_object,
234			   union acpi_operand_object **return_object)
235{
236	union acpi_operand_object *new_object;
237	acpi_status status;
238	u64 value = 0;
239	u32 i;
240
241	switch (original_object->common.type) {
242	case ACPI_TYPE_STRING:
243
244		/* String-to-Integer conversion */
245
246		status = acpi_ut_strtoul64(original_object->string.pointer,
247					   ACPI_ANY_BASE, &value);
248		if (ACPI_FAILURE(status)) {
249			return (status);
250		}
251		break;
252
253	case ACPI_TYPE_BUFFER:
254
255		/* Buffer-to-Integer conversion. Max buffer size is 64 bits. */
256
257		if (original_object->buffer.length > 8) {
258			return (AE_AML_OPERAND_TYPE);
259		}
260
261		/* Extract each buffer byte to create the integer */
262
263		for (i = 0; i < original_object->buffer.length; i++) {
264			value |=
265			    ((u64) original_object->buffer.
266			     pointer[i] << (i * 8));
267		}
268		break;
269
270	default:
271		return (AE_AML_OPERAND_TYPE);
272	}
273
274	new_object = acpi_ut_create_integer_object(value);
275	if (!new_object) {
276		return (AE_NO_MEMORY);
277	}
278
279	*return_object = new_object;
280	return (AE_OK);
281}
282
283/*******************************************************************************
284 *
285 * FUNCTION:    acpi_ns_convert_to_string
286 *
287 * PARAMETERS:  original_object     - Object to be converted
288 *              return_object       - Where the new converted object is returned
289 *
290 * RETURN:      Status. AE_OK if conversion was successful.
291 *
292 * DESCRIPTION: Attempt to convert a Integer/Buffer object to a String.
293 *
294 ******************************************************************************/
295
296static acpi_status
297acpi_ns_convert_to_string(union acpi_operand_object *original_object,
298			  union acpi_operand_object **return_object)
299{
300	union acpi_operand_object *new_object;
301	acpi_size length;
302	acpi_status status;
303
304	switch (original_object->common.type) {
305	case ACPI_TYPE_INTEGER:
306		/*
307		 * Integer-to-String conversion. Commonly, convert
308		 * an integer of value 0 to a NULL string. The last element of
309		 * _BIF and _BIX packages occasionally need this fix.
310		 */
311		if (original_object->integer.value == 0) {
312
313			/* Allocate a new NULL string object */
314
315			new_object = acpi_ut_create_string_object(0);
316			if (!new_object) {
317				return (AE_NO_MEMORY);
318			}
319		} else {
320			status =
321			    acpi_ex_convert_to_string(original_object,
322						      &new_object,
323						      ACPI_IMPLICIT_CONVERT_HEX);
324			if (ACPI_FAILURE(status)) {
325				return (status);
326			}
327		}
328		break;
329
330	case ACPI_TYPE_BUFFER:
331		/*
332		 * Buffer-to-String conversion. Use a to_string
333		 * conversion, no transform performed on the buffer data. The best
334		 * example of this is the _BIF method, where the string data from
335		 * the battery is often (incorrectly) returned as buffer object(s).
336		 */
337		length = 0;
338		while ((length < original_object->buffer.length) &&
339		       (original_object->buffer.pointer[length])) {
340			length++;
341		}
342
343		/* Allocate a new string object */
344
345		new_object = acpi_ut_create_string_object(length);
346		if (!new_object) {
347			return (AE_NO_MEMORY);
348		}
349
350		/*
351		 * Copy the raw buffer data with no transform. String is already NULL
352		 * terminated at Length+1.
353		 */
354		ACPI_MEMCPY(new_object->string.pointer,
355			    original_object->buffer.pointer, length);
356		break;
357
358	default:
359		return (AE_AML_OPERAND_TYPE);
360	}
361
362	*return_object = new_object;
363	return (AE_OK);
364}
365
366/*******************************************************************************
367 *
368 * FUNCTION:    acpi_ns_convert_to_buffer
369 *
370 * PARAMETERS:  original_object     - Object to be converted
371 *              return_object       - Where the new converted object is returned
372 *
373 * RETURN:      Status. AE_OK if conversion was successful.
374 *
375 * DESCRIPTION: Attempt to convert a Integer/String/Package object to a Buffer.
376 *
377 ******************************************************************************/
378
379static acpi_status
380acpi_ns_convert_to_buffer(union acpi_operand_object *original_object,
381			  union acpi_operand_object **return_object)
382{
383	union acpi_operand_object *new_object;
384	acpi_status status;
385	union acpi_operand_object **elements;
386	u32 *dword_buffer;
387	u32 count;
388	u32 i;
389
390	switch (original_object->common.type) {
391	case ACPI_TYPE_INTEGER:
392		/*
393		 * Integer-to-Buffer conversion.
394		 * Convert the Integer to a packed-byte buffer. _MAT and other
395		 * objects need this sometimes, if a read has been performed on a
396		 * Field object that is less than or equal to the global integer
397		 * size (32 or 64 bits).
398		 */
399		status =
400		    acpi_ex_convert_to_buffer(original_object, &new_object);
401		if (ACPI_FAILURE(status)) {
402			return (status);
403		}
404		break;
405
406	case ACPI_TYPE_STRING:
407
408		/* String-to-Buffer conversion. Simple data copy */
409
410		new_object =
411		    acpi_ut_create_buffer_object(original_object->string.
412						 length);
413		if (!new_object) {
414			return (AE_NO_MEMORY);
415		}
416
417		ACPI_MEMCPY(new_object->buffer.pointer,
418			    original_object->string.pointer,
419			    original_object->string.length);
420		break;
421
422	case ACPI_TYPE_PACKAGE:
423		/*
424		 * This case is often seen for predefined names that must return a
425		 * Buffer object with multiple DWORD integers within. For example,
426		 * _FDE and _GTM. The Package can be converted to a Buffer.
427		 */
428
429		/* All elements of the Package must be integers */
430
431		elements = original_object->package.elements;
432		count = original_object->package.count;
433
434		for (i = 0; i < count; i++) {
435			if ((!*elements) ||
436			    ((*elements)->common.type != ACPI_TYPE_INTEGER)) {
437				return (AE_AML_OPERAND_TYPE);
438			}
439			elements++;
440		}
441
442		/* Create the new buffer object to replace the Package */
443
444		new_object = acpi_ut_create_buffer_object(ACPI_MUL_4(count));
445		if (!new_object) {
446			return (AE_NO_MEMORY);
447		}
448
449		/* Copy the package elements (integers) to the buffer as DWORDs */
450
451		elements = original_object->package.elements;
452		dword_buffer = ACPI_CAST_PTR(u32, new_object->buffer.pointer);
453
454		for (i = 0; i < count; i++) {
455			*dword_buffer = (u32) (*elements)->integer.value;
456			dword_buffer++;
457			elements++;
458		}
459		break;
460
461	default:
462		return (AE_AML_OPERAND_TYPE);
463	}
464
465	*return_object = new_object;
466	return (AE_OK);
467}
468
469/*******************************************************************************
470 *
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
471 * FUNCTION:    acpi_ns_repair_null_element
472 *
473 * PARAMETERS:  Data                - Pointer to validation data structure
474 *              expected_btypes     - Object types expected
475 *              package_index       - Index of object within parent package (if
476 *                                    applicable - ACPI_NOT_PACKAGE_ELEMENT
477 *                                    otherwise)
478 *              return_object_ptr   - Pointer to the object returned from the
479 *                                    evaluation of a method or object
480 *
481 * RETURN:      Status. AE_OK if repair was successful.
482 *
483 * DESCRIPTION: Attempt to repair a NULL element of a returned Package object.
484 *
485 ******************************************************************************/
486
487acpi_status
488acpi_ns_repair_null_element(struct acpi_predefined_data *data,
489			    u32 expected_btypes,
490			    u32 package_index,
491			    union acpi_operand_object **return_object_ptr)
492{
493	union acpi_operand_object *return_object = *return_object_ptr;
494	union acpi_operand_object *new_object;
495
496	ACPI_FUNCTION_NAME(ns_repair_null_element);
497
498	/* No repair needed if return object is non-NULL */
499
500	if (return_object) {
501		return (AE_OK);
502	}
503
504	/*
505	 * Attempt to repair a NULL element of a Package object. This applies to
506	 * predefined names that return a fixed-length package and each element
507	 * is required. It does not apply to variable-length packages where NULL
508	 * elements are allowed, especially at the end of the package.
509	 */
510	if (expected_btypes & ACPI_RTYPE_INTEGER) {
511
512		/* Need an Integer - create a zero-value integer */
513
514		new_object = acpi_ut_create_integer_object((u64)0);
515	} else if (expected_btypes & ACPI_RTYPE_STRING) {
516
517		/* Need a String - create a NULL string */
518
519		new_object = acpi_ut_create_string_object(0);
520	} else if (expected_btypes & ACPI_RTYPE_BUFFER) {
521
522		/* Need a Buffer - create a zero-length buffer */
523
524		new_object = acpi_ut_create_buffer_object(0);
525	} else {
526		/* Error for all other expected types */
527
528		return (AE_AML_OPERAND_TYPE);
529	}
530
531	if (!new_object) {
532		return (AE_NO_MEMORY);
533	}
534
535	/* Set the reference count according to the parent Package object */
536
537	new_object->common.reference_count =
538	    data->parent_package->common.reference_count;
539
540	ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
541			  "%s: Converted NULL package element to expected %s at index %u\n",
542			  data->pathname,
543			  acpi_ut_get_object_type_name(new_object),
544			  package_index));
545
546	*return_object_ptr = new_object;
547	data->flags |= ACPI_OBJECT_REPAIRED;
548	return (AE_OK);
549}
550
551/******************************************************************************
552 *
553 * FUNCTION:    acpi_ns_remove_null_elements
554 *
555 * PARAMETERS:  Data                - Pointer to validation data structure
556 *              package_type        - An acpi_return_package_types value
557 *              obj_desc            - A Package object
558 *
559 * RETURN:      None.
560 *
561 * DESCRIPTION: Remove all NULL package elements from packages that contain
562 *              a variable number of sub-packages. For these types of
563 *              packages, NULL elements can be safely removed.
564 *
565 *****************************************************************************/
566
567void
568acpi_ns_remove_null_elements(struct acpi_predefined_data *data,
569			     u8 package_type,
570			     union acpi_operand_object *obj_desc)
571{
572	union acpi_operand_object **source;
573	union acpi_operand_object **dest;
574	u32 count;
575	u32 new_count;
576	u32 i;
577
578	ACPI_FUNCTION_NAME(ns_remove_null_elements);
579
580	/*
581	 * We can safely remove all NULL elements from these package types:
582	 * PTYPE1_VAR packages contain a variable number of simple data types.
583	 * PTYPE2 packages contain a variable number of sub-packages.
584	 */
585	switch (package_type) {
586	case ACPI_PTYPE1_VAR:
587	case ACPI_PTYPE2:
588	case ACPI_PTYPE2_COUNT:
589	case ACPI_PTYPE2_PKG_COUNT:
590	case ACPI_PTYPE2_FIXED:
591	case ACPI_PTYPE2_MIN:
592	case ACPI_PTYPE2_REV_FIXED:
593	case ACPI_PTYPE2_FIX_VAR:
594		break;
595
596	default:
597	case ACPI_PTYPE1_FIXED:
598	case ACPI_PTYPE1_OPTION:
599		return;
600	}
601
602	count = obj_desc->package.count;
603	new_count = count;
604
605	source = obj_desc->package.elements;
606	dest = source;
607
608	/* Examine all elements of the package object, remove nulls */
609
610	for (i = 0; i < count; i++) {
611		if (!*source) {
612			new_count--;
613		} else {
614			*dest = *source;
615			dest++;
616		}
617		source++;
618	}
619
620	/* Update parent package if any null elements were removed */
621
622	if (new_count < count) {
623		ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
624				  "%s: Found and removed %u NULL elements\n",
625				  data->pathname, (count - new_count)));
626
627		/* NULL terminate list and update the package count */
628
629		*dest = NULL;
630		obj_desc->package.count = new_count;
631	}
632}
633
634/*******************************************************************************
635 *
636 * FUNCTION:    acpi_ns_wrap_with_package
637 *
638 * PARAMETERS:  Data                - Pointer to validation data structure
639 *              original_object     - Pointer to the object to repair.
640 *              obj_desc_ptr        - The new package object is returned here
 
641 *
642 * RETURN:      Status, new object in *obj_desc_ptr
643 *
644 * DESCRIPTION: Repair a common problem with objects that are defined to
645 *              return a variable-length Package of sub-objects. If there is
646 *              only one sub-object, some BIOS code mistakenly simply declares
647 *              the single object instead of a Package with one sub-object.
648 *              This function attempts to repair this error by wrapping a
649 *              Package object around the original object, creating the
650 *              correct and expected Package with one sub-object.
651 *
652 *              Names that can be repaired in this manner include:
653 *              _ALR, _CSD, _HPX, _MLS, _PLD, _PRT, _PSS, _TRT, _TSS,
654 *              _BCL, _DOD, _FIX, _Sx
655 *
656 ******************************************************************************/
657
658acpi_status
659acpi_ns_wrap_with_package(struct acpi_predefined_data *data,
660			  union acpi_operand_object *original_object,
661			  union acpi_operand_object **obj_desc_ptr)
662{
663	union acpi_operand_object *pkg_obj_desc;
664
665	ACPI_FUNCTION_NAME(ns_wrap_with_package);
666
667	/*
668	 * Create the new outer package and populate it. The new package will
669	 * have a single element, the lone sub-object.
670	 */
671	pkg_obj_desc = acpi_ut_create_package_object(1);
672	if (!pkg_obj_desc) {
673		return (AE_NO_MEMORY);
674	}
675
676	pkg_obj_desc->package.elements[0] = original_object;
677
678	ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
679			  "%s: Wrapped %s with expected Package object\n",
680			  data->pathname,
681			  acpi_ut_get_object_type_name(original_object)));
682
683	/* Return the new object in the object pointer */
684
685	*obj_desc_ptr = pkg_obj_desc;
686	data->flags |= ACPI_OBJECT_REPAIRED | ACPI_OBJECT_WRAPPED;
 
 
 
 
 
687	return (AE_OK);
688}