aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/resources/rsutils.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/resources/rsutils.c')
-rw-r--r--drivers/acpi/resources/rsutils.c437
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 ******************************************************************************/
67void
68acpi_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
115struct 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
163u16 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
201u32 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
244void
245acpi_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
296u8 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
327static 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
363u16
364acpi_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
442acpi_size
443acpi_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
68acpi_status 501acpi_status
69acpi_rs_get_prt_method_data(acpi_handle handle, struct acpi_buffer *ret_buffer) 502acpi_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 }