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