This source file includes following definitions.
- ACPI_MODULE_NAME
- ACPI_EXPORT_SYMBOL
- ACPI_EXPORT_SYMBOL
- acpi_get_object_info
- ACPI_EXPORT_SYMBOL
1
2
3
4
5
6
7
8
9
10
11 #define EXPORT_ACPI_INTERFACES
12
13 #include <acpi/acpi.h>
14 #include "accommon.h"
15 #include "acnamesp.h"
16 #include "acparser.h"
17 #include "amlcode.h"
18
19 #define _COMPONENT ACPI_NAMESPACE
20 ACPI_MODULE_NAME("nsxfname")
21
22
23 static char *acpi_ns_copy_device_id(struct acpi_pnp_device_id *dest,
24 struct acpi_pnp_device_id *source,
25 char *string_area);
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45 acpi_status
46 acpi_get_handle(acpi_handle parent,
47 acpi_string pathname, acpi_handle *ret_handle)
48 {
49 acpi_status status;
50 struct acpi_namespace_node *node = NULL;
51 struct acpi_namespace_node *prefix_node = NULL;
52
53 ACPI_FUNCTION_ENTRY();
54
55
56
57 if (!ret_handle || !pathname) {
58 return (AE_BAD_PARAMETER);
59 }
60
61
62
63 if (parent) {
64 prefix_node = acpi_ns_validate_handle(parent);
65 if (!prefix_node) {
66 return (AE_BAD_PARAMETER);
67 }
68 }
69
70
71
72
73
74
75
76
77 if (ACPI_IS_ROOT_PREFIX(pathname[0])) {
78
79
80
81
82
83 if (!strcmp(pathname, ACPI_NS_ROOT_PATH)) {
84 *ret_handle =
85 ACPI_CAST_PTR(acpi_handle, acpi_gbl_root_node);
86 return (AE_OK);
87 }
88 } else if (!prefix_node) {
89
90
91
92 return (AE_BAD_PARAMETER);
93 }
94
95
96
97 status =
98 acpi_ns_get_node(prefix_node, pathname, ACPI_NS_NO_UPSEARCH, &node);
99 if (ACPI_SUCCESS(status)) {
100 *ret_handle = ACPI_CAST_PTR(acpi_handle, node);
101 }
102
103 return (status);
104 }
105
106 ACPI_EXPORT_SYMBOL(acpi_get_handle)
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123 acpi_status
124 acpi_get_name(acpi_handle handle, u32 name_type, struct acpi_buffer *buffer)
125 {
126 acpi_status status;
127
128
129
130 if (name_type > ACPI_NAME_TYPE_MAX) {
131 return (AE_BAD_PARAMETER);
132 }
133
134 status = acpi_ut_validate_buffer(buffer);
135 if (ACPI_FAILURE(status)) {
136 return (status);
137 }
138
139
140
141
142
143 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
144 if (ACPI_FAILURE(status)) {
145 return (status);
146 }
147
148 if (name_type == ACPI_FULL_PATHNAME ||
149 name_type == ACPI_FULL_PATHNAME_NO_TRAILING) {
150
151
152
153 status = acpi_ns_handle_to_pathname(handle, buffer,
154 name_type ==
155 ACPI_FULL_PATHNAME ? FALSE :
156 TRUE);
157 } else {
158
159
160 status = acpi_ns_handle_to_name(handle, buffer);
161 }
162
163 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
164 return (status);
165 }
166
167 ACPI_EXPORT_SYMBOL(acpi_get_name)
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182 static char *acpi_ns_copy_device_id(struct acpi_pnp_device_id *dest,
183 struct acpi_pnp_device_id *source,
184 char *string_area)
185 {
186
187
188 dest->string = string_area;
189 dest->length = source->length;
190
191
192
193 memcpy(string_area, source->string, source->length);
194 return (string_area + source->length);
195 }
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225 acpi_status
226 acpi_get_object_info(acpi_handle handle,
227 struct acpi_device_info **return_buffer)
228 {
229 struct acpi_namespace_node *node;
230 struct acpi_device_info *info;
231 struct acpi_pnp_device_id_list *cid_list = NULL;
232 struct acpi_pnp_device_id *hid = NULL;
233 struct acpi_pnp_device_id *uid = NULL;
234 struct acpi_pnp_device_id *cls = NULL;
235 char *next_id_string;
236 acpi_object_type type;
237 acpi_name name;
238 u8 param_count = 0;
239 u16 valid = 0;
240 u32 info_size;
241 u32 i;
242 acpi_status status;
243
244
245
246 if (!handle || !return_buffer) {
247 return (AE_BAD_PARAMETER);
248 }
249
250 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
251 if (ACPI_FAILURE(status)) {
252 return (status);
253 }
254
255 node = acpi_ns_validate_handle(handle);
256 if (!node) {
257 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
258 return (AE_BAD_PARAMETER);
259 }
260
261
262
263 info_size = sizeof(struct acpi_device_info);
264 type = node->type;
265 name = node->name.integer;
266
267 if (node->type == ACPI_TYPE_METHOD) {
268 param_count = node->object->method.param_count;
269 }
270
271 status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
272 if (ACPI_FAILURE(status)) {
273 return (status);
274 }
275
276 if ((type == ACPI_TYPE_DEVICE) || (type == ACPI_TYPE_PROCESSOR)) {
277
278
279
280
281
282
283
284
285
286
287
288 status = acpi_ut_execute_HID(node, &hid);
289 if (ACPI_SUCCESS(status)) {
290 info_size += hid->length;
291 valid |= ACPI_VALID_HID;
292 }
293
294
295
296 status = acpi_ut_execute_UID(node, &uid);
297 if (ACPI_SUCCESS(status)) {
298 info_size += uid->length;
299 valid |= ACPI_VALID_UID;
300 }
301
302
303
304 status = acpi_ut_execute_CID(node, &cid_list);
305 if (ACPI_SUCCESS(status)) {
306
307
308
309 info_size +=
310 (cid_list->list_size -
311 sizeof(struct acpi_pnp_device_id_list));
312 valid |= ACPI_VALID_CID;
313 }
314
315
316
317 status = acpi_ut_execute_CLS(node, &cls);
318 if (ACPI_SUCCESS(status)) {
319 info_size += cls->length;
320 valid |= ACPI_VALID_CLS;
321 }
322 }
323
324
325
326
327
328 info = ACPI_ALLOCATE_ZEROED(info_size);
329 if (!info) {
330 status = AE_NO_MEMORY;
331 goto cleanup;
332 }
333
334
335
336 if ((type == ACPI_TYPE_DEVICE) || (type == ACPI_TYPE_PROCESSOR)) {
337
338
339
340
341
342
343
344
345
346
347
348 status = acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR, node,
349 &info->address);
350 if (ACPI_SUCCESS(status)) {
351 valid |= ACPI_VALID_ADR;
352 }
353
354
355
356 status = acpi_ut_execute_power_methods(node,
357 acpi_gbl_lowest_dstate_names,
358 ACPI_NUM_sx_w_METHODS,
359 info->lowest_dstates);
360 if (ACPI_SUCCESS(status)) {
361 valid |= ACPI_VALID_SXWS;
362 }
363
364
365
366 status = acpi_ut_execute_power_methods(node,
367 acpi_gbl_highest_dstate_names,
368 ACPI_NUM_sx_d_METHODS,
369 info->highest_dstates);
370 if (ACPI_SUCCESS(status)) {
371 valid |= ACPI_VALID_SXDS;
372 }
373 }
374
375
376
377
378
379 next_id_string = ACPI_CAST_PTR(char, info->compatible_id_list.ids);
380 if (cid_list) {
381
382
383
384 next_id_string +=
385 ((acpi_size)cid_list->count *
386 sizeof(struct acpi_pnp_device_id));
387 }
388
389
390
391
392
393
394
395 if (hid) {
396 next_id_string = acpi_ns_copy_device_id(&info->hardware_id,
397 hid, next_id_string);
398
399 if (acpi_ut_is_pci_root_bridge(hid->string)) {
400 info->flags |= ACPI_PCI_ROOT_BRIDGE;
401 }
402 }
403
404 if (uid) {
405 next_id_string = acpi_ns_copy_device_id(&info->unique_id,
406 uid, next_id_string);
407 }
408
409 if (cid_list) {
410 info->compatible_id_list.count = cid_list->count;
411 info->compatible_id_list.list_size = cid_list->list_size;
412
413
414
415 for (i = 0; i < cid_list->count; i++) {
416 next_id_string =
417 acpi_ns_copy_device_id(&info->compatible_id_list.
418 ids[i], &cid_list->ids[i],
419 next_id_string);
420
421 if (acpi_ut_is_pci_root_bridge(cid_list->ids[i].string)) {
422 info->flags |= ACPI_PCI_ROOT_BRIDGE;
423 }
424 }
425 }
426
427 if (cls) {
428 next_id_string = acpi_ns_copy_device_id(&info->class_code,
429 cls, next_id_string);
430 }
431
432
433
434 info->info_size = info_size;
435 info->type = type;
436 info->name = name;
437 info->param_count = param_count;
438 info->valid = valid;
439
440 *return_buffer = info;
441 status = AE_OK;
442
443 cleanup:
444 if (hid) {
445 ACPI_FREE(hid);
446 }
447 if (uid) {
448 ACPI_FREE(uid);
449 }
450 if (cid_list) {
451 ACPI_FREE(cid_list);
452 }
453 if (cls) {
454 ACPI_FREE(cls);
455 }
456 return (status);
457 }
458
459 ACPI_EXPORT_SYMBOL(acpi_get_object_info)
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475 acpi_status acpi_install_method(u8 *buffer)
476 {
477 struct acpi_table_header *table =
478 ACPI_CAST_PTR(struct acpi_table_header, buffer);
479 u8 *aml_buffer;
480 u8 *aml_start;
481 char *path;
482 struct acpi_namespace_node *node;
483 union acpi_operand_object *method_obj;
484 struct acpi_parse_state parser_state;
485 u32 aml_length;
486 u16 opcode;
487 u8 method_flags;
488 acpi_status status;
489
490
491
492 if (!buffer) {
493 return (AE_BAD_PARAMETER);
494 }
495
496
497
498 if (!ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_DSDT) &&
499 !ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_SSDT)) {
500 return (AE_BAD_HEADER);
501 }
502
503
504
505 parser_state.aml = buffer + sizeof(struct acpi_table_header);
506 opcode = acpi_ps_peek_opcode(&parser_state);
507 if (opcode != AML_METHOD_OP) {
508 return (AE_BAD_PARAMETER);
509 }
510
511
512
513 parser_state.aml += acpi_ps_get_opcode_size(opcode);
514 parser_state.pkg_end = acpi_ps_get_next_package_end(&parser_state);
515 path = acpi_ps_get_next_namestring(&parser_state);
516
517 method_flags = *parser_state.aml++;
518 aml_start = parser_state.aml;
519 aml_length = ACPI_PTR_DIFF(parser_state.pkg_end, aml_start);
520
521
522
523
524
525 aml_buffer = ACPI_ALLOCATE(aml_length);
526 if (!aml_buffer) {
527 return (AE_NO_MEMORY);
528 }
529
530 method_obj = acpi_ut_create_internal_object(ACPI_TYPE_METHOD);
531 if (!method_obj) {
532 ACPI_FREE(aml_buffer);
533 return (AE_NO_MEMORY);
534 }
535
536
537
538 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
539 if (ACPI_FAILURE(status)) {
540 goto error_exit;
541 }
542
543
544
545 status =
546 acpi_ns_lookup(NULL, path, ACPI_TYPE_METHOD, ACPI_IMODE_LOAD_PASS1,
547 ACPI_NS_DONT_OPEN_SCOPE | ACPI_NS_ERROR_IF_FOUND,
548 NULL, &node);
549
550 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
551
552 if (ACPI_FAILURE(status)) {
553 if (status != AE_ALREADY_EXISTS) {
554 goto error_exit;
555 }
556
557
558
559 if (node->type != ACPI_TYPE_METHOD) {
560 status = AE_TYPE;
561 goto error_exit;
562 }
563 }
564
565
566
567 memcpy(aml_buffer, aml_start, aml_length);
568
569
570
571 method_obj->method.aml_start = aml_buffer;
572 method_obj->method.aml_length = aml_length;
573
574 method_obj->method.param_count = (u8)
575 (method_flags & AML_METHOD_ARG_COUNT);
576
577 if (method_flags & AML_METHOD_SERIALIZED) {
578 method_obj->method.info_flags = ACPI_METHOD_SERIALIZED;
579
580 method_obj->method.sync_level = (u8)
581 ((method_flags & AML_METHOD_SYNC_LEVEL) >> 4);
582 }
583
584
585
586
587
588 status = acpi_ns_attach_object(node, method_obj, ACPI_TYPE_METHOD);
589
590
591
592
593
594 node->flags |= ANOBJ_ALLOCATED_BUFFER;
595
596
597
598 acpi_ut_remove_reference(method_obj);
599 return (status);
600
601 error_exit:
602
603 ACPI_FREE(aml_buffer);
604 ACPI_FREE(method_obj);
605 return (status);
606 }
607 ACPI_EXPORT_SYMBOL(acpi_install_method)