1 /****************************************************************************** 2 * 3 * Module Name: nsxfname - Public interfaces to the ACPI subsystem 4 * ACPI Namespace oriented interfaces 5 * 6 *****************************************************************************/ 7 8 /* 9 * Copyright (C) 2000 - 2008, Intel Corp. 10 * All rights reserved. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions, and the following disclaimer, 17 * without modification. 18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 19 * substantially similar to the "NO WARRANTY" disclaimer below 20 * ("Disclaimer") and any redistribution must be conditioned upon 21 * including a substantially similar Disclaimer requirement for further 22 * binary redistribution. 23 * 3. Neither the names of the above-listed copyright holders nor the names 24 * of any contributors may be used to endorse or promote products derived 25 * from this software without specific prior written permission. 26 * 27 * Alternatively, this software may be distributed under the terms of the 28 * GNU General Public License ("GPL") version 2 as published by the Free 29 * Software Foundation. 30 * 31 * NO WARRANTY 32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 42 * POSSIBILITY OF SUCH DAMAGES. 43 */ 44 45 #include <acpi/acpi.h> 46 #include "accommon.h" 47 #include "acnamesp.h" 48 49 #define _COMPONENT ACPI_NAMESPACE 50 ACPI_MODULE_NAME("nsxfname") 51 52 /****************************************************************************** 53 * 54 * FUNCTION: acpi_get_handle 55 * 56 * PARAMETERS: Parent - Object to search under (search scope). 57 * Pathname - Pointer to an asciiz string containing the 58 * name 59 * ret_handle - Where the return handle is returned 60 * 61 * RETURN: Status 62 * 63 * DESCRIPTION: This routine will search for a caller specified name in the 64 * name space. The caller can restrict the search region by 65 * specifying a non NULL parent. The parent value is itself a 66 * namespace handle. 67 * 68 ******************************************************************************/ 69 acpi_status 70 acpi_get_handle(acpi_handle parent, 71 acpi_string pathname, acpi_handle * ret_handle) 72 { 73 acpi_status status; 74 struct acpi_namespace_node *node = NULL; 75 struct acpi_namespace_node *prefix_node = NULL; 76 77 ACPI_FUNCTION_ENTRY(); 78 79 /* Parameter Validation */ 80 81 if (!ret_handle || !pathname) { 82 return (AE_BAD_PARAMETER); 83 } 84 85 /* Convert a parent handle to a prefix node */ 86 87 if (parent) { 88 prefix_node = acpi_ns_map_handle_to_node(parent); 89 if (!prefix_node) { 90 return (AE_BAD_PARAMETER); 91 } 92 } 93 94 /* 95 * Valid cases are: 96 * 1) Fully qualified pathname 97 * 2) Parent + Relative pathname 98 * 99 * Error for <null Parent + relative path> 100 */ 101 if (acpi_ns_valid_root_prefix(pathname[0])) { 102 103 /* Pathname is fully qualified (starts with '\') */ 104 105 /* Special case for root-only, since we can't search for it */ 106 107 if (!ACPI_STRCMP(pathname, ACPI_NS_ROOT_PATH)) { 108 *ret_handle = 109 acpi_ns_convert_entry_to_handle(acpi_gbl_root_node); 110 return (AE_OK); 111 } 112 } else if (!prefix_node) { 113 114 /* Relative path with null prefix is disallowed */ 115 116 return (AE_BAD_PARAMETER); 117 } 118 119 /* Find the Node and convert to a handle */ 120 121 status = 122 acpi_ns_get_node(prefix_node, pathname, ACPI_NS_NO_UPSEARCH, &node); 123 if (ACPI_SUCCESS(status)) { 124 *ret_handle = acpi_ns_convert_entry_to_handle(node); 125 } 126 127 return (status); 128 } 129 130 ACPI_EXPORT_SYMBOL(acpi_get_handle) 131 132 /****************************************************************************** 133 * 134 * FUNCTION: acpi_get_name 135 * 136 * PARAMETERS: Handle - Handle to be converted to a pathname 137 * name_type - Full pathname or single segment 138 * Buffer - Buffer for returned path 139 * 140 * RETURN: Pointer to a string containing the fully qualified Name. 141 * 142 * DESCRIPTION: This routine returns the fully qualified name associated with 143 * the Handle parameter. This and the acpi_pathname_to_handle are 144 * complementary functions. 145 * 146 ******************************************************************************/ 147 acpi_status 148 acpi_get_name(acpi_handle handle, u32 name_type, struct acpi_buffer * buffer) 149 { 150 acpi_status status; 151 struct acpi_namespace_node *node; 152 153 /* Parameter validation */ 154 155 if (name_type > ACPI_NAME_TYPE_MAX) { 156 return (AE_BAD_PARAMETER); 157 } 158 159 status = acpi_ut_validate_buffer(buffer); 160 if (ACPI_FAILURE(status)) { 161 return (status); 162 } 163 164 if (name_type == ACPI_FULL_PATHNAME) { 165 166 /* Get the full pathname (From the namespace root) */ 167 168 status = acpi_ns_handle_to_pathname(handle, buffer); 169 return (status); 170 } 171 172 /* 173 * Wants the single segment ACPI name. 174 * Validate handle and convert to a namespace Node 175 */ 176 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); 177 if (ACPI_FAILURE(status)) { 178 return (status); 179 } 180 181 node = acpi_ns_map_handle_to_node(handle); 182 if (!node) { 183 status = AE_BAD_PARAMETER; 184 goto unlock_and_exit; 185 } 186 187 /* Validate/Allocate/Clear caller buffer */ 188 189 status = acpi_ut_initialize_buffer(buffer, ACPI_PATH_SEGMENT_LENGTH); 190 if (ACPI_FAILURE(status)) { 191 goto unlock_and_exit; 192 } 193 194 /* Just copy the ACPI name from the Node and zero terminate it */ 195 196 ACPI_STRNCPY(buffer->pointer, acpi_ut_get_node_name(node), 197 ACPI_NAME_SIZE); 198 ((char *)buffer->pointer)[ACPI_NAME_SIZE] = 0; 199 status = AE_OK; 200 201 unlock_and_exit: 202 203 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); 204 return (status); 205 } 206 207 ACPI_EXPORT_SYMBOL(acpi_get_name) 208 209 /****************************************************************************** 210 * 211 * FUNCTION: acpi_get_object_info 212 * 213 * PARAMETERS: Handle - Object Handle 214 * Buffer - Where the info is returned 215 * 216 * RETURN: Status 217 * 218 * DESCRIPTION: Returns information about an object as gleaned from the 219 * namespace node and possibly by running several standard 220 * control methods (Such as in the case of a device.) 221 * 222 ******************************************************************************/ 223 acpi_status 224 acpi_get_object_info(acpi_handle handle, struct acpi_buffer * buffer) 225 { 226 acpi_status status; 227 struct acpi_namespace_node *node; 228 struct acpi_device_info *info; 229 struct acpi_device_info *return_info; 230 struct acpi_compatible_id_list *cid_list = NULL; 231 acpi_size size; 232 233 /* Parameter validation */ 234 235 if (!handle || !buffer) { 236 return (AE_BAD_PARAMETER); 237 } 238 239 status = acpi_ut_validate_buffer(buffer); 240 if (ACPI_FAILURE(status)) { 241 return (status); 242 } 243 244 info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_device_info)); 245 if (!info) { 246 return (AE_NO_MEMORY); 247 } 248 249 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); 250 if (ACPI_FAILURE(status)) { 251 goto cleanup; 252 } 253 254 node = acpi_ns_map_handle_to_node(handle); 255 if (!node) { 256 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); 257 status = AE_BAD_PARAMETER; 258 goto cleanup; 259 } 260 261 /* Init return structure */ 262 263 size = sizeof(struct acpi_device_info); 264 265 info->type = node->type; 266 info->name = node->name.integer; 267 info->valid = 0; 268 269 if (node->type == ACPI_TYPE_METHOD) { 270 info->param_count = node->object->method.param_count; 271 } 272 273 status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); 274 if (ACPI_FAILURE(status)) { 275 goto cleanup; 276 } 277 278 /* If not a device, we are all done */ 279 280 if (info->type == ACPI_TYPE_DEVICE) { 281 /* 282 * Get extra info for ACPI Devices objects only: 283 * Run the Device _HID, _UID, _CID, _STA, _ADR and _sx_d methods. 284 * 285 * Note: none of these methods are required, so they may or may 286 * not be present for this device. The Info->Valid bitfield is used 287 * to indicate which methods were found and ran successfully. 288 */ 289 290 /* Execute the Device._HID method */ 291 292 status = acpi_ut_execute_HID(node, &info->hardware_id); 293 if (ACPI_SUCCESS(status)) { 294 info->valid |= ACPI_VALID_HID; 295 } 296 297 /* Execute the Device._UID method */ 298 299 status = acpi_ut_execute_UID(node, &info->unique_id); 300 if (ACPI_SUCCESS(status)) { 301 info->valid |= ACPI_VALID_UID; 302 } 303 304 /* Execute the Device._CID method */ 305 306 status = acpi_ut_execute_CID(node, &cid_list); 307 if (ACPI_SUCCESS(status)) { 308 size += cid_list->size; 309 info->valid |= ACPI_VALID_CID; 310 } 311 312 /* Execute the Device._STA method */ 313 314 status = acpi_ut_execute_STA(node, &info->current_status); 315 if (ACPI_SUCCESS(status)) { 316 info->valid |= ACPI_VALID_STA; 317 } 318 319 /* Execute the Device._ADR method */ 320 321 status = acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR, node, 322 &info->address); 323 if (ACPI_SUCCESS(status)) { 324 info->valid |= ACPI_VALID_ADR; 325 } 326 327 /* Execute the Device._sx_d methods */ 328 329 status = acpi_ut_execute_sxds(node, info->highest_dstates); 330 if (ACPI_SUCCESS(status)) { 331 info->valid |= ACPI_VALID_SXDS; 332 } 333 } 334 335 /* Validate/Allocate/Clear caller buffer */ 336 337 status = acpi_ut_initialize_buffer(buffer, size); 338 if (ACPI_FAILURE(status)) { 339 goto cleanup; 340 } 341 342 /* Populate the return buffer */ 343 344 return_info = buffer->pointer; 345 ACPI_MEMCPY(return_info, info, sizeof(struct acpi_device_info)); 346 347 if (cid_list) { 348 ACPI_MEMCPY(&return_info->compatibility_id, cid_list, 349 cid_list->size); 350 } 351 352 cleanup: 353 ACPI_FREE(info); 354 if (cid_list) { 355 ACPI_FREE(cid_list); 356 } 357 return (status); 358 } 359 360 ACPI_EXPORT_SYMBOL(acpi_get_object_info) 361