1
2
3
4
5
6
7
8#define EXPORT_ACPI_INTERFACES
9
10#include <acpi/acpi.h>
11#include "accommon.h"
12#include "acresrc.h"
13#include "acnamesp.h"
14
15#define _COMPONENT ACPI_RESOURCES
16ACPI_MODULE_NAME("rsxface")
17
18
19#define ACPI_COPY_FIELD(out, in, field) ((out)->field = (in)->field)
20#define ACPI_COPY_ADDRESS(out, in) \
21 ACPI_COPY_FIELD(out, in, resource_type); \
22 ACPI_COPY_FIELD(out, in, producer_consumer); \
23 ACPI_COPY_FIELD(out, in, decode); \
24 ACPI_COPY_FIELD(out, in, min_address_fixed); \
25 ACPI_COPY_FIELD(out, in, max_address_fixed); \
26 ACPI_COPY_FIELD(out, in, info); \
27 ACPI_COPY_FIELD(out, in, address.granularity); \
28 ACPI_COPY_FIELD(out, in, address.minimum); \
29 ACPI_COPY_FIELD(out, in, address.maximum); \
30 ACPI_COPY_FIELD(out, in, address.translation_offset); \
31 ACPI_COPY_FIELD(out, in, address.address_length); \
32 ACPI_COPY_FIELD(out, in, resource_source);
33
34static acpi_status
35acpi_rs_match_vendor_resource(struct acpi_resource *resource, void *context);
36
37static acpi_status
38acpi_rs_validate_parameters(acpi_handle device_handle,
39 struct acpi_buffer *buffer,
40 struct acpi_namespace_node **return_node);
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56static acpi_status
57acpi_rs_validate_parameters(acpi_handle device_handle,
58 struct acpi_buffer *buffer,
59 struct acpi_namespace_node **return_node)
60{
61 acpi_status status;
62 struct acpi_namespace_node *node;
63
64 ACPI_FUNCTION_TRACE(rs_validate_parameters);
65
66
67
68
69 if (!device_handle) {
70 return_ACPI_STATUS(AE_BAD_PARAMETER);
71 }
72
73 node = acpi_ns_validate_handle(device_handle);
74 if (!node) {
75 return_ACPI_STATUS(AE_BAD_PARAMETER);
76 }
77
78 if (node->type != ACPI_TYPE_DEVICE) {
79 return_ACPI_STATUS(AE_TYPE);
80 }
81
82
83
84
85
86
87
88
89 status = acpi_ut_validate_buffer(buffer);
90 if (ACPI_FAILURE(status)) {
91 return_ACPI_STATUS(status);
92 }
93
94 *return_node = node;
95 return_ACPI_STATUS(AE_OK);
96}
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121acpi_status
122acpi_get_irq_routing_table(acpi_handle device_handle,
123 struct acpi_buffer *ret_buffer)
124{
125 acpi_status status;
126 struct acpi_namespace_node *node;
127
128 ACPI_FUNCTION_TRACE(acpi_get_irq_routing_table);
129
130
131
132 status = acpi_rs_validate_parameters(device_handle, ret_buffer, &node);
133 if (ACPI_FAILURE(status)) {
134 return_ACPI_STATUS(status);
135 }
136
137 status = acpi_rs_get_prt_method_data(node, ret_buffer);
138 return_ACPI_STATUS(status);
139}
140
141ACPI_EXPORT_SYMBOL(acpi_get_irq_routing_table)
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166acpi_status
167acpi_get_current_resources(acpi_handle device_handle,
168 struct acpi_buffer *ret_buffer)
169{
170 acpi_status status;
171 struct acpi_namespace_node *node;
172
173 ACPI_FUNCTION_TRACE(acpi_get_current_resources);
174
175
176
177 status = acpi_rs_validate_parameters(device_handle, ret_buffer, &node);
178 if (ACPI_FAILURE(status)) {
179 return_ACPI_STATUS(status);
180 }
181
182 status = acpi_rs_get_crs_method_data(node, ret_buffer);
183 return_ACPI_STATUS(status);
184}
185
186ACPI_EXPORT_SYMBOL(acpi_get_current_resources)
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208acpi_status
209acpi_get_possible_resources(acpi_handle device_handle,
210 struct acpi_buffer *ret_buffer)
211{
212 acpi_status status;
213 struct acpi_namespace_node *node;
214
215 ACPI_FUNCTION_TRACE(acpi_get_possible_resources);
216
217
218
219 status = acpi_rs_validate_parameters(device_handle, ret_buffer, &node);
220 if (ACPI_FAILURE(status)) {
221 return_ACPI_STATUS(status);
222 }
223
224 status = acpi_rs_get_prs_method_data(node, ret_buffer);
225 return_ACPI_STATUS(status);
226}
227
228ACPI_EXPORT_SYMBOL(acpi_get_possible_resources)
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247acpi_status
248acpi_set_current_resources(acpi_handle device_handle,
249 struct acpi_buffer *in_buffer)
250{
251 acpi_status status;
252 struct acpi_namespace_node *node;
253
254 ACPI_FUNCTION_TRACE(acpi_set_current_resources);
255
256
257
258 if ((!in_buffer) || (!in_buffer->pointer) || (!in_buffer->length)) {
259 return_ACPI_STATUS(AE_BAD_PARAMETER);
260 }
261
262
263
264 status = acpi_rs_validate_parameters(device_handle, in_buffer, &node);
265 if (ACPI_FAILURE(status)) {
266 return_ACPI_STATUS(status);
267 }
268
269 status = acpi_rs_set_srs_method_data(node, in_buffer);
270 return_ACPI_STATUS(status);
271}
272
273ACPI_EXPORT_SYMBOL(acpi_set_current_resources)
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293acpi_status
294acpi_get_event_resources(acpi_handle device_handle,
295 struct acpi_buffer *ret_buffer)
296{
297 acpi_status status;
298 struct acpi_namespace_node *node;
299
300 ACPI_FUNCTION_TRACE(acpi_get_event_resources);
301
302
303
304 status = acpi_rs_validate_parameters(device_handle, ret_buffer, &node);
305 if (ACPI_FAILURE(status)) {
306 return_ACPI_STATUS(status);
307 }
308
309 status = acpi_rs_get_aei_method_data(node, ret_buffer);
310 return_ACPI_STATUS(status);
311}
312
313ACPI_EXPORT_SYMBOL(acpi_get_event_resources)
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331acpi_status
332acpi_resource_to_address64(struct acpi_resource *resource,
333 struct acpi_resource_address64 *out)
334{
335 struct acpi_resource_address16 *address16;
336 struct acpi_resource_address32 *address32;
337
338 if (!resource || !out) {
339 return (AE_BAD_PARAMETER);
340 }
341
342
343
344 switch (resource->type) {
345 case ACPI_RESOURCE_TYPE_ADDRESS16:
346
347 address16 =
348 ACPI_CAST_PTR(struct acpi_resource_address16,
349 &resource->data);
350 ACPI_COPY_ADDRESS(out, address16);
351 break;
352
353 case ACPI_RESOURCE_TYPE_ADDRESS32:
354
355 address32 =
356 ACPI_CAST_PTR(struct acpi_resource_address32,
357 &resource->data);
358 ACPI_COPY_ADDRESS(out, address32);
359 break;
360
361 case ACPI_RESOURCE_TYPE_ADDRESS64:
362
363
364
365 memcpy(out, &resource->data,
366 sizeof(struct acpi_resource_address64));
367 break;
368
369 default:
370
371 return (AE_BAD_PARAMETER);
372 }
373
374 return (AE_OK);
375}
376
377ACPI_EXPORT_SYMBOL(acpi_resource_to_address64)
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397acpi_status
398acpi_get_vendor_resource(acpi_handle device_handle,
399 char *name,
400 struct acpi_vendor_uuid *uuid,
401 struct acpi_buffer *ret_buffer)
402{
403 struct acpi_vendor_walk_info info;
404 acpi_status status;
405
406
407
408 if (!uuid || !ret_buffer) {
409 return (AE_BAD_PARAMETER);
410 }
411
412 info.uuid = uuid;
413 info.buffer = ret_buffer;
414 info.status = AE_NOT_EXIST;
415
416
417
418 status =
419 acpi_walk_resources(device_handle, name,
420 acpi_rs_match_vendor_resource, &info);
421 if (ACPI_FAILURE(status)) {
422 return (status);
423 }
424
425 return (info.status);
426}
427
428ACPI_EXPORT_SYMBOL(acpi_get_vendor_resource)
429
430
431
432
433
434
435
436
437
438
439
440
441static acpi_status
442acpi_rs_match_vendor_resource(struct acpi_resource *resource, void *context)
443{
444 struct acpi_vendor_walk_info *info = context;
445 struct acpi_resource_vendor_typed *vendor;
446 struct acpi_buffer *buffer;
447 acpi_status status;
448
449
450
451 if (resource->type != ACPI_RESOURCE_TYPE_VENDOR) {
452 return (AE_OK);
453 }
454
455 vendor = &resource->data.vendor_typed;
456
457
458
459
460
461
462
463
464 if ((vendor->byte_length < (ACPI_UUID_LENGTH + 1)) ||
465 (vendor->uuid_subtype != info->uuid->subtype) ||
466 (memcmp(vendor->uuid, info->uuid->data, ACPI_UUID_LENGTH))) {
467 return (AE_OK);
468 }
469
470
471
472 buffer = info->buffer;
473 status = acpi_ut_initialize_buffer(buffer, resource->length);
474 if (ACPI_FAILURE(status)) {
475 return (status);
476 }
477
478
479
480 memcpy(buffer->pointer, resource, resource->length);
481 buffer->length = resource->length;
482
483
484
485 info->status = AE_OK;
486 return (AE_CTRL_TERMINATE);
487}
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505acpi_status
506acpi_walk_resource_buffer(struct acpi_buffer *buffer,
507 acpi_walk_resource_callback user_function,
508 void *context)
509{
510 acpi_status status = AE_OK;
511 struct acpi_resource *resource;
512 struct acpi_resource *resource_end;
513
514 ACPI_FUNCTION_TRACE(acpi_walk_resource_buffer);
515
516
517
518 if (!buffer || !buffer->pointer || !user_function) {
519 return_ACPI_STATUS(AE_BAD_PARAMETER);
520 }
521
522
523
524 resource = ACPI_CAST_PTR(struct acpi_resource, buffer->pointer);
525 resource_end =
526 ACPI_ADD_PTR(struct acpi_resource, buffer->pointer, buffer->length);
527
528
529
530 while (resource < resource_end) {
531
532
533
534 if (resource->type > ACPI_RESOURCE_TYPE_MAX) {
535 status = AE_AML_INVALID_RESOURCE_TYPE;
536 break;
537 }
538
539
540
541 if (!resource->length) {
542 return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH);
543 }
544
545
546
547 status = user_function(resource, context);
548 if (ACPI_FAILURE(status)) {
549 if (status == AE_CTRL_TERMINATE) {
550
551
552
553 status = AE_OK;
554 }
555 break;
556 }
557
558
559
560 if (resource->type == ACPI_RESOURCE_TYPE_END_TAG) {
561 break;
562 }
563
564
565
566 resource = ACPI_NEXT_RESOURCE(resource);
567 }
568
569 return_ACPI_STATUS(status);
570}
571
572ACPI_EXPORT_SYMBOL(acpi_walk_resource_buffer)
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593acpi_status
594acpi_walk_resources(acpi_handle device_handle,
595 char *name,
596 acpi_walk_resource_callback user_function, void *context)
597{
598 acpi_status status;
599 struct acpi_buffer buffer;
600
601 ACPI_FUNCTION_TRACE(acpi_walk_resources);
602
603
604
605 if (!device_handle || !user_function || !name ||
606 (!ACPI_COMPARE_NAMESEG(name, METHOD_NAME__CRS) &&
607 !ACPI_COMPARE_NAMESEG(name, METHOD_NAME__PRS) &&
608 !ACPI_COMPARE_NAMESEG(name, METHOD_NAME__AEI) &&
609 !ACPI_COMPARE_NAMESEG(name, METHOD_NAME__DMA))) {
610 return_ACPI_STATUS(AE_BAD_PARAMETER);
611 }
612
613
614
615 buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
616 status = acpi_rs_get_method_data(device_handle, name, &buffer);
617 if (ACPI_FAILURE(status)) {
618 return_ACPI_STATUS(status);
619 }
620
621
622
623 status = acpi_walk_resource_buffer(&buffer, user_function, context);
624 ACPI_FREE(buffer.pointer);
625 return_ACPI_STATUS(status);
626}
627
628ACPI_EXPORT_SYMBOL(acpi_walk_resources)
629