1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44#include <acpi/acpi.h>
45#include "accommon.h"
46#include "acnamesp.h"
47#include "acinterp.h"
48#include "acpredef.h"
49
50#define _COMPONENT ACPI_NAMESPACE
51ACPI_MODULE_NAME("nsrepair")
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83static acpi_status
84acpi_ns_convert_to_integer(union acpi_operand_object *original_object,
85 union acpi_operand_object **return_object);
86
87static acpi_status
88acpi_ns_convert_to_string(union acpi_operand_object *original_object,
89 union acpi_operand_object **return_object);
90
91static acpi_status
92acpi_ns_convert_to_buffer(union acpi_operand_object *original_object,
93 union acpi_operand_object **return_object);
94
95static acpi_status
96acpi_ns_convert_to_package(union acpi_operand_object *original_object,
97 union acpi_operand_object **return_object);
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118acpi_status
119acpi_ns_repair_object(struct acpi_predefined_data *data,
120 u32 expected_btypes,
121 u32 package_index,
122 union acpi_operand_object **return_object_ptr)
123{
124 union acpi_operand_object *return_object = *return_object_ptr;
125 union acpi_operand_object *new_object;
126 acpi_status status;
127
128 ACPI_FUNCTION_NAME(ns_repair_object);
129
130
131
132
133
134
135
136 if (expected_btypes & ACPI_RTYPE_INTEGER) {
137 status = acpi_ns_convert_to_integer(return_object, &new_object);
138 if (ACPI_SUCCESS(status)) {
139 goto object_repaired;
140 }
141 }
142 if (expected_btypes & ACPI_RTYPE_STRING) {
143 status = acpi_ns_convert_to_string(return_object, &new_object);
144 if (ACPI_SUCCESS(status)) {
145 goto object_repaired;
146 }
147 }
148 if (expected_btypes & ACPI_RTYPE_BUFFER) {
149 status = acpi_ns_convert_to_buffer(return_object, &new_object);
150 if (ACPI_SUCCESS(status)) {
151 goto object_repaired;
152 }
153 }
154 if (expected_btypes & ACPI_RTYPE_PACKAGE) {
155 status = acpi_ns_convert_to_package(return_object, &new_object);
156 if (ACPI_SUCCESS(status)) {
157 goto object_repaired;
158 }
159 }
160
161
162
163 return (AE_AML_OPERAND_TYPE);
164
165 object_repaired:
166
167
168
169
170
171
172
173
174
175 if (package_index != ACPI_NOT_PACKAGE_ELEMENT) {
176 new_object->common.reference_count =
177 return_object->common.reference_count;
178
179 if (return_object->common.reference_count > 1) {
180 return_object->common.reference_count--;
181 }
182
183 ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
184 "%s: Converted %s to expected %s at index %u\n",
185 data->pathname,
186 acpi_ut_get_object_type_name(return_object),
187 acpi_ut_get_object_type_name(new_object),
188 package_index));
189 } else {
190 ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
191 "%s: Converted %s to expected %s\n",
192 data->pathname,
193 acpi_ut_get_object_type_name(return_object),
194 acpi_ut_get_object_type_name(new_object)));
195 }
196
197
198
199 acpi_ut_remove_reference(return_object);
200 *return_object_ptr = new_object;
201 data->flags |= ACPI_OBJECT_REPAIRED;
202 return (AE_OK);
203}
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218static acpi_status
219acpi_ns_convert_to_integer(union acpi_operand_object *original_object,
220 union acpi_operand_object **return_object)
221{
222 union acpi_operand_object *new_object;
223 acpi_status status;
224 u64 value = 0;
225 u32 i;
226
227 switch (original_object->common.type) {
228 case ACPI_TYPE_STRING:
229
230
231
232 status = acpi_ut_strtoul64(original_object->string.pointer,
233 ACPI_ANY_BASE, &value);
234 if (ACPI_FAILURE(status)) {
235 return (status);
236 }
237 break;
238
239 case ACPI_TYPE_BUFFER:
240
241
242
243 if (original_object->buffer.length > 8) {
244 return (AE_AML_OPERAND_TYPE);
245 }
246
247
248
249 for (i = 0; i < original_object->buffer.length; i++) {
250 value |=
251 ((u64) original_object->buffer.
252 pointer[i] << (i * 8));
253 }
254 break;
255
256 default:
257 return (AE_AML_OPERAND_TYPE);
258 }
259
260 new_object = acpi_ut_create_integer_object(value);
261 if (!new_object) {
262 return (AE_NO_MEMORY);
263 }
264
265 *return_object = new_object;
266 return (AE_OK);
267}
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282static acpi_status
283acpi_ns_convert_to_string(union acpi_operand_object *original_object,
284 union acpi_operand_object **return_object)
285{
286 union acpi_operand_object *new_object;
287 acpi_size length;
288 acpi_status status;
289
290 switch (original_object->common.type) {
291 case ACPI_TYPE_INTEGER:
292
293
294
295
296
297 if (original_object->integer.value == 0) {
298
299
300
301 new_object = acpi_ut_create_string_object(0);
302 if (!new_object) {
303 return (AE_NO_MEMORY);
304 }
305 } else {
306 status =
307 acpi_ex_convert_to_string(original_object,
308 &new_object,
309 ACPI_IMPLICIT_CONVERT_HEX);
310 if (ACPI_FAILURE(status)) {
311 return (status);
312 }
313 }
314 break;
315
316 case ACPI_TYPE_BUFFER:
317
318
319
320
321
322
323 length = 0;
324 while ((length < original_object->buffer.length) &&
325 (original_object->buffer.pointer[length])) {
326 length++;
327 }
328
329
330
331 new_object = acpi_ut_create_string_object(length);
332 if (!new_object) {
333 return (AE_NO_MEMORY);
334 }
335
336
337
338
339
340 ACPI_MEMCPY(new_object->string.pointer,
341 original_object->buffer.pointer, length);
342 break;
343
344 default:
345 return (AE_AML_OPERAND_TYPE);
346 }
347
348 *return_object = new_object;
349 return (AE_OK);
350}
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365static acpi_status
366acpi_ns_convert_to_buffer(union acpi_operand_object *original_object,
367 union acpi_operand_object **return_object)
368{
369 union acpi_operand_object *new_object;
370 acpi_status status;
371 union acpi_operand_object **elements;
372 u32 *dword_buffer;
373 u32 count;
374 u32 i;
375
376 switch (original_object->common.type) {
377 case ACPI_TYPE_INTEGER:
378
379
380
381
382
383
384
385 status =
386 acpi_ex_convert_to_buffer(original_object, &new_object);
387 if (ACPI_FAILURE(status)) {
388 return (status);
389 }
390 break;
391
392 case ACPI_TYPE_STRING:
393
394
395
396 new_object =
397 acpi_ut_create_buffer_object(original_object->string.
398 length);
399 if (!new_object) {
400 return (AE_NO_MEMORY);
401 }
402
403 ACPI_MEMCPY(new_object->buffer.pointer,
404 original_object->string.pointer,
405 original_object->string.length);
406 break;
407
408 case ACPI_TYPE_PACKAGE:
409
410
411
412
413
414
415
416
417 elements = original_object->package.elements;
418 count = original_object->package.count;
419
420 for (i = 0; i < count; i++) {
421 if ((!*elements) ||
422 ((*elements)->common.type != ACPI_TYPE_INTEGER)) {
423 return (AE_AML_OPERAND_TYPE);
424 }
425 elements++;
426 }
427
428
429
430 new_object = acpi_ut_create_buffer_object(ACPI_MUL_4(count));
431 if (!new_object) {
432 return (AE_NO_MEMORY);
433 }
434
435
436
437 elements = original_object->package.elements;
438 dword_buffer = ACPI_CAST_PTR(u32, new_object->buffer.pointer);
439
440 for (i = 0; i < count; i++) {
441 *dword_buffer = (u32) (*elements)->integer.value;
442 dword_buffer++;
443 elements++;
444 }
445 break;
446
447 default:
448 return (AE_AML_OPERAND_TYPE);
449 }
450
451 *return_object = new_object;
452 return (AE_OK);
453}
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469static acpi_status
470acpi_ns_convert_to_package(union acpi_operand_object *original_object,
471 union acpi_operand_object **return_object)
472{
473 union acpi_operand_object *new_object;
474 union acpi_operand_object **elements;
475 u32 length;
476 u8 *buffer;
477
478 switch (original_object->common.type) {
479 case ACPI_TYPE_BUFFER:
480
481
482
483 length = original_object->buffer.length;
484 new_object = acpi_ut_create_package_object(length);
485 if (!new_object) {
486 return (AE_NO_MEMORY);
487 }
488
489
490
491 elements = new_object->package.elements;
492 buffer = original_object->buffer.pointer;
493
494 while (length--) {
495 *elements =
496 acpi_ut_create_integer_object((u64) *buffer);
497 if (!*elements) {
498 acpi_ut_remove_reference(new_object);
499 return (AE_NO_MEMORY);
500 }
501 elements++;
502 buffer++;
503 }
504 break;
505
506 default:
507 return (AE_AML_OPERAND_TYPE);
508 }
509
510 *return_object = new_object;
511 return (AE_OK);
512}
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532acpi_status
533acpi_ns_repair_null_element(struct acpi_predefined_data *data,
534 u32 expected_btypes,
535 u32 package_index,
536 union acpi_operand_object **return_object_ptr)
537{
538 union acpi_operand_object *return_object = *return_object_ptr;
539 union acpi_operand_object *new_object;
540
541 ACPI_FUNCTION_NAME(ns_repair_null_element);
542
543
544
545 if (return_object) {
546 return (AE_OK);
547 }
548
549
550
551
552
553
554
555 if (expected_btypes & ACPI_RTYPE_INTEGER) {
556
557
558
559 new_object = acpi_ut_create_integer_object((u64)0);
560 } else if (expected_btypes & ACPI_RTYPE_STRING) {
561
562
563
564 new_object = acpi_ut_create_string_object(0);
565 } else if (expected_btypes & ACPI_RTYPE_BUFFER) {
566
567
568
569 new_object = acpi_ut_create_buffer_object(0);
570 } else {
571
572
573 return (AE_AML_OPERAND_TYPE);
574 }
575
576 if (!new_object) {
577 return (AE_NO_MEMORY);
578 }
579
580
581
582 new_object->common.reference_count =
583 data->parent_package->common.reference_count;
584
585 ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
586 "%s: Converted NULL package element to expected %s at index %u\n",
587 data->pathname,
588 acpi_ut_get_object_type_name(new_object),
589 package_index));
590
591 *return_object_ptr = new_object;
592 data->flags |= ACPI_OBJECT_REPAIRED;
593 return (AE_OK);
594}
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612void
613acpi_ns_remove_null_elements(struct acpi_predefined_data *data,
614 u8 package_type,
615 union acpi_operand_object *obj_desc)
616{
617 union acpi_operand_object **source;
618 union acpi_operand_object **dest;
619 u32 count;
620 u32 new_count;
621 u32 i;
622
623 ACPI_FUNCTION_NAME(ns_remove_null_elements);
624
625
626
627
628
629
630 switch (package_type) {
631 case ACPI_PTYPE1_FIXED:
632 case ACPI_PTYPE1_VAR:
633 case ACPI_PTYPE1_OPTION:
634 return;
635
636 case ACPI_PTYPE2:
637 case ACPI_PTYPE2_COUNT:
638 case ACPI_PTYPE2_PKG_COUNT:
639 case ACPI_PTYPE2_FIXED:
640 case ACPI_PTYPE2_MIN:
641 case ACPI_PTYPE2_REV_FIXED:
642 break;
643
644 default:
645 return;
646 }
647
648 count = obj_desc->package.count;
649 new_count = count;
650
651 source = obj_desc->package.elements;
652 dest = source;
653
654
655
656 for (i = 0; i < count; i++) {
657 if (!*source) {
658 new_count--;
659 } else {
660 *dest = *source;
661 dest++;
662 }
663 source++;
664 }
665
666
667
668 if (new_count < count) {
669 ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
670 "%s: Found and removed %u NULL elements\n",
671 data->pathname, (count - new_count)));
672
673
674
675 *dest = NULL;
676 obj_desc->package.count = new_count;
677 }
678}
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704acpi_status
705acpi_ns_repair_package_list(struct acpi_predefined_data *data,
706 union acpi_operand_object **obj_desc_ptr)
707{
708 union acpi_operand_object *pkg_obj_desc;
709
710 ACPI_FUNCTION_NAME(ns_repair_package_list);
711
712
713
714
715
716 pkg_obj_desc = acpi_ut_create_package_object(1);
717 if (!pkg_obj_desc) {
718 return (AE_NO_MEMORY);
719 }
720
721 pkg_obj_desc->package.elements[0] = *obj_desc_ptr;
722
723
724
725 *obj_desc_ptr = pkg_obj_desc;
726 data->flags |= ACPI_OBJECT_REPAIRED;
727
728 ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
729 "%s: Repaired incorrectly formed Package\n",
730 data->pathname));
731
732 return (AE_OK);
733}
734