1
2
3
4
5
6
7
8#include <acpi/acpi.h>
9#include "accommon.h"
10#include "acresrc.h"
11#include "acnamesp.h"
12
13#define _COMPONENT ACPI_RESOURCES
14ACPI_MODULE_NAME("rscreate")
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29acpi_status
30acpi_buffer_to_resource(u8 *aml_buffer,
31 u16 aml_buffer_length,
32 struct acpi_resource **resource_ptr)
33{
34 acpi_status status;
35 acpi_size list_size_needed;
36 void *resource;
37 void *current_resource_ptr;
38
39 ACPI_FUNCTION_TRACE(acpi_buffer_to_resource);
40
41
42
43
44
45
46
47
48 status =
49 acpi_rs_get_list_length(aml_buffer, aml_buffer_length,
50 &list_size_needed);
51 if (status == AE_AML_NO_RESOURCE_END_TAG) {
52 status = AE_OK;
53 }
54 if (ACPI_FAILURE(status)) {
55 return_ACPI_STATUS(status);
56 }
57
58
59
60 resource = ACPI_ALLOCATE_ZEROED(list_size_needed);
61 current_resource_ptr = resource;
62 if (!resource) {
63 return_ACPI_STATUS(AE_NO_MEMORY);
64 }
65
66
67
68 status = acpi_ut_walk_aml_resources(NULL, aml_buffer, aml_buffer_length,
69 acpi_rs_convert_aml_to_resources,
70 ¤t_resource_ptr);
71 if (status == AE_AML_NO_RESOURCE_END_TAG) {
72 status = AE_OK;
73 }
74 if (ACPI_FAILURE(status)) {
75 ACPI_FREE(resource);
76 } else {
77 *resource_ptr = resource;
78 }
79
80 return_ACPI_STATUS(status);
81}
82
83ACPI_EXPORT_SYMBOL(acpi_buffer_to_resource)
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102acpi_status
103acpi_rs_create_resource_list(union acpi_operand_object *aml_buffer,
104 struct acpi_buffer *output_buffer)
105{
106
107 acpi_status status;
108 u8 *aml_start;
109 acpi_size list_size_needed = 0;
110 u32 aml_buffer_length;
111 void *resource;
112
113 ACPI_FUNCTION_TRACE(rs_create_resource_list);
114
115 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "AmlBuffer = %p\n", aml_buffer));
116
117
118
119 aml_buffer_length = aml_buffer->buffer.length;
120 aml_start = aml_buffer->buffer.pointer;
121
122
123
124
125
126 status = acpi_rs_get_list_length(aml_start, aml_buffer_length,
127 &list_size_needed);
128
129 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Status=%X ListSizeNeeded=%X\n",
130 status, (u32) list_size_needed));
131 if (ACPI_FAILURE(status)) {
132 return_ACPI_STATUS(status);
133 }
134
135
136
137 status = acpi_ut_initialize_buffer(output_buffer, list_size_needed);
138 if (ACPI_FAILURE(status)) {
139 return_ACPI_STATUS(status);
140 }
141
142
143
144 resource = output_buffer->pointer;
145 status = acpi_ut_walk_aml_resources(NULL, aml_start, aml_buffer_length,
146 acpi_rs_convert_aml_to_resources,
147 &resource);
148 if (ACPI_FAILURE(status)) {
149 return_ACPI_STATUS(status);
150 }
151
152 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "OutputBuffer %p Length %X\n",
153 output_buffer->pointer, (u32) output_buffer->length));
154 return_ACPI_STATUS(AE_OK);
155}
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178acpi_status
179acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
180 struct acpi_buffer *output_buffer)
181{
182 u8 *buffer;
183 union acpi_operand_object **top_object_list;
184 union acpi_operand_object **sub_object_list;
185 union acpi_operand_object *obj_desc;
186 acpi_size buffer_size_needed = 0;
187 u32 number_of_elements;
188 u32 index;
189 struct acpi_pci_routing_table *user_prt;
190 struct acpi_namespace_node *node;
191 acpi_status status;
192 struct acpi_buffer path_buffer;
193
194 ACPI_FUNCTION_TRACE(rs_create_pci_routing_table);
195
196
197
198
199
200 status =
201 acpi_rs_get_pci_routing_table_length(package_object,
202 &buffer_size_needed);
203 if (ACPI_FAILURE(status)) {
204 return_ACPI_STATUS(status);
205 }
206
207 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "BufferSizeNeeded = %X\n",
208 (u32) buffer_size_needed));
209
210
211
212 status = acpi_ut_initialize_buffer(output_buffer, buffer_size_needed);
213 if (ACPI_FAILURE(status)) {
214 return_ACPI_STATUS(status);
215 }
216
217
218
219
220
221
222 top_object_list = package_object->package.elements;
223 number_of_elements = package_object->package.count;
224 buffer = output_buffer->pointer;
225 user_prt = ACPI_CAST_PTR(struct acpi_pci_routing_table, buffer);
226
227 for (index = 0; index < number_of_elements; index++) {
228
229
230
231
232
233
234
235 buffer += user_prt->length;
236 user_prt = ACPI_CAST_PTR(struct acpi_pci_routing_table, buffer);
237
238
239
240
241
242
243 user_prt->length = (sizeof(struct acpi_pci_routing_table) - 4);
244
245
246
247 if ((*top_object_list)->package.count != 4) {
248 ACPI_ERROR((AE_INFO,
249 "(PRT[%u]) Need package of length 4, found length %u",
250 index, (*top_object_list)->package.count));
251 return_ACPI_STATUS(AE_AML_PACKAGE_LIMIT);
252 }
253
254
255
256
257
258
259 sub_object_list = (*top_object_list)->package.elements;
260
261
262
263 obj_desc = sub_object_list[0];
264 if (!obj_desc || obj_desc->common.type != ACPI_TYPE_INTEGER) {
265 ACPI_ERROR((AE_INFO,
266 "(PRT[%u].Address) Need Integer, found %s",
267 index,
268 acpi_ut_get_object_type_name(obj_desc)));
269 return_ACPI_STATUS(AE_BAD_DATA);
270 }
271
272 user_prt->address = obj_desc->integer.value;
273
274
275
276 obj_desc = sub_object_list[1];
277 if (!obj_desc || obj_desc->common.type != ACPI_TYPE_INTEGER) {
278 ACPI_ERROR((AE_INFO,
279 "(PRT[%u].Pin) Need Integer, found %s",
280 index,
281 acpi_ut_get_object_type_name(obj_desc)));
282 return_ACPI_STATUS(AE_BAD_DATA);
283 }
284
285 user_prt->pin = (u32) obj_desc->integer.value;
286
287
288
289
290
291 obj_desc = sub_object_list[2];
292 if (obj_desc) {
293 switch (obj_desc->common.type) {
294 case ACPI_TYPE_LOCAL_REFERENCE:
295
296 if (obj_desc->reference.class !=
297 ACPI_REFCLASS_NAME) {
298 ACPI_ERROR((AE_INFO,
299 "(PRT[%u].Source) Need name, found Reference Class 0x%X",
300 index,
301 obj_desc->reference.class));
302 return_ACPI_STATUS(AE_BAD_DATA);
303 }
304
305 node = obj_desc->reference.node;
306
307
308
309 path_buffer.length = output_buffer->length -
310 (u32) ((u8 *) user_prt->source -
311 (u8 *) output_buffer->pointer);
312 path_buffer.pointer = user_prt->source;
313
314 status = acpi_ns_handle_to_pathname((acpi_handle)node, &path_buffer, FALSE);
315
316
317
318 user_prt->length +=
319 (u32)strlen(user_prt->source) + 1;
320 break;
321
322 case ACPI_TYPE_STRING:
323
324 strcpy(user_prt->source,
325 obj_desc->string.pointer);
326
327
328
329
330
331 user_prt->length += obj_desc->string.length + 1;
332 break;
333
334 case ACPI_TYPE_INTEGER:
335
336
337
338
339
340
341 user_prt->length += sizeof(u32);
342 break;
343
344 default:
345
346 ACPI_ERROR((AE_INFO,
347 "(PRT[%u].Source) Need Ref/String/Integer, found %s",
348 index,
349 acpi_ut_get_object_type_name
350 (obj_desc)));
351 return_ACPI_STATUS(AE_BAD_DATA);
352 }
353 }
354
355
356
357 user_prt->length =
358 (u32) ACPI_ROUND_UP_TO_64BIT(user_prt->length);
359
360
361
362 obj_desc = sub_object_list[3];
363 if (!obj_desc || obj_desc->common.type != ACPI_TYPE_INTEGER) {
364 ACPI_ERROR((AE_INFO,
365 "(PRT[%u].SourceIndex) Need Integer, found %s",
366 index,
367 acpi_ut_get_object_type_name(obj_desc)));
368 return_ACPI_STATUS(AE_BAD_DATA);
369 }
370
371 user_prt->source_index = (u32) obj_desc->integer.value;
372
373
374
375 top_object_list++;
376 }
377
378 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "OutputBuffer %p Length %X\n",
379 output_buffer->pointer, (u32) output_buffer->length));
380 return_ACPI_STATUS(AE_OK);
381}
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400acpi_status
401acpi_rs_create_aml_resources(struct acpi_buffer *resource_list,
402 struct acpi_buffer *output_buffer)
403{
404 acpi_status status;
405 acpi_size aml_size_needed = 0;
406
407 ACPI_FUNCTION_TRACE(rs_create_aml_resources);
408
409
410
411 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "ResourceList Buffer = %p\n",
412 resource_list->pointer));
413
414
415
416 status =
417 acpi_rs_get_aml_length(resource_list->pointer,
418 resource_list->length, &aml_size_needed);
419
420 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "AmlSizeNeeded=%X, %s\n",
421 (u32)aml_size_needed, acpi_format_exception(status)));
422 if (ACPI_FAILURE(status)) {
423 return_ACPI_STATUS(status);
424 }
425
426
427
428 status = acpi_ut_initialize_buffer(output_buffer, aml_size_needed);
429 if (ACPI_FAILURE(status)) {
430 return_ACPI_STATUS(status);
431 }
432
433
434
435 status = acpi_rs_convert_resources_to_aml(resource_list->pointer,
436 aml_size_needed,
437 output_buffer->pointer);
438 if (ACPI_FAILURE(status)) {
439 return_ACPI_STATUS(status);
440 }
441
442 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "OutputBuffer %p Length %X\n",
443 output_buffer->pointer, (u32) output_buffer->length));
444 return_ACPI_STATUS(AE_OK);
445}
446