diff options
author | Bob Moore <robert.moore@intel.com> | 2009-10-12 22:20:33 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2009-11-24 20:30:03 -0500 |
commit | 2752699392b828edf3123f911f6e8b4dd7daeb56 (patch) | |
tree | 3f7f0c632f1bee2b45ca743d1127316fae2bea19 /drivers/acpi | |
parent | 648f4e3e50c4793d9dbf9a09afa193631f76fa26 (diff) |
ACPICA: Add repair for bad _BIF/_BIX packages
Add a repair for the "Oem Information" field which is often
mistakenly returned as an integer. It should always be a string.
ACPICA BZ 807.
http://www.acpica.org/bugzilla/show_bug.cgi?id=807
Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Lin Ming <ming.m.lin@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi')
-rw-r--r-- | drivers/acpi/acpica/nsrepair.c | 91 |
1 files changed, 65 insertions, 26 deletions
diff --git a/drivers/acpi/acpica/nsrepair.c b/drivers/acpi/acpica/nsrepair.c index db2b2a99c3a8..dfa31c5ba6c3 100644 --- a/drivers/acpi/acpica/nsrepair.c +++ b/drivers/acpi/acpica/nsrepair.c | |||
@@ -77,6 +77,11 @@ acpi_ns_repair_object(struct acpi_predefined_data *data, | |||
77 | union acpi_operand_object *new_object; | 77 | union acpi_operand_object *new_object; |
78 | acpi_size length; | 78 | acpi_size length; |
79 | 79 | ||
80 | /* | ||
81 | * At this point, we know that the type of the returned object was not | ||
82 | * one of the expected types for this predefined name. Attempt to | ||
83 | * repair the object. Only a limited number of repairs are possible. | ||
84 | */ | ||
80 | switch (return_object->common.type) { | 85 | switch (return_object->common.type) { |
81 | case ACPI_TYPE_BUFFER: | 86 | case ACPI_TYPE_BUFFER: |
82 | 87 | ||
@@ -111,43 +116,77 @@ acpi_ns_repair_object(struct acpi_predefined_data *data, | |||
111 | */ | 116 | */ |
112 | ACPI_MEMCPY(new_object->string.pointer, | 117 | ACPI_MEMCPY(new_object->string.pointer, |
113 | return_object->buffer.pointer, length); | 118 | return_object->buffer.pointer, length); |
119 | break; | ||
114 | 120 | ||
115 | /* | 121 | case ACPI_TYPE_INTEGER: |
116 | * If the original object is a package element, we need to: | 122 | |
117 | * 1. Set the reference count of the new object to match the | 123 | /* Does the method/object legally return a string? */ |
118 | * reference count of the old object. | ||
119 | * 2. Decrement the reference count of the original object. | ||
120 | */ | ||
121 | if (package_index != ACPI_NOT_PACKAGE_ELEMENT) { | ||
122 | new_object->common.reference_count = | ||
123 | return_object->common.reference_count; | ||
124 | 124 | ||
125 | if (return_object->common.reference_count > 1) { | 125 | if (expected_btypes & ACPI_RTYPE_STRING) { |
126 | return_object->common.reference_count--; | 126 | /* |
127 | * The only supported Integer-to-String conversion is to convert | ||
128 | * an integer of value 0 to a NULL string. The last element of | ||
129 | * _BIF and _BIX packages occasionally need this fix. | ||
130 | */ | ||
131 | if (return_object->integer.value != 0) { | ||
132 | return (AE_AML_OPERAND_TYPE); | ||
127 | } | 133 | } |
128 | 134 | ||
129 | ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, | 135 | /* Allocate a new NULL string object */ |
130 | data->node_flags, | 136 | |
131 | "Converted Buffer to expected String at index %u", | 137 | new_object = acpi_ut_create_string_object(0); |
132 | package_index)); | 138 | if (!new_object) { |
139 | return (AE_NO_MEMORY); | ||
140 | } | ||
133 | } else { | 141 | } else { |
134 | ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, | 142 | return (AE_AML_OPERAND_TYPE); |
135 | data->node_flags, | ||
136 | "Converted Buffer to expected String")); | ||
137 | } | 143 | } |
144 | break; | ||
138 | 145 | ||
139 | /* Delete old object, install the new return object */ | 146 | default: |
140 | 147 | ||
141 | acpi_ut_remove_reference(return_object); | 148 | /* We cannot repair this object */ |
142 | *return_object_ptr = new_object; | ||
143 | data->flags |= ACPI_OBJECT_REPAIRED; | ||
144 | return (AE_OK); | ||
145 | 149 | ||
146 | default: | 150 | return (AE_AML_OPERAND_TYPE); |
147 | break; | 151 | } |
152 | |||
153 | /* Object was successfully repaired */ | ||
154 | |||
155 | /* | ||
156 | * If the original object is a package element, we need to: | ||
157 | * 1. Set the reference count of the new object to match the | ||
158 | * reference count of the old object. | ||
159 | * 2. Decrement the reference count of the original object. | ||
160 | */ | ||
161 | if (package_index != ACPI_NOT_PACKAGE_ELEMENT) { | ||
162 | new_object->common.reference_count = | ||
163 | return_object->common.reference_count; | ||
164 | |||
165 | if (return_object->common.reference_count > 1) { | ||
166 | return_object->common.reference_count--; | ||
167 | } | ||
168 | |||
169 | ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags, | ||
170 | "Converted %s to expected %s at index %u", | ||
171 | acpi_ut_get_object_type_name | ||
172 | (return_object), | ||
173 | acpi_ut_get_object_type_name(new_object), | ||
174 | package_index)); | ||
175 | } else { | ||
176 | ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags, | ||
177 | "Converted %s to expected %s", | ||
178 | acpi_ut_get_object_type_name | ||
179 | (return_object), | ||
180 | acpi_ut_get_object_type_name | ||
181 | (new_object))); | ||
148 | } | 182 | } |
149 | 183 | ||
150 | return (AE_AML_OPERAND_TYPE); | 184 | /* Delete old object, install the new return object */ |
185 | |||
186 | acpi_ut_remove_reference(return_object); | ||
187 | *return_object_ptr = new_object; | ||
188 | data->flags |= ACPI_OBJECT_REPAIRED; | ||
189 | return (AE_OK); | ||
151 | } | 190 | } |
152 | 191 | ||
153 | /******************************************************************************* | 192 | /******************************************************************************* |