0001
0002
0003
0004
0005
0006
0007
0008 #include <acpi/acpi.h>
0009 #include "accommon.h"
0010 #include "amlcode.h"
0011 #include "acnamesp.h"
0012
0013 #define _COMPONENT ACPI_NAMESPACE
0014 ACPI_MODULE_NAME("nsnames")
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030 char *acpi_ns_get_external_pathname(struct acpi_namespace_node *node)
0031 {
0032 char *name_buffer;
0033
0034 ACPI_FUNCTION_TRACE_PTR(ns_get_external_pathname, node);
0035
0036 name_buffer = acpi_ns_get_normalized_pathname(node, FALSE);
0037 return_PTR(name_buffer);
0038 }
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052 acpi_size acpi_ns_get_pathname_length(struct acpi_namespace_node *node)
0053 {
0054 acpi_size size;
0055
0056
0057
0058 if (ACPI_GET_DESCRIPTOR_TYPE(node) != ACPI_DESC_TYPE_NAMED) {
0059 ACPI_ERROR((AE_INFO,
0060 "Invalid/cached reference target node: %p, descriptor type %d",
0061 node, ACPI_GET_DESCRIPTOR_TYPE(node)));
0062 return (0);
0063 }
0064
0065 size = acpi_ns_build_normalized_path(node, NULL, 0, FALSE);
0066 return (size);
0067 }
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083 acpi_status
0084 acpi_ns_handle_to_name(acpi_handle target_handle, struct acpi_buffer *buffer)
0085 {
0086 acpi_status status;
0087 struct acpi_namespace_node *node;
0088 const char *node_name;
0089
0090 ACPI_FUNCTION_TRACE_PTR(ns_handle_to_name, target_handle);
0091
0092 node = acpi_ns_validate_handle(target_handle);
0093 if (!node) {
0094 return_ACPI_STATUS(AE_BAD_PARAMETER);
0095 }
0096
0097
0098
0099 status = acpi_ut_initialize_buffer(buffer, ACPI_PATH_SEGMENT_LENGTH);
0100 if (ACPI_FAILURE(status)) {
0101 return_ACPI_STATUS(status);
0102 }
0103
0104
0105
0106 node_name = acpi_ut_get_node_name(node);
0107 ACPI_COPY_NAMESEG(buffer->pointer, node_name);
0108 ((char *)buffer->pointer)[ACPI_NAMESEG_SIZE] = 0;
0109
0110 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%4.4s\n", (char *)buffer->pointer));
0111 return_ACPI_STATUS(AE_OK);
0112 }
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130 acpi_status
0131 acpi_ns_handle_to_pathname(acpi_handle target_handle,
0132 struct acpi_buffer *buffer, u8 no_trailing)
0133 {
0134 acpi_status status;
0135 struct acpi_namespace_node *node;
0136 acpi_size required_size;
0137
0138 ACPI_FUNCTION_TRACE_PTR(ns_handle_to_pathname, target_handle);
0139
0140 node = acpi_ns_validate_handle(target_handle);
0141 if (!node) {
0142 return_ACPI_STATUS(AE_BAD_PARAMETER);
0143 }
0144
0145
0146
0147 required_size =
0148 acpi_ns_build_normalized_path(node, NULL, 0, no_trailing);
0149 if (!required_size) {
0150 return_ACPI_STATUS(AE_BAD_PARAMETER);
0151 }
0152
0153
0154
0155 status = acpi_ut_initialize_buffer(buffer, required_size);
0156 if (ACPI_FAILURE(status)) {
0157 return_ACPI_STATUS(status);
0158 }
0159
0160
0161
0162 (void)acpi_ns_build_normalized_path(node, buffer->pointer,
0163 (u32)required_size, no_trailing);
0164
0165 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%s [%X]\n",
0166 (char *)buffer->pointer, (u32) required_size));
0167 return_ACPI_STATUS(AE_OK);
0168 }
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191
0192 u32
0193 acpi_ns_build_normalized_path(struct acpi_namespace_node *node,
0194 char *full_path, u32 path_size, u8 no_trailing)
0195 {
0196 u32 length = 0, i;
0197 char name[ACPI_NAMESEG_SIZE];
0198 u8 do_no_trailing;
0199 char c, *left, *right;
0200 struct acpi_namespace_node *next_node;
0201
0202 ACPI_FUNCTION_TRACE_PTR(ns_build_normalized_path, node);
0203
0204 #define ACPI_PATH_PUT8(path, size, byte, length) \
0205 do { \
0206 if ((length) < (size)) \
0207 { \
0208 (path)[(length)] = (byte); \
0209 } \
0210 (length)++; \
0211 } while (0)
0212
0213
0214
0215
0216
0217 if (!full_path) {
0218 path_size = 0;
0219 }
0220
0221 if (!node) {
0222 goto build_trailing_null;
0223 }
0224
0225 next_node = node;
0226 while (next_node && next_node != acpi_gbl_root_node) {
0227 if (next_node != node) {
0228 ACPI_PATH_PUT8(full_path, path_size,
0229 AML_DUAL_NAME_PREFIX, length);
0230 }
0231
0232 ACPI_MOVE_32_TO_32(name, &next_node->name);
0233 do_no_trailing = no_trailing;
0234 for (i = 0; i < 4; i++) {
0235 c = name[4 - i - 1];
0236 if (do_no_trailing && c != '_') {
0237 do_no_trailing = FALSE;
0238 }
0239 if (!do_no_trailing) {
0240 ACPI_PATH_PUT8(full_path, path_size, c, length);
0241 }
0242 }
0243
0244 next_node = next_node->parent;
0245 }
0246
0247 ACPI_PATH_PUT8(full_path, path_size, AML_ROOT_PREFIX, length);
0248
0249
0250
0251 if (length <= path_size) {
0252 left = full_path;
0253 right = full_path + length - 1;
0254
0255 while (left < right) {
0256 c = *left;
0257 *left++ = *right;
0258 *right-- = c;
0259 }
0260 }
0261
0262
0263
0264 build_trailing_null:
0265 ACPI_PATH_PUT8(full_path, path_size, '\0', length);
0266
0267 #undef ACPI_PATH_PUT8
0268
0269 return_UINT32(length);
0270 }
0271
0272
0273
0274
0275
0276
0277
0278
0279
0280
0281
0282
0283
0284
0285
0286
0287
0288
0289 char *acpi_ns_get_normalized_pathname(struct acpi_namespace_node *node,
0290 u8 no_trailing)
0291 {
0292 char *name_buffer;
0293 acpi_size size;
0294
0295 ACPI_FUNCTION_TRACE_PTR(ns_get_normalized_pathname, node);
0296
0297
0298
0299 size = acpi_ns_build_normalized_path(node, NULL, 0, no_trailing);
0300 if (!size) {
0301 return_PTR(NULL);
0302 }
0303
0304
0305
0306 name_buffer = ACPI_ALLOCATE_ZEROED(size);
0307 if (!name_buffer) {
0308 ACPI_ERROR((AE_INFO, "Could not allocate %u bytes", (u32)size));
0309 return_PTR(NULL);
0310 }
0311
0312
0313
0314 (void)acpi_ns_build_normalized_path(node, name_buffer, (u32)size,
0315 no_trailing);
0316
0317 ACPI_DEBUG_PRINT_RAW((ACPI_DB_NAMES, "%s: Path \"%s\"\n",
0318 ACPI_GET_FUNCTION_NAME, name_buffer));
0319
0320 return_PTR(name_buffer);
0321 }
0322
0323
0324
0325
0326
0327
0328
0329
0330
0331
0332
0333
0334
0335
0336
0337
0338 char *acpi_ns_build_prefixed_pathname(union acpi_generic_state *prefix_scope,
0339 const char *internal_path)
0340 {
0341 acpi_status status;
0342 char *full_path = NULL;
0343 char *external_path = NULL;
0344 char *prefix_path = NULL;
0345 acpi_size prefix_path_length = 0;
0346
0347
0348
0349 if (prefix_scope && prefix_scope->scope.node) {
0350 prefix_path =
0351 acpi_ns_get_normalized_pathname(prefix_scope->scope.node,
0352 TRUE);
0353 if (prefix_path) {
0354 prefix_path_length = strlen(prefix_path);
0355 }
0356 }
0357
0358 status = acpi_ns_externalize_name(ACPI_UINT32_MAX, internal_path,
0359 NULL, &external_path);
0360 if (ACPI_FAILURE(status)) {
0361 goto cleanup;
0362 }
0363
0364
0365
0366 full_path =
0367 ACPI_ALLOCATE_ZEROED(prefix_path_length + strlen(external_path) +
0368 2);
0369 if (!full_path) {
0370 goto cleanup;
0371 }
0372
0373
0374
0375 if (prefix_path && (*external_path != '\\') && (*external_path != '^')) {
0376 strcat(full_path, prefix_path);
0377 if (prefix_path[1]) {
0378 strcat(full_path, ".");
0379 }
0380 }
0381
0382 acpi_ns_normalize_pathname(external_path);
0383 strcat(full_path, external_path);
0384
0385 cleanup:
0386 if (prefix_path) {
0387 ACPI_FREE(prefix_path);
0388 }
0389 if (external_path) {
0390 ACPI_FREE(external_path);
0391 }
0392
0393 return (full_path);
0394 }
0395
0396
0397
0398
0399
0400
0401
0402
0403
0404
0405
0406
0407
0408
0409
0410 void acpi_ns_normalize_pathname(char *original_path)
0411 {
0412 char *input_path = original_path;
0413 char *new_path_buffer;
0414 char *new_path;
0415 u32 i;
0416
0417
0418
0419 new_path_buffer = ACPI_ALLOCATE_ZEROED(strlen(input_path) + 1);
0420 new_path = new_path_buffer;
0421 if (!new_path_buffer) {
0422 return;
0423 }
0424
0425
0426
0427 if (*input_path == '\\') {
0428 *new_path = *input_path;
0429 new_path++;
0430 input_path++;
0431 }
0432
0433 while (*input_path == '^') {
0434 *new_path = *input_path;
0435 new_path++;
0436 input_path++;
0437 }
0438
0439
0440
0441 while (*input_path) {
0442
0443
0444
0445 for (i = 0; (i < ACPI_NAMESEG_SIZE) && *input_path; i++) {
0446 if ((i == 0) || (*input_path != '_')) {
0447 *new_path = *input_path;
0448 new_path++;
0449 }
0450
0451 input_path++;
0452 }
0453
0454
0455
0456 if (*input_path == '.') {
0457 *new_path = *input_path;
0458 new_path++;
0459 input_path++;
0460 }
0461 }
0462
0463 *new_path = 0;
0464 strcpy(original_path, new_path_buffer);
0465 ACPI_FREE(new_path_buffer);
0466 }