diff options
Diffstat (limited to 'drivers/acpi/resources/rslist.c')
-rw-r--r-- | drivers/acpi/resources/rslist.c | 195 |
1 files changed, 32 insertions, 163 deletions
diff --git a/drivers/acpi/resources/rslist.c b/drivers/acpi/resources/rslist.c index ee17ef3315f8..b83996233c1d 100644 --- a/drivers/acpi/resources/rslist.c +++ b/drivers/acpi/resources/rslist.c | |||
@@ -47,115 +47,12 @@ | |||
47 | #define _COMPONENT ACPI_RESOURCES | 47 | #define _COMPONENT ACPI_RESOURCES |
48 | ACPI_MODULE_NAME("rslist") | 48 | ACPI_MODULE_NAME("rslist") |
49 | 49 | ||
50 | /* Local prototypes */ | ||
51 | static struct acpi_rsconvert_info *acpi_rs_get_conversion_info(u8 | ||
52 | resource_type); | ||
53 | |||
54 | static acpi_status acpi_rs_validate_resource_length(union aml_resource *aml); | ||
55 | |||
56 | /******************************************************************************* | ||
57 | * | ||
58 | * FUNCTION: acpi_rs_validate_resource_length | ||
59 | * | ||
60 | * PARAMETERS: Aml - Pointer to the AML resource descriptor | ||
61 | * | ||
62 | * RETURN: Status - AE_OK if the resource length appears valid | ||
63 | * | ||
64 | * DESCRIPTION: Validate the resource_length. Fixed-length descriptors must | ||
65 | * have the exact length; variable-length descriptors must be | ||
66 | * at least as long as the minimum. Certain Small descriptors | ||
67 | * can vary in size by at most one byte. | ||
68 | * | ||
69 | ******************************************************************************/ | ||
70 | |||
71 | static acpi_status acpi_rs_validate_resource_length(union aml_resource *aml) | ||
72 | { | ||
73 | struct acpi_resource_info *resource_info; | ||
74 | u16 minimum_aml_resource_length; | ||
75 | u16 resource_length; | ||
76 | |||
77 | ACPI_FUNCTION_ENTRY(); | ||
78 | |||
79 | /* Get the size and type info about this resource descriptor */ | ||
80 | |||
81 | resource_info = | ||
82 | acpi_rs_get_resource_info(aml->small_header.descriptor_type); | ||
83 | if (!resource_info) { | ||
84 | return (AE_AML_INVALID_RESOURCE_TYPE); | ||
85 | } | ||
86 | |||
87 | resource_length = acpi_ut_get_resource_length(aml); | ||
88 | minimum_aml_resource_length = | ||
89 | resource_info->minimum_aml_resource_length; | ||
90 | |||
91 | /* Validate based upon the type of resource, fixed length or variable */ | ||
92 | |||
93 | if (resource_info->length_type == ACPI_FIXED_LENGTH) { | ||
94 | /* Fixed length resource, length must match exactly */ | ||
95 | |||
96 | if (resource_length != minimum_aml_resource_length) { | ||
97 | return (AE_AML_BAD_RESOURCE_LENGTH); | ||
98 | } | ||
99 | } else if (resource_info->length_type == ACPI_VARIABLE_LENGTH) { | ||
100 | /* Variable length resource, must be at least the minimum */ | ||
101 | |||
102 | if (resource_length < minimum_aml_resource_length) { | ||
103 | return (AE_AML_BAD_RESOURCE_LENGTH); | ||
104 | } | ||
105 | } else { | ||
106 | /* Small variable length resource, allowed to be (Min) or (Min-1) */ | ||
107 | |||
108 | if ((resource_length > minimum_aml_resource_length) || | ||
109 | (resource_length < (minimum_aml_resource_length - 1))) { | ||
110 | return (AE_AML_BAD_RESOURCE_LENGTH); | ||
111 | } | ||
112 | } | ||
113 | |||
114 | return (AE_OK); | ||
115 | } | ||
116 | |||
117 | /******************************************************************************* | ||
118 | * | ||
119 | * FUNCTION: acpi_rs_get_conversion_info | ||
120 | * | ||
121 | * PARAMETERS: resource_type - Byte 0 of a resource descriptor | ||
122 | * | ||
123 | * RETURN: Pointer to the resource conversion info table | ||
124 | * | ||
125 | * DESCRIPTION: Get the conversion table associated with this resource type | ||
126 | * | ||
127 | ******************************************************************************/ | ||
128 | |||
129 | static struct acpi_rsconvert_info *acpi_rs_get_conversion_info(u8 resource_type) | ||
130 | { | ||
131 | ACPI_FUNCTION_ENTRY(); | ||
132 | |||
133 | /* Determine if this is a small or large resource */ | ||
134 | |||
135 | if (resource_type & ACPI_RESOURCE_NAME_LARGE) { | ||
136 | /* Large Resource Type -- bits 6:0 contain the name */ | ||
137 | |||
138 | if (resource_type > ACPI_RESOURCE_NAME_LARGE_MAX) { | ||
139 | return (NULL); | ||
140 | } | ||
141 | |||
142 | return (acpi_gbl_lg_get_resource_dispatch[(resource_type & | ||
143 | ACPI_RESOURCE_NAME_LARGE_MASK)]); | ||
144 | } else { | ||
145 | /* Small Resource Type -- bits 6:3 contain the name */ | ||
146 | |||
147 | return (acpi_gbl_sm_get_resource_dispatch[((resource_type & | ||
148 | ACPI_RESOURCE_NAME_SMALL_MASK) | ||
149 | >> 3)]); | ||
150 | } | ||
151 | } | ||
152 | |||
153 | /******************************************************************************* | 50 | /******************************************************************************* |
154 | * | 51 | * |
155 | * FUNCTION: acpi_rs_convert_aml_to_resources | 52 | * FUNCTION: acpi_rs_convert_aml_to_resources |
156 | * | 53 | * |
157 | * PARAMETERS: aml_buffer - Pointer to the resource byte stream | 54 | * PARAMETERS: Aml - Pointer to the resource byte stream |
158 | * aml_buffer_length - Length of aml_buffer | 55 | * aml_length - Length of Aml |
159 | * output_buffer - Pointer to the buffer that will | 56 | * output_buffer - Pointer to the buffer that will |
160 | * contain the output structures | 57 | * contain the output structures |
161 | * | 58 | * |
@@ -165,42 +62,24 @@ static struct acpi_rsconvert_info *acpi_rs_get_conversion_info(u8 resource_type) | |||
165 | * linked list of resources in the caller's output buffer | 62 | * linked list of resources in the caller's output buffer |
166 | * | 63 | * |
167 | ******************************************************************************/ | 64 | ******************************************************************************/ |
168 | |||
169 | acpi_status | 65 | acpi_status |
170 | acpi_rs_convert_aml_to_resources(u8 * aml_buffer, | 66 | acpi_rs_convert_aml_to_resources(u8 * aml, u32 aml_length, u8 * output_buffer) |
171 | u32 aml_buffer_length, u8 * output_buffer) | ||
172 | { | 67 | { |
173 | u8 *buffer = output_buffer; | 68 | struct acpi_resource *resource = (void *)output_buffer; |
174 | acpi_status status; | 69 | acpi_status status; |
175 | acpi_size bytes_parsed = 0; | 70 | u8 resource_index; |
176 | struct acpi_resource *resource; | 71 | u8 *end_aml; |
177 | acpi_rsdesc_size descriptor_length; | ||
178 | struct acpi_rsconvert_info *info; | ||
179 | 72 | ||
180 | ACPI_FUNCTION_TRACE("rs_convert_aml_to_resources"); | 73 | ACPI_FUNCTION_TRACE("rs_convert_aml_to_resources"); |
181 | 74 | ||
182 | /* Loop until end-of-buffer or an end_tag is found */ | 75 | end_aml = aml + aml_length; |
183 | |||
184 | while (bytes_parsed < aml_buffer_length) { | ||
185 | /* Get the conversion table associated with this Descriptor Type */ | ||
186 | |||
187 | info = acpi_rs_get_conversion_info(*aml_buffer); | ||
188 | if (!info) { | ||
189 | /* No table indicates an invalid resource type */ | ||
190 | 76 | ||
191 | return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE); | 77 | /* Loop until end-of-buffer or an end_tag is found */ |
192 | } | ||
193 | 78 | ||
194 | descriptor_length = acpi_ut_get_descriptor_length(aml_buffer); | 79 | while (aml < end_aml) { |
80 | /* Validate the Resource Type and Resource Length */ | ||
195 | 81 | ||
196 | /* | 82 | status = acpi_ut_validate_resource(aml, &resource_index); |
197 | * Perform limited validation of the resource length, based upon | ||
198 | * what we know about the resource type | ||
199 | */ | ||
200 | status = | ||
201 | acpi_rs_validate_resource_length(ACPI_CAST_PTR | ||
202 | (union aml_resource, | ||
203 | aml_buffer)); | ||
204 | if (ACPI_FAILURE(status)) { | 83 | if (ACPI_FAILURE(status)) { |
205 | return_ACPI_STATUS(status); | 84 | return_ACPI_STATUS(status); |
206 | } | 85 | } |
@@ -208,42 +87,36 @@ acpi_rs_convert_aml_to_resources(u8 * aml_buffer, | |||
208 | /* Convert the AML byte stream resource to a local resource struct */ | 87 | /* Convert the AML byte stream resource to a local resource struct */ |
209 | 88 | ||
210 | status = | 89 | status = |
211 | acpi_rs_convert_aml_to_resource(ACPI_CAST_PTR | 90 | acpi_rs_convert_aml_to_resource(resource, |
212 | (struct acpi_resource, | ||
213 | buffer), | ||
214 | ACPI_CAST_PTR(union | 91 | ACPI_CAST_PTR(union |
215 | aml_resource, | 92 | aml_resource, |
216 | aml_buffer), | 93 | aml), |
217 | info); | 94 | acpi_gbl_get_resource_dispatch |
95 | [resource_index]); | ||
218 | if (ACPI_FAILURE(status)) { | 96 | if (ACPI_FAILURE(status)) { |
219 | ACPI_REPORT_ERROR(("Could not convert AML resource (type %X) to resource, %s\n", *aml_buffer, acpi_format_exception(status))); | 97 | ACPI_REPORT_ERROR(("Could not convert AML resource (Type %X) to resource, %s\n", *aml, acpi_format_exception(status))); |
220 | return_ACPI_STATUS(status); | 98 | return_ACPI_STATUS(status); |
221 | } | 99 | } |
222 | 100 | ||
223 | /* Set the aligned length of the new resource descriptor */ | ||
224 | |||
225 | resource = ACPI_CAST_PTR(struct acpi_resource, buffer); | ||
226 | resource->length = | ||
227 | (u32) ACPI_ALIGN_RESOURCE_SIZE(resource->length); | ||
228 | |||
229 | /* Normal exit on completion of an end_tag resource descriptor */ | 101 | /* Normal exit on completion of an end_tag resource descriptor */ |
230 | 102 | ||
231 | if (acpi_ut_get_resource_type(aml_buffer) == | 103 | if (acpi_ut_get_resource_type(aml) == |
232 | ACPI_RESOURCE_NAME_END_TAG) { | 104 | ACPI_RESOURCE_NAME_END_TAG) { |
233 | return_ACPI_STATUS(AE_OK); | 105 | return_ACPI_STATUS(AE_OK); |
234 | } | 106 | } |
235 | 107 | ||
236 | /* Update counter and point to the next input resource */ | 108 | /* Point to the next input AML resource */ |
237 | 109 | ||
238 | bytes_parsed += descriptor_length; | 110 | aml += acpi_ut_get_descriptor_length(aml); |
239 | aml_buffer += descriptor_length; | ||
240 | 111 | ||
241 | /* Point to the next structure in the output buffer */ | 112 | /* Point to the next structure in the output buffer */ |
242 | 113 | ||
243 | buffer += resource->length; | 114 | resource = |
115 | ACPI_PTR_ADD(struct acpi_resource, resource, | ||
116 | resource->length); | ||
244 | } | 117 | } |
245 | 118 | ||
246 | /* Completed buffer, but did not find an end_tag resource descriptor */ | 119 | /* Did not find an end_tag resource descriptor */ |
247 | 120 | ||
248 | return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG); | 121 | return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG); |
249 | } | 122 | } |
@@ -271,16 +144,16 @@ acpi_status | |||
271 | acpi_rs_convert_resources_to_aml(struct acpi_resource *resource, | 144 | acpi_rs_convert_resources_to_aml(struct acpi_resource *resource, |
272 | acpi_size aml_size_needed, u8 * output_buffer) | 145 | acpi_size aml_size_needed, u8 * output_buffer) |
273 | { | 146 | { |
274 | u8 *aml_buffer = output_buffer; | 147 | u8 *aml = output_buffer; |
275 | u8 *end_aml_buffer = output_buffer + aml_size_needed; | 148 | u8 *end_aml = output_buffer + aml_size_needed; |
276 | acpi_status status; | 149 | acpi_status status; |
277 | 150 | ||
278 | ACPI_FUNCTION_TRACE("rs_convert_resources_to_aml"); | 151 | ACPI_FUNCTION_TRACE("rs_convert_resources_to_aml"); |
279 | 152 | ||
280 | /* Walk the resource descriptor list, convert each descriptor */ | 153 | /* Walk the resource descriptor list, convert each descriptor */ |
281 | 154 | ||
282 | while (aml_buffer < end_aml_buffer) { | 155 | while (aml < end_aml) { |
283 | /* Validate the Resource Type */ | 156 | /* Validate the (internal) Resource Type */ |
284 | 157 | ||
285 | if (resource->type > ACPI_RESOURCE_TYPE_MAX) { | 158 | if (resource->type > ACPI_RESOURCE_TYPE_MAX) { |
286 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | 159 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, |
@@ -294,7 +167,7 @@ acpi_rs_convert_resources_to_aml(struct acpi_resource *resource, | |||
294 | status = acpi_rs_convert_resource_to_aml(resource, | 167 | status = acpi_rs_convert_resource_to_aml(resource, |
295 | ACPI_CAST_PTR(union | 168 | ACPI_CAST_PTR(union |
296 | aml_resource, | 169 | aml_resource, |
297 | aml_buffer), | 170 | aml), |
298 | acpi_gbl_set_resource_dispatch | 171 | acpi_gbl_set_resource_dispatch |
299 | [resource->type]); | 172 | [resource->type]); |
300 | if (ACPI_FAILURE(status)) { | 173 | if (ACPI_FAILURE(status)) { |
@@ -305,9 +178,8 @@ acpi_rs_convert_resources_to_aml(struct acpi_resource *resource, | |||
305 | /* Perform final sanity check on the new AML resource descriptor */ | 178 | /* Perform final sanity check on the new AML resource descriptor */ |
306 | 179 | ||
307 | status = | 180 | status = |
308 | acpi_rs_validate_resource_length(ACPI_CAST_PTR | 181 | acpi_ut_validate_resource(ACPI_CAST_PTR |
309 | (union aml_resource, | 182 | (union aml_resource, aml), NULL); |
310 | aml_buffer)); | ||
311 | if (ACPI_FAILURE(status)) { | 183 | if (ACPI_FAILURE(status)) { |
312 | return_ACPI_STATUS(status); | 184 | return_ACPI_STATUS(status); |
313 | } | 185 | } |
@@ -322,18 +194,15 @@ acpi_rs_convert_resources_to_aml(struct acpi_resource *resource, | |||
322 | 194 | ||
323 | /* | 195 | /* |
324 | * Extract the total length of the new descriptor and set the | 196 | * Extract the total length of the new descriptor and set the |
325 | * aml_buffer to point to the next (output) resource descriptor | 197 | * Aml to point to the next (output) resource descriptor |
326 | */ | 198 | */ |
327 | aml_buffer += acpi_ut_get_descriptor_length(aml_buffer); | 199 | aml += acpi_ut_get_descriptor_length(aml); |
328 | 200 | ||
329 | /* Point to the next input resource descriptor */ | 201 | /* Point to the next input resource descriptor */ |
330 | 202 | ||
331 | resource = | 203 | resource = |
332 | ACPI_PTR_ADD(struct acpi_resource, resource, | 204 | ACPI_PTR_ADD(struct acpi_resource, resource, |
333 | resource->length); | 205 | resource->length); |
334 | |||
335 | /* Check for end-of-list, normal exit */ | ||
336 | |||
337 | } | 206 | } |
338 | 207 | ||
339 | /* Completed buffer, but did not find an end_tag resource descriptor */ | 208 | /* Completed buffer, but did not find an end_tag resource descriptor */ |