diff options
Diffstat (limited to 'drivers/acpi/resources/rsutils.c')
-rw-r--r-- | drivers/acpi/resources/rsutils.c | 437 |
1 files changed, 435 insertions, 2 deletions
diff --git a/drivers/acpi/resources/rsutils.c b/drivers/acpi/resources/rsutils.c index 4446778eaf79..9d503de1a349 100644 --- a/drivers/acpi/resources/rsutils.c +++ b/drivers/acpi/resources/rsutils.c | |||
@@ -50,6 +50,438 @@ ACPI_MODULE_NAME("rsutils") | |||
50 | 50 | ||
51 | /******************************************************************************* | 51 | /******************************************************************************* |
52 | * | 52 | * |
53 | * FUNCTION: acpi_rs_move_data | ||
54 | * | ||
55 | * PARAMETERS: Destination - Pointer to the destination descriptor | ||
56 | * Source - Pointer to the source descriptor | ||
57 | * item_count - How many items to move | ||
58 | * move_type - Byte width | ||
59 | * | ||
60 | * RETURN: None | ||
61 | * | ||
62 | * DESCRIPTION: Move multiple data items from one descriptor to another. Handles | ||
63 | * alignment issues and endian issues if necessary, as configured | ||
64 | * via the ACPI_MOVE_* macros. (This is why a memcpy is not used) | ||
65 | * | ||
66 | ******************************************************************************/ | ||
67 | void | ||
68 | acpi_rs_move_data(void *destination, void *source, u16 item_count, u8 move_type) | ||
69 | { | ||
70 | acpi_native_uint i; | ||
71 | |||
72 | /* One move per item */ | ||
73 | |||
74 | for (i = 0; i < item_count; i++) { | ||
75 | switch (move_type) { | ||
76 | case ACPI_MOVE_TYPE_16_TO_32: | ||
77 | ACPI_MOVE_16_TO_32(&((u32 *) destination)[i], | ||
78 | &((u16 *) source)[i]); | ||
79 | break; | ||
80 | |||
81 | case ACPI_MOVE_TYPE_32_TO_16: | ||
82 | ACPI_MOVE_32_TO_16(&((u16 *) destination)[i], | ||
83 | &((u32 *) source)[i]); | ||
84 | break; | ||
85 | |||
86 | case ACPI_MOVE_TYPE_32_TO_32: | ||
87 | ACPI_MOVE_32_TO_32(&((u32 *) destination)[i], | ||
88 | &((u32 *) source)[i]); | ||
89 | break; | ||
90 | |||
91 | case ACPI_MOVE_TYPE_64_TO_64: | ||
92 | ACPI_MOVE_64_TO_64(&((u64 *) destination)[i], | ||
93 | &((u64 *) source)[i]); | ||
94 | break; | ||
95 | |||
96 | default: | ||
97 | return; | ||
98 | } | ||
99 | } | ||
100 | } | ||
101 | |||
102 | /******************************************************************************* | ||
103 | * | ||
104 | * FUNCTION: acpi_rs_get_resource_info | ||
105 | * | ||
106 | * PARAMETERS: resource_type - Byte 0 of a resource descriptor | ||
107 | * | ||
108 | * RETURN: Pointer to the resource conversion handler | ||
109 | * | ||
110 | * DESCRIPTION: Extract the Resource Type/Name from the first byte of | ||
111 | * a resource descriptor. | ||
112 | * | ||
113 | ******************************************************************************/ | ||
114 | |||
115 | struct acpi_resource_info *acpi_rs_get_resource_info(u8 resource_type) | ||
116 | { | ||
117 | struct acpi_resource_info *size_info; | ||
118 | |||
119 | ACPI_FUNCTION_ENTRY(); | ||
120 | |||
121 | /* Determine if this is a small or large resource */ | ||
122 | |||
123 | if (resource_type & ACPI_RESOURCE_NAME_LARGE) { | ||
124 | /* Large Resource Type -- bits 6:0 contain the name */ | ||
125 | |||
126 | if (resource_type > ACPI_RESOURCE_NAME_LARGE_MAX) { | ||
127 | return (NULL); | ||
128 | } | ||
129 | |||
130 | size_info = &acpi_gbl_lg_resource_info[(resource_type & | ||
131 | ACPI_RESOURCE_NAME_LARGE_MASK)]; | ||
132 | } else { | ||
133 | /* Small Resource Type -- bits 6:3 contain the name */ | ||
134 | |||
135 | size_info = &acpi_gbl_sm_resource_info[((resource_type & | ||
136 | ACPI_RESOURCE_NAME_SMALL_MASK) | ||
137 | >> 3)]; | ||
138 | } | ||
139 | |||
140 | /* Zero entry indicates an invalid resource type */ | ||
141 | |||
142 | if (!size_info->minimum_internal_struct_length) { | ||
143 | return (NULL); | ||
144 | } | ||
145 | |||
146 | return (size_info); | ||
147 | } | ||
148 | |||
149 | /******************************************************************************* | ||
150 | * | ||
151 | * FUNCTION: acpi_rs_get_resource_length | ||
152 | * | ||
153 | * PARAMETERS: Aml - Pointer to the raw AML resource descriptor | ||
154 | * | ||
155 | * RETURN: Byte Length | ||
156 | * | ||
157 | * DESCRIPTION: Get the "Resource Length" of a raw AML descriptor. By | ||
158 | * definition, this does not include the size of the descriptor | ||
159 | * header or the length field itself. | ||
160 | * | ||
161 | ******************************************************************************/ | ||
162 | |||
163 | u16 acpi_rs_get_resource_length(union aml_resource * aml) | ||
164 | { | ||
165 | u16 resource_length; | ||
166 | |||
167 | ACPI_FUNCTION_ENTRY(); | ||
168 | |||
169 | /* Determine if this is a small or large resource */ | ||
170 | |||
171 | if (aml->large_header.descriptor_type & ACPI_RESOURCE_NAME_LARGE) { | ||
172 | /* Large Resource type -- bytes 1-2 contain the 16-bit length */ | ||
173 | |||
174 | ACPI_MOVE_16_TO_16(&resource_length, | ||
175 | &aml->large_header.resource_length); | ||
176 | |||
177 | } else { | ||
178 | /* Small Resource type -- bits 2:0 of byte 0 contain the length */ | ||
179 | |||
180 | resource_length = (u16) (aml->small_header.descriptor_type & | ||
181 | ACPI_RESOURCE_NAME_SMALL_LENGTH_MASK); | ||
182 | } | ||
183 | |||
184 | return (resource_length); | ||
185 | } | ||
186 | |||
187 | /******************************************************************************* | ||
188 | * | ||
189 | * FUNCTION: acpi_rs_get_descriptor_length | ||
190 | * | ||
191 | * PARAMETERS: Aml - Pointer to the raw AML resource descriptor | ||
192 | * | ||
193 | * RETURN: Byte length | ||
194 | * | ||
195 | * DESCRIPTION: Get the total byte length of a raw AML descriptor, including the | ||
196 | * length of the descriptor header and the length field itself. | ||
197 | * Used to walk descriptor lists. | ||
198 | * | ||
199 | ******************************************************************************/ | ||
200 | |||
201 | u32 acpi_rs_get_descriptor_length(union aml_resource * aml) | ||
202 | { | ||
203 | u32 descriptor_length; | ||
204 | |||
205 | ACPI_FUNCTION_ENTRY(); | ||
206 | |||
207 | /* Determine if this is a small or large resource */ | ||
208 | |||
209 | if (aml->large_header.descriptor_type & ACPI_RESOURCE_NAME_LARGE) { | ||
210 | /* Large Resource type -- bytes 1-2 contain the 16-bit length */ | ||
211 | |||
212 | ACPI_MOVE_16_TO_32(&descriptor_length, | ||
213 | &aml->large_header.resource_length); | ||
214 | descriptor_length += sizeof(struct aml_resource_large_header); | ||
215 | |||
216 | } else { | ||
217 | /* Small Resource type -- bits 2:0 of byte 0 contain the length */ | ||
218 | |||
219 | descriptor_length = (u32) (aml->small_header.descriptor_type & | ||
220 | ACPI_RESOURCE_NAME_SMALL_LENGTH_MASK); | ||
221 | descriptor_length += sizeof(struct aml_resource_small_header); | ||
222 | } | ||
223 | |||
224 | return (descriptor_length); | ||
225 | } | ||
226 | |||
227 | /******************************************************************************* | ||
228 | * | ||
229 | * FUNCTION: acpi_rs_set_resource_header | ||
230 | * | ||
231 | * PARAMETERS: descriptor_type - Byte to be inserted as the type | ||
232 | * total_length - Length of the AML descriptor, including | ||
233 | * the header and length fields. | ||
234 | * Aml - Pointer to the raw AML descriptor | ||
235 | * | ||
236 | * RETURN: None | ||
237 | * | ||
238 | * DESCRIPTION: Set the descriptor_type and resource_length fields of an AML | ||
239 | * resource descriptor, both Large and Small descriptors are | ||
240 | * supported automatically | ||
241 | * | ||
242 | ******************************************************************************/ | ||
243 | |||
244 | void | ||
245 | acpi_rs_set_resource_header(u8 descriptor_type, | ||
246 | acpi_size total_length, union aml_resource *aml) | ||
247 | { | ||
248 | u16 resource_length; | ||
249 | |||
250 | ACPI_FUNCTION_ENTRY(); | ||
251 | |||
252 | /* Set the descriptor type */ | ||
253 | |||
254 | aml->small_header.descriptor_type = descriptor_type; | ||
255 | |||
256 | /* Determine if this is a small or large resource */ | ||
257 | |||
258 | if (aml->small_header.descriptor_type & ACPI_RESOURCE_NAME_LARGE) { | ||
259 | /* Large Resource type -- bytes 1-2 contain the 16-bit length */ | ||
260 | |||
261 | resource_length = | ||
262 | (u16) (total_length - | ||
263 | sizeof(struct aml_resource_large_header)); | ||
264 | |||
265 | /* Insert length into the Large descriptor length field */ | ||
266 | |||
267 | ACPI_MOVE_16_TO_16(&aml->large_header.resource_length, | ||
268 | &resource_length); | ||
269 | } else { | ||
270 | /* Small Resource type -- bits 2:0 of byte 0 contain the length */ | ||
271 | |||
272 | resource_length = | ||
273 | (u16) (total_length - | ||
274 | sizeof(struct aml_resource_small_header)); | ||
275 | |||
276 | /* Insert length into the descriptor type byte */ | ||
277 | |||
278 | aml->small_header.descriptor_type |= (u8) resource_length; | ||
279 | } | ||
280 | } | ||
281 | |||
282 | /******************************************************************************* | ||
283 | * | ||
284 | * FUNCTION: acpi_rs_get_resource_type | ||
285 | * | ||
286 | * PARAMETERS: resource_type - Byte 0 of a resource descriptor | ||
287 | * | ||
288 | * RETURN: The Resource Type with no extraneous bits (except the | ||
289 | * Large/Small descriptor bit -- this is left alone) | ||
290 | * | ||
291 | * DESCRIPTION: Extract the Resource Type/Name from the first byte of | ||
292 | * a resource descriptor. | ||
293 | * | ||
294 | ******************************************************************************/ | ||
295 | |||
296 | u8 acpi_rs_get_resource_type(u8 resource_type) | ||
297 | { | ||
298 | ACPI_FUNCTION_ENTRY(); | ||
299 | |||
300 | /* Determine if this is a small or large resource */ | ||
301 | |||
302 | if (resource_type & ACPI_RESOURCE_NAME_LARGE) { | ||
303 | /* Large Resource Type -- bits 6:0 contain the name */ | ||
304 | |||
305 | return (resource_type); | ||
306 | } else { | ||
307 | /* Small Resource Type -- bits 6:3 contain the name */ | ||
308 | |||
309 | return ((u8) (resource_type & ACPI_RESOURCE_NAME_SMALL_MASK)); | ||
310 | } | ||
311 | } | ||
312 | |||
313 | /******************************************************************************* | ||
314 | * | ||
315 | * FUNCTION: acpi_rs_strcpy | ||
316 | * | ||
317 | * PARAMETERS: Destination - Pointer to the destination string | ||
318 | * Source - Pointer to the source string | ||
319 | * | ||
320 | * RETURN: String length, including NULL terminator | ||
321 | * | ||
322 | * DESCRIPTION: Local string copy that returns the string length, saving a | ||
323 | * strcpy followed by a strlen. | ||
324 | * | ||
325 | ******************************************************************************/ | ||
326 | |||
327 | static u16 acpi_rs_strcpy(char *destination, char *source) | ||
328 | { | ||
329 | u16 i; | ||
330 | |||
331 | ACPI_FUNCTION_ENTRY(); | ||
332 | |||
333 | for (i = 0; source[i]; i++) { | ||
334 | destination[i] = source[i]; | ||
335 | } | ||
336 | |||
337 | destination[i] = 0; | ||
338 | |||
339 | /* Return string length including the NULL terminator */ | ||
340 | |||
341 | return ((u16) (i + 1)); | ||
342 | } | ||
343 | |||
344 | /******************************************************************************* | ||
345 | * | ||
346 | * FUNCTION: acpi_rs_get_resource_source | ||
347 | * | ||
348 | * PARAMETERS: resource_length - Length field of the descriptor | ||
349 | * minimum_length - Minimum length of the descriptor (minus | ||
350 | * any optional fields) | ||
351 | * resource_source - Where the resource_source is returned | ||
352 | * Aml - Pointer to the raw AML descriptor | ||
353 | * string_ptr - (optional) where to store the actual | ||
354 | * resource_source string | ||
355 | * | ||
356 | * RETURN: Length of the string plus NULL terminator, rounded up to 32 bit | ||
357 | * | ||
358 | * DESCRIPTION: Copy the optional resource_source data from a raw AML descriptor | ||
359 | * to an internal resource descriptor | ||
360 | * | ||
361 | ******************************************************************************/ | ||
362 | |||
363 | u16 | ||
364 | acpi_rs_get_resource_source(u16 resource_length, | ||
365 | acpi_size minimum_length, | ||
366 | struct acpi_resource_source * resource_source, | ||
367 | union aml_resource * aml, char *string_ptr) | ||
368 | { | ||
369 | acpi_size total_length; | ||
370 | u8 *aml_resource_source; | ||
371 | |||
372 | ACPI_FUNCTION_ENTRY(); | ||
373 | |||
374 | total_length = | ||
375 | resource_length + sizeof(struct aml_resource_large_header); | ||
376 | aml_resource_source = ((u8 *) aml) + minimum_length; | ||
377 | |||
378 | /* | ||
379 | * resource_source is present if the length of the descriptor is longer than | ||
380 | * the minimum length. | ||
381 | * | ||
382 | * Note: Some resource descriptors will have an additional null, so | ||
383 | * we add 1 to the minimum length. | ||
384 | */ | ||
385 | if (total_length > (minimum_length + 1)) { | ||
386 | /* Get the resource_source_index */ | ||
387 | |||
388 | resource_source->index = aml_resource_source[0]; | ||
389 | |||
390 | resource_source->string_ptr = string_ptr; | ||
391 | if (!string_ptr) { | ||
392 | /* | ||
393 | * String destination pointer is not specified; Set the String | ||
394 | * pointer to the end of the current resource_source structure. | ||
395 | */ | ||
396 | resource_source->string_ptr = (char *) | ||
397 | ((u8 *) resource_source) + | ||
398 | sizeof(struct acpi_resource_source); | ||
399 | } | ||
400 | |||
401 | /* Copy the resource_source string to the destination */ | ||
402 | |||
403 | resource_source->string_length = | ||
404 | acpi_rs_strcpy(resource_source->string_ptr, | ||
405 | (char *)&aml_resource_source[1]); | ||
406 | |||
407 | /* | ||
408 | * In order for the struct_size to fall on a 32-bit boundary, | ||
409 | * calculate the length of the string and expand the | ||
410 | * struct_size to the next 32-bit boundary. | ||
411 | */ | ||
412 | return ((u16) | ||
413 | ACPI_ROUND_UP_to_32_bITS(resource_source-> | ||
414 | string_length)); | ||
415 | } else { | ||
416 | /* resource_source is not present */ | ||
417 | |||
418 | resource_source->index = 0; | ||
419 | resource_source->string_length = 0; | ||
420 | resource_source->string_ptr = NULL; | ||
421 | return (0); | ||
422 | } | ||
423 | } | ||
424 | |||
425 | /******************************************************************************* | ||
426 | * | ||
427 | * FUNCTION: acpi_rs_set_resource_source | ||
428 | * | ||
429 | * PARAMETERS: Aml - Pointer to the raw AML descriptor | ||
430 | * minimum_length - Minimum length of the descriptor (minus | ||
431 | * any optional fields) | ||
432 | * resource_source - Internal resource_source | ||
433 | |||
434 | * | ||
435 | * RETURN: Total length of the AML descriptor | ||
436 | * | ||
437 | * DESCRIPTION: Convert an optoinal resource_source from internal format to a | ||
438 | * raw AML resource descriptor | ||
439 | * | ||
440 | ******************************************************************************/ | ||
441 | |||
442 | acpi_size | ||
443 | acpi_rs_set_resource_source(union aml_resource * aml, | ||
444 | acpi_size minimum_length, | ||
445 | struct acpi_resource_source * resource_source) | ||
446 | { | ||
447 | u8 *aml_resource_source; | ||
448 | acpi_size descriptor_length; | ||
449 | |||
450 | ACPI_FUNCTION_ENTRY(); | ||
451 | |||
452 | descriptor_length = minimum_length; | ||
453 | |||
454 | /* Non-zero string length indicates presence of a resource_source */ | ||
455 | |||
456 | if (resource_source->string_length) { | ||
457 | /* Point to the end of the AML descriptor */ | ||
458 | |||
459 | aml_resource_source = ((u8 *) aml) + minimum_length; | ||
460 | |||
461 | /* Copy the resource_source_index */ | ||
462 | |||
463 | aml_resource_source[0] = (u8) resource_source->index; | ||
464 | |||
465 | /* Copy the resource_source string */ | ||
466 | |||
467 | ACPI_STRCPY((char *)&aml_resource_source[1], | ||
468 | resource_source->string_ptr); | ||
469 | |||
470 | /* | ||
471 | * Add the length of the string (+ 1 for null terminator) to the | ||
472 | * final descriptor length | ||
473 | */ | ||
474 | descriptor_length += | ||
475 | ((acpi_size) resource_source->string_length + 1); | ||
476 | } | ||
477 | |||
478 | /* Return the new total length of the AML descriptor */ | ||
479 | |||
480 | return (descriptor_length); | ||
481 | } | ||
482 | |||
483 | /******************************************************************************* | ||
484 | * | ||
53 | * FUNCTION: acpi_rs_get_prt_method_data | 485 | * FUNCTION: acpi_rs_get_prt_method_data |
54 | * | 486 | * |
55 | * PARAMETERS: Handle - a handle to the containing object | 487 | * PARAMETERS: Handle - a handle to the containing object |
@@ -65,8 +497,9 @@ ACPI_MODULE_NAME("rsutils") | |||
65 | * and the contents of the callers buffer is undefined. | 497 | * and the contents of the callers buffer is undefined. |
66 | * | 498 | * |
67 | ******************************************************************************/ | 499 | ******************************************************************************/ |
500 | |||
68 | acpi_status | 501 | acpi_status |
69 | acpi_rs_get_prt_method_data(acpi_handle handle, struct acpi_buffer *ret_buffer) | 502 | acpi_rs_get_prt_method_data(acpi_handle handle, struct acpi_buffer * ret_buffer) |
70 | { | 503 | { |
71 | union acpi_operand_object *obj_desc; | 504 | union acpi_operand_object *obj_desc; |
72 | acpi_status status; | 505 | acpi_status status; |
@@ -284,7 +717,7 @@ acpi_rs_set_srs_method_data(acpi_handle handle, struct acpi_buffer *in_buffer) | |||
284 | * Convert the linked list into a byte stream | 717 | * Convert the linked list into a byte stream |
285 | */ | 718 | */ |
286 | buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; | 719 | buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; |
287 | status = acpi_rs_create_byte_stream(in_buffer->pointer, &buffer); | 720 | status = acpi_rs_create_aml_resources(in_buffer->pointer, &buffer); |
288 | if (ACPI_FAILURE(status)) { | 721 | if (ACPI_FAILURE(status)) { |
289 | return_ACPI_STATUS(status); | 722 | return_ACPI_STATUS(status); |
290 | } | 723 | } |