[ACPI] ACPICA 20051021
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / acpi / resources / rsutils.c
blob7613033f5dcf3c5e385e4e2503d11a5db4bfa979
1 /*******************************************************************************
3 * Module Name: rsutils - Utilities for the resource manager
5 ******************************************************************************/
7 /*
8 * Copyright (C) 2000 - 2005, R. Byron Moore
9 * All rights reserved.
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.
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.
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.
44 #include <acpi/acpi.h>
45 #include <acpi/acnamesp.h>
46 #include <acpi/acresrc.h>
48 #define _COMPONENT ACPI_RESOURCES
49 ACPI_MODULE_NAME("rsutils")
51 /*******************************************************************************
53 * FUNCTION: acpi_rs_decode_bitmask
55 * PARAMETERS: Mask - Bitmask to decode
56 * List - Where the converted list is returned
58 * RETURN: Count of bits set (length of list)
60 * DESCRIPTION: Convert a bit mask into a list of values
62 ******************************************************************************/
63 u8 acpi_rs_decode_bitmask(u16 mask, u8 * list)
65 acpi_native_uint i;
66 u8 bit_count;
68 /* Decode the mask bits */
70 for (i = 0, bit_count = 0; mask; i++) {
71 if (mask & 0x0001) {
72 list[bit_count] = (u8) i;
73 bit_count++;
76 mask >>= 1;
79 return (bit_count);
82 /*******************************************************************************
84 * FUNCTION: acpi_rs_encode_bitmask
86 * PARAMETERS: List - List of values to encode
87 * Count - Length of list
89 * RETURN: Encoded bitmask
91 * DESCRIPTION: Convert a list of values to an encoded bitmask
93 ******************************************************************************/
95 u16 acpi_rs_encode_bitmask(u8 * list, u8 count)
97 acpi_native_uint i;
98 u16 mask;
100 /* Encode the list into a single bitmask */
102 for (i = 0, mask = 0; i < count; i++) {
103 mask |= (0x0001 << list[i]);
106 return (mask);
109 /*******************************************************************************
111 * FUNCTION: acpi_rs_move_data
113 * PARAMETERS: Destination - Pointer to the destination descriptor
114 * Source - Pointer to the source descriptor
115 * item_count - How many items to move
116 * move_type - Byte width
118 * RETURN: None
120 * DESCRIPTION: Move multiple data items from one descriptor to another. Handles
121 * alignment issues and endian issues if necessary, as configured
122 * via the ACPI_MOVE_* macros. (This is why a memcpy is not used)
124 ******************************************************************************/
126 void
127 acpi_rs_move_data(void *destination, void *source, u16 item_count, u8 move_type)
129 acpi_native_uint i;
131 /* One move per item */
133 for (i = 0; i < item_count; i++) {
134 switch (move_type) {
136 * For the 8-bit case, we can perform the move all at once
137 * since there are no alignment or endian issues
139 case ACPI_RSC_MOVE8:
140 ACPI_MEMCPY(destination, source, item_count);
141 return;
144 * 16-, 32-, and 64-bit cases must use the move macros that perform
145 * endian conversion and/or accomodate hardware that cannot perform
146 * misaligned memory transfers
148 case ACPI_RSC_MOVE16:
149 ACPI_MOVE_16_TO_16(&((u16 *) destination)[i],
150 &((u16 *) source)[i]);
151 break;
153 case ACPI_RSC_MOVE32:
154 ACPI_MOVE_32_TO_32(&((u32 *) destination)[i],
155 &((u32 *) source)[i]);
156 break;
158 case ACPI_RSC_MOVE64:
159 ACPI_MOVE_64_TO_64(&((u64 *) destination)[i],
160 &((u64 *) source)[i]);
161 break;
163 default:
164 return;
169 /*******************************************************************************
171 * FUNCTION: acpi_rs_get_resource_info
173 * PARAMETERS: resource_type - Byte 0 of a resource descriptor
175 * RETURN: Pointer to the resource conversion handler
177 * DESCRIPTION: Extract the Resource Type/Name from the first byte of
178 * a resource descriptor.
180 ******************************************************************************/
182 struct acpi_resource_info *acpi_rs_get_resource_info(u8 resource_type)
184 struct acpi_resource_info *size_info;
186 ACPI_FUNCTION_ENTRY();
188 /* Determine if this is a small or large resource */
190 if (resource_type & ACPI_RESOURCE_NAME_LARGE) {
191 /* Large Resource Type -- bits 6:0 contain the name */
193 if (resource_type > ACPI_RESOURCE_NAME_LARGE_MAX) {
194 return (NULL);
197 size_info = &acpi_gbl_lg_resource_info[(resource_type &
198 ACPI_RESOURCE_NAME_LARGE_MASK)];
199 } else {
200 /* Small Resource Type -- bits 6:3 contain the name */
202 size_info = &acpi_gbl_sm_resource_info[((resource_type &
203 ACPI_RESOURCE_NAME_SMALL_MASK)
204 >> 3)];
207 /* Zero entry indicates an invalid resource type */
209 if (!size_info->minimum_internal_struct_length) {
210 return (NULL);
213 return (size_info);
216 /*******************************************************************************
218 * FUNCTION: acpi_rs_set_resource_length
220 * PARAMETERS: total_length - Length of the AML descriptor, including
221 * the header and length fields.
222 * Aml - Pointer to the raw AML descriptor
224 * RETURN: None
226 * DESCRIPTION: Set the resource_length field of an AML
227 * resource descriptor, both Large and Small descriptors are
228 * supported automatically. Note: Descriptor Type field must
229 * be valid.
231 ******************************************************************************/
233 void
234 acpi_rs_set_resource_length(acpi_rsdesc_size total_length,
235 union aml_resource *aml)
237 acpi_rs_length resource_length;
239 ACPI_FUNCTION_ENTRY();
241 /* Determine if this is a small or large resource */
243 if (aml->small_header.descriptor_type & ACPI_RESOURCE_NAME_LARGE) {
244 /* Large Resource type -- bytes 1-2 contain the 16-bit length */
246 resource_length = (acpi_rs_length)
247 (total_length - sizeof(struct aml_resource_large_header));
249 /* Insert length into the Large descriptor length field */
251 ACPI_MOVE_16_TO_16(&aml->large_header.resource_length,
252 &resource_length);
253 } else {
254 /* Small Resource type -- bits 2:0 of byte 0 contain the length */
256 resource_length = (acpi_rs_length)
257 (total_length - sizeof(struct aml_resource_small_header));
259 /* Insert length into the descriptor type byte */
261 aml->small_header.descriptor_type = (u8)
263 /* Clear any existing length, preserving descriptor type bits */
264 ((aml->small_header.
265 descriptor_type & ~ACPI_RESOURCE_NAME_SMALL_LENGTH_MASK)
267 | resource_length);
271 /*******************************************************************************
273 * FUNCTION: acpi_rs_set_resource_header
275 * PARAMETERS: descriptor_type - Byte to be inserted as the type
276 * total_length - Length of the AML descriptor, including
277 * the header and length fields.
278 * Aml - Pointer to the raw AML descriptor
280 * RETURN: None
282 * DESCRIPTION: Set the descriptor_type and resource_length fields of an AML
283 * resource descriptor, both Large and Small descriptors are
284 * supported automatically
286 ******************************************************************************/
288 void
289 acpi_rs_set_resource_header(u8 descriptor_type,
290 acpi_rsdesc_size total_length,
291 union aml_resource *aml)
293 ACPI_FUNCTION_ENTRY();
295 /* Set the Descriptor Type */
297 aml->small_header.descriptor_type = descriptor_type;
299 /* Set the Resource Length */
301 acpi_rs_set_resource_length(total_length, aml);
304 /*******************************************************************************
306 * FUNCTION: acpi_rs_strcpy
308 * PARAMETERS: Destination - Pointer to the destination string
309 * Source - Pointer to the source string
311 * RETURN: String length, including NULL terminator
313 * DESCRIPTION: Local string copy that returns the string length, saving a
314 * strcpy followed by a strlen.
316 ******************************************************************************/
318 static u16 acpi_rs_strcpy(char *destination, char *source)
320 u16 i;
322 ACPI_FUNCTION_ENTRY();
324 for (i = 0; source[i]; i++) {
325 destination[i] = source[i];
328 destination[i] = 0;
330 /* Return string length including the NULL terminator */
332 return ((u16) (i + 1));
335 /*******************************************************************************
337 * FUNCTION: acpi_rs_get_resource_source
339 * PARAMETERS: resource_length - Length field of the descriptor
340 * minimum_length - Minimum length of the descriptor (minus
341 * any optional fields)
342 * resource_source - Where the resource_source is returned
343 * Aml - Pointer to the raw AML descriptor
344 * string_ptr - (optional) where to store the actual
345 * resource_source string
347 * RETURN: Length of the string plus NULL terminator, rounded up to 32 bit
349 * DESCRIPTION: Copy the optional resource_source data from a raw AML descriptor
350 * to an internal resource descriptor
352 ******************************************************************************/
354 acpi_rs_length
355 acpi_rs_get_resource_source(acpi_rs_length resource_length,
356 acpi_rs_length minimum_length,
357 struct acpi_resource_source * resource_source,
358 union aml_resource * aml, char *string_ptr)
360 acpi_rsdesc_size total_length;
361 u8 *aml_resource_source;
363 ACPI_FUNCTION_ENTRY();
365 total_length =
366 resource_length + sizeof(struct aml_resource_large_header);
367 aml_resource_source = ((u8 *) aml) + minimum_length;
370 * resource_source is present if the length of the descriptor is longer than
371 * the minimum length.
373 * Note: Some resource descriptors will have an additional null, so
374 * we add 1 to the minimum length.
376 if (total_length > (acpi_rsdesc_size) (minimum_length + 1)) {
377 /* Get the resource_source_index */
379 resource_source->index = aml_resource_source[0];
381 resource_source->string_ptr = string_ptr;
382 if (!string_ptr) {
384 * String destination pointer is not specified; Set the String
385 * pointer to the end of the current resource_source structure.
387 resource_source->string_ptr = (char *)
388 ((u8 *) resource_source) +
389 sizeof(struct acpi_resource_source);
393 * In order for the struct_size to fall on a 32-bit boundary, calculate
394 * the length of the string (+1 for the NULL terminator) and expand the
395 * struct_size to the next 32-bit boundary.
397 * Zero the entire area of the buffer.
399 total_length =
400 ACPI_ROUND_UP_to_32_bITS(ACPI_STRLEN
401 ((char *)&aml_resource_source[1]) +
403 ACPI_MEMSET(resource_source->string_ptr, 0, total_length);
405 /* Copy the resource_source string to the destination */
407 resource_source->string_length =
408 acpi_rs_strcpy(resource_source->string_ptr,
409 (char *)&aml_resource_source[1]);
411 return ((acpi_rs_length) total_length);
412 } else {
413 /* resource_source is not present */
415 resource_source->index = 0;
416 resource_source->string_length = 0;
417 resource_source->string_ptr = NULL;
418 return (0);
422 /*******************************************************************************
424 * FUNCTION: acpi_rs_set_resource_source
426 * PARAMETERS: Aml - Pointer to the raw AML descriptor
427 * minimum_length - Minimum length of the descriptor (minus
428 * any optional fields)
429 * resource_source - Internal resource_source
432 * RETURN: Total length of the AML descriptor
434 * DESCRIPTION: Convert an optional resource_source from internal format to a
435 * raw AML resource descriptor
437 ******************************************************************************/
439 acpi_rsdesc_size
440 acpi_rs_set_resource_source(union aml_resource * aml,
441 acpi_rs_length minimum_length,
442 struct acpi_resource_source * resource_source)
444 u8 *aml_resource_source;
445 acpi_rsdesc_size descriptor_length;
447 ACPI_FUNCTION_ENTRY();
449 descriptor_length = minimum_length;
451 /* Non-zero string length indicates presence of a resource_source */
453 if (resource_source->string_length) {
454 /* Point to the end of the AML descriptor */
456 aml_resource_source = ((u8 *) aml) + minimum_length;
458 /* Copy the resource_source_index */
460 aml_resource_source[0] = (u8) resource_source->index;
462 /* Copy the resource_source string */
464 ACPI_STRCPY((char *)&aml_resource_source[1],
465 resource_source->string_ptr);
468 * Add the length of the string (+ 1 for null terminator) to the
469 * final descriptor length
471 descriptor_length +=
472 ((acpi_rsdesc_size) resource_source->string_length + 1);
475 /* Return the new total length of the AML descriptor */
477 return (descriptor_length);
480 /*******************************************************************************
482 * FUNCTION: acpi_rs_get_prt_method_data
484 * PARAMETERS: Handle - a handle to the containing object
485 * ret_buffer - a pointer to a buffer structure for the
486 * results
488 * RETURN: Status
490 * DESCRIPTION: This function is called to get the _PRT value of an object
491 * contained in an object specified by the handle passed in
493 * If the function fails an appropriate status will be returned
494 * and the contents of the callers buffer is undefined.
496 ******************************************************************************/
498 acpi_status
499 acpi_rs_get_prt_method_data(acpi_handle handle, struct acpi_buffer * ret_buffer)
501 union acpi_operand_object *obj_desc;
502 acpi_status status;
504 ACPI_FUNCTION_TRACE("rs_get_prt_method_data");
506 /* Parameters guaranteed valid by caller */
508 /* Execute the method, no parameters */
510 status = acpi_ut_evaluate_object(handle, METHOD_NAME__PRT,
511 ACPI_BTYPE_PACKAGE, &obj_desc);
512 if (ACPI_FAILURE(status)) {
513 return_ACPI_STATUS(status);
517 * Create a resource linked list from the byte stream buffer that comes
518 * back from the _CRS method execution.
520 status = acpi_rs_create_pci_routing_table(obj_desc, ret_buffer);
522 /* On exit, we must delete the object returned by evaluate_object */
524 acpi_ut_remove_reference(obj_desc);
525 return_ACPI_STATUS(status);
528 /*******************************************************************************
530 * FUNCTION: acpi_rs_get_crs_method_data
532 * PARAMETERS: Handle - a handle to the containing object
533 * ret_buffer - a pointer to a buffer structure for the
534 * results
536 * RETURN: Status
538 * DESCRIPTION: This function is called to get the _CRS value of an object
539 * contained in an object specified by the handle passed in
541 * If the function fails an appropriate status will be returned
542 * and the contents of the callers buffer is undefined.
544 ******************************************************************************/
546 acpi_status
547 acpi_rs_get_crs_method_data(acpi_handle handle, struct acpi_buffer *ret_buffer)
549 union acpi_operand_object *obj_desc;
550 acpi_status status;
552 ACPI_FUNCTION_TRACE("rs_get_crs_method_data");
554 /* Parameters guaranteed valid by caller */
556 /* Execute the method, no parameters */
558 status = acpi_ut_evaluate_object(handle, METHOD_NAME__CRS,
559 ACPI_BTYPE_BUFFER, &obj_desc);
560 if (ACPI_FAILURE(status)) {
561 return_ACPI_STATUS(status);
565 * Make the call to create a resource linked list from the
566 * byte stream buffer that comes back from the _CRS method
567 * execution.
569 status = acpi_rs_create_resource_list(obj_desc, ret_buffer);
571 /* on exit, we must delete the object returned by evaluate_object */
573 acpi_ut_remove_reference(obj_desc);
574 return_ACPI_STATUS(status);
577 /*******************************************************************************
579 * FUNCTION: acpi_rs_get_prs_method_data
581 * PARAMETERS: Handle - a handle to the containing object
582 * ret_buffer - a pointer to a buffer structure for the
583 * results
585 * RETURN: Status
587 * DESCRIPTION: This function is called to get the _PRS value of an object
588 * contained in an object specified by the handle passed in
590 * If the function fails an appropriate status will be returned
591 * and the contents of the callers buffer is undefined.
593 ******************************************************************************/
595 #ifdef ACPI_FUTURE_USAGE
596 acpi_status
597 acpi_rs_get_prs_method_data(acpi_handle handle, struct acpi_buffer *ret_buffer)
599 union acpi_operand_object *obj_desc;
600 acpi_status status;
602 ACPI_FUNCTION_TRACE("rs_get_prs_method_data");
604 /* Parameters guaranteed valid by caller */
606 /* Execute the method, no parameters */
608 status = acpi_ut_evaluate_object(handle, METHOD_NAME__PRS,
609 ACPI_BTYPE_BUFFER, &obj_desc);
610 if (ACPI_FAILURE(status)) {
611 return_ACPI_STATUS(status);
615 * Make the call to create a resource linked list from the
616 * byte stream buffer that comes back from the _CRS method
617 * execution.
619 status = acpi_rs_create_resource_list(obj_desc, ret_buffer);
621 /* on exit, we must delete the object returned by evaluate_object */
623 acpi_ut_remove_reference(obj_desc);
624 return_ACPI_STATUS(status);
626 #endif /* ACPI_FUTURE_USAGE */
628 /*******************************************************************************
630 * FUNCTION: acpi_rs_get_method_data
632 * PARAMETERS: Handle - a handle to the containing object
633 * Path - Path to method, relative to Handle
634 * ret_buffer - a pointer to a buffer structure for the
635 * results
637 * RETURN: Status
639 * DESCRIPTION: This function is called to get the _CRS or _PRS value of an
640 * object contained in an object specified by the handle passed in
642 * If the function fails an appropriate status will be returned
643 * and the contents of the callers buffer is undefined.
645 ******************************************************************************/
647 acpi_status
648 acpi_rs_get_method_data(acpi_handle handle,
649 char *path, struct acpi_buffer *ret_buffer)
651 union acpi_operand_object *obj_desc;
652 acpi_status status;
654 ACPI_FUNCTION_TRACE("rs_get_method_data");
656 /* Parameters guaranteed valid by caller */
658 /* Execute the method, no parameters */
660 status =
661 acpi_ut_evaluate_object(handle, path, ACPI_BTYPE_BUFFER, &obj_desc);
662 if (ACPI_FAILURE(status)) {
663 return_ACPI_STATUS(status);
667 * Make the call to create a resource linked list from the
668 * byte stream buffer that comes back from the method
669 * execution.
671 status = acpi_rs_create_resource_list(obj_desc, ret_buffer);
673 /* On exit, we must delete the object returned by evaluate_object */
675 acpi_ut_remove_reference(obj_desc);
676 return_ACPI_STATUS(status);
679 /*******************************************************************************
681 * FUNCTION: acpi_rs_set_srs_method_data
683 * PARAMETERS: Handle - a handle to the containing object
684 * in_buffer - a pointer to a buffer structure of the
685 * parameter
687 * RETURN: Status
689 * DESCRIPTION: This function is called to set the _SRS of an object contained
690 * in an object specified by the handle passed in
692 * If the function fails an appropriate status will be returned
693 * and the contents of the callers buffer is undefined.
695 ******************************************************************************/
697 acpi_status
698 acpi_rs_set_srs_method_data(acpi_handle handle, struct acpi_buffer *in_buffer)
700 struct acpi_parameter_info info;
701 union acpi_operand_object *params[2];
702 acpi_status status;
703 struct acpi_buffer buffer;
705 ACPI_FUNCTION_TRACE("rs_set_srs_method_data");
707 /* Parameters guaranteed valid by caller */
710 * The in_buffer parameter will point to a linked list of
711 * resource parameters. It needs to be formatted into a
712 * byte stream to be sent in as an input parameter to _SRS
714 * Convert the linked list into a byte stream
716 buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
717 status = acpi_rs_create_aml_resources(in_buffer->pointer, &buffer);
718 if (ACPI_FAILURE(status)) {
719 return_ACPI_STATUS(status);
722 /* Init the param object */
724 params[0] = acpi_ut_create_internal_object(ACPI_TYPE_BUFFER);
725 if (!params[0]) {
726 acpi_os_free(buffer.pointer);
727 return_ACPI_STATUS(AE_NO_MEMORY);
730 /* Set up the parameter object */
732 params[0]->buffer.length = (u32) buffer.length;
733 params[0]->buffer.pointer = buffer.pointer;
734 params[0]->common.flags = AOPOBJ_DATA_VALID;
735 params[1] = NULL;
737 info.node = handle;
738 info.parameters = params;
739 info.parameter_type = ACPI_PARAM_ARGS;
741 /* Execute the method, no return value */
743 status = acpi_ns_evaluate_relative(METHOD_NAME__SRS, &info);
744 if (ACPI_SUCCESS(status)) {
745 /* Delete any return object (especially if implicit_return is enabled) */
747 if (info.return_object) {
748 acpi_ut_remove_reference(info.return_object);
752 /* Clean up and return the status from acpi_ns_evaluate_relative */
754 acpi_ut_remove_reference(params[0]);
755 return_ACPI_STATUS(status);