0001
0002
0003
0004
0005
0006
0007
0008 #include <acpi/acpi.h>
0009 #include "accommon.h"
0010 #include "acresrc.h"
0011 #include "acnamesp.h"
0012
0013 #define _COMPONENT ACPI_RESOURCES
0014 ACPI_MODULE_NAME("rscreate")
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029 acpi_status
0030 acpi_buffer_to_resource(u8 *aml_buffer,
0031 u16 aml_buffer_length,
0032 struct acpi_resource **resource_ptr)
0033 {
0034 acpi_status status;
0035 acpi_size list_size_needed;
0036 void *resource;
0037 void *current_resource_ptr;
0038
0039 ACPI_FUNCTION_TRACE(acpi_buffer_to_resource);
0040
0041
0042
0043
0044
0045
0046
0047
0048 status =
0049 acpi_rs_get_list_length(aml_buffer, aml_buffer_length,
0050 &list_size_needed);
0051 if (status == AE_AML_NO_RESOURCE_END_TAG) {
0052 status = AE_OK;
0053 }
0054 if (ACPI_FAILURE(status)) {
0055 return_ACPI_STATUS(status);
0056 }
0057
0058
0059
0060 resource = ACPI_ALLOCATE_ZEROED(list_size_needed);
0061 current_resource_ptr = resource;
0062 if (!resource) {
0063 return_ACPI_STATUS(AE_NO_MEMORY);
0064 }
0065
0066
0067
0068 status = acpi_ut_walk_aml_resources(NULL, aml_buffer, aml_buffer_length,
0069 acpi_rs_convert_aml_to_resources,
0070 ¤t_resource_ptr);
0071 if (status == AE_AML_NO_RESOURCE_END_TAG) {
0072 status = AE_OK;
0073 }
0074 if (ACPI_FAILURE(status)) {
0075 ACPI_FREE(resource);
0076 } else {
0077 *resource_ptr = resource;
0078 }
0079
0080 return_ACPI_STATUS(status);
0081 }
0082
0083 ACPI_EXPORT_SYMBOL(acpi_buffer_to_resource)
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102 acpi_status
0103 acpi_rs_create_resource_list(union acpi_operand_object *aml_buffer,
0104 struct acpi_buffer *output_buffer)
0105 {
0106
0107 acpi_status status;
0108 u8 *aml_start;
0109 acpi_size list_size_needed = 0;
0110 u32 aml_buffer_length;
0111 void *resource;
0112
0113 ACPI_FUNCTION_TRACE(rs_create_resource_list);
0114
0115 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "AmlBuffer = %p\n", aml_buffer));
0116
0117
0118
0119 aml_buffer_length = aml_buffer->buffer.length;
0120 aml_start = aml_buffer->buffer.pointer;
0121
0122
0123
0124
0125
0126 status = acpi_rs_get_list_length(aml_start, aml_buffer_length,
0127 &list_size_needed);
0128
0129 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Status=%X ListSizeNeeded=%X\n",
0130 status, (u32) list_size_needed));
0131 if (ACPI_FAILURE(status)) {
0132 return_ACPI_STATUS(status);
0133 }
0134
0135
0136
0137 status = acpi_ut_initialize_buffer(output_buffer, list_size_needed);
0138 if (ACPI_FAILURE(status)) {
0139 return_ACPI_STATUS(status);
0140 }
0141
0142
0143
0144 resource = output_buffer->pointer;
0145 status = acpi_ut_walk_aml_resources(NULL, aml_start, aml_buffer_length,
0146 acpi_rs_convert_aml_to_resources,
0147 &resource);
0148 if (ACPI_FAILURE(status)) {
0149 return_ACPI_STATUS(status);
0150 }
0151
0152 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "OutputBuffer %p Length %X\n",
0153 output_buffer->pointer, (u32) output_buffer->length));
0154 return_ACPI_STATUS(AE_OK);
0155 }
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178 acpi_status
0179 acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
0180 struct acpi_buffer *output_buffer)
0181 {
0182 u8 *buffer;
0183 union acpi_operand_object **top_object_list;
0184 union acpi_operand_object **sub_object_list;
0185 union acpi_operand_object *obj_desc;
0186 acpi_size buffer_size_needed = 0;
0187 u32 number_of_elements;
0188 u32 index;
0189 struct acpi_pci_routing_table *user_prt;
0190 struct acpi_namespace_node *node;
0191 acpi_status status;
0192 struct acpi_buffer path_buffer;
0193
0194 ACPI_FUNCTION_TRACE(rs_create_pci_routing_table);
0195
0196
0197
0198
0199
0200 status =
0201 acpi_rs_get_pci_routing_table_length(package_object,
0202 &buffer_size_needed);
0203 if (ACPI_FAILURE(status)) {
0204 return_ACPI_STATUS(status);
0205 }
0206
0207 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "BufferSizeNeeded = %X\n",
0208 (u32) buffer_size_needed));
0209
0210
0211
0212 status = acpi_ut_initialize_buffer(output_buffer, buffer_size_needed);
0213 if (ACPI_FAILURE(status)) {
0214 return_ACPI_STATUS(status);
0215 }
0216
0217
0218
0219
0220
0221
0222 top_object_list = package_object->package.elements;
0223 number_of_elements = package_object->package.count;
0224 buffer = output_buffer->pointer;
0225 user_prt = ACPI_CAST_PTR(struct acpi_pci_routing_table, buffer);
0226
0227 for (index = 0; index < number_of_elements; index++) {
0228
0229
0230
0231
0232
0233
0234
0235 buffer += user_prt->length;
0236 user_prt = ACPI_CAST_PTR(struct acpi_pci_routing_table, buffer);
0237
0238
0239
0240
0241
0242
0243 user_prt->length = (sizeof(struct acpi_pci_routing_table) - 4);
0244
0245
0246
0247 if ((*top_object_list)->package.count != 4) {
0248 ACPI_ERROR((AE_INFO,
0249 "(PRT[%u]) Need package of length 4, found length %u",
0250 index, (*top_object_list)->package.count));
0251 return_ACPI_STATUS(AE_AML_PACKAGE_LIMIT);
0252 }
0253
0254
0255
0256
0257
0258
0259 sub_object_list = (*top_object_list)->package.elements;
0260
0261
0262
0263 obj_desc = sub_object_list[0];
0264 if (!obj_desc || obj_desc->common.type != ACPI_TYPE_INTEGER) {
0265 ACPI_ERROR((AE_INFO,
0266 "(PRT[%u].Address) Need Integer, found %s",
0267 index,
0268 acpi_ut_get_object_type_name(obj_desc)));
0269 return_ACPI_STATUS(AE_BAD_DATA);
0270 }
0271
0272 user_prt->address = obj_desc->integer.value;
0273
0274
0275
0276 obj_desc = sub_object_list[1];
0277 if (!obj_desc || obj_desc->common.type != ACPI_TYPE_INTEGER) {
0278 ACPI_ERROR((AE_INFO,
0279 "(PRT[%u].Pin) Need Integer, found %s",
0280 index,
0281 acpi_ut_get_object_type_name(obj_desc)));
0282 return_ACPI_STATUS(AE_BAD_DATA);
0283 }
0284
0285 user_prt->pin = (u32) obj_desc->integer.value;
0286
0287
0288
0289
0290
0291 obj_desc = sub_object_list[2];
0292 if (obj_desc) {
0293 switch (obj_desc->common.type) {
0294 case ACPI_TYPE_LOCAL_REFERENCE:
0295
0296 if (obj_desc->reference.class !=
0297 ACPI_REFCLASS_NAME) {
0298 ACPI_ERROR((AE_INFO,
0299 "(PRT[%u].Source) Need name, found Reference Class 0x%X",
0300 index,
0301 obj_desc->reference.class));
0302 return_ACPI_STATUS(AE_BAD_DATA);
0303 }
0304
0305 node = obj_desc->reference.node;
0306
0307
0308
0309 path_buffer.length = output_buffer->length -
0310 (u32) ((u8 *) user_prt->source -
0311 (u8 *) output_buffer->pointer);
0312 path_buffer.pointer = user_prt->source;
0313
0314 status = acpi_ns_handle_to_pathname((acpi_handle)node, &path_buffer, FALSE);
0315 if (ACPI_FAILURE(status)) {
0316 return_ACPI_STATUS(status);
0317 }
0318
0319
0320
0321 user_prt->length +=
0322 (u32)strlen(user_prt->source) + 1;
0323 break;
0324
0325 case ACPI_TYPE_STRING:
0326
0327 strcpy(user_prt->source,
0328 obj_desc->string.pointer);
0329
0330
0331
0332
0333
0334 user_prt->length += obj_desc->string.length + 1;
0335 break;
0336
0337 case ACPI_TYPE_INTEGER:
0338
0339
0340
0341
0342
0343
0344 user_prt->length += sizeof(u32);
0345 break;
0346
0347 default:
0348
0349 ACPI_ERROR((AE_INFO,
0350 "(PRT[%u].Source) Need Ref/String/Integer, found %s",
0351 index,
0352 acpi_ut_get_object_type_name
0353 (obj_desc)));
0354 return_ACPI_STATUS(AE_BAD_DATA);
0355 }
0356 }
0357
0358
0359
0360 user_prt->length =
0361 (u32) ACPI_ROUND_UP_TO_64BIT(user_prt->length);
0362
0363
0364
0365 obj_desc = sub_object_list[3];
0366 if (!obj_desc || obj_desc->common.type != ACPI_TYPE_INTEGER) {
0367 ACPI_ERROR((AE_INFO,
0368 "(PRT[%u].SourceIndex) Need Integer, found %s",
0369 index,
0370 acpi_ut_get_object_type_name(obj_desc)));
0371 return_ACPI_STATUS(AE_BAD_DATA);
0372 }
0373
0374 user_prt->source_index = (u32) obj_desc->integer.value;
0375
0376
0377
0378 top_object_list++;
0379 }
0380
0381 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "OutputBuffer %p Length %X\n",
0382 output_buffer->pointer, (u32) output_buffer->length));
0383 return_ACPI_STATUS(AE_OK);
0384 }
0385
0386
0387
0388
0389
0390
0391
0392
0393
0394
0395
0396
0397
0398
0399
0400
0401
0402
0403 acpi_status
0404 acpi_rs_create_aml_resources(struct acpi_buffer *resource_list,
0405 struct acpi_buffer *output_buffer)
0406 {
0407 acpi_status status;
0408 acpi_size aml_size_needed = 0;
0409
0410 ACPI_FUNCTION_TRACE(rs_create_aml_resources);
0411
0412
0413
0414 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "ResourceList Buffer = %p\n",
0415 resource_list->pointer));
0416
0417
0418
0419 status =
0420 acpi_rs_get_aml_length(resource_list->pointer,
0421 resource_list->length, &aml_size_needed);
0422
0423 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "AmlSizeNeeded=%X, %s\n",
0424 (u32)aml_size_needed, acpi_format_exception(status)));
0425 if (ACPI_FAILURE(status)) {
0426 return_ACPI_STATUS(status);
0427 }
0428
0429
0430
0431 status = acpi_ut_initialize_buffer(output_buffer, aml_size_needed);
0432 if (ACPI_FAILURE(status)) {
0433 return_ACPI_STATUS(status);
0434 }
0435
0436
0437
0438 status = acpi_rs_convert_resources_to_aml(resource_list->pointer,
0439 aml_size_needed,
0440 output_buffer->pointer);
0441 if (ACPI_FAILURE(status)) {
0442 return_ACPI_STATUS(status);
0443 }
0444
0445 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "OutputBuffer %p Length %X\n",
0446 output_buffer->pointer, (u32) output_buffer->length));
0447 return_ACPI_STATUS(AE_OK);
0448 }