0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <acpi/acpi.h>
0011 #include "accommon.h"
0012 #include "acnamesp.h"
0013 #include "acinterp.h"
0014 #include "acpredef.h"
0015 #include "amlresrc.h"
0016
0017 #define _COMPONENT ACPI_NAMESPACE
0018 ACPI_MODULE_NAME("nsrepair")
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053 static const struct acpi_simple_repair_info *acpi_ns_match_simple_repair(struct
0054 acpi_namespace_node
0055 *node,
0056 u32
0057 return_btype,
0058 u32
0059 package_index);
0060
0061
0062
0063
0064
0065
0066 static const struct acpi_simple_repair_info acpi_object_repair_info[] = {
0067
0068
0069 {"_CRS",
0070 ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING | ACPI_RTYPE_BUFFER |
0071 ACPI_RTYPE_NONE,
0072 ACPI_NOT_PACKAGE_ELEMENT,
0073 acpi_ns_convert_to_resource},
0074 {"_DMA",
0075 ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING | ACPI_RTYPE_BUFFER |
0076 ACPI_RTYPE_NONE,
0077 ACPI_NOT_PACKAGE_ELEMENT,
0078 acpi_ns_convert_to_resource},
0079 {"_PRS",
0080 ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING | ACPI_RTYPE_BUFFER |
0081 ACPI_RTYPE_NONE,
0082 ACPI_NOT_PACKAGE_ELEMENT,
0083 acpi_ns_convert_to_resource},
0084
0085
0086
0087 {"_DEP", ACPI_RTYPE_STRING, ACPI_ALL_PACKAGE_ELEMENTS,
0088 acpi_ns_convert_to_reference},
0089
0090
0091
0092 {"_MLS", ACPI_RTYPE_STRING, 1,
0093 acpi_ns_convert_to_unicode},
0094 {"_STR", ACPI_RTYPE_STRING | ACPI_RTYPE_BUFFER,
0095 ACPI_NOT_PACKAGE_ELEMENT,
0096 acpi_ns_convert_to_unicode},
0097 {{0, 0, 0, 0}, 0, 0, NULL}
0098 };
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119 acpi_status
0120 acpi_ns_simple_repair(struct acpi_evaluate_info *info,
0121 u32 expected_btypes,
0122 u32 package_index,
0123 union acpi_operand_object **return_object_ptr)
0124 {
0125 union acpi_operand_object *return_object = *return_object_ptr;
0126 union acpi_operand_object *new_object = NULL;
0127 acpi_status status;
0128 const struct acpi_simple_repair_info *predefined;
0129
0130 ACPI_FUNCTION_NAME(ns_simple_repair);
0131
0132
0133
0134
0135
0136 predefined = acpi_ns_match_simple_repair(info->node,
0137 info->return_btype,
0138 package_index);
0139 if (predefined) {
0140 if (!return_object) {
0141 ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
0142 ACPI_WARN_ALWAYS,
0143 "Missing expected return value"));
0144 }
0145
0146 status = predefined->object_converter(info->node, return_object,
0147 &new_object);
0148 if (ACPI_FAILURE(status)) {
0149
0150
0151
0152 ACPI_EXCEPTION((AE_INFO, status,
0153 "During return object analysis"));
0154 return (status);
0155 }
0156 if (new_object) {
0157 goto object_repaired;
0158 }
0159 }
0160
0161
0162
0163
0164
0165 if (info->return_btype & expected_btypes) {
0166 return (AE_OK);
0167 }
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183 if (!return_object) {
0184 if (expected_btypes && (!(expected_btypes & ACPI_RTYPE_NONE))) {
0185 if (package_index != ACPI_NOT_PACKAGE_ELEMENT) {
0186 ACPI_WARN_PREDEFINED((AE_INFO,
0187 info->full_pathname,
0188 ACPI_WARN_ALWAYS,
0189 "Found unexpected NULL package element"));
0190
0191 status =
0192 acpi_ns_repair_null_element(info,
0193 expected_btypes,
0194 package_index,
0195 return_object_ptr);
0196 if (ACPI_SUCCESS(status)) {
0197 return (AE_OK);
0198 }
0199 } else {
0200 ACPI_WARN_PREDEFINED((AE_INFO,
0201 info->full_pathname,
0202 ACPI_WARN_ALWAYS,
0203 "Missing expected return value"));
0204 }
0205
0206 return (AE_AML_NO_RETURN_VALUE);
0207 }
0208 }
0209
0210 if (expected_btypes & ACPI_RTYPE_INTEGER) {
0211 status = acpi_ns_convert_to_integer(return_object, &new_object);
0212 if (ACPI_SUCCESS(status)) {
0213 goto object_repaired;
0214 }
0215 }
0216 if (expected_btypes & ACPI_RTYPE_STRING) {
0217 status = acpi_ns_convert_to_string(return_object, &new_object);
0218 if (ACPI_SUCCESS(status)) {
0219 goto object_repaired;
0220 }
0221 }
0222 if (expected_btypes & ACPI_RTYPE_BUFFER) {
0223 status = acpi_ns_convert_to_buffer(return_object, &new_object);
0224 if (ACPI_SUCCESS(status)) {
0225 goto object_repaired;
0226 }
0227 }
0228 if (expected_btypes & ACPI_RTYPE_PACKAGE) {
0229
0230
0231
0232
0233
0234
0235
0236
0237 status =
0238 acpi_ns_wrap_with_package(info, return_object, &new_object);
0239 if (ACPI_SUCCESS(status)) {
0240
0241
0242
0243
0244 *return_object_ptr = new_object;
0245 info->return_flags |= ACPI_OBJECT_REPAIRED;
0246 return (AE_OK);
0247 }
0248 }
0249
0250
0251
0252 return (AE_AML_OPERAND_TYPE);
0253
0254 object_repaired:
0255
0256
0257
0258 if (package_index != ACPI_NOT_PACKAGE_ELEMENT) {
0259
0260
0261
0262 if (!(info->return_flags & ACPI_OBJECT_WRAPPED)) {
0263 new_object->common.reference_count =
0264 return_object->common.reference_count;
0265 }
0266
0267 ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
0268 "%s: Converted %s to expected %s at Package index %u\n",
0269 info->full_pathname,
0270 acpi_ut_get_object_type_name(return_object),
0271 acpi_ut_get_object_type_name(new_object),
0272 package_index));
0273 } else {
0274 ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
0275 "%s: Converted %s to expected %s\n",
0276 info->full_pathname,
0277 acpi_ut_get_object_type_name(return_object),
0278 acpi_ut_get_object_type_name(new_object)));
0279 }
0280
0281
0282
0283 acpi_ut_remove_reference(return_object);
0284 *return_object_ptr = new_object;
0285 info->return_flags |= ACPI_OBJECT_REPAIRED;
0286 return (AE_OK);
0287 }
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300
0301
0302
0303
0304
0305 static const struct acpi_simple_repair_info *acpi_ns_match_simple_repair(struct
0306 acpi_namespace_node
0307 *node,
0308 u32
0309 return_btype,
0310 u32
0311 package_index)
0312 {
0313 const struct acpi_simple_repair_info *this_name;
0314
0315
0316
0317 this_name = acpi_object_repair_info;
0318 while (this_name->object_converter) {
0319 if (ACPI_COMPARE_NAMESEG(node->name.ascii, this_name->name)) {
0320
0321
0322
0323 if ((return_btype & this_name->unexpected_btypes) &&
0324 (this_name->package_index ==
0325 ACPI_ALL_PACKAGE_ELEMENTS
0326 || package_index == this_name->package_index)) {
0327 return (this_name);
0328 }
0329
0330 return (NULL);
0331 }
0332
0333 this_name++;
0334 }
0335
0336 return (NULL);
0337 }
0338
0339
0340
0341
0342
0343
0344
0345
0346
0347
0348
0349
0350
0351
0352
0353
0354
0355
0356
0357 acpi_status
0358 acpi_ns_repair_null_element(struct acpi_evaluate_info *info,
0359 u32 expected_btypes,
0360 u32 package_index,
0361 union acpi_operand_object **return_object_ptr)
0362 {
0363 union acpi_operand_object *return_object = *return_object_ptr;
0364 union acpi_operand_object *new_object;
0365
0366 ACPI_FUNCTION_NAME(ns_repair_null_element);
0367
0368
0369
0370 if (return_object) {
0371 return (AE_OK);
0372 }
0373
0374
0375
0376
0377
0378
0379
0380 if (expected_btypes & ACPI_RTYPE_INTEGER) {
0381
0382
0383
0384 new_object = acpi_ut_create_integer_object((u64)0);
0385 } else if (expected_btypes & ACPI_RTYPE_STRING) {
0386
0387
0388
0389 new_object = acpi_ut_create_string_object(0);
0390 } else if (expected_btypes & ACPI_RTYPE_BUFFER) {
0391
0392
0393
0394 new_object = acpi_ut_create_buffer_object(0);
0395 } else {
0396
0397
0398 return (AE_AML_OPERAND_TYPE);
0399 }
0400
0401 if (!new_object) {
0402 return (AE_NO_MEMORY);
0403 }
0404
0405
0406
0407 new_object->common.reference_count =
0408 info->parent_package->common.reference_count;
0409
0410 ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
0411 "%s: Converted NULL package element to expected %s at index %u\n",
0412 info->full_pathname,
0413 acpi_ut_get_object_type_name(new_object),
0414 package_index));
0415
0416 *return_object_ptr = new_object;
0417 info->return_flags |= ACPI_OBJECT_REPAIRED;
0418 return (AE_OK);
0419 }
0420
0421
0422
0423
0424
0425
0426
0427
0428
0429
0430
0431
0432
0433
0434
0435
0436
0437 void
0438 acpi_ns_remove_null_elements(struct acpi_evaluate_info *info,
0439 u8 package_type,
0440 union acpi_operand_object *obj_desc)
0441 {
0442 union acpi_operand_object **source;
0443 union acpi_operand_object **dest;
0444 u32 count;
0445 u32 new_count;
0446 u32 i;
0447
0448 ACPI_FUNCTION_NAME(ns_remove_null_elements);
0449
0450
0451
0452
0453
0454
0455 switch (package_type) {
0456 case ACPI_PTYPE1_VAR:
0457 case ACPI_PTYPE2:
0458 case ACPI_PTYPE2_COUNT:
0459 case ACPI_PTYPE2_PKG_COUNT:
0460 case ACPI_PTYPE2_FIXED:
0461 case ACPI_PTYPE2_MIN:
0462 case ACPI_PTYPE2_REV_FIXED:
0463 case ACPI_PTYPE2_FIX_VAR:
0464 break;
0465
0466 default:
0467 case ACPI_PTYPE2_VAR_VAR:
0468 case ACPI_PTYPE1_FIXED:
0469 case ACPI_PTYPE1_OPTION:
0470 return;
0471 }
0472
0473 count = obj_desc->package.count;
0474 new_count = count;
0475
0476 source = obj_desc->package.elements;
0477 dest = source;
0478
0479
0480
0481 for (i = 0; i < count; i++) {
0482 if (!*source) {
0483 new_count--;
0484 } else {
0485 *dest = *source;
0486 dest++;
0487 }
0488
0489 source++;
0490 }
0491
0492
0493
0494 if (new_count < count) {
0495 ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
0496 "%s: Found and removed %u NULL elements\n",
0497 info->full_pathname, (count - new_count)));
0498
0499
0500
0501 *dest = NULL;
0502 obj_desc->package.count = new_count;
0503 }
0504 }
0505
0506
0507
0508
0509
0510
0511
0512
0513
0514
0515
0516
0517
0518
0519
0520
0521
0522
0523
0524
0525
0526
0527
0528
0529
0530 acpi_status
0531 acpi_ns_wrap_with_package(struct acpi_evaluate_info *info,
0532 union acpi_operand_object *original_object,
0533 union acpi_operand_object **obj_desc_ptr)
0534 {
0535 union acpi_operand_object *pkg_obj_desc;
0536
0537 ACPI_FUNCTION_NAME(ns_wrap_with_package);
0538
0539
0540
0541
0542
0543 pkg_obj_desc = acpi_ut_create_package_object(1);
0544 if (!pkg_obj_desc) {
0545 return (AE_NO_MEMORY);
0546 }
0547
0548 pkg_obj_desc->package.elements[0] = original_object;
0549
0550 ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
0551 "%s: Wrapped %s with expected Package object\n",
0552 info->full_pathname,
0553 acpi_ut_get_object_type_name(original_object)));
0554
0555
0556
0557 *obj_desc_ptr = pkg_obj_desc;
0558 info->return_flags |= ACPI_OBJECT_REPAIRED | ACPI_OBJECT_WRAPPED;
0559 return (AE_OK);
0560 }