0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <acpi/acpi.h>
0011 #include "accommon.h"
0012 #include "acinterp.h"
0013 #include "amlcode.h"
0014
0015 #define _COMPONENT ACPI_EXECUTER
0016 ACPI_MODULE_NAME("exnames")
0017
0018
0019 static char *acpi_ex_allocate_name_string(u32 prefix_count, u32 num_name_segs);
0020
0021 static acpi_status acpi_ex_name_segment(u8 **in_aml_address, char *name_string);
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039 static char *acpi_ex_allocate_name_string(u32 prefix_count, u32 num_name_segs)
0040 {
0041 char *temp_ptr;
0042 char *name_string;
0043 u32 size_needed;
0044
0045 ACPI_FUNCTION_TRACE(ex_allocate_name_string);
0046
0047
0048
0049
0050
0051
0052 if (prefix_count == ACPI_UINT32_MAX) {
0053
0054
0055
0056 size_needed = 1 + (ACPI_NAMESEG_SIZE * num_name_segs) + 2 + 1;
0057 } else {
0058 size_needed =
0059 prefix_count + (ACPI_NAMESEG_SIZE * num_name_segs) + 2 + 1;
0060 }
0061
0062
0063
0064
0065
0066 name_string = ACPI_ALLOCATE(size_needed);
0067 if (!name_string) {
0068 ACPI_ERROR((AE_INFO,
0069 "Could not allocate size %u", size_needed));
0070 return_PTR(NULL);
0071 }
0072
0073 temp_ptr = name_string;
0074
0075
0076
0077 if (prefix_count == ACPI_UINT32_MAX) {
0078 *temp_ptr++ = AML_ROOT_PREFIX;
0079 } else {
0080 while (prefix_count--) {
0081 *temp_ptr++ = AML_PARENT_PREFIX;
0082 }
0083 }
0084
0085
0086
0087 if (num_name_segs > 2) {
0088
0089
0090
0091 *temp_ptr++ = AML_MULTI_NAME_PREFIX;
0092 *temp_ptr++ = (char)num_name_segs;
0093 } else if (2 == num_name_segs) {
0094
0095
0096
0097 *temp_ptr++ = AML_DUAL_NAME_PREFIX;
0098 }
0099
0100
0101
0102
0103
0104 *temp_ptr = 0;
0105
0106 return_PTR(name_string);
0107 }
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123 static acpi_status acpi_ex_name_segment(u8 ** in_aml_address, char *name_string)
0124 {
0125 char *aml_address = (void *)*in_aml_address;
0126 acpi_status status = AE_OK;
0127 u32 index;
0128 char char_buf[5];
0129
0130 ACPI_FUNCTION_TRACE(ex_name_segment);
0131
0132
0133
0134
0135
0136 char_buf[0] = *aml_address;
0137
0138 if ('0' <= char_buf[0] && char_buf[0] <= '9') {
0139 ACPI_ERROR((AE_INFO, "Invalid leading digit: %c", char_buf[0]));
0140 return_ACPI_STATUS(AE_CTRL_PENDING);
0141 }
0142
0143 for (index = 0;
0144 (index < ACPI_NAMESEG_SIZE)
0145 && (acpi_ut_valid_name_char(*aml_address, 0)); index++) {
0146 char_buf[index] = *aml_address++;
0147 }
0148
0149
0150
0151 if (index == 4) {
0152
0153
0154
0155 char_buf[4] = '\0';
0156
0157 if (name_string) {
0158 ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
0159 "Appending NameSeg %s\n", char_buf));
0160 strcat(name_string, char_buf);
0161 } else {
0162 ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
0163 "No Name string - %s\n", char_buf));
0164 }
0165 } else if (index == 0) {
0166
0167
0168
0169
0170 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
0171 "Leading character is not alpha: %02Xh (not a name)\n",
0172 char_buf[0]));
0173 status = AE_CTRL_PENDING;
0174 } else {
0175
0176
0177
0178
0179 status = AE_AML_BAD_NAME;
0180 ACPI_ERROR((AE_INFO,
0181 "Bad character 0x%02x in name, at %p",
0182 *aml_address, aml_address));
0183 }
0184
0185 *in_aml_address = ACPI_CAST_PTR(u8, aml_address);
0186 return_ACPI_STATUS(status);
0187 }
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206 acpi_status
0207 acpi_ex_get_name_string(acpi_object_type data_type,
0208 u8 * in_aml_address,
0209 char **out_name_string, u32 * out_name_length)
0210 {
0211 acpi_status status = AE_OK;
0212 u8 *aml_address = in_aml_address;
0213 char *name_string = NULL;
0214 u32 num_segments;
0215 u32 prefix_count = 0;
0216 u8 has_prefix = FALSE;
0217
0218 ACPI_FUNCTION_TRACE_PTR(ex_get_name_string, aml_address);
0219
0220 if (ACPI_TYPE_LOCAL_REGION_FIELD == data_type ||
0221 ACPI_TYPE_LOCAL_BANK_FIELD == data_type ||
0222 ACPI_TYPE_LOCAL_INDEX_FIELD == data_type) {
0223
0224
0225
0226 name_string = acpi_ex_allocate_name_string(0, 1);
0227 if (!name_string) {
0228 status = AE_NO_MEMORY;
0229 } else {
0230 status =
0231 acpi_ex_name_segment(&aml_address, name_string);
0232 }
0233 } else {
0234
0235
0236
0237
0238 switch (*aml_address) {
0239 case AML_ROOT_PREFIX:
0240
0241 ACPI_DEBUG_PRINT((ACPI_DB_LOAD,
0242 "RootPrefix(\\) at %p\n",
0243 aml_address));
0244
0245
0246
0247
0248
0249 aml_address++;
0250 prefix_count = ACPI_UINT32_MAX;
0251 has_prefix = TRUE;
0252 break;
0253
0254 case AML_PARENT_PREFIX:
0255
0256
0257
0258 do {
0259 ACPI_DEBUG_PRINT((ACPI_DB_LOAD,
0260 "ParentPrefix (^) at %p\n",
0261 aml_address));
0262
0263 aml_address++;
0264 prefix_count++;
0265
0266 } while (*aml_address == AML_PARENT_PREFIX);
0267
0268 has_prefix = TRUE;
0269 break;
0270
0271 default:
0272
0273
0274
0275 break;
0276 }
0277
0278
0279
0280 switch (*aml_address) {
0281 case AML_DUAL_NAME_PREFIX:
0282
0283 ACPI_DEBUG_PRINT((ACPI_DB_LOAD,
0284 "DualNamePrefix at %p\n",
0285 aml_address));
0286
0287 aml_address++;
0288 name_string =
0289 acpi_ex_allocate_name_string(prefix_count, 2);
0290 if (!name_string) {
0291 status = AE_NO_MEMORY;
0292 break;
0293 }
0294
0295
0296
0297 has_prefix = TRUE;
0298
0299 status =
0300 acpi_ex_name_segment(&aml_address, name_string);
0301 if (ACPI_SUCCESS(status)) {
0302 status =
0303 acpi_ex_name_segment(&aml_address,
0304 name_string);
0305 }
0306 break;
0307
0308 case AML_MULTI_NAME_PREFIX:
0309
0310 ACPI_DEBUG_PRINT((ACPI_DB_LOAD,
0311 "MultiNamePrefix at %p\n",
0312 aml_address));
0313
0314
0315
0316 aml_address++;
0317 num_segments = *aml_address;
0318
0319 name_string =
0320 acpi_ex_allocate_name_string(prefix_count,
0321 num_segments);
0322 if (!name_string) {
0323 status = AE_NO_MEMORY;
0324 break;
0325 }
0326
0327
0328
0329 aml_address++;
0330 has_prefix = TRUE;
0331
0332 while (num_segments &&
0333 (status =
0334 acpi_ex_name_segment(&aml_address,
0335 name_string)) == AE_OK) {
0336 num_segments--;
0337 }
0338
0339 break;
0340
0341 case 0:
0342
0343
0344
0345 if (prefix_count == ACPI_UINT32_MAX) {
0346 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
0347 "NameSeg is \"\\\" followed by NULL\n"));
0348 }
0349
0350
0351
0352 aml_address++;
0353 name_string =
0354 acpi_ex_allocate_name_string(prefix_count, 0);
0355 if (!name_string) {
0356 status = AE_NO_MEMORY;
0357 break;
0358 }
0359
0360 break;
0361
0362 default:
0363
0364
0365
0366 name_string =
0367 acpi_ex_allocate_name_string(prefix_count, 1);
0368 if (!name_string) {
0369 status = AE_NO_MEMORY;
0370 break;
0371 }
0372
0373 status =
0374 acpi_ex_name_segment(&aml_address, name_string);
0375 break;
0376 }
0377 }
0378
0379 if (AE_CTRL_PENDING == status && has_prefix) {
0380
0381
0382
0383 ACPI_ERROR((AE_INFO, "Malformed Name at %p", name_string));
0384 status = AE_AML_BAD_NAME;
0385 }
0386
0387 if (ACPI_FAILURE(status)) {
0388 if (name_string) {
0389 ACPI_FREE(name_string);
0390 }
0391 return_ACPI_STATUS(status);
0392 }
0393
0394 *out_name_string = name_string;
0395 *out_name_length = (u32) (aml_address - in_aml_address);
0396
0397 return_ACPI_STATUS(status);
0398 }