0001
0002
0003
0004
0005
0006
0007
0008 #define EXPORT_ACPI_INTERFACES
0009
0010 #include <acpi/acpi.h>
0011 #include "accommon.h"
0012 #include "acresrc.h"
0013 #include "acnamesp.h"
0014
0015 #define _COMPONENT ACPI_RESOURCES
0016 ACPI_MODULE_NAME("rsxface")
0017
0018
0019 #define ACPI_COPY_FIELD(out, in, field) ((out)->field = (in)->field)
0020 #define ACPI_COPY_ADDRESS(out, in) \
0021 ACPI_COPY_FIELD(out, in, resource_type); \
0022 ACPI_COPY_FIELD(out, in, producer_consumer); \
0023 ACPI_COPY_FIELD(out, in, decode); \
0024 ACPI_COPY_FIELD(out, in, min_address_fixed); \
0025 ACPI_COPY_FIELD(out, in, max_address_fixed); \
0026 ACPI_COPY_FIELD(out, in, info); \
0027 ACPI_COPY_FIELD(out, in, address.granularity); \
0028 ACPI_COPY_FIELD(out, in, address.minimum); \
0029 ACPI_COPY_FIELD(out, in, address.maximum); \
0030 ACPI_COPY_FIELD(out, in, address.translation_offset); \
0031 ACPI_COPY_FIELD(out, in, address.address_length); \
0032 ACPI_COPY_FIELD(out, in, resource_source);
0033
0034 static acpi_status
0035 acpi_rs_match_vendor_resource(struct acpi_resource *resource, void *context);
0036
0037 static acpi_status
0038 acpi_rs_validate_parameters(acpi_handle device_handle,
0039 struct acpi_buffer *buffer,
0040 struct acpi_namespace_node **return_node);
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056 static acpi_status
0057 acpi_rs_validate_parameters(acpi_handle device_handle,
0058 struct acpi_buffer *buffer,
0059 struct acpi_namespace_node **return_node)
0060 {
0061 acpi_status status;
0062 struct acpi_namespace_node *node;
0063
0064 ACPI_FUNCTION_TRACE(rs_validate_parameters);
0065
0066
0067
0068
0069 if (!device_handle) {
0070 return_ACPI_STATUS(AE_BAD_PARAMETER);
0071 }
0072
0073 node = acpi_ns_validate_handle(device_handle);
0074 if (!node) {
0075 return_ACPI_STATUS(AE_BAD_PARAMETER);
0076 }
0077
0078 if (node->type != ACPI_TYPE_DEVICE) {
0079 return_ACPI_STATUS(AE_TYPE);
0080 }
0081
0082
0083
0084
0085
0086
0087
0088
0089 status = acpi_ut_validate_buffer(buffer);
0090 if (ACPI_FAILURE(status)) {
0091 return_ACPI_STATUS(status);
0092 }
0093
0094 *return_node = node;
0095 return_ACPI_STATUS(AE_OK);
0096 }
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121 acpi_status
0122 acpi_get_irq_routing_table(acpi_handle device_handle,
0123 struct acpi_buffer *ret_buffer)
0124 {
0125 acpi_status status;
0126 struct acpi_namespace_node *node;
0127
0128 ACPI_FUNCTION_TRACE(acpi_get_irq_routing_table);
0129
0130
0131
0132 status = acpi_rs_validate_parameters(device_handle, ret_buffer, &node);
0133 if (ACPI_FAILURE(status)) {
0134 return_ACPI_STATUS(status);
0135 }
0136
0137 status = acpi_rs_get_prt_method_data(node, ret_buffer);
0138 return_ACPI_STATUS(status);
0139 }
0140
0141 ACPI_EXPORT_SYMBOL(acpi_get_irq_routing_table)
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166 acpi_status
0167 acpi_get_current_resources(acpi_handle device_handle,
0168 struct acpi_buffer *ret_buffer)
0169 {
0170 acpi_status status;
0171 struct acpi_namespace_node *node;
0172
0173 ACPI_FUNCTION_TRACE(acpi_get_current_resources);
0174
0175
0176
0177 status = acpi_rs_validate_parameters(device_handle, ret_buffer, &node);
0178 if (ACPI_FAILURE(status)) {
0179 return_ACPI_STATUS(status);
0180 }
0181
0182 status = acpi_rs_get_crs_method_data(node, ret_buffer);
0183 return_ACPI_STATUS(status);
0184 }
0185
0186 ACPI_EXPORT_SYMBOL(acpi_get_current_resources)
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208 acpi_status
0209 acpi_get_possible_resources(acpi_handle device_handle,
0210 struct acpi_buffer *ret_buffer)
0211 {
0212 acpi_status status;
0213 struct acpi_namespace_node *node;
0214
0215 ACPI_FUNCTION_TRACE(acpi_get_possible_resources);
0216
0217
0218
0219 status = acpi_rs_validate_parameters(device_handle, ret_buffer, &node);
0220 if (ACPI_FAILURE(status)) {
0221 return_ACPI_STATUS(status);
0222 }
0223
0224 status = acpi_rs_get_prs_method_data(node, ret_buffer);
0225 return_ACPI_STATUS(status);
0226 }
0227
0228 ACPI_EXPORT_SYMBOL(acpi_get_possible_resources)
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247 acpi_status
0248 acpi_set_current_resources(acpi_handle device_handle,
0249 struct acpi_buffer *in_buffer)
0250 {
0251 acpi_status status;
0252 struct acpi_namespace_node *node;
0253
0254 ACPI_FUNCTION_TRACE(acpi_set_current_resources);
0255
0256
0257
0258 if ((!in_buffer) || (!in_buffer->pointer) || (!in_buffer->length)) {
0259 return_ACPI_STATUS(AE_BAD_PARAMETER);
0260 }
0261
0262
0263
0264 status = acpi_rs_validate_parameters(device_handle, in_buffer, &node);
0265 if (ACPI_FAILURE(status)) {
0266 return_ACPI_STATUS(status);
0267 }
0268
0269 status = acpi_rs_set_srs_method_data(node, in_buffer);
0270 return_ACPI_STATUS(status);
0271 }
0272
0273 ACPI_EXPORT_SYMBOL(acpi_set_current_resources)
0274
0275
0276
0277
0278
0279
0280
0281
0282
0283
0284
0285
0286
0287
0288
0289
0290
0291
0292
0293 acpi_status
0294 acpi_get_event_resources(acpi_handle device_handle,
0295 struct acpi_buffer *ret_buffer)
0296 {
0297 acpi_status status;
0298 struct acpi_namespace_node *node;
0299
0300 ACPI_FUNCTION_TRACE(acpi_get_event_resources);
0301
0302
0303
0304 status = acpi_rs_validate_parameters(device_handle, ret_buffer, &node);
0305 if (ACPI_FAILURE(status)) {
0306 return_ACPI_STATUS(status);
0307 }
0308
0309 status = acpi_rs_get_aei_method_data(node, ret_buffer);
0310 return_ACPI_STATUS(status);
0311 }
0312
0313 ACPI_EXPORT_SYMBOL(acpi_get_event_resources)
0314
0315
0316
0317
0318
0319
0320
0321
0322
0323
0324
0325
0326
0327
0328
0329
0330
0331 acpi_status
0332 acpi_resource_to_address64(struct acpi_resource *resource,
0333 struct acpi_resource_address64 *out)
0334 {
0335 struct acpi_resource_address16 *address16;
0336 struct acpi_resource_address32 *address32;
0337
0338 if (!resource || !out) {
0339 return (AE_BAD_PARAMETER);
0340 }
0341
0342
0343
0344 switch (resource->type) {
0345 case ACPI_RESOURCE_TYPE_ADDRESS16:
0346
0347 address16 =
0348 ACPI_CAST_PTR(struct acpi_resource_address16,
0349 &resource->data);
0350 ACPI_COPY_ADDRESS(out, address16);
0351 break;
0352
0353 case ACPI_RESOURCE_TYPE_ADDRESS32:
0354
0355 address32 =
0356 ACPI_CAST_PTR(struct acpi_resource_address32,
0357 &resource->data);
0358 ACPI_COPY_ADDRESS(out, address32);
0359 break;
0360
0361 case ACPI_RESOURCE_TYPE_ADDRESS64:
0362
0363
0364
0365 memcpy(out, &resource->data,
0366 sizeof(struct acpi_resource_address64));
0367 break;
0368
0369 default:
0370
0371 return (AE_BAD_PARAMETER);
0372 }
0373
0374 return (AE_OK);
0375 }
0376
0377 ACPI_EXPORT_SYMBOL(acpi_resource_to_address64)
0378
0379
0380
0381
0382
0383
0384
0385
0386
0387
0388
0389
0390
0391
0392
0393
0394
0395
0396
0397 acpi_status
0398 acpi_get_vendor_resource(acpi_handle device_handle,
0399 char *name,
0400 struct acpi_vendor_uuid *uuid,
0401 struct acpi_buffer *ret_buffer)
0402 {
0403 struct acpi_vendor_walk_info info;
0404 acpi_status status;
0405
0406
0407
0408 if (!uuid || !ret_buffer) {
0409 return (AE_BAD_PARAMETER);
0410 }
0411
0412 info.uuid = uuid;
0413 info.buffer = ret_buffer;
0414 info.status = AE_NOT_EXIST;
0415
0416
0417
0418 status =
0419 acpi_walk_resources(device_handle, name,
0420 acpi_rs_match_vendor_resource, &info);
0421 if (ACPI_FAILURE(status)) {
0422 return (status);
0423 }
0424
0425 return (info.status);
0426 }
0427
0428 ACPI_EXPORT_SYMBOL(acpi_get_vendor_resource)
0429
0430
0431
0432
0433
0434
0435
0436
0437
0438
0439
0440
0441 static acpi_status
0442 acpi_rs_match_vendor_resource(struct acpi_resource *resource, void *context)
0443 {
0444 struct acpi_vendor_walk_info *info = context;
0445 struct acpi_resource_vendor_typed *vendor;
0446 struct acpi_buffer *buffer;
0447 acpi_status status;
0448
0449
0450
0451 if (resource->type != ACPI_RESOURCE_TYPE_VENDOR) {
0452 return (AE_OK);
0453 }
0454
0455 vendor = &resource->data.vendor_typed;
0456
0457
0458
0459
0460
0461
0462
0463
0464 if ((vendor->byte_length < (ACPI_UUID_LENGTH + 1)) ||
0465 (vendor->uuid_subtype != info->uuid->subtype) ||
0466 (memcmp(vendor->uuid, info->uuid->data, ACPI_UUID_LENGTH))) {
0467 return (AE_OK);
0468 }
0469
0470
0471
0472 buffer = info->buffer;
0473 status = acpi_ut_initialize_buffer(buffer, resource->length);
0474 if (ACPI_FAILURE(status)) {
0475 return (status);
0476 }
0477
0478
0479
0480 memcpy(buffer->pointer, resource, resource->length);
0481 buffer->length = resource->length;
0482
0483
0484
0485 info->status = AE_OK;
0486 return (AE_CTRL_TERMINATE);
0487 }
0488
0489
0490
0491
0492
0493
0494
0495
0496
0497
0498
0499
0500
0501
0502
0503
0504
0505 acpi_status
0506 acpi_walk_resource_buffer(struct acpi_buffer *buffer,
0507 acpi_walk_resource_callback user_function,
0508 void *context)
0509 {
0510 acpi_status status = AE_OK;
0511 struct acpi_resource *resource;
0512 struct acpi_resource *resource_end;
0513
0514 ACPI_FUNCTION_TRACE(acpi_walk_resource_buffer);
0515
0516
0517
0518 if (!buffer || !buffer->pointer || !user_function) {
0519 return_ACPI_STATUS(AE_BAD_PARAMETER);
0520 }
0521
0522
0523
0524 resource = ACPI_CAST_PTR(struct acpi_resource, buffer->pointer);
0525 resource_end =
0526 ACPI_ADD_PTR(struct acpi_resource, buffer->pointer, buffer->length);
0527
0528
0529
0530 while (resource < resource_end) {
0531
0532
0533
0534 if (resource->type > ACPI_RESOURCE_TYPE_MAX) {
0535 status = AE_AML_INVALID_RESOURCE_TYPE;
0536 break;
0537 }
0538
0539
0540
0541 if (!resource->length) {
0542 return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH);
0543 }
0544
0545
0546
0547 status = user_function(resource, context);
0548 if (ACPI_FAILURE(status)) {
0549 if (status == AE_CTRL_TERMINATE) {
0550
0551
0552
0553 status = AE_OK;
0554 }
0555 break;
0556 }
0557
0558
0559
0560 if (resource->type == ACPI_RESOURCE_TYPE_END_TAG) {
0561 break;
0562 }
0563
0564
0565
0566 resource = ACPI_NEXT_RESOURCE(resource);
0567 }
0568
0569 return_ACPI_STATUS(status);
0570 }
0571
0572 ACPI_EXPORT_SYMBOL(acpi_walk_resource_buffer)
0573
0574
0575
0576
0577
0578
0579
0580
0581
0582
0583
0584
0585
0586
0587
0588
0589
0590
0591
0592
0593 acpi_status
0594 acpi_walk_resources(acpi_handle device_handle,
0595 char *name,
0596 acpi_walk_resource_callback user_function, void *context)
0597 {
0598 acpi_status status;
0599 struct acpi_buffer buffer;
0600
0601 ACPI_FUNCTION_TRACE(acpi_walk_resources);
0602
0603
0604
0605 if (!device_handle || !user_function || !name ||
0606 (!ACPI_COMPARE_NAMESEG(name, METHOD_NAME__CRS) &&
0607 !ACPI_COMPARE_NAMESEG(name, METHOD_NAME__PRS) &&
0608 !ACPI_COMPARE_NAMESEG(name, METHOD_NAME__AEI) &&
0609 !ACPI_COMPARE_NAMESEG(name, METHOD_NAME__DMA))) {
0610 return_ACPI_STATUS(AE_BAD_PARAMETER);
0611 }
0612
0613
0614
0615 buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
0616 status = acpi_rs_get_method_data(device_handle, name, &buffer);
0617 if (ACPI_FAILURE(status)) {
0618 return_ACPI_STATUS(status);
0619 }
0620
0621
0622
0623 status = acpi_walk_resource_buffer(&buffer, user_function, context);
0624 ACPI_FREE(buffer.pointer);
0625 return_ACPI_STATUS(status);
0626 }
0627
0628 ACPI_EXPORT_SYMBOL(acpi_walk_resources)