11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/******************************************************************************* 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Module Name: rscreate - Create resource lists/tables 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ******************************************************************************/ 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 877848130e53b06c22fe37a7b6acbb82bb3e9bfbaBob Moore * Copyright (C) 2000 - 2012, Intel Corp. 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * All rights reserved. 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Redistribution and use in source and binary forms, with or without 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * modification, are permitted provided that the following conditions 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * are met: 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1. Redistributions of source code must retain the above copyright 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * notice, this list of conditions, and the following disclaimer, 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * without modification. 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2. Redistributions in binary form must reproduce at minimum a disclaimer 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * substantially similar to the "NO WARRANTY" disclaimer below 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * ("Disclaimer") and any redistribution must be conditioned upon 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * including a substantially similar Disclaimer requirement for further 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * binary redistribution. 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 3. Neither the names of the above-listed copyright holders nor the names 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * of any contributors may be used to endorse or promote products derived 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * from this software without specific prior written permission. 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Alternatively, this software may be distributed under the terms of the 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * GNU General Public License ("GPL") version 2 as published by the Free 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Software Foundation. 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * NO WARRANTY 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * POSSIBILITY OF SUCH DAMAGES. 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <acpi/acpi.h> 45e2f7a7772880458edff1b1cc5a988947229fac26Len Brown#include "accommon.h" 46e2f7a7772880458edff1b1cc5a988947229fac26Len Brown#include "acresrc.h" 47e2f7a7772880458edff1b1cc5a988947229fac26Len Brown#include "acnamesp.h" 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define _COMPONENT ACPI_RESOURCES 504be44fcd3bf648b782f4460fd06dfae6c42ded4bLen BrownACPI_MODULE_NAME("rscreate") 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/******************************************************************************* 531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 540e243178047c0219b3367dd44f81040826b7ea83Bob Moore * FUNCTION: acpi_buffer_to_resource 550e243178047c0219b3367dd44f81040826b7ea83Bob Moore * 560e243178047c0219b3367dd44f81040826b7ea83Bob Moore * PARAMETERS: aml_buffer - Pointer to the resource byte stream 570e243178047c0219b3367dd44f81040826b7ea83Bob Moore * aml_buffer_length - Length of the aml_buffer 580e243178047c0219b3367dd44f81040826b7ea83Bob Moore * resource_ptr - Where the converted resource is returned 590e243178047c0219b3367dd44f81040826b7ea83Bob Moore * 600e243178047c0219b3367dd44f81040826b7ea83Bob Moore * RETURN: Status 610e243178047c0219b3367dd44f81040826b7ea83Bob Moore * 620e243178047c0219b3367dd44f81040826b7ea83Bob Moore * DESCRIPTION: Convert a raw AML buffer to a resource list 630e243178047c0219b3367dd44f81040826b7ea83Bob Moore * 640e243178047c0219b3367dd44f81040826b7ea83Bob Moore ******************************************************************************/ 650e243178047c0219b3367dd44f81040826b7ea83Bob Mooreacpi_status 660e243178047c0219b3367dd44f81040826b7ea83Bob Mooreacpi_buffer_to_resource(u8 *aml_buffer, 670e243178047c0219b3367dd44f81040826b7ea83Bob Moore u16 aml_buffer_length, 680e243178047c0219b3367dd44f81040826b7ea83Bob Moore struct acpi_resource **resource_ptr) 690e243178047c0219b3367dd44f81040826b7ea83Bob Moore{ 700e243178047c0219b3367dd44f81040826b7ea83Bob Moore acpi_status status; 710e243178047c0219b3367dd44f81040826b7ea83Bob Moore acpi_size list_size_needed; 720e243178047c0219b3367dd44f81040826b7ea83Bob Moore void *resource; 730e243178047c0219b3367dd44f81040826b7ea83Bob Moore void *current_resource_ptr; 740e243178047c0219b3367dd44f81040826b7ea83Bob Moore 750e243178047c0219b3367dd44f81040826b7ea83Bob Moore /* 760e243178047c0219b3367dd44f81040826b7ea83Bob Moore * Note: we allow AE_AML_NO_RESOURCE_END_TAG, since an end tag 770e243178047c0219b3367dd44f81040826b7ea83Bob Moore * is not required here. 780e243178047c0219b3367dd44f81040826b7ea83Bob Moore */ 790e243178047c0219b3367dd44f81040826b7ea83Bob Moore 800e243178047c0219b3367dd44f81040826b7ea83Bob Moore /* Get the required length for the converted resource */ 810e243178047c0219b3367dd44f81040826b7ea83Bob Moore 820e243178047c0219b3367dd44f81040826b7ea83Bob Moore status = acpi_rs_get_list_length(aml_buffer, aml_buffer_length, 830e243178047c0219b3367dd44f81040826b7ea83Bob Moore &list_size_needed); 840e243178047c0219b3367dd44f81040826b7ea83Bob Moore if (status == AE_AML_NO_RESOURCE_END_TAG) { 850e243178047c0219b3367dd44f81040826b7ea83Bob Moore status = AE_OK; 860e243178047c0219b3367dd44f81040826b7ea83Bob Moore } 870e243178047c0219b3367dd44f81040826b7ea83Bob Moore if (ACPI_FAILURE(status)) { 880e243178047c0219b3367dd44f81040826b7ea83Bob Moore return (status); 890e243178047c0219b3367dd44f81040826b7ea83Bob Moore } 900e243178047c0219b3367dd44f81040826b7ea83Bob Moore 910e243178047c0219b3367dd44f81040826b7ea83Bob Moore /* Allocate a buffer for the converted resource */ 920e243178047c0219b3367dd44f81040826b7ea83Bob Moore 930e243178047c0219b3367dd44f81040826b7ea83Bob Moore resource = ACPI_ALLOCATE_ZEROED(list_size_needed); 940e243178047c0219b3367dd44f81040826b7ea83Bob Moore current_resource_ptr = resource; 950e243178047c0219b3367dd44f81040826b7ea83Bob Moore if (!resource) { 960e243178047c0219b3367dd44f81040826b7ea83Bob Moore return (AE_NO_MEMORY); 970e243178047c0219b3367dd44f81040826b7ea83Bob Moore } 980e243178047c0219b3367dd44f81040826b7ea83Bob Moore 990e243178047c0219b3367dd44f81040826b7ea83Bob Moore /* Perform the AML-to-Resource conversion */ 1000e243178047c0219b3367dd44f81040826b7ea83Bob Moore 1010e243178047c0219b3367dd44f81040826b7ea83Bob Moore status = acpi_ut_walk_aml_resources(aml_buffer, aml_buffer_length, 1020e243178047c0219b3367dd44f81040826b7ea83Bob Moore acpi_rs_convert_aml_to_resources, 1030e243178047c0219b3367dd44f81040826b7ea83Bob Moore ¤t_resource_ptr); 1040e243178047c0219b3367dd44f81040826b7ea83Bob Moore if (status == AE_AML_NO_RESOURCE_END_TAG) { 1050e243178047c0219b3367dd44f81040826b7ea83Bob Moore status = AE_OK; 1060e243178047c0219b3367dd44f81040826b7ea83Bob Moore } 1070e243178047c0219b3367dd44f81040826b7ea83Bob Moore if (ACPI_FAILURE(status)) { 1080e243178047c0219b3367dd44f81040826b7ea83Bob Moore ACPI_FREE(resource); 1090e243178047c0219b3367dd44f81040826b7ea83Bob Moore } else { 1100e243178047c0219b3367dd44f81040826b7ea83Bob Moore *resource_ptr = resource; 1110e243178047c0219b3367dd44f81040826b7ea83Bob Moore } 1120e243178047c0219b3367dd44f81040826b7ea83Bob Moore 1130e243178047c0219b3367dd44f81040826b7ea83Bob Moore return (status); 1140e243178047c0219b3367dd44f81040826b7ea83Bob Moore} 1150e243178047c0219b3367dd44f81040826b7ea83Bob Moore 1160e243178047c0219b3367dd44f81040826b7ea83Bob Moore/******************************************************************************* 1170e243178047c0219b3367dd44f81040826b7ea83Bob Moore * 1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * FUNCTION: acpi_rs_create_resource_list 1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 12050eca3eb89d73d9f0aa070b126c7ee6a616016abBob Moore * PARAMETERS: aml_buffer - Pointer to the resource byte stream 12150eca3eb89d73d9f0aa070b126c7ee6a616016abBob Moore * output_buffer - Pointer to the user's buffer 1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 12350eca3eb89d73d9f0aa070b126c7ee6a616016abBob Moore * RETURN: Status: AE_OK if okay, else a valid acpi_status code 1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * If output_buffer is not large enough, output_buffer_length 1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * indicates how large output_buffer should be, else it 1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * indicates how may u8 elements of output_buffer are valid. 1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * DESCRIPTION: Takes the byte stream returned from a _CRS, _PRS control method 1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * execution and parses the stream to create a linked list 1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * of device resources. 1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ******************************************************************************/ 133e0fe0a8d4ed5474261d0ee1452f5d9ae77236958Lin Ming 1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsacpi_status 13550eca3eb89d73d9f0aa070b126c7ee6a616016abBob Mooreacpi_rs_create_resource_list(union acpi_operand_object *aml_buffer, 136e0fe0a8d4ed5474261d0ee1452f5d9ae77236958Lin Ming struct acpi_buffer * output_buffer) 1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1394be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown acpi_status status; 14050eca3eb89d73d9f0aa070b126c7ee6a616016abBob Moore u8 *aml_start; 1414be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown acpi_size list_size_needed = 0; 14250eca3eb89d73d9f0aa070b126c7ee6a616016abBob Moore u32 aml_buffer_length; 14361686124f47d7c4b78610346c5f8f9d8a6d46bb5Bob Moore void *resource; 1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 145b229cf92eee616c7cb5ad8cdb35a19b119f00bc8Bob Moore ACPI_FUNCTION_TRACE(rs_create_resource_list); 1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 147b229cf92eee616c7cb5ad8cdb35a19b119f00bc8Bob Moore ACPI_DEBUG_PRINT((ACPI_DB_INFO, "AmlBuffer = %p\n", aml_buffer)); 1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14944f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore /* Params already validated, so we don't re-validate here */ 15044f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore 15150eca3eb89d73d9f0aa070b126c7ee6a616016abBob Moore aml_buffer_length = aml_buffer->buffer.length; 15250eca3eb89d73d9f0aa070b126c7ee6a616016abBob Moore aml_start = aml_buffer->buffer.pointer; 1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 15550eca3eb89d73d9f0aa070b126c7ee6a616016abBob Moore * Pass the aml_buffer into a module that can calculate 1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the buffer size needed for the linked list 1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 15850eca3eb89d73d9f0aa070b126c7ee6a616016abBob Moore status = acpi_rs_get_list_length(aml_start, aml_buffer_length, 15950eca3eb89d73d9f0aa070b126c7ee6a616016abBob Moore &list_size_needed); 1604be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown 161b229cf92eee616c7cb5ad8cdb35a19b119f00bc8Bob Moore ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Status=%X ListSizeNeeded=%X\n", 1624be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown status, (u32) list_size_needed)); 1634be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown if (ACPI_FAILURE(status)) { 1644be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown return_ACPI_STATUS(status); 1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Validate/Allocate/Clear caller buffer */ 1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1694be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown status = acpi_ut_initialize_buffer(output_buffer, list_size_needed); 1704be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown if (ACPI_FAILURE(status)) { 1714be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown return_ACPI_STATUS(status); 1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Do the conversion */ 1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17661686124f47d7c4b78610346c5f8f9d8a6d46bb5Bob Moore resource = output_buffer->pointer; 17761686124f47d7c4b78610346c5f8f9d8a6d46bb5Bob Moore status = acpi_ut_walk_aml_resources(aml_start, aml_buffer_length, 17861686124f47d7c4b78610346c5f8f9d8a6d46bb5Bob Moore acpi_rs_convert_aml_to_resources, 17961686124f47d7c4b78610346c5f8f9d8a6d46bb5Bob Moore &resource); 1804be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown if (ACPI_FAILURE(status)) { 1814be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown return_ACPI_STATUS(status); 1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 184b229cf92eee616c7cb5ad8cdb35a19b119f00bc8Bob Moore ACPI_DEBUG_PRINT((ACPI_DB_INFO, "OutputBuffer %p Length %X\n", 1854be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown output_buffer->pointer, (u32) output_buffer->length)); 1864be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown return_ACPI_STATUS(AE_OK); 1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/******************************************************************************* 1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * FUNCTION: acpi_rs_create_pci_routing_table 1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1930211a9c8508b2183e0e539509aad60414f1c3813Frederik Schwarzer * PARAMETERS: package_object - Pointer to a union acpi_operand_object 1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * package 1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * output_buffer - Pointer to the user's buffer 1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * RETURN: Status AE_OK if okay, else a valid acpi_status code. 1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * If the output_buffer is too small, the error will be 1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * AE_BUFFER_OVERFLOW and output_buffer->Length will point 2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * to the size buffer needed. 2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * DESCRIPTION: Takes the union acpi_operand_object package and creates a 2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * linked list of PCI interrupt descriptions 2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * NOTE: It is the caller's responsibility to ensure that the start of the 2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * output buffer is aligned properly (if necessary). 2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ******************************************************************************/ 2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsacpi_status 2114be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brownacpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, 2124be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown struct acpi_buffer *output_buffer) 2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2144be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown u8 *buffer; 2154be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown union acpi_operand_object **top_object_list; 2164be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown union acpi_operand_object **sub_object_list; 2174be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown union acpi_operand_object *obj_desc; 2184be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown acpi_size buffer_size_needed = 0; 2194be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown u32 number_of_elements; 2204be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown u32 index; 2214be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown struct acpi_pci_routing_table *user_prt; 2224be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown struct acpi_namespace_node *node; 2234be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown acpi_status status; 2244be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown struct acpi_buffer path_buffer; 2254be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown 226b229cf92eee616c7cb5ad8cdb35a19b119f00bc8Bob Moore ACPI_FUNCTION_TRACE(rs_create_pci_routing_table); 2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Params already validated, so we don't re-validate here */ 2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 23044f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore /* Get the required buffer length */ 23144f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore 2324be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown status = acpi_rs_get_pci_routing_table_length(package_object, 2334be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown &buffer_size_needed); 2344be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown if (ACPI_FAILURE(status)) { 2354be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown return_ACPI_STATUS(status); 2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 238b229cf92eee616c7cb5ad8cdb35a19b119f00bc8Bob Moore ACPI_DEBUG_PRINT((ACPI_DB_INFO, "BufferSizeNeeded = %X\n", 2394be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown (u32) buffer_size_needed)); 2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Validate/Allocate/Clear caller buffer */ 2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2434be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown status = acpi_ut_initialize_buffer(output_buffer, buffer_size_needed); 2444be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown if (ACPI_FAILURE(status)) { 2454be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown return_ACPI_STATUS(status); 2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 249fd0a43276dc986e186eb27e5755a18e97e07a7ebBob Moore * Loop through the ACPI_INTERNAL_OBJECTS - Each object should be a 2505df7e6cb42da36c7d878239bebc81907b15f3943Bob Moore * package that in turn contains an u64 Address, a u8 Pin, 251fd0a43276dc986e186eb27e5755a18e97e07a7ebBob Moore * a Name, and a u8 source_index. 2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2534be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown top_object_list = package_object->package.elements; 2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds number_of_elements = package_object->package.count; 2554be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown buffer = output_buffer->pointer; 2564be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown user_prt = ACPI_CAST_PTR(struct acpi_pci_routing_table, buffer); 2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (index = 0; index < number_of_elements; index++) { 2592f894ef9c8b36a35d80709bedca276d2fc691941Shaohua Li 2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Point user_prt past this current structure 2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * NOTE: On the first iteration, user_prt->Length will 2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * be zero because we cleared the return buffer earlier 2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buffer += user_prt->length; 2674be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown user_prt = ACPI_CAST_PTR(struct acpi_pci_routing_table, buffer); 2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Fill in the Length field with the information we have at this point. 2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * The minus four is to subtract the size of the u8 Source[4] member 2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * because it is added below. 2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2744be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown user_prt->length = (sizeof(struct acpi_pci_routing_table) - 4); 2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 27644f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore /* Each element of the top-level package must also be a package */ 27744f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore 2783371c19c294a4cb3649aa4e84606be8a1d999e61Bob Moore if ((*top_object_list)->common.type != ACPI_TYPE_PACKAGE) { 279b8e4d89357fc434618a59c1047cac72641191805Bob Moore ACPI_ERROR((AE_INFO, 280f6a22b0bc417042e83117f52ab1a03696af185abBob Moore "(PRT[%u]) Need sub-package, found %s", 281b8e4d89357fc434618a59c1047cac72641191805Bob Moore index, 282b8e4d89357fc434618a59c1047cac72641191805Bob Moore acpi_ut_get_object_type_name 283b8e4d89357fc434618a59c1047cac72641191805Bob Moore (*top_object_list))); 2844be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown return_ACPI_STATUS(AE_AML_OPERAND_TYPE); 2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Each sub-package must be of length 4 */ 2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((*top_object_list)->package.count != 4) { 290b8e4d89357fc434618a59c1047cac72641191805Bob Moore ACPI_ERROR((AE_INFO, 291f6a22b0bc417042e83117f52ab1a03696af185abBob Moore "(PRT[%u]) Need package of length 4, found length %u", 292b8e4d89357fc434618a59c1047cac72641191805Bob Moore index, (*top_object_list)->package.count)); 2934be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown return_ACPI_STATUS(AE_AML_PACKAGE_LIMIT); 2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Dereference the sub-package. 2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * The sub_object_list will now point to an array of the four IRQ 2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * elements: [Address, Pin, Source, source_index] 3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sub_object_list = (*top_object_list)->package.elements; 3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 30344f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore /* 1) First subobject: Dereference the PRT.Address */ 30444f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore 3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds obj_desc = sub_object_list[0]; 3063371c19c294a4cb3649aa4e84606be8a1d999e61Bob Moore if (obj_desc->common.type != ACPI_TYPE_INTEGER) { 307b8e4d89357fc434618a59c1047cac72641191805Bob Moore ACPI_ERROR((AE_INFO, 308f6a22b0bc417042e83117f52ab1a03696af185abBob Moore "(PRT[%u].Address) Need Integer, found %s", 309b8e4d89357fc434618a59c1047cac72641191805Bob Moore index, 310b8e4d89357fc434618a59c1047cac72641191805Bob Moore acpi_ut_get_object_type_name(obj_desc))); 3114be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown return_ACPI_STATUS(AE_BAD_DATA); 3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 314fd0a43276dc986e186eb27e5755a18e97e07a7ebBob Moore user_prt->address = obj_desc->integer.value; 315fd0a43276dc986e186eb27e5755a18e97e07a7ebBob Moore 31644f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore /* 2) Second subobject: Dereference the PRT.Pin */ 31744f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore 3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds obj_desc = sub_object_list[1]; 3193371c19c294a4cb3649aa4e84606be8a1d999e61Bob Moore if (obj_desc->common.type != ACPI_TYPE_INTEGER) { 320b8e4d89357fc434618a59c1047cac72641191805Bob Moore ACPI_ERROR((AE_INFO, 321f6a22b0bc417042e83117f52ab1a03696af185abBob Moore "(PRT[%u].Pin) Need Integer, found %s", 322b8e4d89357fc434618a59c1047cac72641191805Bob Moore index, 323b8e4d89357fc434618a59c1047cac72641191805Bob Moore acpi_ut_get_object_type_name(obj_desc))); 3244be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown return_ACPI_STATUS(AE_BAD_DATA); 3251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 327fd0a43276dc986e186eb27e5755a18e97e07a7ebBob Moore user_prt->pin = (u32) obj_desc->integer.value; 328fd0a43276dc986e186eb27e5755a18e97e07a7ebBob Moore 3292f894ef9c8b36a35d80709bedca276d2fc691941Shaohua Li /* 330d0e184abc5983281ef189db2c759d65d56eb1b80Bob Moore * If the BIOS has erroneously reversed the _PRT source_name (index 2) 331d0e184abc5983281ef189db2c759d65d56eb1b80Bob Moore * and the source_index (index 3), fix it. _PRT is important enough to 332d0e184abc5983281ef189db2c759d65d56eb1b80Bob Moore * workaround this BIOS error. This also provides compatibility with 333d0e184abc5983281ef189db2c759d65d56eb1b80Bob Moore * other ACPI implementations. 334d0e184abc5983281ef189db2c759d65d56eb1b80Bob Moore */ 335d0e184abc5983281ef189db2c759d65d56eb1b80Bob Moore obj_desc = sub_object_list[3]; 3363371c19c294a4cb3649aa4e84606be8a1d999e61Bob Moore if (!obj_desc || (obj_desc->common.type != ACPI_TYPE_INTEGER)) { 337d0e184abc5983281ef189db2c759d65d56eb1b80Bob Moore sub_object_list[3] = sub_object_list[2]; 338d0e184abc5983281ef189db2c759d65d56eb1b80Bob Moore sub_object_list[2] = obj_desc; 339d0e184abc5983281ef189db2c759d65d56eb1b80Bob Moore 340d0e184abc5983281ef189db2c759d65d56eb1b80Bob Moore ACPI_WARNING((AE_INFO, 341d0e184abc5983281ef189db2c759d65d56eb1b80Bob Moore "(PRT[%X].Source) SourceName and SourceIndex are reversed, fixed", 342d0e184abc5983281ef189db2c759d65d56eb1b80Bob Moore index)); 343d0e184abc5983281ef189db2c759d65d56eb1b80Bob Moore } 344d0e184abc5983281ef189db2c759d65d56eb1b80Bob Moore 345d0e184abc5983281ef189db2c759d65d56eb1b80Bob Moore /* 346b8e4d89357fc434618a59c1047cac72641191805Bob Moore * 3) Third subobject: Dereference the PRT.source_name 347b8e4d89357fc434618a59c1047cac72641191805Bob Moore * The name may be unresolved (slack mode), so allow a null object 348b8e4d89357fc434618a59c1047cac72641191805Bob Moore */ 34982babbb3887e234c995626e4121d411ea9070ca5Zhang Rui obj_desc = sub_object_list[2]; 350b8e4d89357fc434618a59c1047cac72641191805Bob Moore if (obj_desc) { 3513371c19c294a4cb3649aa4e84606be8a1d999e61Bob Moore switch (obj_desc->common.type) { 352b8e4d89357fc434618a59c1047cac72641191805Bob Moore case ACPI_TYPE_LOCAL_REFERENCE: 353b8e4d89357fc434618a59c1047cac72641191805Bob Moore 3541044f1f65b7df2aae979e397904c4985eeb99ba2Bob Moore if (obj_desc->reference.class != 3551044f1f65b7df2aae979e397904c4985eeb99ba2Bob Moore ACPI_REFCLASS_NAME) { 356b8e4d89357fc434618a59c1047cac72641191805Bob Moore ACPI_ERROR((AE_INFO, 357f6a22b0bc417042e83117f52ab1a03696af185abBob Moore "(PRT[%u].Source) Need name, found Reference Class 0x%X", 358b8e4d89357fc434618a59c1047cac72641191805Bob Moore index, 3591044f1f65b7df2aae979e397904c4985eeb99ba2Bob Moore obj_desc->reference.class)); 360b8e4d89357fc434618a59c1047cac72641191805Bob Moore return_ACPI_STATUS(AE_BAD_DATA); 361b8e4d89357fc434618a59c1047cac72641191805Bob Moore } 362b8e4d89357fc434618a59c1047cac72641191805Bob Moore 363b8e4d89357fc434618a59c1047cac72641191805Bob Moore node = obj_desc->reference.node; 364b8e4d89357fc434618a59c1047cac72641191805Bob Moore 365b8e4d89357fc434618a59c1047cac72641191805Bob Moore /* Use *remaining* length of the buffer as max for pathname */ 366b8e4d89357fc434618a59c1047cac72641191805Bob Moore 367b8e4d89357fc434618a59c1047cac72641191805Bob Moore path_buffer.length = output_buffer->length - 368b8e4d89357fc434618a59c1047cac72641191805Bob Moore (u32) ((u8 *) user_prt->source - 369b8e4d89357fc434618a59c1047cac72641191805Bob Moore (u8 *) output_buffer->pointer); 370b8e4d89357fc434618a59c1047cac72641191805Bob Moore path_buffer.pointer = user_prt->source; 371b8e4d89357fc434618a59c1047cac72641191805Bob Moore 372b8e4d89357fc434618a59c1047cac72641191805Bob Moore status = 373b8e4d89357fc434618a59c1047cac72641191805Bob Moore acpi_ns_handle_to_pathname((acpi_handle) 374b8e4d89357fc434618a59c1047cac72641191805Bob Moore node, 375b8e4d89357fc434618a59c1047cac72641191805Bob Moore &path_buffer); 376b8e4d89357fc434618a59c1047cac72641191805Bob Moore 377b8e4d89357fc434618a59c1047cac72641191805Bob Moore /* +1 to include null terminator */ 378b8e4d89357fc434618a59c1047cac72641191805Bob Moore 379b8e4d89357fc434618a59c1047cac72641191805Bob Moore user_prt->length += 380b8e4d89357fc434618a59c1047cac72641191805Bob Moore (u32) ACPI_STRLEN(user_prt->source) + 1; 381b8e4d89357fc434618a59c1047cac72641191805Bob Moore break; 382b8e4d89357fc434618a59c1047cac72641191805Bob Moore 383b8e4d89357fc434618a59c1047cac72641191805Bob Moore case ACPI_TYPE_STRING: 384b8e4d89357fc434618a59c1047cac72641191805Bob Moore 385b8e4d89357fc434618a59c1047cac72641191805Bob Moore ACPI_STRCPY(user_prt->source, 386b8e4d89357fc434618a59c1047cac72641191805Bob Moore obj_desc->string.pointer); 387b8e4d89357fc434618a59c1047cac72641191805Bob Moore 388b8e4d89357fc434618a59c1047cac72641191805Bob Moore /* 389b8e4d89357fc434618a59c1047cac72641191805Bob Moore * Add to the Length field the length of the string 390b8e4d89357fc434618a59c1047cac72641191805Bob Moore * (add 1 for terminator) 391b8e4d89357fc434618a59c1047cac72641191805Bob Moore */ 392b8e4d89357fc434618a59c1047cac72641191805Bob Moore user_prt->length += obj_desc->string.length + 1; 393b8e4d89357fc434618a59c1047cac72641191805Bob Moore break; 394b8e4d89357fc434618a59c1047cac72641191805Bob Moore 395b8e4d89357fc434618a59c1047cac72641191805Bob Moore case ACPI_TYPE_INTEGER: 396b8e4d89357fc434618a59c1047cac72641191805Bob Moore /* 397b8e4d89357fc434618a59c1047cac72641191805Bob Moore * If this is a number, then the Source Name is NULL, since the 398b8e4d89357fc434618a59c1047cac72641191805Bob Moore * entire buffer was zeroed out, we can leave this alone. 399b8e4d89357fc434618a59c1047cac72641191805Bob Moore * 400b8e4d89357fc434618a59c1047cac72641191805Bob Moore * Add to the Length field the length of the u32 NULL 401b8e4d89357fc434618a59c1047cac72641191805Bob Moore */ 402b8e4d89357fc434618a59c1047cac72641191805Bob Moore user_prt->length += sizeof(u32); 403b8e4d89357fc434618a59c1047cac72641191805Bob Moore break; 404b8e4d89357fc434618a59c1047cac72641191805Bob Moore 405b8e4d89357fc434618a59c1047cac72641191805Bob Moore default: 406b8e4d89357fc434618a59c1047cac72641191805Bob Moore 407b8e4d89357fc434618a59c1047cac72641191805Bob Moore ACPI_ERROR((AE_INFO, 408f6a22b0bc417042e83117f52ab1a03696af185abBob Moore "(PRT[%u].Source) Need Ref/String/Integer, found %s", 409b8e4d89357fc434618a59c1047cac72641191805Bob Moore index, 410b8e4d89357fc434618a59c1047cac72641191805Bob Moore acpi_ut_get_object_type_name 411b8e4d89357fc434618a59c1047cac72641191805Bob Moore (obj_desc))); 4124be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown return_ACPI_STATUS(AE_BAD_DATA); 4131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Now align the current length */ 4171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4184be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown user_prt->length = 419958dd242b691f64ab4632b4903dbb1e16fee8269Bob Moore (u32) ACPI_ROUND_UP_TO_64BIT(user_prt->length); 4201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 42144f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore /* 4) Fourth subobject: Dereference the PRT.source_index */ 42244f6c01242da4e162f28d8e1216a8c7a91174605Robert Moore 42382babbb3887e234c995626e4121d411ea9070ca5Zhang Rui obj_desc = sub_object_list[3]; 4243371c19c294a4cb3649aa4e84606be8a1d999e61Bob Moore if (obj_desc->common.type != ACPI_TYPE_INTEGER) { 425b8e4d89357fc434618a59c1047cac72641191805Bob Moore ACPI_ERROR((AE_INFO, 426f6a22b0bc417042e83117f52ab1a03696af185abBob Moore "(PRT[%u].SourceIndex) Need Integer, found %s", 427b8e4d89357fc434618a59c1047cac72641191805Bob Moore index, 428b8e4d89357fc434618a59c1047cac72641191805Bob Moore acpi_ut_get_object_type_name(obj_desc))); 4294be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown return_ACPI_STATUS(AE_BAD_DATA); 4301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 432fd0a43276dc986e186eb27e5755a18e97e07a7ebBob Moore user_prt->source_index = (u32) obj_desc->integer.value; 433fd0a43276dc986e186eb27e5755a18e97e07a7ebBob Moore 4341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Point to the next union acpi_operand_object in the top level package */ 4351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds top_object_list++; 4371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 439b229cf92eee616c7cb5ad8cdb35a19b119f00bc8Bob Moore ACPI_DEBUG_PRINT((ACPI_DB_INFO, "OutputBuffer %p Length %X\n", 4404be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown output_buffer->pointer, (u32) output_buffer->length)); 4414be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown return_ACPI_STATUS(AE_OK); 4421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/******************************************************************************* 4451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 44650eca3eb89d73d9f0aa070b126c7ee6a616016abBob Moore * FUNCTION: acpi_rs_create_aml_resources 4471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 4481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * PARAMETERS: linked_list_buffer - Pointer to the resource linked list 4491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * output_buffer - Pointer to the user's buffer 4501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 4511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * RETURN: Status AE_OK if okay, else a valid acpi_status code. 4521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * If the output_buffer is too small, the error will be 4531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * AE_BUFFER_OVERFLOW and output_buffer->Length will point 4541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * to the size buffer needed. 4551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 4561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * DESCRIPTION: Takes the linked list of device resources and 4571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * creates a bytestream to be used as input for the 4581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * _SRS control method. 4591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 4601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ******************************************************************************/ 4611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsacpi_status 46350eca3eb89d73d9f0aa070b126c7ee6a616016abBob Mooreacpi_rs_create_aml_resources(struct acpi_resource *linked_list_buffer, 46450eca3eb89d73d9f0aa070b126c7ee6a616016abBob Moore struct acpi_buffer *output_buffer) 4651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4664be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown acpi_status status; 46750eca3eb89d73d9f0aa070b126c7ee6a616016abBob Moore acpi_size aml_size_needed = 0; 4681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 469b229cf92eee616c7cb5ad8cdb35a19b119f00bc8Bob Moore ACPI_FUNCTION_TRACE(rs_create_aml_resources); 4701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 471b229cf92eee616c7cb5ad8cdb35a19b119f00bc8Bob Moore ACPI_DEBUG_PRINT((ACPI_DB_INFO, "LinkedListBuffer = %p\n", 4724be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown linked_list_buffer)); 4731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 4751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Params already validated, so we don't re-validate here 4761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 4771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Pass the linked_list_buffer into a module that calculates 4781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the buffer size needed for the byte stream. 4791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 48050eca3eb89d73d9f0aa070b126c7ee6a616016abBob Moore status = acpi_rs_get_aml_length(linked_list_buffer, &aml_size_needed); 4814be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown 482b229cf92eee616c7cb5ad8cdb35a19b119f00bc8Bob Moore ACPI_DEBUG_PRINT((ACPI_DB_INFO, "AmlSizeNeeded=%X, %s\n", 48350eca3eb89d73d9f0aa070b126c7ee6a616016abBob Moore (u32) aml_size_needed, 4844be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown acpi_format_exception(status))); 4854be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown if (ACPI_FAILURE(status)) { 4864be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown return_ACPI_STATUS(status); 4871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Validate/Allocate/Clear caller buffer */ 4901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 49150eca3eb89d73d9f0aa070b126c7ee6a616016abBob Moore status = acpi_ut_initialize_buffer(output_buffer, aml_size_needed); 4924be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown if (ACPI_FAILURE(status)) { 4934be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown return_ACPI_STATUS(status); 4941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Do the conversion */ 4971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4984be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown status = 49950eca3eb89d73d9f0aa070b126c7ee6a616016abBob Moore acpi_rs_convert_resources_to_aml(linked_list_buffer, 50050eca3eb89d73d9f0aa070b126c7ee6a616016abBob Moore aml_size_needed, 50150eca3eb89d73d9f0aa070b126c7ee6a616016abBob Moore output_buffer->pointer); 5024be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown if (ACPI_FAILURE(status)) { 5034be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown return_ACPI_STATUS(status); 5041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 506b229cf92eee616c7cb5ad8cdb35a19b119f00bc8Bob Moore ACPI_DEBUG_PRINT((ACPI_DB_INFO, "OutputBuffer %p Length %X\n", 5074be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown output_buffer->pointer, (u32) output_buffer->length)); 5084be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown return_ACPI_STATUS(AE_OK); 5091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 510