diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/acpi/resources |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'drivers/acpi/resources')
-rw-r--r-- | drivers/acpi/resources/Makefile | 10 | ||||
-rw-r--r-- | drivers/acpi/resources/rsaddr.c | 1225 | ||||
-rw-r--r-- | drivers/acpi/resources/rscalc.c | 841 | ||||
-rw-r--r-- | drivers/acpi/resources/rscreate.c | 428 | ||||
-rw-r--r-- | drivers/acpi/resources/rsdump.c | 1150 | ||||
-rw-r--r-- | drivers/acpi/resources/rsio.c | 545 | ||||
-rw-r--r-- | drivers/acpi/resources/rsirq.c | 592 | ||||
-rw-r--r-- | drivers/acpi/resources/rslist.c | 518 | ||||
-rw-r--r-- | drivers/acpi/resources/rsmemory.c | 566 | ||||
-rw-r--r-- | drivers/acpi/resources/rsmisc.c | 597 | ||||
-rw-r--r-- | drivers/acpi/resources/rsutils.c | 356 | ||||
-rw-r--r-- | drivers/acpi/resources/rsxface.c | 437 |
12 files changed, 7265 insertions, 0 deletions
diff --git a/drivers/acpi/resources/Makefile b/drivers/acpi/resources/Makefile new file mode 100644 index 000000000000..2130b74170c3 --- /dev/null +++ b/drivers/acpi/resources/Makefile | |||
@@ -0,0 +1,10 @@ | |||
1 | # | ||
2 | # Makefile for all Linux ACPI interpreter subdirectories | ||
3 | # | ||
4 | |||
5 | obj-y := rsaddr.o rscreate.o rsio.o rslist.o rsmisc.o rsxface.o \ | ||
6 | rscalc.o rsirq.o rsmemory.o rsutils.o | ||
7 | |||
8 | obj-$(ACPI_FUTURE_USAGE) += rsdump.o | ||
9 | |||
10 | EXTRA_CFLAGS += $(ACPI_CFLAGS) | ||
diff --git a/drivers/acpi/resources/rsaddr.c b/drivers/acpi/resources/rsaddr.c new file mode 100644 index 000000000000..4788c079735d --- /dev/null +++ b/drivers/acpi/resources/rsaddr.c | |||
@@ -0,0 +1,1225 @@ | |||
1 | /******************************************************************************* | ||
2 | * | ||
3 | * Module Name: rsaddr - Address resource descriptors (16/32/64) | ||
4 | * | ||
5 | ******************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2005, R. Byron Moore | ||
9 | * All rights reserved. | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions, and the following disclaimer, | ||
16 | * without modification. | ||
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
18 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
19 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
20 | * including a substantially similar Disclaimer requirement for further | ||
21 | * binary redistribution. | ||
22 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
23 | * of any contributors may be used to endorse or promote products derived | ||
24 | * from this software without specific prior written permission. | ||
25 | * | ||
26 | * Alternatively, this software may be distributed under the terms of the | ||
27 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
28 | * Software Foundation. | ||
29 | * | ||
30 | * NO WARRANTY | ||
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
41 | * POSSIBILITY OF SUCH DAMAGES. | ||
42 | */ | ||
43 | |||
44 | |||
45 | #include <acpi/acpi.h> | ||
46 | #include <acpi/acresrc.h> | ||
47 | |||
48 | #define _COMPONENT ACPI_RESOURCES | ||
49 | ACPI_MODULE_NAME ("rsaddr") | ||
50 | |||
51 | |||
52 | /******************************************************************************* | ||
53 | * | ||
54 | * FUNCTION: acpi_rs_address16_resource | ||
55 | * | ||
56 | * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte | ||
57 | * stream | ||
58 | * bytes_consumed - Pointer to where the number of bytes | ||
59 | * consumed the byte_stream_buffer is | ||
60 | * returned | ||
61 | * output_buffer - Pointer to the return data buffer | ||
62 | * structure_size - Pointer to where the number of bytes | ||
63 | * in the return data struct is returned | ||
64 | * | ||
65 | * RETURN: Status | ||
66 | * | ||
67 | * DESCRIPTION: Take the resource byte stream and fill out the appropriate | ||
68 | * structure pointed to by the output_buffer. Return the | ||
69 | * number of bytes consumed from the byte stream. | ||
70 | * | ||
71 | ******************************************************************************/ | ||
72 | |||
73 | acpi_status | ||
74 | acpi_rs_address16_resource ( | ||
75 | u8 *byte_stream_buffer, | ||
76 | acpi_size *bytes_consumed, | ||
77 | u8 **output_buffer, | ||
78 | acpi_size *structure_size) | ||
79 | { | ||
80 | u8 *buffer = byte_stream_buffer; | ||
81 | struct acpi_resource *output_struct = (void *) *output_buffer; | ||
82 | u8 *temp_ptr; | ||
83 | acpi_size struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_address16); | ||
84 | u32 index; | ||
85 | u16 temp16; | ||
86 | u8 temp8; | ||
87 | |||
88 | |||
89 | ACPI_FUNCTION_TRACE ("rs_address16_resource"); | ||
90 | |||
91 | |||
92 | /* | ||
93 | * Point past the Descriptor to get the number of bytes consumed | ||
94 | */ | ||
95 | buffer += 1; | ||
96 | ACPI_MOVE_16_TO_16 (&temp16, buffer); | ||
97 | |||
98 | /* Validate minimum descriptor length */ | ||
99 | |||
100 | if (temp16 < 13) { | ||
101 | return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH); | ||
102 | } | ||
103 | |||
104 | *bytes_consumed = temp16 + 3; | ||
105 | output_struct->id = ACPI_RSTYPE_ADDRESS16; | ||
106 | |||
107 | /* | ||
108 | * Get the Resource Type (Byte3) | ||
109 | */ | ||
110 | buffer += 2; | ||
111 | temp8 = *buffer; | ||
112 | |||
113 | /* Values 0-2 and 0xC0-0xFF are valid */ | ||
114 | |||
115 | if ((temp8 > 2) && (temp8 < 0xC0)) { | ||
116 | return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE); | ||
117 | } | ||
118 | |||
119 | output_struct->data.address16.resource_type = temp8; | ||
120 | |||
121 | /* | ||
122 | * Get the General Flags (Byte4) | ||
123 | */ | ||
124 | buffer += 1; | ||
125 | temp8 = *buffer; | ||
126 | |||
127 | /* Producer / Consumer */ | ||
128 | |||
129 | output_struct->data.address16.producer_consumer = temp8 & 0x01; | ||
130 | |||
131 | /* Decode */ | ||
132 | |||
133 | output_struct->data.address16.decode = (temp8 >> 1) & 0x01; | ||
134 | |||
135 | /* Min Address Fixed */ | ||
136 | |||
137 | output_struct->data.address16.min_address_fixed = (temp8 >> 2) & 0x01; | ||
138 | |||
139 | /* Max Address Fixed */ | ||
140 | |||
141 | output_struct->data.address16.max_address_fixed = (temp8 >> 3) & 0x01; | ||
142 | |||
143 | /* | ||
144 | * Get the Type Specific Flags (Byte5) | ||
145 | */ | ||
146 | buffer += 1; | ||
147 | temp8 = *buffer; | ||
148 | |||
149 | if (ACPI_MEMORY_RANGE == output_struct->data.address16.resource_type) { | ||
150 | output_struct->data.address16.attribute.memory.read_write_attribute = | ||
151 | (u16) (temp8 & 0x01); | ||
152 | output_struct->data.address16.attribute.memory.cache_attribute = | ||
153 | (u16) ((temp8 >> 1) & 0x03); | ||
154 | } | ||
155 | else { | ||
156 | if (ACPI_IO_RANGE == output_struct->data.address16.resource_type) { | ||
157 | output_struct->data.address16.attribute.io.range_attribute = | ||
158 | (u16) (temp8 & 0x03); | ||
159 | output_struct->data.address16.attribute.io.translation_attribute = | ||
160 | (u16) ((temp8 >> 4) & 0x03); | ||
161 | } | ||
162 | else { | ||
163 | /* BUS_NUMBER_RANGE == Address16.Data->resource_type */ | ||
164 | /* Nothing needs to be filled in */ | ||
165 | } | ||
166 | } | ||
167 | |||
168 | /* | ||
169 | * Get Granularity (Bytes 6-7) | ||
170 | */ | ||
171 | buffer += 1; | ||
172 | ACPI_MOVE_16_TO_32 (&output_struct->data.address16.granularity, buffer); | ||
173 | |||
174 | /* | ||
175 | * Get min_address_range (Bytes 8-9) | ||
176 | */ | ||
177 | buffer += 2; | ||
178 | ACPI_MOVE_16_TO_32 (&output_struct->data.address16.min_address_range, buffer); | ||
179 | |||
180 | /* | ||
181 | * Get max_address_range (Bytes 10-11) | ||
182 | */ | ||
183 | buffer += 2; | ||
184 | ACPI_MOVE_16_TO_32 (&output_struct->data.address16.max_address_range, buffer); | ||
185 | |||
186 | /* | ||
187 | * Get address_translation_offset (Bytes 12-13) | ||
188 | */ | ||
189 | buffer += 2; | ||
190 | ACPI_MOVE_16_TO_32 (&output_struct->data.address16.address_translation_offset, buffer); | ||
191 | |||
192 | /* | ||
193 | * Get address_length (Bytes 14-15) | ||
194 | */ | ||
195 | buffer += 2; | ||
196 | ACPI_MOVE_16_TO_32 (&output_struct->data.address16.address_length, buffer); | ||
197 | |||
198 | /* | ||
199 | * Resource Source Index (if present) | ||
200 | */ | ||
201 | buffer += 2; | ||
202 | |||
203 | /* | ||
204 | * This will leave us pointing to the Resource Source Index | ||
205 | * If it is present, then save it off and calculate the | ||
206 | * pointer to where the null terminated string goes: | ||
207 | * Each Interrupt takes 32-bits + the 5 bytes of the | ||
208 | * stream that are default. | ||
209 | * | ||
210 | * Note: Some resource descriptors will have an additional null, so | ||
211 | * we add 1 to the length. | ||
212 | */ | ||
213 | if (*bytes_consumed > (16 + 1)) { | ||
214 | /* Dereference the Index */ | ||
215 | |||
216 | temp8 = *buffer; | ||
217 | output_struct->data.address16.resource_source.index = (u32) temp8; | ||
218 | |||
219 | /* Point to the String */ | ||
220 | |||
221 | buffer += 1; | ||
222 | |||
223 | /* Point the String pointer to the end of this structure */ | ||
224 | |||
225 | output_struct->data.address16.resource_source.string_ptr = | ||
226 | (char *)((u8 * )output_struct + struct_size); | ||
227 | |||
228 | temp_ptr = (u8 *) output_struct->data.address16.resource_source.string_ptr; | ||
229 | |||
230 | /* Copy the string into the buffer */ | ||
231 | |||
232 | index = 0; | ||
233 | |||
234 | while (0x00 != *buffer) { | ||
235 | *temp_ptr = *buffer; | ||
236 | |||
237 | temp_ptr += 1; | ||
238 | buffer += 1; | ||
239 | index += 1; | ||
240 | } | ||
241 | |||
242 | /* | ||
243 | * Add the terminating null | ||
244 | */ | ||
245 | *temp_ptr = 0x00; | ||
246 | |||
247 | output_struct->data.address16.resource_source.string_length = index + 1; | ||
248 | |||
249 | /* | ||
250 | * In order for the struct_size to fall on a 32-bit boundary, | ||
251 | * calculate the length of the string and expand the | ||
252 | * struct_size to the next 32-bit boundary. | ||
253 | */ | ||
254 | temp8 = (u8) (index + 1); | ||
255 | struct_size += ACPI_ROUND_UP_to_32_bITS (temp8); | ||
256 | } | ||
257 | else { | ||
258 | output_struct->data.address16.resource_source.index = 0x00; | ||
259 | output_struct->data.address16.resource_source.string_length = 0; | ||
260 | output_struct->data.address16.resource_source.string_ptr = NULL; | ||
261 | } | ||
262 | |||
263 | /* | ||
264 | * Set the Length parameter | ||
265 | */ | ||
266 | output_struct->length = (u32) struct_size; | ||
267 | |||
268 | /* | ||
269 | * Return the final size of the structure | ||
270 | */ | ||
271 | *structure_size = struct_size; | ||
272 | return_ACPI_STATUS (AE_OK); | ||
273 | } | ||
274 | |||
275 | |||
276 | /******************************************************************************* | ||
277 | * | ||
278 | * FUNCTION: acpi_rs_address16_stream | ||
279 | * | ||
280 | * PARAMETERS: linked_list - Pointer to the resource linked list | ||
281 | * output_buffer - Pointer to the user's return buffer | ||
282 | * bytes_consumed - Pointer to where the number of bytes | ||
283 | * used in the output_buffer is returned | ||
284 | * | ||
285 | * RETURN: Status | ||
286 | * | ||
287 | * DESCRIPTION: Take the linked list resource structure and fills in the | ||
288 | * the appropriate bytes in a byte stream | ||
289 | * | ||
290 | ******************************************************************************/ | ||
291 | |||
292 | acpi_status | ||
293 | acpi_rs_address16_stream ( | ||
294 | struct acpi_resource *linked_list, | ||
295 | u8 **output_buffer, | ||
296 | acpi_size *bytes_consumed) | ||
297 | { | ||
298 | u8 *buffer = *output_buffer; | ||
299 | u8 *length_field; | ||
300 | u8 temp8; | ||
301 | char *temp_pointer = NULL; | ||
302 | acpi_size actual_bytes; | ||
303 | |||
304 | |||
305 | ACPI_FUNCTION_TRACE ("rs_address16_stream"); | ||
306 | |||
307 | |||
308 | /* | ||
309 | * The descriptor field is static | ||
310 | */ | ||
311 | *buffer = 0x88; | ||
312 | buffer += 1; | ||
313 | |||
314 | /* | ||
315 | * Save a pointer to the Length field - to be filled in later | ||
316 | */ | ||
317 | length_field = buffer; | ||
318 | buffer += 2; | ||
319 | |||
320 | /* | ||
321 | * Set the Resource Type (Memory, Io, bus_number) | ||
322 | */ | ||
323 | temp8 = (u8) (linked_list->data.address16.resource_type & 0x03); | ||
324 | *buffer = temp8; | ||
325 | buffer += 1; | ||
326 | |||
327 | /* | ||
328 | * Set the general flags | ||
329 | */ | ||
330 | temp8 = (u8) (linked_list->data.address16.producer_consumer & 0x01); | ||
331 | |||
332 | temp8 |= (linked_list->data.address16.decode & 0x01) << 1; | ||
333 | temp8 |= (linked_list->data.address16.min_address_fixed & 0x01) << 2; | ||
334 | temp8 |= (linked_list->data.address16.max_address_fixed & 0x01) << 3; | ||
335 | |||
336 | *buffer = temp8; | ||
337 | buffer += 1; | ||
338 | |||
339 | /* | ||
340 | * Set the type specific flags | ||
341 | */ | ||
342 | temp8 = 0; | ||
343 | |||
344 | if (ACPI_MEMORY_RANGE == linked_list->data.address16.resource_type) { | ||
345 | temp8 = (u8) | ||
346 | (linked_list->data.address16.attribute.memory.read_write_attribute & | ||
347 | 0x01); | ||
348 | |||
349 | temp8 |= | ||
350 | (linked_list->data.address16.attribute.memory.cache_attribute & | ||
351 | 0x03) << 1; | ||
352 | } | ||
353 | else if (ACPI_IO_RANGE == linked_list->data.address16.resource_type) { | ||
354 | temp8 = (u8) | ||
355 | (linked_list->data.address16.attribute.io.range_attribute & | ||
356 | 0x03); | ||
357 | temp8 |= | ||
358 | (linked_list->data.address16.attribute.io.translation_attribute & | ||
359 | 0x03) << 4; | ||
360 | } | ||
361 | |||
362 | *buffer = temp8; | ||
363 | buffer += 1; | ||
364 | |||
365 | /* | ||
366 | * Set the address space granularity | ||
367 | */ | ||
368 | ACPI_MOVE_32_TO_16 (buffer, &linked_list->data.address16.granularity); | ||
369 | buffer += 2; | ||
370 | |||
371 | /* | ||
372 | * Set the address range minimum | ||
373 | */ | ||
374 | ACPI_MOVE_32_TO_16 (buffer, &linked_list->data.address16.min_address_range); | ||
375 | buffer += 2; | ||
376 | |||
377 | /* | ||
378 | * Set the address range maximum | ||
379 | */ | ||
380 | ACPI_MOVE_32_TO_16 (buffer, &linked_list->data.address16.max_address_range); | ||
381 | buffer += 2; | ||
382 | |||
383 | /* | ||
384 | * Set the address translation offset | ||
385 | */ | ||
386 | ACPI_MOVE_32_TO_16 (buffer, &linked_list->data.address16.address_translation_offset); | ||
387 | buffer += 2; | ||
388 | |||
389 | /* | ||
390 | * Set the address length | ||
391 | */ | ||
392 | ACPI_MOVE_32_TO_16 (buffer, &linked_list->data.address16.address_length); | ||
393 | buffer += 2; | ||
394 | |||
395 | /* | ||
396 | * Resource Source Index and Resource Source are optional | ||
397 | */ | ||
398 | if (0 != linked_list->data.address16.resource_source.string_length) { | ||
399 | temp8 = (u8) linked_list->data.address16.resource_source.index; | ||
400 | |||
401 | *buffer = temp8; | ||
402 | buffer += 1; | ||
403 | |||
404 | temp_pointer = (char *) buffer; | ||
405 | |||
406 | /* | ||
407 | * Copy the string | ||
408 | */ | ||
409 | ACPI_STRCPY (temp_pointer, | ||
410 | linked_list->data.address16.resource_source.string_ptr); | ||
411 | |||
412 | /* | ||
413 | * Buffer needs to be set to the length of the sting + one for the | ||
414 | * terminating null | ||
415 | */ | ||
416 | buffer += (acpi_size)(ACPI_STRLEN (linked_list->data.address16.resource_source.string_ptr) + 1); | ||
417 | } | ||
418 | |||
419 | /* | ||
420 | * Return the number of bytes consumed in this operation | ||
421 | */ | ||
422 | actual_bytes = ACPI_PTR_DIFF (buffer, *output_buffer); | ||
423 | *bytes_consumed = actual_bytes; | ||
424 | |||
425 | /* | ||
426 | * Set the length field to the number of bytes consumed | ||
427 | * minus the header size (3 bytes) | ||
428 | */ | ||
429 | actual_bytes -= 3; | ||
430 | ACPI_MOVE_SIZE_TO_16 (length_field, &actual_bytes); | ||
431 | return_ACPI_STATUS (AE_OK); | ||
432 | } | ||
433 | |||
434 | |||
435 | /******************************************************************************* | ||
436 | * | ||
437 | * FUNCTION: acpi_rs_address32_resource | ||
438 | * | ||
439 | * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte | ||
440 | * stream | ||
441 | * bytes_consumed - Pointer to where the number of bytes | ||
442 | * consumed the byte_stream_buffer is | ||
443 | * returned | ||
444 | * output_buffer - Pointer to the return data buffer | ||
445 | * structure_size - Pointer to where the number of bytes | ||
446 | * in the return data struct is returned | ||
447 | * | ||
448 | * RETURN: Status | ||
449 | * | ||
450 | * DESCRIPTION: Take the resource byte stream and fill out the appropriate | ||
451 | * structure pointed to by the output_buffer. Return the | ||
452 | * number of bytes consumed from the byte stream. | ||
453 | * | ||
454 | ******************************************************************************/ | ||
455 | |||
456 | acpi_status | ||
457 | acpi_rs_address32_resource ( | ||
458 | u8 *byte_stream_buffer, | ||
459 | acpi_size *bytes_consumed, | ||
460 | u8 **output_buffer, | ||
461 | acpi_size *structure_size) | ||
462 | { | ||
463 | u8 *buffer; | ||
464 | struct acpi_resource *output_struct= (void *) *output_buffer; | ||
465 | u16 temp16; | ||
466 | u8 temp8; | ||
467 | u8 *temp_ptr; | ||
468 | acpi_size struct_size; | ||
469 | u32 index; | ||
470 | |||
471 | |||
472 | ACPI_FUNCTION_TRACE ("rs_address32_resource"); | ||
473 | |||
474 | |||
475 | buffer = byte_stream_buffer; | ||
476 | struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_address32); | ||
477 | |||
478 | /* | ||
479 | * Point past the Descriptor to get the number of bytes consumed | ||
480 | */ | ||
481 | buffer += 1; | ||
482 | ACPI_MOVE_16_TO_16 (&temp16, buffer); | ||
483 | |||
484 | /* Validate minimum descriptor length */ | ||
485 | |||
486 | if (temp16 < 23) { | ||
487 | return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH); | ||
488 | } | ||
489 | |||
490 | *bytes_consumed = temp16 + 3; | ||
491 | output_struct->id = ACPI_RSTYPE_ADDRESS32; | ||
492 | |||
493 | /* | ||
494 | * Get the Resource Type (Byte3) | ||
495 | */ | ||
496 | buffer += 2; | ||
497 | temp8 = *buffer; | ||
498 | |||
499 | /* Values 0-2 and 0xC0-0xFF are valid */ | ||
500 | |||
501 | if ((temp8 > 2) && (temp8 < 0xC0)) { | ||
502 | return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE); | ||
503 | } | ||
504 | |||
505 | output_struct->data.address32.resource_type = temp8; | ||
506 | |||
507 | /* | ||
508 | * Get the General Flags (Byte4) | ||
509 | */ | ||
510 | buffer += 1; | ||
511 | temp8 = *buffer; | ||
512 | |||
513 | /* | ||
514 | * Producer / Consumer | ||
515 | */ | ||
516 | output_struct->data.address32.producer_consumer = temp8 & 0x01; | ||
517 | |||
518 | /* | ||
519 | * Decode | ||
520 | */ | ||
521 | output_struct->data.address32.decode = (temp8 >> 1) & 0x01; | ||
522 | |||
523 | /* | ||
524 | * Min Address Fixed | ||
525 | */ | ||
526 | output_struct->data.address32.min_address_fixed = (temp8 >> 2) & 0x01; | ||
527 | |||
528 | /* | ||
529 | * Max Address Fixed | ||
530 | */ | ||
531 | output_struct->data.address32.max_address_fixed = (temp8 >> 3) & 0x01; | ||
532 | |||
533 | /* | ||
534 | * Get the Type Specific Flags (Byte5) | ||
535 | */ | ||
536 | buffer += 1; | ||
537 | temp8 = *buffer; | ||
538 | |||
539 | if (ACPI_MEMORY_RANGE == output_struct->data.address32.resource_type) { | ||
540 | output_struct->data.address32.attribute.memory.read_write_attribute = | ||
541 | (u16) (temp8 & 0x01); | ||
542 | |||
543 | output_struct->data.address32.attribute.memory.cache_attribute = | ||
544 | (u16) ((temp8 >> 1) & 0x03); | ||
545 | } | ||
546 | else { | ||
547 | if (ACPI_IO_RANGE == output_struct->data.address32.resource_type) { | ||
548 | output_struct->data.address32.attribute.io.range_attribute = | ||
549 | (u16) (temp8 & 0x03); | ||
550 | output_struct->data.address32.attribute.io.translation_attribute = | ||
551 | (u16) ((temp8 >> 4) & 0x03); | ||
552 | } | ||
553 | else { | ||
554 | /* BUS_NUMBER_RANGE == output_struct->Data.Address32.resource_type */ | ||
555 | /* Nothing needs to be filled in */ | ||
556 | } | ||
557 | } | ||
558 | |||
559 | /* | ||
560 | * Get Granularity (Bytes 6-9) | ||
561 | */ | ||
562 | buffer += 1; | ||
563 | ACPI_MOVE_32_TO_32 (&output_struct->data.address32.granularity, buffer); | ||
564 | |||
565 | /* | ||
566 | * Get min_address_range (Bytes 10-13) | ||
567 | */ | ||
568 | buffer += 4; | ||
569 | ACPI_MOVE_32_TO_32 (&output_struct->data.address32.min_address_range, buffer); | ||
570 | |||
571 | /* | ||
572 | * Get max_address_range (Bytes 14-17) | ||
573 | */ | ||
574 | buffer += 4; | ||
575 | ACPI_MOVE_32_TO_32 (&output_struct->data.address32.max_address_range, buffer); | ||
576 | |||
577 | /* | ||
578 | * Get address_translation_offset (Bytes 18-21) | ||
579 | */ | ||
580 | buffer += 4; | ||
581 | ACPI_MOVE_32_TO_32 (&output_struct->data.address32.address_translation_offset, buffer); | ||
582 | |||
583 | /* | ||
584 | * Get address_length (Bytes 22-25) | ||
585 | */ | ||
586 | buffer += 4; | ||
587 | ACPI_MOVE_32_TO_32 (&output_struct->data.address32.address_length, buffer); | ||
588 | |||
589 | /* | ||
590 | * Resource Source Index (if present) | ||
591 | */ | ||
592 | buffer += 4; | ||
593 | |||
594 | /* | ||
595 | * This will leave us pointing to the Resource Source Index | ||
596 | * If it is present, then save it off and calculate the | ||
597 | * pointer to where the null terminated string goes: | ||
598 | * | ||
599 | * Note: Some resource descriptors will have an additional null, so | ||
600 | * we add 1 to the length. | ||
601 | */ | ||
602 | if (*bytes_consumed > (26 + 1)) { | ||
603 | /* Dereference the Index */ | ||
604 | |||
605 | temp8 = *buffer; | ||
606 | output_struct->data.address32.resource_source.index = | ||
607 | (u32) temp8; | ||
608 | |||
609 | /* Point to the String */ | ||
610 | |||
611 | buffer += 1; | ||
612 | |||
613 | /* Point the String pointer to the end of this structure */ | ||
614 | |||
615 | output_struct->data.address32.resource_source.string_ptr = | ||
616 | (char *)((u8 *)output_struct + struct_size); | ||
617 | |||
618 | temp_ptr = (u8 *) output_struct->data.address32.resource_source.string_ptr; | ||
619 | |||
620 | /* Copy the string into the buffer */ | ||
621 | |||
622 | index = 0; | ||
623 | while (0x00 != *buffer) { | ||
624 | *temp_ptr = *buffer; | ||
625 | |||
626 | temp_ptr += 1; | ||
627 | buffer += 1; | ||
628 | index += 1; | ||
629 | } | ||
630 | |||
631 | /* | ||
632 | * Add the terminating null | ||
633 | */ | ||
634 | *temp_ptr = 0x00; | ||
635 | output_struct->data.address32.resource_source.string_length = index + 1; | ||
636 | |||
637 | /* | ||
638 | * In order for the struct_size to fall on a 32-bit boundary, | ||
639 | * calculate the length of the string and expand the | ||
640 | * struct_size to the next 32-bit boundary. | ||
641 | */ | ||
642 | temp8 = (u8) (index + 1); | ||
643 | struct_size += ACPI_ROUND_UP_to_32_bITS (temp8); | ||
644 | } | ||
645 | else { | ||
646 | output_struct->data.address32.resource_source.index = 0x00; | ||
647 | output_struct->data.address32.resource_source.string_length = 0; | ||
648 | output_struct->data.address32.resource_source.string_ptr = NULL; | ||
649 | } | ||
650 | |||
651 | /* | ||
652 | * Set the Length parameter | ||
653 | */ | ||
654 | output_struct->length = (u32) struct_size; | ||
655 | |||
656 | /* | ||
657 | * Return the final size of the structure | ||
658 | */ | ||
659 | *structure_size = struct_size; | ||
660 | return_ACPI_STATUS (AE_OK); | ||
661 | } | ||
662 | |||
663 | |||
664 | /******************************************************************************* | ||
665 | * | ||
666 | * FUNCTION: acpi_rs_address32_stream | ||
667 | * | ||
668 | * PARAMETERS: linked_list - Pointer to the resource linked list | ||
669 | * output_buffer - Pointer to the user's return buffer | ||
670 | * bytes_consumed - Pointer to where the number of bytes | ||
671 | * used in the output_buffer is returned | ||
672 | * | ||
673 | * RETURN: Status | ||
674 | * | ||
675 | * DESCRIPTION: Take the linked list resource structure and fills in the | ||
676 | * the appropriate bytes in a byte stream | ||
677 | * | ||
678 | ******************************************************************************/ | ||
679 | |||
680 | acpi_status | ||
681 | acpi_rs_address32_stream ( | ||
682 | struct acpi_resource *linked_list, | ||
683 | u8 **output_buffer, | ||
684 | acpi_size *bytes_consumed) | ||
685 | { | ||
686 | u8 *buffer; | ||
687 | u16 *length_field; | ||
688 | u8 temp8; | ||
689 | char *temp_pointer; | ||
690 | |||
691 | |||
692 | ACPI_FUNCTION_TRACE ("rs_address32_stream"); | ||
693 | |||
694 | |||
695 | buffer = *output_buffer; | ||
696 | |||
697 | /* | ||
698 | * The descriptor field is static | ||
699 | */ | ||
700 | *buffer = 0x87; | ||
701 | buffer += 1; | ||
702 | |||
703 | /* | ||
704 | * Set a pointer to the Length field - to be filled in later | ||
705 | */ | ||
706 | length_field = ACPI_CAST_PTR (u16, buffer); | ||
707 | buffer += 2; | ||
708 | |||
709 | /* | ||
710 | * Set the Resource Type (Memory, Io, bus_number) | ||
711 | */ | ||
712 | temp8 = (u8) (linked_list->data.address32.resource_type & 0x03); | ||
713 | |||
714 | *buffer = temp8; | ||
715 | buffer += 1; | ||
716 | |||
717 | /* | ||
718 | * Set the general flags | ||
719 | */ | ||
720 | temp8 = (u8) (linked_list->data.address32.producer_consumer & 0x01); | ||
721 | temp8 |= (linked_list->data.address32.decode & 0x01) << 1; | ||
722 | temp8 |= (linked_list->data.address32.min_address_fixed & 0x01) << 2; | ||
723 | temp8 |= (linked_list->data.address32.max_address_fixed & 0x01) << 3; | ||
724 | |||
725 | *buffer = temp8; | ||
726 | buffer += 1; | ||
727 | |||
728 | /* | ||
729 | * Set the type specific flags | ||
730 | */ | ||
731 | temp8 = 0; | ||
732 | |||
733 | if (ACPI_MEMORY_RANGE == linked_list->data.address32.resource_type) { | ||
734 | temp8 = (u8) | ||
735 | (linked_list->data.address32.attribute.memory.read_write_attribute & | ||
736 | 0x01); | ||
737 | |||
738 | temp8 |= | ||
739 | (linked_list->data.address32.attribute.memory.cache_attribute & | ||
740 | 0x03) << 1; | ||
741 | } | ||
742 | else if (ACPI_IO_RANGE == linked_list->data.address32.resource_type) { | ||
743 | temp8 = (u8) | ||
744 | (linked_list->data.address32.attribute.io.range_attribute & | ||
745 | 0x03); | ||
746 | temp8 |= | ||
747 | (linked_list->data.address32.attribute.io.translation_attribute & | ||
748 | 0x03) << 4; | ||
749 | } | ||
750 | |||
751 | *buffer = temp8; | ||
752 | buffer += 1; | ||
753 | |||
754 | /* | ||
755 | * Set the address space granularity | ||
756 | */ | ||
757 | ACPI_MOVE_32_TO_32 (buffer, &linked_list->data.address32.granularity); | ||
758 | buffer += 4; | ||
759 | |||
760 | /* | ||
761 | * Set the address range minimum | ||
762 | */ | ||
763 | ACPI_MOVE_32_TO_32 (buffer, &linked_list->data.address32.min_address_range); | ||
764 | buffer += 4; | ||
765 | |||
766 | /* | ||
767 | * Set the address range maximum | ||
768 | */ | ||
769 | ACPI_MOVE_32_TO_32 (buffer, &linked_list->data.address32.max_address_range); | ||
770 | buffer += 4; | ||
771 | |||
772 | /* | ||
773 | * Set the address translation offset | ||
774 | */ | ||
775 | ACPI_MOVE_32_TO_32 (buffer, &linked_list->data.address32.address_translation_offset); | ||
776 | buffer += 4; | ||
777 | |||
778 | /* | ||
779 | * Set the address length | ||
780 | */ | ||
781 | ACPI_MOVE_32_TO_32 (buffer, &linked_list->data.address32.address_length); | ||
782 | buffer += 4; | ||
783 | |||
784 | /* | ||
785 | * Resource Source Index and Resource Source are optional | ||
786 | */ | ||
787 | if (0 != linked_list->data.address32.resource_source.string_length) { | ||
788 | temp8 = (u8) linked_list->data.address32.resource_source.index; | ||
789 | |||
790 | *buffer = temp8; | ||
791 | buffer += 1; | ||
792 | |||
793 | temp_pointer = (char *) buffer; | ||
794 | |||
795 | /* | ||
796 | * Copy the string | ||
797 | */ | ||
798 | ACPI_STRCPY (temp_pointer, | ||
799 | linked_list->data.address32.resource_source.string_ptr); | ||
800 | |||
801 | /* | ||
802 | * Buffer needs to be set to the length of the sting + one for the | ||
803 | * terminating null | ||
804 | */ | ||
805 | buffer += (acpi_size)(ACPI_STRLEN (linked_list->data.address32.resource_source.string_ptr) + 1); | ||
806 | } | ||
807 | |||
808 | /* | ||
809 | * Return the number of bytes consumed in this operation | ||
810 | */ | ||
811 | *bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer); | ||
812 | |||
813 | /* | ||
814 | * Set the length field to the number of bytes consumed | ||
815 | * minus the header size (3 bytes) | ||
816 | */ | ||
817 | *length_field = (u16) (*bytes_consumed - 3); | ||
818 | return_ACPI_STATUS (AE_OK); | ||
819 | } | ||
820 | |||
821 | |||
822 | /******************************************************************************* | ||
823 | * | ||
824 | * FUNCTION: acpi_rs_address64_resource | ||
825 | * | ||
826 | * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte | ||
827 | * stream | ||
828 | * bytes_consumed - Pointer to where the number of bytes | ||
829 | * consumed the byte_stream_buffer is | ||
830 | * returned | ||
831 | * output_buffer - Pointer to the return data buffer | ||
832 | * structure_size - Pointer to where the number of bytes | ||
833 | * in the return data struct is returned | ||
834 | * | ||
835 | * RETURN: Status | ||
836 | * | ||
837 | * DESCRIPTION: Take the resource byte stream and fill out the appropriate | ||
838 | * structure pointed to by the output_buffer. Return the | ||
839 | * number of bytes consumed from the byte stream. | ||
840 | * | ||
841 | ******************************************************************************/ | ||
842 | |||
843 | acpi_status | ||
844 | acpi_rs_address64_resource ( | ||
845 | u8 *byte_stream_buffer, | ||
846 | acpi_size *bytes_consumed, | ||
847 | u8 **output_buffer, | ||
848 | acpi_size *structure_size) | ||
849 | { | ||
850 | u8 *buffer; | ||
851 | struct acpi_resource *output_struct = (void *) *output_buffer; | ||
852 | u16 temp16; | ||
853 | u8 temp8; | ||
854 | u8 resource_type; | ||
855 | u8 *temp_ptr; | ||
856 | acpi_size struct_size; | ||
857 | u32 index; | ||
858 | |||
859 | |||
860 | ACPI_FUNCTION_TRACE ("rs_address64_resource"); | ||
861 | |||
862 | |||
863 | buffer = byte_stream_buffer; | ||
864 | struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_address64); | ||
865 | resource_type = *buffer; | ||
866 | |||
867 | /* | ||
868 | * Point past the Descriptor to get the number of bytes consumed | ||
869 | */ | ||
870 | buffer += 1; | ||
871 | ACPI_MOVE_16_TO_16 (&temp16, buffer); | ||
872 | |||
873 | /* Validate minimum descriptor length */ | ||
874 | |||
875 | if (temp16 < 43) { | ||
876 | return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH); | ||
877 | } | ||
878 | |||
879 | *bytes_consumed = temp16 + 3; | ||
880 | output_struct->id = ACPI_RSTYPE_ADDRESS64; | ||
881 | |||
882 | /* | ||
883 | * Get the Resource Type (Byte3) | ||
884 | */ | ||
885 | buffer += 2; | ||
886 | temp8 = *buffer; | ||
887 | |||
888 | /* Values 0-2 and 0xC0-0xFF are valid */ | ||
889 | |||
890 | if ((temp8 > 2) && (temp8 < 0xC0)) { | ||
891 | return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE); | ||
892 | } | ||
893 | |||
894 | output_struct->data.address64.resource_type = temp8; | ||
895 | |||
896 | /* | ||
897 | * Get the General Flags (Byte4) | ||
898 | */ | ||
899 | buffer += 1; | ||
900 | temp8 = *buffer; | ||
901 | |||
902 | /* | ||
903 | * Producer / Consumer | ||
904 | */ | ||
905 | output_struct->data.address64.producer_consumer = temp8 & 0x01; | ||
906 | |||
907 | /* | ||
908 | * Decode | ||
909 | */ | ||
910 | output_struct->data.address64.decode = (temp8 >> 1) & 0x01; | ||
911 | |||
912 | /* | ||
913 | * Min Address Fixed | ||
914 | */ | ||
915 | output_struct->data.address64.min_address_fixed = (temp8 >> 2) & 0x01; | ||
916 | |||
917 | /* | ||
918 | * Max Address Fixed | ||
919 | */ | ||
920 | output_struct->data.address64.max_address_fixed = (temp8 >> 3) & 0x01; | ||
921 | |||
922 | /* | ||
923 | * Get the Type Specific Flags (Byte5) | ||
924 | */ | ||
925 | buffer += 1; | ||
926 | temp8 = *buffer; | ||
927 | |||
928 | if (ACPI_MEMORY_RANGE == output_struct->data.address64.resource_type) { | ||
929 | output_struct->data.address64.attribute.memory.read_write_attribute = | ||
930 | (u16) (temp8 & 0x01); | ||
931 | |||
932 | output_struct->data.address64.attribute.memory.cache_attribute = | ||
933 | (u16) ((temp8 >> 1) & 0x03); | ||
934 | } | ||
935 | else { | ||
936 | if (ACPI_IO_RANGE == output_struct->data.address64.resource_type) { | ||
937 | output_struct->data.address64.attribute.io.range_attribute = | ||
938 | (u16) (temp8 & 0x03); | ||
939 | output_struct->data.address64.attribute.io.translation_attribute = | ||
940 | (u16) ((temp8 >> 4) & 0x03); | ||
941 | } | ||
942 | else { | ||
943 | /* BUS_NUMBER_RANGE == output_struct->Data.Address64.resource_type */ | ||
944 | /* Nothing needs to be filled in */ | ||
945 | } | ||
946 | } | ||
947 | |||
948 | if (resource_type == ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE) { | ||
949 | /* Move past revision_id and Reserved byte */ | ||
950 | |||
951 | buffer += 2; | ||
952 | } | ||
953 | |||
954 | /* | ||
955 | * Get Granularity (Bytes 6-13) or (Bytes 8-15) | ||
956 | */ | ||
957 | buffer += 1; | ||
958 | ACPI_MOVE_64_TO_64 (&output_struct->data.address64.granularity, buffer); | ||
959 | |||
960 | /* | ||
961 | * Get min_address_range (Bytes 14-21) or (Bytes 16-23) | ||
962 | */ | ||
963 | buffer += 8; | ||
964 | ACPI_MOVE_64_TO_64 (&output_struct->data.address64.min_address_range, buffer); | ||
965 | |||
966 | /* | ||
967 | * Get max_address_range (Bytes 22-29) or (Bytes 24-31) | ||
968 | */ | ||
969 | buffer += 8; | ||
970 | ACPI_MOVE_64_TO_64 (&output_struct->data.address64.max_address_range, buffer); | ||
971 | |||
972 | /* | ||
973 | * Get address_translation_offset (Bytes 30-37) or (Bytes 32-39) | ||
974 | */ | ||
975 | buffer += 8; | ||
976 | ACPI_MOVE_64_TO_64 (&output_struct->data.address64.address_translation_offset, buffer); | ||
977 | |||
978 | /* | ||
979 | * Get address_length (Bytes 38-45) or (Bytes 40-47) | ||
980 | */ | ||
981 | buffer += 8; | ||
982 | ACPI_MOVE_64_TO_64 (&output_struct->data.address64.address_length, buffer); | ||
983 | |||
984 | output_struct->data.address64.resource_source.index = 0x00; | ||
985 | output_struct->data.address64.resource_source.string_length = 0; | ||
986 | output_struct->data.address64.resource_source.string_ptr = NULL; | ||
987 | |||
988 | if (resource_type == ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE) { | ||
989 | /* Get type_specific_attribute (Bytes 48-55) */ | ||
990 | |||
991 | buffer += 8; | ||
992 | ACPI_MOVE_64_TO_64 (&output_struct->data.address64.type_specific_attributes, buffer); | ||
993 | } | ||
994 | else { | ||
995 | output_struct->data.address64.type_specific_attributes = 0; | ||
996 | |||
997 | /* | ||
998 | * Resource Source Index (if present) | ||
999 | */ | ||
1000 | buffer += 8; | ||
1001 | |||
1002 | /* | ||
1003 | * This will leave us pointing to the Resource Source Index | ||
1004 | * If it is present, then save it off and calculate the | ||
1005 | * pointer to where the null terminated string goes: | ||
1006 | * Each Interrupt takes 32-bits + the 5 bytes of the | ||
1007 | * stream that are default. | ||
1008 | * | ||
1009 | * Note: Some resource descriptors will have an additional null, so | ||
1010 | * we add 1 to the length. | ||
1011 | */ | ||
1012 | if (*bytes_consumed > (46 + 1)) { | ||
1013 | /* Dereference the Index */ | ||
1014 | |||
1015 | temp8 = *buffer; | ||
1016 | output_struct->data.address64.resource_source.index = | ||
1017 | (u32) temp8; | ||
1018 | |||
1019 | /* Point to the String */ | ||
1020 | |||
1021 | buffer += 1; | ||
1022 | |||
1023 | /* Point the String pointer to the end of this structure */ | ||
1024 | |||
1025 | output_struct->data.address64.resource_source.string_ptr = | ||
1026 | (char *)((u8 *)output_struct + struct_size); | ||
1027 | |||
1028 | temp_ptr = (u8 *) output_struct->data.address64.resource_source.string_ptr; | ||
1029 | |||
1030 | /* Copy the string into the buffer */ | ||
1031 | |||
1032 | index = 0; | ||
1033 | while (0x00 != *buffer) { | ||
1034 | *temp_ptr = *buffer; | ||
1035 | |||
1036 | temp_ptr += 1; | ||
1037 | buffer += 1; | ||
1038 | index += 1; | ||
1039 | } | ||
1040 | |||
1041 | /* | ||
1042 | * Add the terminating null | ||
1043 | */ | ||
1044 | *temp_ptr = 0x00; | ||
1045 | output_struct->data.address64.resource_source.string_length = index + 1; | ||
1046 | |||
1047 | /* | ||
1048 | * In order for the struct_size to fall on a 32-bit boundary, | ||
1049 | * calculate the length of the string and expand the | ||
1050 | * struct_size to the next 32-bit boundary. | ||
1051 | */ | ||
1052 | temp8 = (u8) (index + 1); | ||
1053 | struct_size += ACPI_ROUND_UP_to_32_bITS (temp8); | ||
1054 | } | ||
1055 | } | ||
1056 | |||
1057 | /* | ||
1058 | * Set the Length parameter | ||
1059 | */ | ||
1060 | output_struct->length = (u32) struct_size; | ||
1061 | |||
1062 | /* | ||
1063 | * Return the final size of the structure | ||
1064 | */ | ||
1065 | *structure_size = struct_size; | ||
1066 | return_ACPI_STATUS (AE_OK); | ||
1067 | } | ||
1068 | |||
1069 | |||
1070 | /******************************************************************************* | ||
1071 | * | ||
1072 | * FUNCTION: acpi_rs_address64_stream | ||
1073 | * | ||
1074 | * PARAMETERS: linked_list - Pointer to the resource linked list | ||
1075 | * output_buffer - Pointer to the user's return buffer | ||
1076 | * bytes_consumed - Pointer to where the number of bytes | ||
1077 | * used in the output_buffer is returned | ||
1078 | * | ||
1079 | * RETURN: Status | ||
1080 | * | ||
1081 | * DESCRIPTION: Take the linked list resource structure and fills in the | ||
1082 | * the appropriate bytes in a byte stream | ||
1083 | * | ||
1084 | ******************************************************************************/ | ||
1085 | |||
1086 | acpi_status | ||
1087 | acpi_rs_address64_stream ( | ||
1088 | struct acpi_resource *linked_list, | ||
1089 | u8 **output_buffer, | ||
1090 | acpi_size *bytes_consumed) | ||
1091 | { | ||
1092 | u8 *buffer; | ||
1093 | u16 *length_field; | ||
1094 | u8 temp8; | ||
1095 | char *temp_pointer; | ||
1096 | |||
1097 | |||
1098 | ACPI_FUNCTION_TRACE ("rs_address64_stream"); | ||
1099 | |||
1100 | |||
1101 | buffer = *output_buffer; | ||
1102 | |||
1103 | /* | ||
1104 | * The descriptor field is static | ||
1105 | */ | ||
1106 | *buffer = 0x8A; | ||
1107 | buffer += 1; | ||
1108 | |||
1109 | /* | ||
1110 | * Set a pointer to the Length field - to be filled in later | ||
1111 | */ | ||
1112 | length_field = ACPI_CAST_PTR (u16, buffer); | ||
1113 | buffer += 2; | ||
1114 | |||
1115 | /* | ||
1116 | * Set the Resource Type (Memory, Io, bus_number) | ||
1117 | */ | ||
1118 | temp8 = (u8) (linked_list->data.address64.resource_type & 0x03); | ||
1119 | |||
1120 | *buffer = temp8; | ||
1121 | buffer += 1; | ||
1122 | |||
1123 | /* | ||
1124 | * Set the general flags | ||
1125 | */ | ||
1126 | temp8 = (u8) (linked_list->data.address64.producer_consumer & 0x01); | ||
1127 | temp8 |= (linked_list->data.address64.decode & 0x01) << 1; | ||
1128 | temp8 |= (linked_list->data.address64.min_address_fixed & 0x01) << 2; | ||
1129 | temp8 |= (linked_list->data.address64.max_address_fixed & 0x01) << 3; | ||
1130 | |||
1131 | *buffer = temp8; | ||
1132 | buffer += 1; | ||
1133 | |||
1134 | /* | ||
1135 | * Set the type specific flags | ||
1136 | */ | ||
1137 | temp8 = 0; | ||
1138 | |||
1139 | if (ACPI_MEMORY_RANGE == linked_list->data.address64.resource_type) { | ||
1140 | temp8 = (u8) | ||
1141 | (linked_list->data.address64.attribute.memory.read_write_attribute & | ||
1142 | 0x01); | ||
1143 | |||
1144 | temp8 |= | ||
1145 | (linked_list->data.address64.attribute.memory.cache_attribute & | ||
1146 | 0x03) << 1; | ||
1147 | } | ||
1148 | else if (ACPI_IO_RANGE == linked_list->data.address64.resource_type) { | ||
1149 | temp8 = (u8) | ||
1150 | (linked_list->data.address64.attribute.io.range_attribute & | ||
1151 | 0x03); | ||
1152 | temp8 |= | ||
1153 | (linked_list->data.address64.attribute.io.range_attribute & | ||
1154 | 0x03) << 4; | ||
1155 | } | ||
1156 | |||
1157 | *buffer = temp8; | ||
1158 | buffer += 1; | ||
1159 | |||
1160 | /* | ||
1161 | * Set the address space granularity | ||
1162 | */ | ||
1163 | ACPI_MOVE_64_TO_64 (buffer, &linked_list->data.address64.granularity); | ||
1164 | buffer += 8; | ||
1165 | |||
1166 | /* | ||
1167 | * Set the address range minimum | ||
1168 | */ | ||
1169 | ACPI_MOVE_64_TO_64 (buffer, &linked_list->data.address64.min_address_range); | ||
1170 | buffer += 8; | ||
1171 | |||
1172 | /* | ||
1173 | * Set the address range maximum | ||
1174 | */ | ||
1175 | ACPI_MOVE_64_TO_64 (buffer, &linked_list->data.address64.max_address_range); | ||
1176 | buffer += 8; | ||
1177 | |||
1178 | /* | ||
1179 | * Set the address translation offset | ||
1180 | */ | ||
1181 | ACPI_MOVE_64_TO_64 (buffer, &linked_list->data.address64.address_translation_offset); | ||
1182 | buffer += 8; | ||
1183 | |||
1184 | /* | ||
1185 | * Set the address length | ||
1186 | */ | ||
1187 | ACPI_MOVE_64_TO_64 (buffer, &linked_list->data.address64.address_length); | ||
1188 | buffer += 8; | ||
1189 | |||
1190 | /* | ||
1191 | * Resource Source Index and Resource Source are optional | ||
1192 | */ | ||
1193 | if (0 != linked_list->data.address64.resource_source.string_length) { | ||
1194 | temp8 = (u8) linked_list->data.address64.resource_source.index; | ||
1195 | |||
1196 | *buffer = temp8; | ||
1197 | buffer += 1; | ||
1198 | |||
1199 | temp_pointer = (char *) buffer; | ||
1200 | |||
1201 | /* | ||
1202 | * Copy the string | ||
1203 | */ | ||
1204 | ACPI_STRCPY (temp_pointer, linked_list->data.address64.resource_source.string_ptr); | ||
1205 | |||
1206 | /* | ||
1207 | * Buffer needs to be set to the length of the sting + one for the | ||
1208 | * terminating null | ||
1209 | */ | ||
1210 | buffer += (acpi_size)(ACPI_STRLEN (linked_list->data.address64.resource_source.string_ptr) + 1); | ||
1211 | } | ||
1212 | |||
1213 | /* | ||
1214 | * Return the number of bytes consumed in this operation | ||
1215 | */ | ||
1216 | *bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer); | ||
1217 | |||
1218 | /* | ||
1219 | * Set the length field to the number of bytes consumed | ||
1220 | * minus the header size (3 bytes) | ||
1221 | */ | ||
1222 | *length_field = (u16) (*bytes_consumed - 3); | ||
1223 | return_ACPI_STATUS (AE_OK); | ||
1224 | } | ||
1225 | |||
diff --git a/drivers/acpi/resources/rscalc.c b/drivers/acpi/resources/rscalc.c new file mode 100644 index 000000000000..8a5f0a52371d --- /dev/null +++ b/drivers/acpi/resources/rscalc.c | |||
@@ -0,0 +1,841 @@ | |||
1 | /******************************************************************************* | ||
2 | * | ||
3 | * Module Name: rscalc - Calculate stream and list lengths | ||
4 | * | ||
5 | ******************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2005, R. Byron Moore | ||
9 | * All rights reserved. | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions, and the following disclaimer, | ||
16 | * without modification. | ||
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
18 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
19 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
20 | * including a substantially similar Disclaimer requirement for further | ||
21 | * binary redistribution. | ||
22 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
23 | * of any contributors may be used to endorse or promote products derived | ||
24 | * from this software without specific prior written permission. | ||
25 | * | ||
26 | * Alternatively, this software may be distributed under the terms of the | ||
27 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
28 | * Software Foundation. | ||
29 | * | ||
30 | * NO WARRANTY | ||
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
41 | * POSSIBILITY OF SUCH DAMAGES. | ||
42 | */ | ||
43 | |||
44 | |||
45 | #include <acpi/acpi.h> | ||
46 | #include <acpi/acresrc.h> | ||
47 | #include <acpi/amlcode.h> | ||
48 | #include <acpi/acnamesp.h> | ||
49 | |||
50 | #define _COMPONENT ACPI_RESOURCES | ||
51 | ACPI_MODULE_NAME ("rscalc") | ||
52 | |||
53 | |||
54 | /******************************************************************************* | ||
55 | * | ||
56 | * FUNCTION: acpi_rs_get_byte_stream_length | ||
57 | * | ||
58 | * PARAMETERS: linked_list - Pointer to the resource linked list | ||
59 | * size_needed - u32 pointer of the size buffer needed | ||
60 | * to properly return the parsed data | ||
61 | * | ||
62 | * RETURN: Status | ||
63 | * | ||
64 | * DESCRIPTION: Takes the resource byte stream and parses it once, calculating | ||
65 | * the size buffer needed to hold the linked list that conveys | ||
66 | * the resource data. | ||
67 | * | ||
68 | ******************************************************************************/ | ||
69 | |||
70 | acpi_status | ||
71 | acpi_rs_get_byte_stream_length ( | ||
72 | struct acpi_resource *linked_list, | ||
73 | acpi_size *size_needed) | ||
74 | { | ||
75 | acpi_size byte_stream_size_needed = 0; | ||
76 | acpi_size segment_size; | ||
77 | u8 done = FALSE; | ||
78 | |||
79 | |||
80 | ACPI_FUNCTION_TRACE ("rs_get_byte_stream_length"); | ||
81 | |||
82 | |||
83 | while (!done) { | ||
84 | /* | ||
85 | * Init the variable that will hold the size to add to the total. | ||
86 | */ | ||
87 | segment_size = 0; | ||
88 | |||
89 | switch (linked_list->id) { | ||
90 | case ACPI_RSTYPE_IRQ: | ||
91 | /* | ||
92 | * IRQ Resource | ||
93 | * For an IRQ Resource, Byte 3, although optional, will always be | ||
94 | * created - it holds IRQ information. | ||
95 | */ | ||
96 | segment_size = 4; | ||
97 | break; | ||
98 | |||
99 | case ACPI_RSTYPE_DMA: | ||
100 | /* | ||
101 | * DMA Resource | ||
102 | * For this resource the size is static | ||
103 | */ | ||
104 | segment_size = 3; | ||
105 | break; | ||
106 | |||
107 | case ACPI_RSTYPE_START_DPF: | ||
108 | /* | ||
109 | * Start Dependent Functions Resource | ||
110 | * For a start_dependent_functions Resource, Byte 1, although | ||
111 | * optional, will always be created. | ||
112 | */ | ||
113 | segment_size = 2; | ||
114 | break; | ||
115 | |||
116 | case ACPI_RSTYPE_END_DPF: | ||
117 | /* | ||
118 | * End Dependent Functions Resource | ||
119 | * For this resource the size is static | ||
120 | */ | ||
121 | segment_size = 1; | ||
122 | break; | ||
123 | |||
124 | case ACPI_RSTYPE_IO: | ||
125 | /* | ||
126 | * IO Port Resource | ||
127 | * For this resource the size is static | ||
128 | */ | ||
129 | segment_size = 8; | ||
130 | break; | ||
131 | |||
132 | case ACPI_RSTYPE_FIXED_IO: | ||
133 | /* | ||
134 | * Fixed IO Port Resource | ||
135 | * For this resource the size is static | ||
136 | */ | ||
137 | segment_size = 4; | ||
138 | break; | ||
139 | |||
140 | case ACPI_RSTYPE_VENDOR: | ||
141 | /* | ||
142 | * Vendor Defined Resource | ||
143 | * For a Vendor Specific resource, if the Length is between 1 and 7 | ||
144 | * it will be created as a Small Resource data type, otherwise it | ||
145 | * is a Large Resource data type. | ||
146 | */ | ||
147 | if (linked_list->data.vendor_specific.length > 7) { | ||
148 | segment_size = 3; | ||
149 | } | ||
150 | else { | ||
151 | segment_size = 1; | ||
152 | } | ||
153 | segment_size += linked_list->data.vendor_specific.length; | ||
154 | break; | ||
155 | |||
156 | case ACPI_RSTYPE_END_TAG: | ||
157 | /* | ||
158 | * End Tag | ||
159 | * For this resource the size is static | ||
160 | */ | ||
161 | segment_size = 2; | ||
162 | done = TRUE; | ||
163 | break; | ||
164 | |||
165 | case ACPI_RSTYPE_MEM24: | ||
166 | /* | ||
167 | * 24-Bit Memory Resource | ||
168 | * For this resource the size is static | ||
169 | */ | ||
170 | segment_size = 12; | ||
171 | break; | ||
172 | |||
173 | case ACPI_RSTYPE_MEM32: | ||
174 | /* | ||
175 | * 32-Bit Memory Range Resource | ||
176 | * For this resource the size is static | ||
177 | */ | ||
178 | segment_size = 20; | ||
179 | break; | ||
180 | |||
181 | case ACPI_RSTYPE_FIXED_MEM32: | ||
182 | /* | ||
183 | * 32-Bit Fixed Memory Resource | ||
184 | * For this resource the size is static | ||
185 | */ | ||
186 | segment_size = 12; | ||
187 | break; | ||
188 | |||
189 | case ACPI_RSTYPE_ADDRESS16: | ||
190 | /* | ||
191 | * 16-Bit Address Resource | ||
192 | * The base size of this byte stream is 16. If a Resource Source | ||
193 | * string is not NULL, add 1 for the Index + the length of the null | ||
194 | * terminated string Resource Source + 1 for the null. | ||
195 | */ | ||
196 | segment_size = 16; | ||
197 | |||
198 | if (linked_list->data.address16.resource_source.string_ptr) { | ||
199 | segment_size += linked_list->data.address16.resource_source.string_length; | ||
200 | segment_size++; | ||
201 | } | ||
202 | break; | ||
203 | |||
204 | case ACPI_RSTYPE_ADDRESS32: | ||
205 | /* | ||
206 | * 32-Bit Address Resource | ||
207 | * The base size of this byte stream is 26. If a Resource | ||
208 | * Source string is not NULL, add 1 for the Index + the | ||
209 | * length of the null terminated string Resource Source + | ||
210 | * 1 for the null. | ||
211 | */ | ||
212 | segment_size = 26; | ||
213 | |||
214 | if (linked_list->data.address32.resource_source.string_ptr) { | ||
215 | segment_size += linked_list->data.address32.resource_source.string_length; | ||
216 | segment_size++; | ||
217 | } | ||
218 | break; | ||
219 | |||
220 | case ACPI_RSTYPE_ADDRESS64: | ||
221 | /* | ||
222 | * 64-Bit Address Resource | ||
223 | * The base size of this byte stream is 46. If a resource_source | ||
224 | * string is not NULL, add 1 for the Index + the length of the null | ||
225 | * terminated string Resource Source + 1 for the null. | ||
226 | */ | ||
227 | segment_size = 46; | ||
228 | |||
229 | if (linked_list->data.address64.resource_source.string_ptr) { | ||
230 | segment_size += linked_list->data.address64.resource_source.string_length; | ||
231 | segment_size++; | ||
232 | } | ||
233 | break; | ||
234 | |||
235 | case ACPI_RSTYPE_EXT_IRQ: | ||
236 | /* | ||
237 | * Extended IRQ Resource | ||
238 | * The base size of this byte stream is 9. This is for an Interrupt | ||
239 | * table length of 1. For each additional interrupt, add 4. | ||
240 | * If a Resource Source string is not NULL, add 1 for the | ||
241 | * Index + the length of the null terminated string | ||
242 | * Resource Source + 1 for the null. | ||
243 | */ | ||
244 | segment_size = 9 + | ||
245 | (((acpi_size) linked_list->data.extended_irq.number_of_interrupts - 1) * 4); | ||
246 | |||
247 | if (linked_list->data.extended_irq.resource_source.string_ptr) { | ||
248 | segment_size += linked_list->data.extended_irq.resource_source.string_length; | ||
249 | segment_size++; | ||
250 | } | ||
251 | break; | ||
252 | |||
253 | default: | ||
254 | /* | ||
255 | * If we get here, everything is out of sync, exit with error | ||
256 | */ | ||
257 | return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE); | ||
258 | |||
259 | } /* switch (linked_list->Id) */ | ||
260 | |||
261 | /* | ||
262 | * Update the total | ||
263 | */ | ||
264 | byte_stream_size_needed += segment_size; | ||
265 | |||
266 | /* | ||
267 | * Point to the next object | ||
268 | */ | ||
269 | linked_list = ACPI_PTR_ADD (struct acpi_resource, | ||
270 | linked_list, linked_list->length); | ||
271 | } | ||
272 | |||
273 | /* | ||
274 | * This is the data the caller needs | ||
275 | */ | ||
276 | *size_needed = byte_stream_size_needed; | ||
277 | return_ACPI_STATUS (AE_OK); | ||
278 | } | ||
279 | |||
280 | |||
281 | /******************************************************************************* | ||
282 | * | ||
283 | * FUNCTION: acpi_rs_get_list_length | ||
284 | * | ||
285 | * PARAMETERS: byte_stream_buffer - Pointer to the resource byte stream | ||
286 | * byte_stream_buffer_length - Size of byte_stream_buffer | ||
287 | * size_needed - u32 pointer of the size buffer | ||
288 | * needed to properly return the | ||
289 | * parsed data | ||
290 | * | ||
291 | * RETURN: Status | ||
292 | * | ||
293 | * DESCRIPTION: Takes the resource byte stream and parses it once, calculating | ||
294 | * the size buffer needed to hold the linked list that conveys | ||
295 | * the resource data. | ||
296 | * | ||
297 | ******************************************************************************/ | ||
298 | |||
299 | acpi_status | ||
300 | acpi_rs_get_list_length ( | ||
301 | u8 *byte_stream_buffer, | ||
302 | u32 byte_stream_buffer_length, | ||
303 | acpi_size *size_needed) | ||
304 | { | ||
305 | u32 buffer_size = 0; | ||
306 | u32 bytes_parsed = 0; | ||
307 | u8 number_of_interrupts = 0; | ||
308 | u8 number_of_channels = 0; | ||
309 | u8 resource_type; | ||
310 | u32 structure_size; | ||
311 | u32 bytes_consumed; | ||
312 | u8 *buffer; | ||
313 | u8 temp8; | ||
314 | u16 temp16; | ||
315 | u8 index; | ||
316 | u8 additional_bytes; | ||
317 | |||
318 | |||
319 | ACPI_FUNCTION_TRACE ("rs_get_list_length"); | ||
320 | |||
321 | |||
322 | while (bytes_parsed < byte_stream_buffer_length) { | ||
323 | /* | ||
324 | * The next byte in the stream is the resource type | ||
325 | */ | ||
326 | resource_type = acpi_rs_get_resource_type (*byte_stream_buffer); | ||
327 | |||
328 | switch (resource_type) { | ||
329 | case ACPI_RDESC_TYPE_MEMORY_24: | ||
330 | /* | ||
331 | * 24-Bit Memory Resource | ||
332 | */ | ||
333 | bytes_consumed = 12; | ||
334 | |||
335 | structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_mem24); | ||
336 | break; | ||
337 | |||
338 | |||
339 | case ACPI_RDESC_TYPE_LARGE_VENDOR: | ||
340 | /* | ||
341 | * Vendor Defined Resource | ||
342 | */ | ||
343 | buffer = byte_stream_buffer; | ||
344 | ++buffer; | ||
345 | |||
346 | ACPI_MOVE_16_TO_16 (&temp16, buffer); | ||
347 | bytes_consumed = temp16 + 3; | ||
348 | |||
349 | /* | ||
350 | * Ensure a 32-bit boundary for the structure | ||
351 | */ | ||
352 | temp16 = (u16) ACPI_ROUND_UP_to_32_bITS (temp16); | ||
353 | |||
354 | structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_vendor) + | ||
355 | (temp16 * sizeof (u8)); | ||
356 | break; | ||
357 | |||
358 | |||
359 | case ACPI_RDESC_TYPE_MEMORY_32: | ||
360 | /* | ||
361 | * 32-Bit Memory Range Resource | ||
362 | */ | ||
363 | bytes_consumed = 20; | ||
364 | |||
365 | structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_mem32); | ||
366 | break; | ||
367 | |||
368 | |||
369 | case ACPI_RDESC_TYPE_FIXED_MEMORY_32: | ||
370 | /* | ||
371 | * 32-Bit Fixed Memory Resource | ||
372 | */ | ||
373 | bytes_consumed = 12; | ||
374 | |||
375 | structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_fixed_mem32); | ||
376 | break; | ||
377 | |||
378 | |||
379 | case ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE: | ||
380 | /* | ||
381 | * 64-Bit Address Resource | ||
382 | */ | ||
383 | buffer = byte_stream_buffer; | ||
384 | |||
385 | ++buffer; | ||
386 | ACPI_MOVE_16_TO_16 (&temp16, buffer); | ||
387 | |||
388 | bytes_consumed = temp16 + 3; | ||
389 | structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_address64); | ||
390 | break; | ||
391 | |||
392 | |||
393 | case ACPI_RDESC_TYPE_QWORD_ADDRESS_SPACE: | ||
394 | /* | ||
395 | * 64-Bit Address Resource | ||
396 | */ | ||
397 | buffer = byte_stream_buffer; | ||
398 | |||
399 | ++buffer; | ||
400 | ACPI_MOVE_16_TO_16 (&temp16, buffer); | ||
401 | |||
402 | bytes_consumed = temp16 + 3; | ||
403 | |||
404 | /* | ||
405 | * Resource Source Index and Resource Source are optional elements. | ||
406 | * Check the length of the Bytestream. If it is greater than 43, | ||
407 | * that means that an Index exists and is followed by a null | ||
408 | * terminated string. Therefore, set the temp variable to the | ||
409 | * length minus the minimum byte stream length plus the byte for | ||
410 | * the Index to determine the size of the NULL terminated string. | ||
411 | */ | ||
412 | if (43 < temp16) { | ||
413 | temp8 = (u8) (temp16 - 44); | ||
414 | } | ||
415 | else { | ||
416 | temp8 = 0; | ||
417 | } | ||
418 | |||
419 | /* | ||
420 | * Ensure a 64-bit boundary for the structure | ||
421 | */ | ||
422 | temp8 = (u8) ACPI_ROUND_UP_to_64_bITS (temp8); | ||
423 | |||
424 | structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_address64) + | ||
425 | (temp8 * sizeof (u8)); | ||
426 | break; | ||
427 | |||
428 | |||
429 | case ACPI_RDESC_TYPE_DWORD_ADDRESS_SPACE: | ||
430 | /* | ||
431 | * 32-Bit Address Resource | ||
432 | */ | ||
433 | buffer = byte_stream_buffer; | ||
434 | |||
435 | ++buffer; | ||
436 | ACPI_MOVE_16_TO_16 (&temp16, buffer); | ||
437 | |||
438 | bytes_consumed = temp16 + 3; | ||
439 | |||
440 | /* | ||
441 | * Resource Source Index and Resource Source are optional elements. | ||
442 | * Check the length of the Bytestream. If it is greater than 23, | ||
443 | * that means that an Index exists and is followed by a null | ||
444 | * terminated string. Therefore, set the temp variable to the | ||
445 | * length minus the minimum byte stream length plus the byte for | ||
446 | * the Index to determine the size of the NULL terminated string. | ||
447 | */ | ||
448 | if (23 < temp16) { | ||
449 | temp8 = (u8) (temp16 - 24); | ||
450 | } | ||
451 | else { | ||
452 | temp8 = 0; | ||
453 | } | ||
454 | |||
455 | /* | ||
456 | * Ensure a 32-bit boundary for the structure | ||
457 | */ | ||
458 | temp8 = (u8) ACPI_ROUND_UP_to_32_bITS (temp8); | ||
459 | |||
460 | structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_address32) + | ||
461 | (temp8 * sizeof (u8)); | ||
462 | break; | ||
463 | |||
464 | |||
465 | case ACPI_RDESC_TYPE_WORD_ADDRESS_SPACE: | ||
466 | /* | ||
467 | * 16-Bit Address Resource | ||
468 | */ | ||
469 | buffer = byte_stream_buffer; | ||
470 | |||
471 | ++buffer; | ||
472 | ACPI_MOVE_16_TO_16 (&temp16, buffer); | ||
473 | |||
474 | bytes_consumed = temp16 + 3; | ||
475 | |||
476 | /* | ||
477 | * Resource Source Index and Resource Source are optional elements. | ||
478 | * Check the length of the Bytestream. If it is greater than 13, | ||
479 | * that means that an Index exists and is followed by a null | ||
480 | * terminated string. Therefore, set the temp variable to the | ||
481 | * length minus the minimum byte stream length plus the byte for | ||
482 | * the Index to determine the size of the NULL terminated string. | ||
483 | */ | ||
484 | if (13 < temp16) { | ||
485 | temp8 = (u8) (temp16 - 14); | ||
486 | } | ||
487 | else { | ||
488 | temp8 = 0; | ||
489 | } | ||
490 | |||
491 | /* | ||
492 | * Ensure a 32-bit boundary for the structure | ||
493 | */ | ||
494 | temp8 = (u8) ACPI_ROUND_UP_to_32_bITS (temp8); | ||
495 | |||
496 | structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_address16) + | ||
497 | (temp8 * sizeof (u8)); | ||
498 | break; | ||
499 | |||
500 | |||
501 | case ACPI_RDESC_TYPE_EXTENDED_XRUPT: | ||
502 | /* | ||
503 | * Extended IRQ | ||
504 | */ | ||
505 | buffer = byte_stream_buffer; | ||
506 | |||
507 | ++buffer; | ||
508 | ACPI_MOVE_16_TO_16 (&temp16, buffer); | ||
509 | |||
510 | bytes_consumed = temp16 + 3; | ||
511 | |||
512 | /* | ||
513 | * Point past the length field and the Interrupt vector flags to | ||
514 | * save off the Interrupt table length to the Temp8 variable. | ||
515 | */ | ||
516 | buffer += 3; | ||
517 | temp8 = *buffer; | ||
518 | |||
519 | /* | ||
520 | * To compensate for multiple interrupt numbers, add 4 bytes for | ||
521 | * each additional interrupts greater than 1 | ||
522 | */ | ||
523 | additional_bytes = (u8) ((temp8 - 1) * 4); | ||
524 | |||
525 | /* | ||
526 | * Resource Source Index and Resource Source are optional elements. | ||
527 | * Check the length of the Bytestream. If it is greater than 9, | ||
528 | * that means that an Index exists and is followed by a null | ||
529 | * terminated string. Therefore, set the temp variable to the | ||
530 | * length minus the minimum byte stream length plus the byte for | ||
531 | * the Index to determine the size of the NULL terminated string. | ||
532 | */ | ||
533 | if (9 + additional_bytes < temp16) { | ||
534 | temp8 = (u8) (temp16 - (9 + additional_bytes)); | ||
535 | } | ||
536 | else { | ||
537 | temp8 = 0; | ||
538 | } | ||
539 | |||
540 | /* | ||
541 | * Ensure a 32-bit boundary for the structure | ||
542 | */ | ||
543 | temp8 = (u8) ACPI_ROUND_UP_to_32_bITS (temp8); | ||
544 | |||
545 | structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_ext_irq) + | ||
546 | (additional_bytes * sizeof (u8)) + | ||
547 | (temp8 * sizeof (u8)); | ||
548 | break; | ||
549 | |||
550 | |||
551 | case ACPI_RDESC_TYPE_IRQ_FORMAT: | ||
552 | /* | ||
553 | * IRQ Resource. | ||
554 | * Determine if it there are two or three trailing bytes | ||
555 | */ | ||
556 | buffer = byte_stream_buffer; | ||
557 | temp8 = *buffer; | ||
558 | |||
559 | if(temp8 & 0x01) { | ||
560 | bytes_consumed = 4; | ||
561 | } | ||
562 | else { | ||
563 | bytes_consumed = 3; | ||
564 | } | ||
565 | |||
566 | /* Point past the descriptor */ | ||
567 | |||
568 | ++buffer; | ||
569 | |||
570 | /* | ||
571 | * Look at the number of bits set | ||
572 | */ | ||
573 | ACPI_MOVE_16_TO_16 (&temp16, buffer); | ||
574 | |||
575 | for (index = 0; index < 16; index++) { | ||
576 | if (temp16 & 0x1) { | ||
577 | ++number_of_interrupts; | ||
578 | } | ||
579 | |||
580 | temp16 >>= 1; | ||
581 | } | ||
582 | |||
583 | structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_io) + | ||
584 | (number_of_interrupts * sizeof (u32)); | ||
585 | break; | ||
586 | |||
587 | |||
588 | case ACPI_RDESC_TYPE_DMA_FORMAT: | ||
589 | /* | ||
590 | * DMA Resource | ||
591 | */ | ||
592 | buffer = byte_stream_buffer; | ||
593 | bytes_consumed = 3; | ||
594 | |||
595 | /* Point past the descriptor */ | ||
596 | |||
597 | ++buffer; | ||
598 | |||
599 | /* | ||
600 | * Look at the number of bits set | ||
601 | */ | ||
602 | temp8 = *buffer; | ||
603 | |||
604 | for(index = 0; index < 8; index++) { | ||
605 | if(temp8 & 0x1) { | ||
606 | ++number_of_channels; | ||
607 | } | ||
608 | |||
609 | temp8 >>= 1; | ||
610 | } | ||
611 | |||
612 | structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_dma) + | ||
613 | (number_of_channels * sizeof (u32)); | ||
614 | break; | ||
615 | |||
616 | |||
617 | case ACPI_RDESC_TYPE_START_DEPENDENT: | ||
618 | /* | ||
619 | * Start Dependent Functions Resource | ||
620 | * Determine if it there are two or three trailing bytes | ||
621 | */ | ||
622 | buffer = byte_stream_buffer; | ||
623 | temp8 = *buffer; | ||
624 | |||
625 | if(temp8 & 0x01) { | ||
626 | bytes_consumed = 2; | ||
627 | } | ||
628 | else { | ||
629 | bytes_consumed = 1; | ||
630 | } | ||
631 | |||
632 | structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_start_dpf); | ||
633 | break; | ||
634 | |||
635 | |||
636 | case ACPI_RDESC_TYPE_END_DEPENDENT: | ||
637 | /* | ||
638 | * End Dependent Functions Resource | ||
639 | */ | ||
640 | bytes_consumed = 1; | ||
641 | structure_size = ACPI_RESOURCE_LENGTH; | ||
642 | break; | ||
643 | |||
644 | |||
645 | case ACPI_RDESC_TYPE_IO_PORT: | ||
646 | /* | ||
647 | * IO Port Resource | ||
648 | */ | ||
649 | bytes_consumed = 8; | ||
650 | structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_io); | ||
651 | break; | ||
652 | |||
653 | |||
654 | case ACPI_RDESC_TYPE_FIXED_IO_PORT: | ||
655 | /* | ||
656 | * Fixed IO Port Resource | ||
657 | */ | ||
658 | bytes_consumed = 4; | ||
659 | structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_fixed_io); | ||
660 | break; | ||
661 | |||
662 | |||
663 | case ACPI_RDESC_TYPE_SMALL_VENDOR: | ||
664 | /* | ||
665 | * Vendor Specific Resource | ||
666 | */ | ||
667 | buffer = byte_stream_buffer; | ||
668 | |||
669 | temp8 = *buffer; | ||
670 | temp8 = (u8) (temp8 & 0x7); | ||
671 | bytes_consumed = temp8 + 1; | ||
672 | |||
673 | /* | ||
674 | * Ensure a 32-bit boundary for the structure | ||
675 | */ | ||
676 | temp8 = (u8) ACPI_ROUND_UP_to_32_bITS (temp8); | ||
677 | structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_vendor) + | ||
678 | (temp8 * sizeof (u8)); | ||
679 | break; | ||
680 | |||
681 | |||
682 | case ACPI_RDESC_TYPE_END_TAG: | ||
683 | /* | ||
684 | * End Tag | ||
685 | */ | ||
686 | bytes_consumed = 2; | ||
687 | structure_size = ACPI_RESOURCE_LENGTH; | ||
688 | byte_stream_buffer_length = bytes_parsed; | ||
689 | break; | ||
690 | |||
691 | |||
692 | default: | ||
693 | /* | ||
694 | * If we get here, everything is out of sync, | ||
695 | * exit with an error | ||
696 | */ | ||
697 | return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE); | ||
698 | } | ||
699 | |||
700 | /* | ||
701 | * Update the return value and counter | ||
702 | */ | ||
703 | buffer_size += (u32) ACPI_ALIGN_RESOURCE_SIZE (structure_size); | ||
704 | bytes_parsed += bytes_consumed; | ||
705 | |||
706 | /* | ||
707 | * Set the byte stream to point to the next resource | ||
708 | */ | ||
709 | byte_stream_buffer += bytes_consumed; | ||
710 | } | ||
711 | |||
712 | /* | ||
713 | * This is the data the caller needs | ||
714 | */ | ||
715 | *size_needed = buffer_size; | ||
716 | return_ACPI_STATUS (AE_OK); | ||
717 | } | ||
718 | |||
719 | |||
720 | /******************************************************************************* | ||
721 | * | ||
722 | * FUNCTION: acpi_rs_get_pci_routing_table_length | ||
723 | * | ||
724 | * PARAMETERS: package_object - Pointer to the package object | ||
725 | * buffer_size_needed - u32 pointer of the size buffer | ||
726 | * needed to properly return the | ||
727 | * parsed data | ||
728 | * | ||
729 | * RETURN: Status | ||
730 | * | ||
731 | * DESCRIPTION: Given a package representing a PCI routing table, this | ||
732 | * calculates the size of the corresponding linked list of | ||
733 | * descriptions. | ||
734 | * | ||
735 | ******************************************************************************/ | ||
736 | |||
737 | acpi_status | ||
738 | acpi_rs_get_pci_routing_table_length ( | ||
739 | union acpi_operand_object *package_object, | ||
740 | acpi_size *buffer_size_needed) | ||
741 | { | ||
742 | u32 number_of_elements; | ||
743 | acpi_size temp_size_needed = 0; | ||
744 | union acpi_operand_object **top_object_list; | ||
745 | u32 index; | ||
746 | union acpi_operand_object *package_element; | ||
747 | union acpi_operand_object **sub_object_list; | ||
748 | u8 name_found; | ||
749 | u32 table_index; | ||
750 | |||
751 | |||
752 | ACPI_FUNCTION_TRACE ("rs_get_pci_routing_table_length"); | ||
753 | |||
754 | |||
755 | number_of_elements = package_object->package.count; | ||
756 | |||
757 | /* | ||
758 | * Calculate the size of the return buffer. | ||
759 | * The base size is the number of elements * the sizes of the | ||
760 | * structures. Additional space for the strings is added below. | ||
761 | * The minus one is to subtract the size of the u8 Source[1] | ||
762 | * member because it is added below. | ||
763 | * | ||
764 | * But each PRT_ENTRY structure has a pointer to a string and | ||
765 | * the size of that string must be found. | ||
766 | */ | ||
767 | top_object_list = package_object->package.elements; | ||
768 | |||
769 | for (index = 0; index < number_of_elements; index++) { | ||
770 | /* | ||
771 | * Dereference the sub-package | ||
772 | */ | ||
773 | package_element = *top_object_list; | ||
774 | |||
775 | /* | ||
776 | * The sub_object_list will now point to an array of the | ||
777 | * four IRQ elements: Address, Pin, Source and source_index | ||
778 | */ | ||
779 | sub_object_list = package_element->package.elements; | ||
780 | |||
781 | /* | ||
782 | * Scan the irq_table_elements for the Source Name String | ||
783 | */ | ||
784 | name_found = FALSE; | ||
785 | |||
786 | for (table_index = 0; table_index < 4 && !name_found; table_index++) { | ||
787 | if ((ACPI_TYPE_STRING == ACPI_GET_OBJECT_TYPE (*sub_object_list)) || | ||
788 | ((ACPI_TYPE_LOCAL_REFERENCE == ACPI_GET_OBJECT_TYPE (*sub_object_list)) && | ||
789 | ((*sub_object_list)->reference.opcode == AML_INT_NAMEPATH_OP))) { | ||
790 | name_found = TRUE; | ||
791 | } | ||
792 | else { | ||
793 | /* | ||
794 | * Look at the next element | ||
795 | */ | ||
796 | sub_object_list++; | ||
797 | } | ||
798 | } | ||
799 | |||
800 | temp_size_needed += (sizeof (struct acpi_pci_routing_table) - 4); | ||
801 | |||
802 | /* | ||
803 | * Was a String type found? | ||
804 | */ | ||
805 | if (name_found) { | ||
806 | if (ACPI_GET_OBJECT_TYPE (*sub_object_list) == ACPI_TYPE_STRING) { | ||
807 | /* | ||
808 | * The length String.Length field does not include the | ||
809 | * terminating NULL, add 1 | ||
810 | */ | ||
811 | temp_size_needed += ((acpi_size) (*sub_object_list)->string.length + 1); | ||
812 | } | ||
813 | else { | ||
814 | temp_size_needed += acpi_ns_get_pathname_length ( | ||
815 | (*sub_object_list)->reference.node); | ||
816 | } | ||
817 | } | ||
818 | else { | ||
819 | /* | ||
820 | * If no name was found, then this is a NULL, which is | ||
821 | * translated as a u32 zero. | ||
822 | */ | ||
823 | temp_size_needed += sizeof (u32); | ||
824 | } | ||
825 | |||
826 | /* Round up the size since each element must be aligned */ | ||
827 | |||
828 | temp_size_needed = ACPI_ROUND_UP_to_64_bITS (temp_size_needed); | ||
829 | |||
830 | /* | ||
831 | * Point to the next union acpi_operand_object | ||
832 | */ | ||
833 | top_object_list++; | ||
834 | } | ||
835 | |||
836 | /* | ||
837 | * Adding an extra element to the end of the list, essentially a NULL terminator | ||
838 | */ | ||
839 | *buffer_size_needed = temp_size_needed + sizeof (struct acpi_pci_routing_table); | ||
840 | return_ACPI_STATUS (AE_OK); | ||
841 | } | ||
diff --git a/drivers/acpi/resources/rscreate.c b/drivers/acpi/resources/rscreate.c new file mode 100644 index 000000000000..a3a0cbfda68d --- /dev/null +++ b/drivers/acpi/resources/rscreate.c | |||
@@ -0,0 +1,428 @@ | |||
1 | /******************************************************************************* | ||
2 | * | ||
3 | * Module Name: rscreate - Create resource lists/tables | ||
4 | * | ||
5 | ******************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2005, R. Byron Moore | ||
9 | * All rights reserved. | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions, and the following disclaimer, | ||
16 | * without modification. | ||
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
18 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
19 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
20 | * including a substantially similar Disclaimer requirement for further | ||
21 | * binary redistribution. | ||
22 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
23 | * of any contributors may be used to endorse or promote products derived | ||
24 | * from this software without specific prior written permission. | ||
25 | * | ||
26 | * Alternatively, this software may be distributed under the terms of the | ||
27 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
28 | * Software Foundation. | ||
29 | * | ||
30 | * NO WARRANTY | ||
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
41 | * POSSIBILITY OF SUCH DAMAGES. | ||
42 | */ | ||
43 | |||
44 | |||
45 | #include <acpi/acpi.h> | ||
46 | #include <acpi/acresrc.h> | ||
47 | #include <acpi/amlcode.h> | ||
48 | #include <acpi/acnamesp.h> | ||
49 | |||
50 | #define _COMPONENT ACPI_RESOURCES | ||
51 | ACPI_MODULE_NAME ("rscreate") | ||
52 | |||
53 | |||
54 | /******************************************************************************* | ||
55 | * | ||
56 | * FUNCTION: acpi_rs_create_resource_list | ||
57 | * | ||
58 | * PARAMETERS: byte_stream_buffer - Pointer to the resource byte stream | ||
59 | * output_buffer - Pointer to the user's buffer | ||
60 | * | ||
61 | * RETURN: Status - AE_OK if okay, else a valid acpi_status code | ||
62 | * If output_buffer is not large enough, output_buffer_length | ||
63 | * indicates how large output_buffer should be, else it | ||
64 | * indicates how may u8 elements of output_buffer are valid. | ||
65 | * | ||
66 | * DESCRIPTION: Takes the byte stream returned from a _CRS, _PRS control method | ||
67 | * execution and parses the stream to create a linked list | ||
68 | * of device resources. | ||
69 | * | ||
70 | ******************************************************************************/ | ||
71 | |||
72 | acpi_status | ||
73 | acpi_rs_create_resource_list ( | ||
74 | union acpi_operand_object *byte_stream_buffer, | ||
75 | struct acpi_buffer *output_buffer) | ||
76 | { | ||
77 | |||
78 | acpi_status status; | ||
79 | u8 *byte_stream_start; | ||
80 | acpi_size list_size_needed = 0; | ||
81 | u32 byte_stream_buffer_length; | ||
82 | |||
83 | |||
84 | ACPI_FUNCTION_TRACE ("rs_create_resource_list"); | ||
85 | |||
86 | |||
87 | ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "byte_stream_buffer = %p\n", | ||
88 | byte_stream_buffer)); | ||
89 | |||
90 | /* | ||
91 | * Params already validated, so we don't re-validate here | ||
92 | */ | ||
93 | byte_stream_buffer_length = byte_stream_buffer->buffer.length; | ||
94 | byte_stream_start = byte_stream_buffer->buffer.pointer; | ||
95 | |||
96 | /* | ||
97 | * Pass the byte_stream_buffer into a module that can calculate | ||
98 | * the buffer size needed for the linked list | ||
99 | */ | ||
100 | status = acpi_rs_get_list_length (byte_stream_start, byte_stream_buffer_length, | ||
101 | &list_size_needed); | ||
102 | |||
103 | ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Status=%X list_size_needed=%X\n", | ||
104 | status, (u32) list_size_needed)); | ||
105 | if (ACPI_FAILURE (status)) { | ||
106 | return_ACPI_STATUS (status); | ||
107 | } | ||
108 | |||
109 | /* Validate/Allocate/Clear caller buffer */ | ||
110 | |||
111 | status = acpi_ut_initialize_buffer (output_buffer, list_size_needed); | ||
112 | if (ACPI_FAILURE (status)) { | ||
113 | return_ACPI_STATUS (status); | ||
114 | } | ||
115 | |||
116 | /* Do the conversion */ | ||
117 | |||
118 | status = acpi_rs_byte_stream_to_list (byte_stream_start, byte_stream_buffer_length, | ||
119 | output_buffer->pointer); | ||
120 | if (ACPI_FAILURE (status)) { | ||
121 | return_ACPI_STATUS (status); | ||
122 | } | ||
123 | |||
124 | ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "output_buffer %p Length %X\n", | ||
125 | output_buffer->pointer, (u32) output_buffer->length)); | ||
126 | return_ACPI_STATUS (AE_OK); | ||
127 | } | ||
128 | |||
129 | |||
130 | /******************************************************************************* | ||
131 | * | ||
132 | * FUNCTION: acpi_rs_create_pci_routing_table | ||
133 | * | ||
134 | * PARAMETERS: package_object - Pointer to an union acpi_operand_object | ||
135 | * package | ||
136 | * output_buffer - Pointer to the user's buffer | ||
137 | * | ||
138 | * RETURN: Status AE_OK if okay, else a valid acpi_status code. | ||
139 | * If the output_buffer is too small, the error will be | ||
140 | * AE_BUFFER_OVERFLOW and output_buffer->Length will point | ||
141 | * to the size buffer needed. | ||
142 | * | ||
143 | * DESCRIPTION: Takes the union acpi_operand_object package and creates a | ||
144 | * linked list of PCI interrupt descriptions | ||
145 | * | ||
146 | * NOTE: It is the caller's responsibility to ensure that the start of the | ||
147 | * output buffer is aligned properly (if necessary). | ||
148 | * | ||
149 | ******************************************************************************/ | ||
150 | |||
151 | acpi_status | ||
152 | acpi_rs_create_pci_routing_table ( | ||
153 | union acpi_operand_object *package_object, | ||
154 | struct acpi_buffer *output_buffer) | ||
155 | { | ||
156 | u8 *buffer; | ||
157 | union acpi_operand_object **top_object_list; | ||
158 | union acpi_operand_object **sub_object_list; | ||
159 | union acpi_operand_object *obj_desc; | ||
160 | acpi_size buffer_size_needed = 0; | ||
161 | u32 number_of_elements; | ||
162 | u32 index; | ||
163 | struct acpi_pci_routing_table *user_prt; | ||
164 | struct acpi_namespace_node *node; | ||
165 | acpi_status status; | ||
166 | struct acpi_buffer path_buffer; | ||
167 | |||
168 | |||
169 | ACPI_FUNCTION_TRACE ("rs_create_pci_routing_table"); | ||
170 | |||
171 | |||
172 | /* Params already validated, so we don't re-validate here */ | ||
173 | |||
174 | /* | ||
175 | * Get the required buffer length | ||
176 | */ | ||
177 | status = acpi_rs_get_pci_routing_table_length (package_object, | ||
178 | &buffer_size_needed); | ||
179 | if (ACPI_FAILURE (status)) { | ||
180 | return_ACPI_STATUS (status); | ||
181 | } | ||
182 | |||
183 | ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "buffer_size_needed = %X\n", | ||
184 | (u32) buffer_size_needed)); | ||
185 | |||
186 | /* Validate/Allocate/Clear caller buffer */ | ||
187 | |||
188 | status = acpi_ut_initialize_buffer (output_buffer, buffer_size_needed); | ||
189 | if (ACPI_FAILURE (status)) { | ||
190 | return_ACPI_STATUS (status); | ||
191 | } | ||
192 | |||
193 | /* | ||
194 | * Loop through the ACPI_INTERNAL_OBJECTS - Each object | ||
195 | * should be a package that in turn contains an | ||
196 | * acpi_integer Address, a u8 Pin, a Name and a u8 source_index. | ||
197 | */ | ||
198 | top_object_list = package_object->package.elements; | ||
199 | number_of_elements = package_object->package.count; | ||
200 | buffer = output_buffer->pointer; | ||
201 | user_prt = ACPI_CAST_PTR (struct acpi_pci_routing_table, buffer); | ||
202 | |||
203 | for (index = 0; index < number_of_elements; index++) { | ||
204 | /* | ||
205 | * Point user_prt past this current structure | ||
206 | * | ||
207 | * NOTE: On the first iteration, user_prt->Length will | ||
208 | * be zero because we cleared the return buffer earlier | ||
209 | */ | ||
210 | buffer += user_prt->length; | ||
211 | user_prt = ACPI_CAST_PTR (struct acpi_pci_routing_table, buffer); | ||
212 | |||
213 | /* | ||
214 | * Fill in the Length field with the information we have at this point. | ||
215 | * The minus four is to subtract the size of the u8 Source[4] member | ||
216 | * because it is added below. | ||
217 | */ | ||
218 | user_prt->length = (sizeof (struct acpi_pci_routing_table) - 4); | ||
219 | |||
220 | /* | ||
221 | * Each element of the top-level package must also be a package | ||
222 | */ | ||
223 | if (ACPI_GET_OBJECT_TYPE (*top_object_list) != ACPI_TYPE_PACKAGE) { | ||
224 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, | ||
225 | "(PRT[%X]) Need sub-package, found %s\n", | ||
226 | index, acpi_ut_get_object_type_name (*top_object_list))); | ||
227 | return_ACPI_STATUS (AE_AML_OPERAND_TYPE); | ||
228 | } | ||
229 | |||
230 | /* Each sub-package must be of length 4 */ | ||
231 | |||
232 | if ((*top_object_list)->package.count != 4) { | ||
233 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, | ||
234 | "(PRT[%X]) Need package of length 4, found length %d\n", | ||
235 | index, (*top_object_list)->package.count)); | ||
236 | return_ACPI_STATUS (AE_AML_PACKAGE_LIMIT); | ||
237 | } | ||
238 | |||
239 | /* | ||
240 | * Dereference the sub-package. | ||
241 | * The sub_object_list will now point to an array of the four IRQ | ||
242 | * elements: [Address, Pin, Source, source_index] | ||
243 | */ | ||
244 | sub_object_list = (*top_object_list)->package.elements; | ||
245 | |||
246 | /* | ||
247 | * 1) First subobject: Dereference the PRT.Address | ||
248 | */ | ||
249 | obj_desc = sub_object_list[0]; | ||
250 | if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) { | ||
251 | user_prt->address = obj_desc->integer.value; | ||
252 | } | ||
253 | else { | ||
254 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, | ||
255 | "(PRT[%X].Address) Need Integer, found %s\n", | ||
256 | index, acpi_ut_get_object_type_name (obj_desc))); | ||
257 | return_ACPI_STATUS (AE_BAD_DATA); | ||
258 | } | ||
259 | |||
260 | /* | ||
261 | * 2) Second subobject: Dereference the PRT.Pin | ||
262 | */ | ||
263 | obj_desc = sub_object_list[1]; | ||
264 | if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) { | ||
265 | user_prt->pin = (u32) obj_desc->integer.value; | ||
266 | } | ||
267 | else { | ||
268 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, | ||
269 | "(PRT[%X].Pin) Need Integer, found %s\n", | ||
270 | index, acpi_ut_get_object_type_name (obj_desc))); | ||
271 | return_ACPI_STATUS (AE_BAD_DATA); | ||
272 | } | ||
273 | |||
274 | /* | ||
275 | * 3) Third subobject: Dereference the PRT.source_name | ||
276 | */ | ||
277 | obj_desc = sub_object_list[2]; | ||
278 | switch (ACPI_GET_OBJECT_TYPE (obj_desc)) { | ||
279 | case ACPI_TYPE_LOCAL_REFERENCE: | ||
280 | |||
281 | if (obj_desc->reference.opcode != AML_INT_NAMEPATH_OP) { | ||
282 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, | ||
283 | "(PRT[%X].Source) Need name, found reference op %X\n", | ||
284 | index, obj_desc->reference.opcode)); | ||
285 | return_ACPI_STATUS (AE_BAD_DATA); | ||
286 | } | ||
287 | |||
288 | node = obj_desc->reference.node; | ||
289 | |||
290 | /* Use *remaining* length of the buffer as max for pathname */ | ||
291 | |||
292 | path_buffer.length = output_buffer->length - | ||
293 | (u32) ((u8 *) user_prt->source - | ||
294 | (u8 *) output_buffer->pointer); | ||
295 | path_buffer.pointer = user_prt->source; | ||
296 | |||
297 | status = acpi_ns_handle_to_pathname ((acpi_handle) node, &path_buffer); | ||
298 | |||
299 | user_prt->length += (u32) ACPI_STRLEN (user_prt->source) + 1; /* include null terminator */ | ||
300 | break; | ||
301 | |||
302 | |||
303 | case ACPI_TYPE_STRING: | ||
304 | |||
305 | ACPI_STRCPY (user_prt->source, obj_desc->string.pointer); | ||
306 | |||
307 | /* Add to the Length field the length of the string (add 1 for terminator) */ | ||
308 | |||
309 | user_prt->length += obj_desc->string.length + 1; | ||
310 | break; | ||
311 | |||
312 | |||
313 | case ACPI_TYPE_INTEGER: | ||
314 | /* | ||
315 | * If this is a number, then the Source Name is NULL, since the | ||
316 | * entire buffer was zeroed out, we can leave this alone. | ||
317 | * | ||
318 | * Add to the Length field the length of the u32 NULL | ||
319 | */ | ||
320 | user_prt->length += sizeof (u32); | ||
321 | break; | ||
322 | |||
323 | |||
324 | default: | ||
325 | |||
326 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, | ||
327 | "(PRT[%X].Source) Need Ref/String/Integer, found %s\n", | ||
328 | index, acpi_ut_get_object_type_name (obj_desc))); | ||
329 | return_ACPI_STATUS (AE_BAD_DATA); | ||
330 | } | ||
331 | |||
332 | /* Now align the current length */ | ||
333 | |||
334 | user_prt->length = (u32) ACPI_ROUND_UP_to_64_bITS (user_prt->length); | ||
335 | |||
336 | /* | ||
337 | * 4) Fourth subobject: Dereference the PRT.source_index | ||
338 | */ | ||
339 | obj_desc = sub_object_list[3]; | ||
340 | if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) { | ||
341 | user_prt->source_index = (u32) obj_desc->integer.value; | ||
342 | } | ||
343 | else { | ||
344 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, | ||
345 | "(PRT[%X].source_index) Need Integer, found %s\n", | ||
346 | index, acpi_ut_get_object_type_name (obj_desc))); | ||
347 | return_ACPI_STATUS (AE_BAD_DATA); | ||
348 | } | ||
349 | |||
350 | /* Point to the next union acpi_operand_object in the top level package */ | ||
351 | |||
352 | top_object_list++; | ||
353 | } | ||
354 | |||
355 | ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "output_buffer %p Length %X\n", | ||
356 | output_buffer->pointer, (u32) output_buffer->length)); | ||
357 | return_ACPI_STATUS (AE_OK); | ||
358 | } | ||
359 | |||
360 | |||
361 | /******************************************************************************* | ||
362 | * | ||
363 | * FUNCTION: acpi_rs_create_byte_stream | ||
364 | * | ||
365 | * PARAMETERS: linked_list_buffer - Pointer to the resource linked list | ||
366 | * output_buffer - Pointer to the user's buffer | ||
367 | * | ||
368 | * RETURN: Status AE_OK if okay, else a valid acpi_status code. | ||
369 | * If the output_buffer is too small, the error will be | ||
370 | * AE_BUFFER_OVERFLOW and output_buffer->Length will point | ||
371 | * to the size buffer needed. | ||
372 | * | ||
373 | * DESCRIPTION: Takes the linked list of device resources and | ||
374 | * creates a bytestream to be used as input for the | ||
375 | * _SRS control method. | ||
376 | * | ||
377 | ******************************************************************************/ | ||
378 | |||
379 | acpi_status | ||
380 | acpi_rs_create_byte_stream ( | ||
381 | struct acpi_resource *linked_list_buffer, | ||
382 | struct acpi_buffer *output_buffer) | ||
383 | { | ||
384 | acpi_status status; | ||
385 | acpi_size byte_stream_size_needed = 0; | ||
386 | |||
387 | |||
388 | ACPI_FUNCTION_TRACE ("rs_create_byte_stream"); | ||
389 | |||
390 | |||
391 | ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "linked_list_buffer = %p\n", | ||
392 | linked_list_buffer)); | ||
393 | |||
394 | /* | ||
395 | * Params already validated, so we don't re-validate here | ||
396 | * | ||
397 | * Pass the linked_list_buffer into a module that calculates | ||
398 | * the buffer size needed for the byte stream. | ||
399 | */ | ||
400 | status = acpi_rs_get_byte_stream_length (linked_list_buffer, | ||
401 | &byte_stream_size_needed); | ||
402 | |||
403 | ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "byte_stream_size_needed=%X, %s\n", | ||
404 | (u32) byte_stream_size_needed, acpi_format_exception (status))); | ||
405 | if (ACPI_FAILURE (status)) { | ||
406 | return_ACPI_STATUS (status); | ||
407 | } | ||
408 | |||
409 | /* Validate/Allocate/Clear caller buffer */ | ||
410 | |||
411 | status = acpi_ut_initialize_buffer (output_buffer, byte_stream_size_needed); | ||
412 | if (ACPI_FAILURE (status)) { | ||
413 | return_ACPI_STATUS (status); | ||
414 | } | ||
415 | |||
416 | /* Do the conversion */ | ||
417 | |||
418 | status = acpi_rs_list_to_byte_stream (linked_list_buffer, byte_stream_size_needed, | ||
419 | output_buffer->pointer); | ||
420 | if (ACPI_FAILURE (status)) { | ||
421 | return_ACPI_STATUS (status); | ||
422 | } | ||
423 | |||
424 | ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "output_buffer %p Length %X\n", | ||
425 | output_buffer->pointer, (u32) output_buffer->length)); | ||
426 | return_ACPI_STATUS (AE_OK); | ||
427 | } | ||
428 | |||
diff --git a/drivers/acpi/resources/rsdump.c b/drivers/acpi/resources/rsdump.c new file mode 100644 index 000000000000..eef1b1f2c685 --- /dev/null +++ b/drivers/acpi/resources/rsdump.c | |||
@@ -0,0 +1,1150 @@ | |||
1 | /******************************************************************************* | ||
2 | * | ||
3 | * Module Name: rsdump - Functions to display the resource structures. | ||
4 | * | ||
5 | ******************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2005, R. Byron Moore | ||
9 | * All rights reserved. | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions, and the following disclaimer, | ||
16 | * without modification. | ||
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
18 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
19 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
20 | * including a substantially similar Disclaimer requirement for further | ||
21 | * binary redistribution. | ||
22 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
23 | * of any contributors may be used to endorse or promote products derived | ||
24 | * from this software without specific prior written permission. | ||
25 | * | ||
26 | * Alternatively, this software may be distributed under the terms of the | ||
27 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
28 | * Software Foundation. | ||
29 | * | ||
30 | * NO WARRANTY | ||
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
41 | * POSSIBILITY OF SUCH DAMAGES. | ||
42 | */ | ||
43 | |||
44 | |||
45 | #include <acpi/acpi.h> | ||
46 | #include <acpi/acresrc.h> | ||
47 | |||
48 | #define _COMPONENT ACPI_RESOURCES | ||
49 | ACPI_MODULE_NAME ("rsdump") | ||
50 | |||
51 | |||
52 | #if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) | ||
53 | |||
54 | /******************************************************************************* | ||
55 | * | ||
56 | * FUNCTION: acpi_rs_dump_irq | ||
57 | * | ||
58 | * PARAMETERS: Data - pointer to the resource structure to dump. | ||
59 | * | ||
60 | * RETURN: None | ||
61 | * | ||
62 | * DESCRIPTION: Prints out the various members of the Data structure type. | ||
63 | * | ||
64 | ******************************************************************************/ | ||
65 | |||
66 | void | ||
67 | acpi_rs_dump_irq ( | ||
68 | union acpi_resource_data *data) | ||
69 | { | ||
70 | struct acpi_resource_irq *irq_data = (struct acpi_resource_irq *) data; | ||
71 | u8 index = 0; | ||
72 | |||
73 | |||
74 | ACPI_FUNCTION_ENTRY (); | ||
75 | |||
76 | |||
77 | acpi_os_printf ("IRQ Resource\n"); | ||
78 | |||
79 | acpi_os_printf (" %s Triggered\n", | ||
80 | ACPI_LEVEL_SENSITIVE == irq_data->edge_level ? "Level" : "Edge"); | ||
81 | |||
82 | acpi_os_printf (" Active %s\n", | ||
83 | ACPI_ACTIVE_LOW == irq_data->active_high_low ? "Low" : "High"); | ||
84 | |||
85 | acpi_os_printf (" %s\n", | ||
86 | ACPI_SHARED == irq_data->shared_exclusive ? "Shared" : "Exclusive"); | ||
87 | |||
88 | acpi_os_printf (" %X Interrupts ( ", irq_data->number_of_interrupts); | ||
89 | |||
90 | for (index = 0; index < irq_data->number_of_interrupts; index++) { | ||
91 | acpi_os_printf ("%X ", irq_data->interrupts[index]); | ||
92 | } | ||
93 | |||
94 | acpi_os_printf (")\n"); | ||
95 | return; | ||
96 | } | ||
97 | |||
98 | |||
99 | /******************************************************************************* | ||
100 | * | ||
101 | * FUNCTION: acpi_rs_dump_dma | ||
102 | * | ||
103 | * PARAMETERS: Data - pointer to the resource structure to dump. | ||
104 | * | ||
105 | * RETURN: None | ||
106 | * | ||
107 | * DESCRIPTION: Prints out the various members of the Data structure type. | ||
108 | * | ||
109 | ******************************************************************************/ | ||
110 | |||
111 | void | ||
112 | acpi_rs_dump_dma ( | ||
113 | union acpi_resource_data *data) | ||
114 | { | ||
115 | struct acpi_resource_dma *dma_data = (struct acpi_resource_dma *) data; | ||
116 | u8 index = 0; | ||
117 | |||
118 | |||
119 | ACPI_FUNCTION_ENTRY (); | ||
120 | |||
121 | |||
122 | acpi_os_printf ("DMA Resource\n"); | ||
123 | |||
124 | switch (dma_data->type) { | ||
125 | case ACPI_COMPATIBILITY: | ||
126 | acpi_os_printf (" Compatibility mode\n"); | ||
127 | break; | ||
128 | |||
129 | case ACPI_TYPE_A: | ||
130 | acpi_os_printf (" Type A\n"); | ||
131 | break; | ||
132 | |||
133 | case ACPI_TYPE_B: | ||
134 | acpi_os_printf (" Type B\n"); | ||
135 | break; | ||
136 | |||
137 | case ACPI_TYPE_F: | ||
138 | acpi_os_printf (" Type F\n"); | ||
139 | break; | ||
140 | |||
141 | default: | ||
142 | acpi_os_printf (" Invalid DMA type\n"); | ||
143 | break; | ||
144 | } | ||
145 | |||
146 | acpi_os_printf (" %sBus Master\n", | ||
147 | ACPI_BUS_MASTER == dma_data->bus_master ? "" : "Not a "); | ||
148 | |||
149 | |||
150 | switch (dma_data->transfer) { | ||
151 | case ACPI_TRANSFER_8: | ||
152 | acpi_os_printf (" 8-bit only transfer\n"); | ||
153 | break; | ||
154 | |||
155 | case ACPI_TRANSFER_8_16: | ||
156 | acpi_os_printf (" 8 and 16-bit transfer\n"); | ||
157 | break; | ||
158 | |||
159 | case ACPI_TRANSFER_16: | ||
160 | acpi_os_printf (" 16 bit only transfer\n"); | ||
161 | break; | ||
162 | |||
163 | default: | ||
164 | acpi_os_printf (" Invalid transfer preference\n"); | ||
165 | break; | ||
166 | } | ||
167 | |||
168 | acpi_os_printf (" Number of Channels: %X ( ", dma_data->number_of_channels); | ||
169 | |||
170 | for (index = 0; index < dma_data->number_of_channels; index++) { | ||
171 | acpi_os_printf ("%X ", dma_data->channels[index]); | ||
172 | } | ||
173 | |||
174 | acpi_os_printf (")\n"); | ||
175 | return; | ||
176 | } | ||
177 | |||
178 | |||
179 | /******************************************************************************* | ||
180 | * | ||
181 | * FUNCTION: acpi_rs_dump_start_depend_fns | ||
182 | * | ||
183 | * PARAMETERS: Data - pointer to the resource structure to dump. | ||
184 | * | ||
185 | * RETURN: None | ||
186 | * | ||
187 | * DESCRIPTION: Prints out the various members of the Data structure type. | ||
188 | * | ||
189 | ******************************************************************************/ | ||
190 | |||
191 | void | ||
192 | acpi_rs_dump_start_depend_fns ( | ||
193 | union acpi_resource_data *data) | ||
194 | { | ||
195 | struct acpi_resource_start_dpf *sdf_data = (struct acpi_resource_start_dpf *) data; | ||
196 | |||
197 | |||
198 | ACPI_FUNCTION_ENTRY (); | ||
199 | |||
200 | |||
201 | acpi_os_printf ("Start Dependent Functions Resource\n"); | ||
202 | |||
203 | switch (sdf_data->compatibility_priority) { | ||
204 | case ACPI_GOOD_CONFIGURATION: | ||
205 | acpi_os_printf (" Good configuration\n"); | ||
206 | break; | ||
207 | |||
208 | case ACPI_ACCEPTABLE_CONFIGURATION: | ||
209 | acpi_os_printf (" Acceptable configuration\n"); | ||
210 | break; | ||
211 | |||
212 | case ACPI_SUB_OPTIMAL_CONFIGURATION: | ||
213 | acpi_os_printf (" Sub-optimal configuration\n"); | ||
214 | break; | ||
215 | |||
216 | default: | ||
217 | acpi_os_printf (" Invalid compatibility priority\n"); | ||
218 | break; | ||
219 | } | ||
220 | |||
221 | switch(sdf_data->performance_robustness) { | ||
222 | case ACPI_GOOD_CONFIGURATION: | ||
223 | acpi_os_printf (" Good configuration\n"); | ||
224 | break; | ||
225 | |||
226 | case ACPI_ACCEPTABLE_CONFIGURATION: | ||
227 | acpi_os_printf (" Acceptable configuration\n"); | ||
228 | break; | ||
229 | |||
230 | case ACPI_SUB_OPTIMAL_CONFIGURATION: | ||
231 | acpi_os_printf (" Sub-optimal configuration\n"); | ||
232 | break; | ||
233 | |||
234 | default: | ||
235 | acpi_os_printf (" Invalid performance " | ||
236 | "robustness preference\n"); | ||
237 | break; | ||
238 | } | ||
239 | |||
240 | return; | ||
241 | } | ||
242 | |||
243 | |||
244 | /******************************************************************************* | ||
245 | * | ||
246 | * FUNCTION: acpi_rs_dump_io | ||
247 | * | ||
248 | * PARAMETERS: Data - pointer to the resource structure to dump. | ||
249 | * | ||
250 | * RETURN: None | ||
251 | * | ||
252 | * DESCRIPTION: Prints out the various members of the Data structure type. | ||
253 | * | ||
254 | ******************************************************************************/ | ||
255 | |||
256 | void | ||
257 | acpi_rs_dump_io ( | ||
258 | union acpi_resource_data *data) | ||
259 | { | ||
260 | struct acpi_resource_io *io_data = (struct acpi_resource_io *) data; | ||
261 | |||
262 | |||
263 | ACPI_FUNCTION_ENTRY (); | ||
264 | |||
265 | |||
266 | acpi_os_printf ("Io Resource\n"); | ||
267 | |||
268 | acpi_os_printf (" %d bit decode\n", | ||
269 | ACPI_DECODE_16 == io_data->io_decode ? 16 : 10); | ||
270 | |||
271 | acpi_os_printf (" Range minimum base: %08X\n", | ||
272 | io_data->min_base_address); | ||
273 | |||
274 | acpi_os_printf (" Range maximum base: %08X\n", | ||
275 | io_data->max_base_address); | ||
276 | |||
277 | acpi_os_printf (" Alignment: %08X\n", | ||
278 | io_data->alignment); | ||
279 | |||
280 | acpi_os_printf (" Range Length: %08X\n", | ||
281 | io_data->range_length); | ||
282 | |||
283 | return; | ||
284 | } | ||
285 | |||
286 | |||
287 | /******************************************************************************* | ||
288 | * | ||
289 | * FUNCTION: acpi_rs_dump_fixed_io | ||
290 | * | ||
291 | * PARAMETERS: Data - pointer to the resource structure to dump. | ||
292 | * | ||
293 | * RETURN: None | ||
294 | * | ||
295 | * DESCRIPTION: Prints out the various members of the Data structure type. | ||
296 | * | ||
297 | ******************************************************************************/ | ||
298 | |||
299 | void | ||
300 | acpi_rs_dump_fixed_io ( | ||
301 | union acpi_resource_data *data) | ||
302 | { | ||
303 | struct acpi_resource_fixed_io *fixed_io_data = (struct acpi_resource_fixed_io *) data; | ||
304 | |||
305 | |||
306 | ACPI_FUNCTION_ENTRY (); | ||
307 | |||
308 | |||
309 | acpi_os_printf ("Fixed Io Resource\n"); | ||
310 | acpi_os_printf (" Range base address: %08X", | ||
311 | fixed_io_data->base_address); | ||
312 | |||
313 | acpi_os_printf (" Range length: %08X", | ||
314 | fixed_io_data->range_length); | ||
315 | |||
316 | return; | ||
317 | } | ||
318 | |||
319 | |||
320 | /******************************************************************************* | ||
321 | * | ||
322 | * FUNCTION: acpi_rs_dump_vendor_specific | ||
323 | * | ||
324 | * PARAMETERS: Data - pointer to the resource structure to dump. | ||
325 | * | ||
326 | * RETURN: None | ||
327 | * | ||
328 | * DESCRIPTION: Prints out the various members of the Data structure type. | ||
329 | * | ||
330 | ******************************************************************************/ | ||
331 | |||
332 | void | ||
333 | acpi_rs_dump_vendor_specific ( | ||
334 | union acpi_resource_data *data) | ||
335 | { | ||
336 | struct acpi_resource_vendor *vendor_data = (struct acpi_resource_vendor *) data; | ||
337 | u16 index = 0; | ||
338 | |||
339 | |||
340 | ACPI_FUNCTION_ENTRY (); | ||
341 | |||
342 | |||
343 | acpi_os_printf ("Vendor Specific Resource\n"); | ||
344 | |||
345 | acpi_os_printf (" Length: %08X\n", vendor_data->length); | ||
346 | |||
347 | for (index = 0; index < vendor_data->length; index++) { | ||
348 | acpi_os_printf (" Byte %X: %08X\n", | ||
349 | index, vendor_data->reserved[index]); | ||
350 | } | ||
351 | |||
352 | return; | ||
353 | } | ||
354 | |||
355 | |||
356 | /******************************************************************************* | ||
357 | * | ||
358 | * FUNCTION: acpi_rs_dump_memory24 | ||
359 | * | ||
360 | * PARAMETERS: Data - pointer to the resource structure to dump. | ||
361 | * | ||
362 | * RETURN: None | ||
363 | * | ||
364 | * DESCRIPTION: Prints out the various members of the Data structure type. | ||
365 | * | ||
366 | ******************************************************************************/ | ||
367 | |||
368 | void | ||
369 | acpi_rs_dump_memory24 ( | ||
370 | union acpi_resource_data *data) | ||
371 | { | ||
372 | struct acpi_resource_mem24 *memory24_data = (struct acpi_resource_mem24 *) data; | ||
373 | |||
374 | |||
375 | ACPI_FUNCTION_ENTRY (); | ||
376 | |||
377 | |||
378 | acpi_os_printf ("24-Bit Memory Range Resource\n"); | ||
379 | |||
380 | acpi_os_printf (" Read%s\n", | ||
381 | ACPI_READ_WRITE_MEMORY == | ||
382 | memory24_data->read_write_attribute ? | ||
383 | "/Write" : " only"); | ||
384 | |||
385 | acpi_os_printf (" Range minimum base: %08X\n", | ||
386 | memory24_data->min_base_address); | ||
387 | |||
388 | acpi_os_printf (" Range maximum base: %08X\n", | ||
389 | memory24_data->max_base_address); | ||
390 | |||
391 | acpi_os_printf (" Alignment: %08X\n", | ||
392 | memory24_data->alignment); | ||
393 | |||
394 | acpi_os_printf (" Range length: %08X\n", | ||
395 | memory24_data->range_length); | ||
396 | |||
397 | return; | ||
398 | } | ||
399 | |||
400 | |||
401 | /******************************************************************************* | ||
402 | * | ||
403 | * FUNCTION: acpi_rs_dump_memory32 | ||
404 | * | ||
405 | * PARAMETERS: Data - pointer to the resource structure to dump. | ||
406 | * | ||
407 | * RETURN: None | ||
408 | * | ||
409 | * DESCRIPTION: Prints out the various members of the Data structure type. | ||
410 | * | ||
411 | ******************************************************************************/ | ||
412 | |||
413 | void | ||
414 | acpi_rs_dump_memory32 ( | ||
415 | union acpi_resource_data *data) | ||
416 | { | ||
417 | struct acpi_resource_mem32 *memory32_data = (struct acpi_resource_mem32 *) data; | ||
418 | |||
419 | |||
420 | ACPI_FUNCTION_ENTRY (); | ||
421 | |||
422 | |||
423 | acpi_os_printf ("32-Bit Memory Range Resource\n"); | ||
424 | |||
425 | acpi_os_printf (" Read%s\n", | ||
426 | ACPI_READ_WRITE_MEMORY == | ||
427 | memory32_data->read_write_attribute ? | ||
428 | "/Write" : " only"); | ||
429 | |||
430 | acpi_os_printf (" Range minimum base: %08X\n", | ||
431 | memory32_data->min_base_address); | ||
432 | |||
433 | acpi_os_printf (" Range maximum base: %08X\n", | ||
434 | memory32_data->max_base_address); | ||
435 | |||
436 | acpi_os_printf (" Alignment: %08X\n", | ||
437 | memory32_data->alignment); | ||
438 | |||
439 | acpi_os_printf (" Range length: %08X\n", | ||
440 | memory32_data->range_length); | ||
441 | |||
442 | return; | ||
443 | } | ||
444 | |||
445 | |||
446 | /******************************************************************************* | ||
447 | * | ||
448 | * FUNCTION: acpi_rs_dump_fixed_memory32 | ||
449 | * | ||
450 | * PARAMETERS: Data - pointer to the resource structure to dump. | ||
451 | * | ||
452 | * RETURN: | ||
453 | * | ||
454 | * DESCRIPTION: Prints out the various members of the Data structure type. | ||
455 | * | ||
456 | ******************************************************************************/ | ||
457 | |||
458 | void | ||
459 | acpi_rs_dump_fixed_memory32 ( | ||
460 | union acpi_resource_data *data) | ||
461 | { | ||
462 | struct acpi_resource_fixed_mem32 *fixed_memory32_data = (struct acpi_resource_fixed_mem32 *) data; | ||
463 | |||
464 | |||
465 | ACPI_FUNCTION_ENTRY (); | ||
466 | |||
467 | |||
468 | acpi_os_printf ("32-Bit Fixed Location Memory Range Resource\n"); | ||
469 | |||
470 | acpi_os_printf (" Read%s\n", | ||
471 | ACPI_READ_WRITE_MEMORY == | ||
472 | fixed_memory32_data->read_write_attribute ? | ||
473 | "/Write" : " Only"); | ||
474 | |||
475 | acpi_os_printf (" Range base address: %08X\n", | ||
476 | fixed_memory32_data->range_base_address); | ||
477 | |||
478 | acpi_os_printf (" Range length: %08X\n", | ||
479 | fixed_memory32_data->range_length); | ||
480 | |||
481 | return; | ||
482 | } | ||
483 | |||
484 | |||
485 | /******************************************************************************* | ||
486 | * | ||
487 | * FUNCTION: acpi_rs_dump_address16 | ||
488 | * | ||
489 | * PARAMETERS: Data - pointer to the resource structure to dump. | ||
490 | * | ||
491 | * RETURN: None | ||
492 | * | ||
493 | * DESCRIPTION: Prints out the various members of the Data structure type. | ||
494 | * | ||
495 | ******************************************************************************/ | ||
496 | |||
497 | void | ||
498 | acpi_rs_dump_address16 ( | ||
499 | union acpi_resource_data *data) | ||
500 | { | ||
501 | struct acpi_resource_address16 *address16_data = (struct acpi_resource_address16 *) data; | ||
502 | |||
503 | |||
504 | ACPI_FUNCTION_ENTRY (); | ||
505 | |||
506 | |||
507 | acpi_os_printf ("16-Bit Address Space Resource\n"); | ||
508 | acpi_os_printf (" Resource Type: "); | ||
509 | |||
510 | switch (address16_data->resource_type) { | ||
511 | case ACPI_MEMORY_RANGE: | ||
512 | |||
513 | acpi_os_printf ("Memory Range\n"); | ||
514 | |||
515 | switch (address16_data->attribute.memory.cache_attribute) { | ||
516 | case ACPI_NON_CACHEABLE_MEMORY: | ||
517 | acpi_os_printf (" Type Specific: " | ||
518 | "Noncacheable memory\n"); | ||
519 | break; | ||
520 | |||
521 | case ACPI_CACHABLE_MEMORY: | ||
522 | acpi_os_printf (" Type Specific: " | ||
523 | "Cacheable memory\n"); | ||
524 | break; | ||
525 | |||
526 | case ACPI_WRITE_COMBINING_MEMORY: | ||
527 | acpi_os_printf (" Type Specific: " | ||
528 | "Write-combining memory\n"); | ||
529 | break; | ||
530 | |||
531 | case ACPI_PREFETCHABLE_MEMORY: | ||
532 | acpi_os_printf (" Type Specific: " | ||
533 | "Prefetchable memory\n"); | ||
534 | break; | ||
535 | |||
536 | default: | ||
537 | acpi_os_printf (" Type Specific: " | ||
538 | "Invalid cache attribute\n"); | ||
539 | break; | ||
540 | } | ||
541 | |||
542 | acpi_os_printf (" Type Specific: Read%s\n", | ||
543 | ACPI_READ_WRITE_MEMORY == | ||
544 | address16_data->attribute.memory.read_write_attribute ? | ||
545 | "/Write" : " Only"); | ||
546 | break; | ||
547 | |||
548 | case ACPI_IO_RANGE: | ||
549 | |||
550 | acpi_os_printf ("I/O Range\n"); | ||
551 | |||
552 | switch (address16_data->attribute.io.range_attribute) { | ||
553 | case ACPI_NON_ISA_ONLY_RANGES: | ||
554 | acpi_os_printf (" Type Specific: " | ||
555 | "Non-ISA Io Addresses\n"); | ||
556 | break; | ||
557 | |||
558 | case ACPI_ISA_ONLY_RANGES: | ||
559 | acpi_os_printf (" Type Specific: " | ||
560 | "ISA Io Addresses\n"); | ||
561 | break; | ||
562 | |||
563 | case ACPI_ENTIRE_RANGE: | ||
564 | acpi_os_printf (" Type Specific: " | ||
565 | "ISA and non-ISA Io Addresses\n"); | ||
566 | break; | ||
567 | |||
568 | default: | ||
569 | acpi_os_printf (" Type Specific: " | ||
570 | "Invalid range attribute\n"); | ||
571 | break; | ||
572 | } | ||
573 | |||
574 | acpi_os_printf (" Type Specific: %s Translation\n", | ||
575 | ACPI_SPARSE_TRANSLATION == | ||
576 | address16_data->attribute.io.translation_attribute ? | ||
577 | "Sparse" : "Dense"); | ||
578 | break; | ||
579 | |||
580 | case ACPI_BUS_NUMBER_RANGE: | ||
581 | |||
582 | acpi_os_printf ("Bus Number Range\n"); | ||
583 | break; | ||
584 | |||
585 | default: | ||
586 | |||
587 | acpi_os_printf ("0x%2.2X\n", address16_data->resource_type); | ||
588 | break; | ||
589 | } | ||
590 | |||
591 | acpi_os_printf (" Resource %s\n", | ||
592 | ACPI_CONSUMER == address16_data->producer_consumer ? | ||
593 | "Consumer" : "Producer"); | ||
594 | |||
595 | acpi_os_printf (" %s decode\n", | ||
596 | ACPI_SUB_DECODE == address16_data->decode ? | ||
597 | "Subtractive" : "Positive"); | ||
598 | |||
599 | acpi_os_printf (" Min address is %s fixed\n", | ||
600 | ACPI_ADDRESS_FIXED == address16_data->min_address_fixed ? | ||
601 | "" : "not"); | ||
602 | |||
603 | acpi_os_printf (" Max address is %s fixed\n", | ||
604 | ACPI_ADDRESS_FIXED == address16_data->max_address_fixed ? | ||
605 | "" : "not"); | ||
606 | |||
607 | acpi_os_printf (" Granularity: %08X\n", | ||
608 | address16_data->granularity); | ||
609 | |||
610 | acpi_os_printf (" Address range min: %08X\n", | ||
611 | address16_data->min_address_range); | ||
612 | |||
613 | acpi_os_printf (" Address range max: %08X\n", | ||
614 | address16_data->max_address_range); | ||
615 | |||
616 | acpi_os_printf (" Address translation offset: %08X\n", | ||
617 | address16_data->address_translation_offset); | ||
618 | |||
619 | acpi_os_printf (" Address Length: %08X\n", | ||
620 | address16_data->address_length); | ||
621 | |||
622 | if (0xFF != address16_data->resource_source.index) { | ||
623 | acpi_os_printf (" Resource Source Index: %X\n", | ||
624 | address16_data->resource_source.index); | ||
625 | acpi_os_printf (" Resource Source: %s\n", | ||
626 | address16_data->resource_source.string_ptr); | ||
627 | } | ||
628 | |||
629 | return; | ||
630 | } | ||
631 | |||
632 | |||
633 | /******************************************************************************* | ||
634 | * | ||
635 | * FUNCTION: acpi_rs_dump_address32 | ||
636 | * | ||
637 | * PARAMETERS: Data - pointer to the resource structure to dump. | ||
638 | * | ||
639 | * RETURN: None | ||
640 | * | ||
641 | * DESCRIPTION: Prints out the various members of the Data structure type. | ||
642 | * | ||
643 | ******************************************************************************/ | ||
644 | |||
645 | void | ||
646 | acpi_rs_dump_address32 ( | ||
647 | union acpi_resource_data *data) | ||
648 | { | ||
649 | struct acpi_resource_address32 *address32_data = (struct acpi_resource_address32 *) data; | ||
650 | |||
651 | |||
652 | ACPI_FUNCTION_ENTRY (); | ||
653 | |||
654 | |||
655 | acpi_os_printf ("32-Bit Address Space Resource\n"); | ||
656 | |||
657 | switch (address32_data->resource_type) { | ||
658 | case ACPI_MEMORY_RANGE: | ||
659 | |||
660 | acpi_os_printf (" Resource Type: Memory Range\n"); | ||
661 | |||
662 | switch (address32_data->attribute.memory.cache_attribute) { | ||
663 | case ACPI_NON_CACHEABLE_MEMORY: | ||
664 | acpi_os_printf (" Type Specific: " | ||
665 | "Noncacheable memory\n"); | ||
666 | break; | ||
667 | |||
668 | case ACPI_CACHABLE_MEMORY: | ||
669 | acpi_os_printf (" Type Specific: " | ||
670 | "Cacheable memory\n"); | ||
671 | break; | ||
672 | |||
673 | case ACPI_WRITE_COMBINING_MEMORY: | ||
674 | acpi_os_printf (" Type Specific: " | ||
675 | "Write-combining memory\n"); | ||
676 | break; | ||
677 | |||
678 | case ACPI_PREFETCHABLE_MEMORY: | ||
679 | acpi_os_printf (" Type Specific: " | ||
680 | "Prefetchable memory\n"); | ||
681 | break; | ||
682 | |||
683 | default: | ||
684 | acpi_os_printf (" Type Specific: " | ||
685 | "Invalid cache attribute\n"); | ||
686 | break; | ||
687 | } | ||
688 | |||
689 | acpi_os_printf (" Type Specific: Read%s\n", | ||
690 | ACPI_READ_WRITE_MEMORY == | ||
691 | address32_data->attribute.memory.read_write_attribute ? | ||
692 | "/Write" : " Only"); | ||
693 | break; | ||
694 | |||
695 | case ACPI_IO_RANGE: | ||
696 | |||
697 | acpi_os_printf (" Resource Type: Io Range\n"); | ||
698 | |||
699 | switch (address32_data->attribute.io.range_attribute) { | ||
700 | case ACPI_NON_ISA_ONLY_RANGES: | ||
701 | acpi_os_printf (" Type Specific: " | ||
702 | "Non-ISA Io Addresses\n"); | ||
703 | break; | ||
704 | |||
705 | case ACPI_ISA_ONLY_RANGES: | ||
706 | acpi_os_printf (" Type Specific: " | ||
707 | "ISA Io Addresses\n"); | ||
708 | break; | ||
709 | |||
710 | case ACPI_ENTIRE_RANGE: | ||
711 | acpi_os_printf (" Type Specific: " | ||
712 | "ISA and non-ISA Io Addresses\n"); | ||
713 | break; | ||
714 | |||
715 | default: | ||
716 | acpi_os_printf (" Type Specific: " | ||
717 | "Invalid Range attribute"); | ||
718 | break; | ||
719 | } | ||
720 | |||
721 | acpi_os_printf (" Type Specific: %s Translation\n", | ||
722 | ACPI_SPARSE_TRANSLATION == | ||
723 | address32_data->attribute.io.translation_attribute ? | ||
724 | "Sparse" : "Dense"); | ||
725 | break; | ||
726 | |||
727 | case ACPI_BUS_NUMBER_RANGE: | ||
728 | |||
729 | acpi_os_printf (" Resource Type: Bus Number Range\n"); | ||
730 | break; | ||
731 | |||
732 | default: | ||
733 | |||
734 | acpi_os_printf (" Resource Type: 0x%2.2X\n", address32_data->resource_type); | ||
735 | break; | ||
736 | } | ||
737 | |||
738 | acpi_os_printf (" Resource %s\n", | ||
739 | ACPI_CONSUMER == address32_data->producer_consumer ? | ||
740 | "Consumer" : "Producer"); | ||
741 | |||
742 | acpi_os_printf (" %s decode\n", | ||
743 | ACPI_SUB_DECODE == address32_data->decode ? | ||
744 | "Subtractive" : "Positive"); | ||
745 | |||
746 | acpi_os_printf (" Min address is %s fixed\n", | ||
747 | ACPI_ADDRESS_FIXED == address32_data->min_address_fixed ? | ||
748 | "" : "not "); | ||
749 | |||
750 | acpi_os_printf (" Max address is %s fixed\n", | ||
751 | ACPI_ADDRESS_FIXED == address32_data->max_address_fixed ? | ||
752 | "" : "not "); | ||
753 | |||
754 | acpi_os_printf (" Granularity: %08X\n", | ||
755 | address32_data->granularity); | ||
756 | |||
757 | acpi_os_printf (" Address range min: %08X\n", | ||
758 | address32_data->min_address_range); | ||
759 | |||
760 | acpi_os_printf (" Address range max: %08X\n", | ||
761 | address32_data->max_address_range); | ||
762 | |||
763 | acpi_os_printf (" Address translation offset: %08X\n", | ||
764 | address32_data->address_translation_offset); | ||
765 | |||
766 | acpi_os_printf (" Address Length: %08X\n", | ||
767 | address32_data->address_length); | ||
768 | |||
769 | if(0xFF != address32_data->resource_source.index) { | ||
770 | acpi_os_printf (" Resource Source Index: %X\n", | ||
771 | address32_data->resource_source.index); | ||
772 | acpi_os_printf (" Resource Source: %s\n", | ||
773 | address32_data->resource_source.string_ptr); | ||
774 | } | ||
775 | |||
776 | return; | ||
777 | } | ||
778 | |||
779 | |||
780 | /******************************************************************************* | ||
781 | * | ||
782 | * FUNCTION: acpi_rs_dump_address64 | ||
783 | * | ||
784 | * PARAMETERS: Data - pointer to the resource structure to dump. | ||
785 | * | ||
786 | * RETURN: None | ||
787 | * | ||
788 | * DESCRIPTION: Prints out the various members of the Data structure type. | ||
789 | * | ||
790 | ******************************************************************************/ | ||
791 | |||
792 | void | ||
793 | acpi_rs_dump_address64 ( | ||
794 | union acpi_resource_data *data) | ||
795 | { | ||
796 | struct acpi_resource_address64 *address64_data = (struct acpi_resource_address64 *) data; | ||
797 | |||
798 | |||
799 | ACPI_FUNCTION_ENTRY (); | ||
800 | |||
801 | |||
802 | acpi_os_printf ("64-Bit Address Space Resource\n"); | ||
803 | |||
804 | switch (address64_data->resource_type) { | ||
805 | case ACPI_MEMORY_RANGE: | ||
806 | |||
807 | acpi_os_printf (" Resource Type: Memory Range\n"); | ||
808 | |||
809 | switch (address64_data->attribute.memory.cache_attribute) { | ||
810 | case ACPI_NON_CACHEABLE_MEMORY: | ||
811 | acpi_os_printf (" Type Specific: " | ||
812 | "Noncacheable memory\n"); | ||
813 | break; | ||
814 | |||
815 | case ACPI_CACHABLE_MEMORY: | ||
816 | acpi_os_printf (" Type Specific: " | ||
817 | "Cacheable memory\n"); | ||
818 | break; | ||
819 | |||
820 | case ACPI_WRITE_COMBINING_MEMORY: | ||
821 | acpi_os_printf (" Type Specific: " | ||
822 | "Write-combining memory\n"); | ||
823 | break; | ||
824 | |||
825 | case ACPI_PREFETCHABLE_MEMORY: | ||
826 | acpi_os_printf (" Type Specific: " | ||
827 | "Prefetchable memory\n"); | ||
828 | break; | ||
829 | |||
830 | default: | ||
831 | acpi_os_printf (" Type Specific: " | ||
832 | "Invalid cache attribute\n"); | ||
833 | break; | ||
834 | } | ||
835 | |||
836 | acpi_os_printf (" Type Specific: Read%s\n", | ||
837 | ACPI_READ_WRITE_MEMORY == | ||
838 | address64_data->attribute.memory.read_write_attribute ? | ||
839 | "/Write" : " Only"); | ||
840 | break; | ||
841 | |||
842 | case ACPI_IO_RANGE: | ||
843 | |||
844 | acpi_os_printf (" Resource Type: Io Range\n"); | ||
845 | |||
846 | switch (address64_data->attribute.io.range_attribute) { | ||
847 | case ACPI_NON_ISA_ONLY_RANGES: | ||
848 | acpi_os_printf (" Type Specific: " | ||
849 | "Non-ISA Io Addresses\n"); | ||
850 | break; | ||
851 | |||
852 | case ACPI_ISA_ONLY_RANGES: | ||
853 | acpi_os_printf (" Type Specific: " | ||
854 | "ISA Io Addresses\n"); | ||
855 | break; | ||
856 | |||
857 | case ACPI_ENTIRE_RANGE: | ||
858 | acpi_os_printf (" Type Specific: " | ||
859 | "ISA and non-ISA Io Addresses\n"); | ||
860 | break; | ||
861 | |||
862 | default: | ||
863 | acpi_os_printf (" Type Specific: " | ||
864 | "Invalid Range attribute"); | ||
865 | break; | ||
866 | } | ||
867 | |||
868 | acpi_os_printf (" Type Specific: %s Translation\n", | ||
869 | ACPI_SPARSE_TRANSLATION == | ||
870 | address64_data->attribute.io.translation_attribute ? | ||
871 | "Sparse" : "Dense"); | ||
872 | break; | ||
873 | |||
874 | case ACPI_BUS_NUMBER_RANGE: | ||
875 | |||
876 | acpi_os_printf (" Resource Type: Bus Number Range\n"); | ||
877 | break; | ||
878 | |||
879 | default: | ||
880 | |||
881 | acpi_os_printf (" Resource Type: 0x%2.2X\n", address64_data->resource_type); | ||
882 | break; | ||
883 | } | ||
884 | |||
885 | acpi_os_printf (" Resource %s\n", | ||
886 | ACPI_CONSUMER == address64_data->producer_consumer ? | ||
887 | "Consumer" : "Producer"); | ||
888 | |||
889 | acpi_os_printf (" %s decode\n", | ||
890 | ACPI_SUB_DECODE == address64_data->decode ? | ||
891 | "Subtractive" : "Positive"); | ||
892 | |||
893 | acpi_os_printf (" Min address is %s fixed\n", | ||
894 | ACPI_ADDRESS_FIXED == address64_data->min_address_fixed ? | ||
895 | "" : "not "); | ||
896 | |||
897 | acpi_os_printf (" Max address is %s fixed\n", | ||
898 | ACPI_ADDRESS_FIXED == address64_data->max_address_fixed ? | ||
899 | "" : "not "); | ||
900 | |||
901 | acpi_os_printf (" Granularity: %8.8X%8.8X\n", | ||
902 | ACPI_FORMAT_UINT64 (address64_data->granularity)); | ||
903 | |||
904 | acpi_os_printf (" Address range min: %8.8X%8.8X\n", | ||
905 | ACPI_FORMAT_UINT64 (address64_data->min_address_range)); | ||
906 | |||
907 | acpi_os_printf (" Address range max: %8.8X%8.8X\n", | ||
908 | ACPI_FORMAT_UINT64 (address64_data->max_address_range)); | ||
909 | |||
910 | acpi_os_printf (" Address translation offset: %8.8X%8.8X\n", | ||
911 | ACPI_FORMAT_UINT64 (address64_data->address_translation_offset)); | ||
912 | |||
913 | acpi_os_printf (" Address Length: %8.8X%8.8X\n", | ||
914 | ACPI_FORMAT_UINT64 (address64_data->address_length)); | ||
915 | |||
916 | acpi_os_printf (" Type Specific Attributes: %8.8X%8.8X\n", | ||
917 | ACPI_FORMAT_UINT64 (address64_data->type_specific_attributes)); | ||
918 | |||
919 | if (0xFF != address64_data->resource_source.index) { | ||
920 | acpi_os_printf (" Resource Source Index: %X\n", | ||
921 | address64_data->resource_source.index); | ||
922 | acpi_os_printf (" Resource Source: %s\n", | ||
923 | address64_data->resource_source.string_ptr); | ||
924 | } | ||
925 | |||
926 | return; | ||
927 | } | ||
928 | |||
929 | |||
930 | /******************************************************************************* | ||
931 | * | ||
932 | * FUNCTION: acpi_rs_dump_extended_irq | ||
933 | * | ||
934 | * PARAMETERS: Data - pointer to the resource structure to dump. | ||
935 | * | ||
936 | * RETURN: None | ||
937 | * | ||
938 | * DESCRIPTION: Prints out the various members of the Data structure type. | ||
939 | * | ||
940 | ******************************************************************************/ | ||
941 | |||
942 | void | ||
943 | acpi_rs_dump_extended_irq ( | ||
944 | union acpi_resource_data *data) | ||
945 | { | ||
946 | struct acpi_resource_ext_irq *ext_irq_data = (struct acpi_resource_ext_irq *) data; | ||
947 | u8 index = 0; | ||
948 | |||
949 | |||
950 | ACPI_FUNCTION_ENTRY (); | ||
951 | |||
952 | |||
953 | acpi_os_printf ("Extended IRQ Resource\n"); | ||
954 | |||
955 | acpi_os_printf (" Resource %s\n", | ||
956 | ACPI_CONSUMER == ext_irq_data->producer_consumer ? | ||
957 | "Consumer" : "Producer"); | ||
958 | |||
959 | acpi_os_printf (" %s\n", | ||
960 | ACPI_LEVEL_SENSITIVE == ext_irq_data->edge_level ? | ||
961 | "Level" : "Edge"); | ||
962 | |||
963 | acpi_os_printf (" Active %s\n", | ||
964 | ACPI_ACTIVE_LOW == ext_irq_data->active_high_low ? | ||
965 | "low" : "high"); | ||
966 | |||
967 | acpi_os_printf (" %s\n", | ||
968 | ACPI_SHARED == ext_irq_data->shared_exclusive ? | ||
969 | "Shared" : "Exclusive"); | ||
970 | |||
971 | acpi_os_printf (" Interrupts : %X ( ", | ||
972 | ext_irq_data->number_of_interrupts); | ||
973 | |||
974 | for (index = 0; index < ext_irq_data->number_of_interrupts; index++) { | ||
975 | acpi_os_printf ("%X ", ext_irq_data->interrupts[index]); | ||
976 | } | ||
977 | |||
978 | acpi_os_printf (")\n"); | ||
979 | |||
980 | if(0xFF != ext_irq_data->resource_source.index) { | ||
981 | acpi_os_printf (" Resource Source Index: %X", | ||
982 | ext_irq_data->resource_source.index); | ||
983 | acpi_os_printf (" Resource Source: %s", | ||
984 | ext_irq_data->resource_source.string_ptr); | ||
985 | } | ||
986 | |||
987 | return; | ||
988 | } | ||
989 | |||
990 | |||
991 | /******************************************************************************* | ||
992 | * | ||
993 | * FUNCTION: acpi_rs_dump_resource_list | ||
994 | * | ||
995 | * PARAMETERS: Data - pointer to the resource structure to dump. | ||
996 | * | ||
997 | * RETURN: None | ||
998 | * | ||
999 | * DESCRIPTION: Dispatches the structure to the correct dump routine. | ||
1000 | * | ||
1001 | ******************************************************************************/ | ||
1002 | |||
1003 | void | ||
1004 | acpi_rs_dump_resource_list ( | ||
1005 | struct acpi_resource *resource) | ||
1006 | { | ||
1007 | u8 count = 0; | ||
1008 | u8 done = FALSE; | ||
1009 | |||
1010 | |||
1011 | ACPI_FUNCTION_ENTRY (); | ||
1012 | |||
1013 | |||
1014 | if (acpi_dbg_level & ACPI_LV_RESOURCES && _COMPONENT & acpi_dbg_layer) { | ||
1015 | while (!done) { | ||
1016 | acpi_os_printf ("Resource structure %X.\n", count++); | ||
1017 | |||
1018 | switch (resource->id) { | ||
1019 | case ACPI_RSTYPE_IRQ: | ||
1020 | acpi_rs_dump_irq (&resource->data); | ||
1021 | break; | ||
1022 | |||
1023 | case ACPI_RSTYPE_DMA: | ||
1024 | acpi_rs_dump_dma (&resource->data); | ||
1025 | break; | ||
1026 | |||
1027 | case ACPI_RSTYPE_START_DPF: | ||
1028 | acpi_rs_dump_start_depend_fns (&resource->data); | ||
1029 | break; | ||
1030 | |||
1031 | case ACPI_RSTYPE_END_DPF: | ||
1032 | acpi_os_printf ("end_dependent_functions Resource\n"); | ||
1033 | /* acpi_rs_dump_end_dependent_functions (Resource->Data);*/ | ||
1034 | break; | ||
1035 | |||
1036 | case ACPI_RSTYPE_IO: | ||
1037 | acpi_rs_dump_io (&resource->data); | ||
1038 | break; | ||
1039 | |||
1040 | case ACPI_RSTYPE_FIXED_IO: | ||
1041 | acpi_rs_dump_fixed_io (&resource->data); | ||
1042 | break; | ||
1043 | |||
1044 | case ACPI_RSTYPE_VENDOR: | ||
1045 | acpi_rs_dump_vendor_specific (&resource->data); | ||
1046 | break; | ||
1047 | |||
1048 | case ACPI_RSTYPE_END_TAG: | ||
1049 | /*rs_dump_end_tag (Resource->Data);*/ | ||
1050 | acpi_os_printf ("end_tag Resource\n"); | ||
1051 | done = TRUE; | ||
1052 | break; | ||
1053 | |||
1054 | case ACPI_RSTYPE_MEM24: | ||
1055 | acpi_rs_dump_memory24 (&resource->data); | ||
1056 | break; | ||
1057 | |||
1058 | case ACPI_RSTYPE_MEM32: | ||
1059 | acpi_rs_dump_memory32 (&resource->data); | ||
1060 | break; | ||
1061 | |||
1062 | case ACPI_RSTYPE_FIXED_MEM32: | ||
1063 | acpi_rs_dump_fixed_memory32 (&resource->data); | ||
1064 | break; | ||
1065 | |||
1066 | case ACPI_RSTYPE_ADDRESS16: | ||
1067 | acpi_rs_dump_address16 (&resource->data); | ||
1068 | break; | ||
1069 | |||
1070 | case ACPI_RSTYPE_ADDRESS32: | ||
1071 | acpi_rs_dump_address32 (&resource->data); | ||
1072 | break; | ||
1073 | |||
1074 | case ACPI_RSTYPE_ADDRESS64: | ||
1075 | acpi_rs_dump_address64 (&resource->data); | ||
1076 | break; | ||
1077 | |||
1078 | case ACPI_RSTYPE_EXT_IRQ: | ||
1079 | acpi_rs_dump_extended_irq (&resource->data); | ||
1080 | break; | ||
1081 | |||
1082 | default: | ||
1083 | acpi_os_printf ("Invalid resource type\n"); | ||
1084 | break; | ||
1085 | |||
1086 | } | ||
1087 | |||
1088 | resource = ACPI_PTR_ADD (struct acpi_resource, resource, resource->length); | ||
1089 | } | ||
1090 | } | ||
1091 | |||
1092 | return; | ||
1093 | } | ||
1094 | |||
1095 | /******************************************************************************* | ||
1096 | * | ||
1097 | * FUNCTION: acpi_rs_dump_irq_list | ||
1098 | * | ||
1099 | * PARAMETERS: Data - pointer to the routing table to dump. | ||
1100 | * | ||
1101 | * RETURN: None | ||
1102 | * | ||
1103 | * DESCRIPTION: Dispatches the structures to the correct dump routine. | ||
1104 | * | ||
1105 | ******************************************************************************/ | ||
1106 | |||
1107 | void | ||
1108 | acpi_rs_dump_irq_list ( | ||
1109 | u8 *route_table) | ||
1110 | { | ||
1111 | u8 *buffer = route_table; | ||
1112 | u8 count = 0; | ||
1113 | u8 done = FALSE; | ||
1114 | struct acpi_pci_routing_table *prt_element; | ||
1115 | |||
1116 | |||
1117 | ACPI_FUNCTION_ENTRY (); | ||
1118 | |||
1119 | |||
1120 | if (acpi_dbg_level & ACPI_LV_RESOURCES && _COMPONENT & acpi_dbg_layer) { | ||
1121 | prt_element = ACPI_CAST_PTR (struct acpi_pci_routing_table, buffer); | ||
1122 | |||
1123 | while (!done) { | ||
1124 | acpi_os_printf ("PCI IRQ Routing Table structure %X.\n", count++); | ||
1125 | |||
1126 | acpi_os_printf (" Address: %8.8X%8.8X\n", | ||
1127 | ACPI_FORMAT_UINT64 (prt_element->address)); | ||
1128 | |||
1129 | acpi_os_printf (" Pin: %X\n", prt_element->pin); | ||
1130 | |||
1131 | acpi_os_printf (" Source: %s\n", prt_element->source); | ||
1132 | |||
1133 | acpi_os_printf (" source_index: %X\n", | ||
1134 | prt_element->source_index); | ||
1135 | |||
1136 | buffer += prt_element->length; | ||
1137 | |||
1138 | prt_element = ACPI_CAST_PTR (struct acpi_pci_routing_table, buffer); | ||
1139 | |||
1140 | if(0 == prt_element->length) { | ||
1141 | done = TRUE; | ||
1142 | } | ||
1143 | } | ||
1144 | } | ||
1145 | |||
1146 | return; | ||
1147 | } | ||
1148 | |||
1149 | #endif | ||
1150 | |||
diff --git a/drivers/acpi/resources/rsio.c b/drivers/acpi/resources/rsio.c new file mode 100644 index 000000000000..972c746d37e4 --- /dev/null +++ b/drivers/acpi/resources/rsio.c | |||
@@ -0,0 +1,545 @@ | |||
1 | /******************************************************************************* | ||
2 | * | ||
3 | * Module Name: rsio - IO and DMA resource descriptors | ||
4 | * | ||
5 | ******************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2005, R. Byron Moore | ||
9 | * All rights reserved. | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions, and the following disclaimer, | ||
16 | * without modification. | ||
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
18 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
19 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
20 | * including a substantially similar Disclaimer requirement for further | ||
21 | * binary redistribution. | ||
22 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
23 | * of any contributors may be used to endorse or promote products derived | ||
24 | * from this software without specific prior written permission. | ||
25 | * | ||
26 | * Alternatively, this software may be distributed under the terms of the | ||
27 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
28 | * Software Foundation. | ||
29 | * | ||
30 | * NO WARRANTY | ||
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
41 | * POSSIBILITY OF SUCH DAMAGES. | ||
42 | */ | ||
43 | |||
44 | |||
45 | #include <acpi/acpi.h> | ||
46 | #include <acpi/acresrc.h> | ||
47 | |||
48 | #define _COMPONENT ACPI_RESOURCES | ||
49 | ACPI_MODULE_NAME ("rsio") | ||
50 | |||
51 | |||
52 | /******************************************************************************* | ||
53 | * | ||
54 | * FUNCTION: acpi_rs_io_resource | ||
55 | * | ||
56 | * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte | ||
57 | * stream | ||
58 | * bytes_consumed - Pointer to where the number of bytes | ||
59 | * consumed the byte_stream_buffer is | ||
60 | * returned | ||
61 | * output_buffer - Pointer to the return data buffer | ||
62 | * structure_size - Pointer to where the number of bytes | ||
63 | * in the return data struct is returned | ||
64 | * | ||
65 | * RETURN: Status | ||
66 | * | ||
67 | * DESCRIPTION: Take the resource byte stream and fill out the appropriate | ||
68 | * structure pointed to by the output_buffer. Return the | ||
69 | * number of bytes consumed from the byte stream. | ||
70 | * | ||
71 | ******************************************************************************/ | ||
72 | |||
73 | acpi_status | ||
74 | acpi_rs_io_resource ( | ||
75 | u8 *byte_stream_buffer, | ||
76 | acpi_size *bytes_consumed, | ||
77 | u8 **output_buffer, | ||
78 | acpi_size *structure_size) | ||
79 | { | ||
80 | u8 *buffer = byte_stream_buffer; | ||
81 | struct acpi_resource *output_struct = (void *) *output_buffer; | ||
82 | u16 temp16 = 0; | ||
83 | u8 temp8 = 0; | ||
84 | acpi_size struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_io); | ||
85 | |||
86 | |||
87 | ACPI_FUNCTION_TRACE ("rs_io_resource"); | ||
88 | |||
89 | |||
90 | /* | ||
91 | * The number of bytes consumed are Constant | ||
92 | */ | ||
93 | *bytes_consumed = 8; | ||
94 | |||
95 | output_struct->id = ACPI_RSTYPE_IO; | ||
96 | |||
97 | /* | ||
98 | * Check Decode | ||
99 | */ | ||
100 | buffer += 1; | ||
101 | temp8 = *buffer; | ||
102 | |||
103 | output_struct->data.io.io_decode = temp8 & 0x01; | ||
104 | |||
105 | /* | ||
106 | * Check min_base Address | ||
107 | */ | ||
108 | buffer += 1; | ||
109 | ACPI_MOVE_16_TO_16 (&temp16, buffer); | ||
110 | |||
111 | output_struct->data.io.min_base_address = temp16; | ||
112 | |||
113 | /* | ||
114 | * Check max_base Address | ||
115 | */ | ||
116 | buffer += 2; | ||
117 | ACPI_MOVE_16_TO_16 (&temp16, buffer); | ||
118 | |||
119 | output_struct->data.io.max_base_address = temp16; | ||
120 | |||
121 | /* | ||
122 | * Check Base alignment | ||
123 | */ | ||
124 | buffer += 2; | ||
125 | temp8 = *buffer; | ||
126 | |||
127 | output_struct->data.io.alignment = temp8; | ||
128 | |||
129 | /* | ||
130 | * Check range_length | ||
131 | */ | ||
132 | buffer += 1; | ||
133 | temp8 = *buffer; | ||
134 | |||
135 | output_struct->data.io.range_length = temp8; | ||
136 | |||
137 | /* | ||
138 | * Set the Length parameter | ||
139 | */ | ||
140 | output_struct->length = (u32) struct_size; | ||
141 | |||
142 | /* | ||
143 | * Return the final size of the structure | ||
144 | */ | ||
145 | *structure_size = struct_size; | ||
146 | return_ACPI_STATUS (AE_OK); | ||
147 | } | ||
148 | |||
149 | |||
150 | /******************************************************************************* | ||
151 | * | ||
152 | * FUNCTION: acpi_rs_fixed_io_resource | ||
153 | * | ||
154 | * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte | ||
155 | * stream | ||
156 | * bytes_consumed - Pointer to where the number of bytes | ||
157 | * consumed the byte_stream_buffer is | ||
158 | * returned | ||
159 | * output_buffer - Pointer to the return data buffer | ||
160 | * structure_size - Pointer to where the number of bytes | ||
161 | * in the return data struct is returned | ||
162 | * | ||
163 | * RETURN: Status | ||
164 | * | ||
165 | * DESCRIPTION: Take the resource byte stream and fill out the appropriate | ||
166 | * structure pointed to by the output_buffer. Return the | ||
167 | * number of bytes consumed from the byte stream. | ||
168 | * | ||
169 | ******************************************************************************/ | ||
170 | |||
171 | acpi_status | ||
172 | acpi_rs_fixed_io_resource ( | ||
173 | u8 *byte_stream_buffer, | ||
174 | acpi_size *bytes_consumed, | ||
175 | u8 **output_buffer, | ||
176 | acpi_size *structure_size) | ||
177 | { | ||
178 | u8 *buffer = byte_stream_buffer; | ||
179 | struct acpi_resource *output_struct = (void *) *output_buffer; | ||
180 | u16 temp16 = 0; | ||
181 | u8 temp8 = 0; | ||
182 | acpi_size struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_fixed_io); | ||
183 | |||
184 | |||
185 | ACPI_FUNCTION_TRACE ("rs_fixed_io_resource"); | ||
186 | |||
187 | |||
188 | /* | ||
189 | * The number of bytes consumed are Constant | ||
190 | */ | ||
191 | *bytes_consumed = 4; | ||
192 | |||
193 | output_struct->id = ACPI_RSTYPE_FIXED_IO; | ||
194 | |||
195 | /* | ||
196 | * Check Range Base Address | ||
197 | */ | ||
198 | buffer += 1; | ||
199 | ACPI_MOVE_16_TO_16 (&temp16, buffer); | ||
200 | |||
201 | output_struct->data.fixed_io.base_address = temp16; | ||
202 | |||
203 | /* | ||
204 | * Check range_length | ||
205 | */ | ||
206 | buffer += 2; | ||
207 | temp8 = *buffer; | ||
208 | |||
209 | output_struct->data.fixed_io.range_length = temp8; | ||
210 | |||
211 | /* | ||
212 | * Set the Length parameter | ||
213 | */ | ||
214 | output_struct->length = (u32) struct_size; | ||
215 | |||
216 | /* | ||
217 | * Return the final size of the structure | ||
218 | */ | ||
219 | *structure_size = struct_size; | ||
220 | return_ACPI_STATUS (AE_OK); | ||
221 | } | ||
222 | |||
223 | |||
224 | /******************************************************************************* | ||
225 | * | ||
226 | * FUNCTION: acpi_rs_io_stream | ||
227 | * | ||
228 | * PARAMETERS: linked_list - Pointer to the resource linked list | ||
229 | * output_buffer - Pointer to the user's return buffer | ||
230 | * bytes_consumed - Pointer to where the number of bytes | ||
231 | * used in the output_buffer is returned | ||
232 | * | ||
233 | * RETURN: Status | ||
234 | * | ||
235 | * DESCRIPTION: Take the linked list resource structure and fills in the | ||
236 | * the appropriate bytes in a byte stream | ||
237 | * | ||
238 | ******************************************************************************/ | ||
239 | |||
240 | acpi_status | ||
241 | acpi_rs_io_stream ( | ||
242 | struct acpi_resource *linked_list, | ||
243 | u8 **output_buffer, | ||
244 | acpi_size *bytes_consumed) | ||
245 | { | ||
246 | u8 *buffer = *output_buffer; | ||
247 | u16 temp16 = 0; | ||
248 | u8 temp8 = 0; | ||
249 | |||
250 | |||
251 | ACPI_FUNCTION_TRACE ("rs_io_stream"); | ||
252 | |||
253 | |||
254 | /* | ||
255 | * The descriptor field is static | ||
256 | */ | ||
257 | *buffer = 0x47; | ||
258 | buffer += 1; | ||
259 | |||
260 | /* | ||
261 | * Io Information Byte | ||
262 | */ | ||
263 | temp8 = (u8) (linked_list->data.io.io_decode & 0x01); | ||
264 | |||
265 | *buffer = temp8; | ||
266 | buffer += 1; | ||
267 | |||
268 | /* | ||
269 | * Set the Range minimum base address | ||
270 | */ | ||
271 | temp16 = (u16) linked_list->data.io.min_base_address; | ||
272 | |||
273 | ACPI_MOVE_16_TO_16 (buffer, &temp16); | ||
274 | buffer += 2; | ||
275 | |||
276 | /* | ||
277 | * Set the Range maximum base address | ||
278 | */ | ||
279 | temp16 = (u16) linked_list->data.io.max_base_address; | ||
280 | |||
281 | ACPI_MOVE_16_TO_16 (buffer, &temp16); | ||
282 | buffer += 2; | ||
283 | |||
284 | /* | ||
285 | * Set the base alignment | ||
286 | */ | ||
287 | temp8 = (u8) linked_list->data.io.alignment; | ||
288 | |||
289 | *buffer = temp8; | ||
290 | buffer += 1; | ||
291 | |||
292 | /* | ||
293 | * Set the range length | ||
294 | */ | ||
295 | temp8 = (u8) linked_list->data.io.range_length; | ||
296 | |||
297 | *buffer = temp8; | ||
298 | buffer += 1; | ||
299 | |||
300 | /* | ||
301 | * Return the number of bytes consumed in this operation | ||
302 | */ | ||
303 | *bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer); | ||
304 | return_ACPI_STATUS (AE_OK); | ||
305 | } | ||
306 | |||
307 | |||
308 | /******************************************************************************* | ||
309 | * | ||
310 | * FUNCTION: acpi_rs_fixed_io_stream | ||
311 | * | ||
312 | * PARAMETERS: linked_list - Pointer to the resource linked list | ||
313 | * output_buffer - Pointer to the user's return buffer | ||
314 | * bytes_consumed - Pointer to where the number of bytes | ||
315 | * used in the output_buffer is returned | ||
316 | * | ||
317 | * RETURN: Status | ||
318 | * | ||
319 | * DESCRIPTION: Take the linked list resource structure and fills in the | ||
320 | * the appropriate bytes in a byte stream | ||
321 | * | ||
322 | ******************************************************************************/ | ||
323 | |||
324 | acpi_status | ||
325 | acpi_rs_fixed_io_stream ( | ||
326 | struct acpi_resource *linked_list, | ||
327 | u8 **output_buffer, | ||
328 | acpi_size *bytes_consumed) | ||
329 | { | ||
330 | u8 *buffer = *output_buffer; | ||
331 | u16 temp16 = 0; | ||
332 | u8 temp8 = 0; | ||
333 | |||
334 | |||
335 | ACPI_FUNCTION_TRACE ("rs_fixed_io_stream"); | ||
336 | |||
337 | |||
338 | /* | ||
339 | * The descriptor field is static | ||
340 | */ | ||
341 | *buffer = 0x4B; | ||
342 | |||
343 | buffer += 1; | ||
344 | |||
345 | /* | ||
346 | * Set the Range base address | ||
347 | */ | ||
348 | temp16 = (u16) linked_list->data.fixed_io.base_address; | ||
349 | |||
350 | ACPI_MOVE_16_TO_16 (buffer, &temp16); | ||
351 | buffer += 2; | ||
352 | |||
353 | /* | ||
354 | * Set the range length | ||
355 | */ | ||
356 | temp8 = (u8) linked_list->data.fixed_io.range_length; | ||
357 | |||
358 | *buffer = temp8; | ||
359 | buffer += 1; | ||
360 | |||
361 | /* | ||
362 | * Return the number of bytes consumed in this operation | ||
363 | */ | ||
364 | *bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer); | ||
365 | return_ACPI_STATUS (AE_OK); | ||
366 | } | ||
367 | |||
368 | |||
369 | /******************************************************************************* | ||
370 | * | ||
371 | * FUNCTION: acpi_rs_dma_resource | ||
372 | * | ||
373 | * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte | ||
374 | * stream | ||
375 | * bytes_consumed - Pointer to where the number of bytes | ||
376 | * consumed the byte_stream_buffer is | ||
377 | * returned | ||
378 | * output_buffer - Pointer to the return data buffer | ||
379 | * structure_size - Pointer to where the number of bytes | ||
380 | * in the return data struct is returned | ||
381 | * | ||
382 | * RETURN: Status | ||
383 | * | ||
384 | * DESCRIPTION: Take the resource byte stream and fill out the appropriate | ||
385 | * structure pointed to by the output_buffer. Return the | ||
386 | * number of bytes consumed from the byte stream. | ||
387 | * | ||
388 | ******************************************************************************/ | ||
389 | |||
390 | acpi_status | ||
391 | acpi_rs_dma_resource ( | ||
392 | u8 *byte_stream_buffer, | ||
393 | acpi_size *bytes_consumed, | ||
394 | u8 **output_buffer, | ||
395 | acpi_size *structure_size) | ||
396 | { | ||
397 | u8 *buffer = byte_stream_buffer; | ||
398 | struct acpi_resource *output_struct = (void *) *output_buffer; | ||
399 | u8 temp8 = 0; | ||
400 | u8 index; | ||
401 | u8 i; | ||
402 | acpi_size struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_dma); | ||
403 | |||
404 | |||
405 | ACPI_FUNCTION_TRACE ("rs_dma_resource"); | ||
406 | |||
407 | |||
408 | /* | ||
409 | * The number of bytes consumed are Constant | ||
410 | */ | ||
411 | *bytes_consumed = 3; | ||
412 | output_struct->id = ACPI_RSTYPE_DMA; | ||
413 | |||
414 | /* | ||
415 | * Point to the 8-bits of Byte 1 | ||
416 | */ | ||
417 | buffer += 1; | ||
418 | temp8 = *buffer; | ||
419 | |||
420 | /* Decode the DMA channel bits */ | ||
421 | |||
422 | for (i = 0, index = 0; index < 8; index++) { | ||
423 | if ((temp8 >> index) & 0x01) { | ||
424 | output_struct->data.dma.channels[i] = index; | ||
425 | i++; | ||
426 | } | ||
427 | } | ||
428 | |||
429 | /* Zero DMA channels is valid */ | ||
430 | |||
431 | output_struct->data.dma.number_of_channels = i; | ||
432 | if (i > 0) { | ||
433 | /* | ||
434 | * Calculate the structure size based upon the number of interrupts | ||
435 | */ | ||
436 | struct_size += ((acpi_size) i - 1) * 4; | ||
437 | } | ||
438 | |||
439 | /* | ||
440 | * Point to Byte 2 | ||
441 | */ | ||
442 | buffer += 1; | ||
443 | temp8 = *buffer; | ||
444 | |||
445 | /* | ||
446 | * Check for transfer preference (Bits[1:0]) | ||
447 | */ | ||
448 | output_struct->data.dma.transfer = temp8 & 0x03; | ||
449 | |||
450 | if (0x03 == output_struct->data.dma.transfer) { | ||
451 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid DMA.Transfer preference (3)\n")); | ||
452 | return_ACPI_STATUS (AE_BAD_DATA); | ||
453 | } | ||
454 | |||
455 | /* | ||
456 | * Get bus master preference (Bit[2]) | ||
457 | */ | ||
458 | output_struct->data.dma.bus_master = (temp8 >> 2) & 0x01; | ||
459 | |||
460 | /* | ||
461 | * Get channel speed support (Bits[6:5]) | ||
462 | */ | ||
463 | output_struct->data.dma.type = (temp8 >> 5) & 0x03; | ||
464 | |||
465 | /* | ||
466 | * Set the Length parameter | ||
467 | */ | ||
468 | output_struct->length = (u32) struct_size; | ||
469 | |||
470 | /* | ||
471 | * Return the final size of the structure | ||
472 | */ | ||
473 | *structure_size = struct_size; | ||
474 | return_ACPI_STATUS (AE_OK); | ||
475 | } | ||
476 | |||
477 | |||
478 | /******************************************************************************* | ||
479 | * | ||
480 | * FUNCTION: acpi_rs_dma_stream | ||
481 | * | ||
482 | * PARAMETERS: linked_list - Pointer to the resource linked list | ||
483 | * output_buffer - Pointer to the user's return buffer | ||
484 | * bytes_consumed - Pointer to where the number of bytes | ||
485 | * used in the output_buffer is returned | ||
486 | * | ||
487 | * RETURN: Status | ||
488 | * | ||
489 | * DESCRIPTION: Take the linked list resource structure and fills in the | ||
490 | * the appropriate bytes in a byte stream | ||
491 | * | ||
492 | ******************************************************************************/ | ||
493 | |||
494 | acpi_status | ||
495 | acpi_rs_dma_stream ( | ||
496 | struct acpi_resource *linked_list, | ||
497 | u8 **output_buffer, | ||
498 | acpi_size *bytes_consumed) | ||
499 | { | ||
500 | u8 *buffer = *output_buffer; | ||
501 | u16 temp16 = 0; | ||
502 | u8 temp8 = 0; | ||
503 | u8 index; | ||
504 | |||
505 | |||
506 | ACPI_FUNCTION_TRACE ("rs_dma_stream"); | ||
507 | |||
508 | |||
509 | /* | ||
510 | * The descriptor field is static | ||
511 | */ | ||
512 | *buffer = 0x2A; | ||
513 | buffer += 1; | ||
514 | temp8 = 0; | ||
515 | |||
516 | /* | ||
517 | * Loop through all of the Channels and set the mask bits | ||
518 | */ | ||
519 | for (index = 0; | ||
520 | index < linked_list->data.dma.number_of_channels; | ||
521 | index++) { | ||
522 | temp16 = (u16) linked_list->data.dma.channels[index]; | ||
523 | temp8 |= 0x1 << temp16; | ||
524 | } | ||
525 | |||
526 | *buffer = temp8; | ||
527 | buffer += 1; | ||
528 | |||
529 | /* | ||
530 | * Set the DMA Info | ||
531 | */ | ||
532 | temp8 = (u8) ((linked_list->data.dma.type & 0x03) << 5); | ||
533 | temp8 |= ((linked_list->data.dma.bus_master & 0x01) << 2); | ||
534 | temp8 |= (linked_list->data.dma.transfer & 0x03); | ||
535 | |||
536 | *buffer = temp8; | ||
537 | buffer += 1; | ||
538 | |||
539 | /* | ||
540 | * Return the number of bytes consumed in this operation | ||
541 | */ | ||
542 | *bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer); | ||
543 | return_ACPI_STATUS (AE_OK); | ||
544 | } | ||
545 | |||
diff --git a/drivers/acpi/resources/rsirq.c b/drivers/acpi/resources/rsirq.c new file mode 100644 index 000000000000..fd07a8702fbe --- /dev/null +++ b/drivers/acpi/resources/rsirq.c | |||
@@ -0,0 +1,592 @@ | |||
1 | /******************************************************************************* | ||
2 | * | ||
3 | * Module Name: rsirq - IRQ resource descriptors | ||
4 | * | ||
5 | ******************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2005, R. Byron Moore | ||
9 | * All rights reserved. | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions, and the following disclaimer, | ||
16 | * without modification. | ||
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
18 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
19 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
20 | * including a substantially similar Disclaimer requirement for further | ||
21 | * binary redistribution. | ||
22 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
23 | * of any contributors may be used to endorse or promote products derived | ||
24 | * from this software without specific prior written permission. | ||
25 | * | ||
26 | * Alternatively, this software may be distributed under the terms of the | ||
27 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
28 | * Software Foundation. | ||
29 | * | ||
30 | * NO WARRANTY | ||
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
41 | * POSSIBILITY OF SUCH DAMAGES. | ||
42 | */ | ||
43 | |||
44 | |||
45 | #include <acpi/acpi.h> | ||
46 | #include <acpi/acresrc.h> | ||
47 | |||
48 | #define _COMPONENT ACPI_RESOURCES | ||
49 | ACPI_MODULE_NAME ("rsirq") | ||
50 | |||
51 | |||
52 | /******************************************************************************* | ||
53 | * | ||
54 | * FUNCTION: acpi_rs_irq_resource | ||
55 | * | ||
56 | * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte | ||
57 | * stream | ||
58 | * bytes_consumed - Pointer to where the number of bytes | ||
59 | * consumed the byte_stream_buffer is | ||
60 | * returned | ||
61 | * output_buffer - Pointer to the return data buffer | ||
62 | * structure_size - Pointer to where the number of bytes | ||
63 | * in the return data struct is returned | ||
64 | * | ||
65 | * RETURN: Status | ||
66 | * | ||
67 | * DESCRIPTION: Take the resource byte stream and fill out the appropriate | ||
68 | * structure pointed to by the output_buffer. Return the | ||
69 | * number of bytes consumed from the byte stream. | ||
70 | * | ||
71 | ******************************************************************************/ | ||
72 | |||
73 | acpi_status | ||
74 | acpi_rs_irq_resource ( | ||
75 | u8 *byte_stream_buffer, | ||
76 | acpi_size *bytes_consumed, | ||
77 | u8 **output_buffer, | ||
78 | acpi_size *structure_size) | ||
79 | { | ||
80 | u8 *buffer = byte_stream_buffer; | ||
81 | struct acpi_resource *output_struct = (void *) *output_buffer; | ||
82 | u16 temp16 = 0; | ||
83 | u8 temp8 = 0; | ||
84 | u8 index; | ||
85 | u8 i; | ||
86 | acpi_size struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_irq); | ||
87 | |||
88 | |||
89 | ACPI_FUNCTION_TRACE ("rs_irq_resource"); | ||
90 | |||
91 | |||
92 | /* | ||
93 | * The number of bytes consumed are contained in the descriptor | ||
94 | * (Bits:0-1) | ||
95 | */ | ||
96 | temp8 = *buffer; | ||
97 | *bytes_consumed = (temp8 & 0x03) + 1; | ||
98 | output_struct->id = ACPI_RSTYPE_IRQ; | ||
99 | |||
100 | /* | ||
101 | * Point to the 16-bits of Bytes 1 and 2 | ||
102 | */ | ||
103 | buffer += 1; | ||
104 | ACPI_MOVE_16_TO_16 (&temp16, buffer); | ||
105 | |||
106 | output_struct->data.irq.number_of_interrupts = 0; | ||
107 | |||
108 | /* Decode the IRQ bits */ | ||
109 | |||
110 | for (i = 0, index = 0; index < 16; index++) { | ||
111 | if ((temp16 >> index) & 0x01) { | ||
112 | output_struct->data.irq.interrupts[i] = index; | ||
113 | i++; | ||
114 | } | ||
115 | } | ||
116 | |||
117 | /* Zero interrupts is valid */ | ||
118 | |||
119 | output_struct->data.irq.number_of_interrupts = i; | ||
120 | if (i > 0) { | ||
121 | /* | ||
122 | * Calculate the structure size based upon the number of interrupts | ||
123 | */ | ||
124 | struct_size += ((acpi_size) i - 1) * 4; | ||
125 | } | ||
126 | |||
127 | /* | ||
128 | * Point to Byte 3 if it is used | ||
129 | */ | ||
130 | if (4 == *bytes_consumed) { | ||
131 | buffer += 2; | ||
132 | temp8 = *buffer; | ||
133 | |||
134 | /* | ||
135 | * Check for HE, LL interrupts | ||
136 | */ | ||
137 | switch (temp8 & 0x09) { | ||
138 | case 0x01: /* HE */ | ||
139 | output_struct->data.irq.edge_level = ACPI_EDGE_SENSITIVE; | ||
140 | output_struct->data.irq.active_high_low = ACPI_ACTIVE_HIGH; | ||
141 | break; | ||
142 | |||
143 | case 0x08: /* LL */ | ||
144 | output_struct->data.irq.edge_level = ACPI_LEVEL_SENSITIVE; | ||
145 | output_struct->data.irq.active_high_low = ACPI_ACTIVE_LOW; | ||
146 | break; | ||
147 | |||
148 | default: | ||
149 | /* | ||
150 | * Only _LL and _HE polarity/trigger interrupts | ||
151 | * are allowed (ACPI spec, section "IRQ Format") | ||
152 | * so 0x00 and 0x09 are illegal. | ||
153 | */ | ||
154 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, | ||
155 | "Invalid interrupt polarity/trigger in resource list, %X\n", temp8)); | ||
156 | return_ACPI_STATUS (AE_BAD_DATA); | ||
157 | } | ||
158 | |||
159 | /* | ||
160 | * Check for sharable | ||
161 | */ | ||
162 | output_struct->data.irq.shared_exclusive = (temp8 >> 3) & 0x01; | ||
163 | } | ||
164 | else { | ||
165 | /* | ||
166 | * Assume Edge Sensitive, Active High, Non-Sharable | ||
167 | * per ACPI Specification | ||
168 | */ | ||
169 | output_struct->data.irq.edge_level = ACPI_EDGE_SENSITIVE; | ||
170 | output_struct->data.irq.active_high_low = ACPI_ACTIVE_HIGH; | ||
171 | output_struct->data.irq.shared_exclusive = ACPI_EXCLUSIVE; | ||
172 | } | ||
173 | |||
174 | /* | ||
175 | * Set the Length parameter | ||
176 | */ | ||
177 | output_struct->length = (u32) struct_size; | ||
178 | |||
179 | /* | ||
180 | * Return the final size of the structure | ||
181 | */ | ||
182 | *structure_size = struct_size; | ||
183 | return_ACPI_STATUS (AE_OK); | ||
184 | } | ||
185 | |||
186 | |||
187 | /******************************************************************************* | ||
188 | * | ||
189 | * FUNCTION: acpi_rs_irq_stream | ||
190 | * | ||
191 | * PARAMETERS: linked_list - Pointer to the resource linked list | ||
192 | * output_buffer - Pointer to the user's return buffer | ||
193 | * bytes_consumed - Pointer to where the number of bytes | ||
194 | * used in the output_buffer is returned | ||
195 | * | ||
196 | * RETURN: Status | ||
197 | * | ||
198 | * DESCRIPTION: Take the linked list resource structure and fills in the | ||
199 | * the appropriate bytes in a byte stream | ||
200 | * | ||
201 | ******************************************************************************/ | ||
202 | |||
203 | acpi_status | ||
204 | acpi_rs_irq_stream ( | ||
205 | struct acpi_resource *linked_list, | ||
206 | u8 **output_buffer, | ||
207 | acpi_size *bytes_consumed) | ||
208 | { | ||
209 | u8 *buffer = *output_buffer; | ||
210 | u16 temp16 = 0; | ||
211 | u8 temp8 = 0; | ||
212 | u8 index; | ||
213 | u8 IRqinfo_byte_needed; | ||
214 | |||
215 | |||
216 | ACPI_FUNCTION_TRACE ("rs_irq_stream"); | ||
217 | |||
218 | |||
219 | /* | ||
220 | * The descriptor field is set based upon whether a third byte is | ||
221 | * needed to contain the IRQ Information. | ||
222 | */ | ||
223 | if (ACPI_EDGE_SENSITIVE == linked_list->data.irq.edge_level && | ||
224 | ACPI_ACTIVE_HIGH == linked_list->data.irq.active_high_low && | ||
225 | ACPI_EXCLUSIVE == linked_list->data.irq.shared_exclusive) { | ||
226 | *buffer = 0x22; | ||
227 | IRqinfo_byte_needed = FALSE; | ||
228 | } | ||
229 | else { | ||
230 | *buffer = 0x23; | ||
231 | IRqinfo_byte_needed = TRUE; | ||
232 | } | ||
233 | |||
234 | buffer += 1; | ||
235 | temp16 = 0; | ||
236 | |||
237 | /* | ||
238 | * Loop through all of the interrupts and set the mask bits | ||
239 | */ | ||
240 | for(index = 0; | ||
241 | index < linked_list->data.irq.number_of_interrupts; | ||
242 | index++) { | ||
243 | temp8 = (u8) linked_list->data.irq.interrupts[index]; | ||
244 | temp16 |= 0x1 << temp8; | ||
245 | } | ||
246 | |||
247 | ACPI_MOVE_16_TO_16 (buffer, &temp16); | ||
248 | buffer += 2; | ||
249 | |||
250 | /* | ||
251 | * Set the IRQ Info byte if needed. | ||
252 | */ | ||
253 | if (IRqinfo_byte_needed) { | ||
254 | temp8 = 0; | ||
255 | temp8 = (u8) ((linked_list->data.irq.shared_exclusive & | ||
256 | 0x01) << 4); | ||
257 | |||
258 | if (ACPI_LEVEL_SENSITIVE == linked_list->data.irq.edge_level && | ||
259 | ACPI_ACTIVE_LOW == linked_list->data.irq.active_high_low) { | ||
260 | temp8 |= 0x08; | ||
261 | } | ||
262 | else { | ||
263 | temp8 |= 0x01; | ||
264 | } | ||
265 | |||
266 | *buffer = temp8; | ||
267 | buffer += 1; | ||
268 | } | ||
269 | |||
270 | /* | ||
271 | * Return the number of bytes consumed in this operation | ||
272 | */ | ||
273 | *bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer); | ||
274 | return_ACPI_STATUS (AE_OK); | ||
275 | } | ||
276 | |||
277 | |||
278 | /******************************************************************************* | ||
279 | * | ||
280 | * FUNCTION: acpi_rs_extended_irq_resource | ||
281 | * | ||
282 | * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte | ||
283 | * stream | ||
284 | * bytes_consumed - Pointer to where the number of bytes | ||
285 | * consumed the byte_stream_buffer is | ||
286 | * returned | ||
287 | * output_buffer - Pointer to the return data buffer | ||
288 | * structure_size - Pointer to where the number of bytes | ||
289 | * in the return data struct is returned | ||
290 | * | ||
291 | * RETURN: Status | ||
292 | * | ||
293 | * DESCRIPTION: Take the resource byte stream and fill out the appropriate | ||
294 | * structure pointed to by the output_buffer. Return the | ||
295 | * number of bytes consumed from the byte stream. | ||
296 | * | ||
297 | ******************************************************************************/ | ||
298 | |||
299 | acpi_status | ||
300 | acpi_rs_extended_irq_resource ( | ||
301 | u8 *byte_stream_buffer, | ||
302 | acpi_size *bytes_consumed, | ||
303 | u8 **output_buffer, | ||
304 | acpi_size *structure_size) | ||
305 | { | ||
306 | u8 *buffer = byte_stream_buffer; | ||
307 | struct acpi_resource *output_struct = (void *) *output_buffer; | ||
308 | u16 temp16 = 0; | ||
309 | u8 temp8 = 0; | ||
310 | u8 *temp_ptr; | ||
311 | u8 index; | ||
312 | acpi_size struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_ext_irq); | ||
313 | |||
314 | |||
315 | ACPI_FUNCTION_TRACE ("rs_extended_irq_resource"); | ||
316 | |||
317 | |||
318 | /* | ||
319 | * Point past the Descriptor to get the number of bytes consumed | ||
320 | */ | ||
321 | buffer += 1; | ||
322 | ACPI_MOVE_16_TO_16 (&temp16, buffer); | ||
323 | |||
324 | /* Validate minimum descriptor length */ | ||
325 | |||
326 | if (temp16 < 6) { | ||
327 | return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH); | ||
328 | } | ||
329 | |||
330 | *bytes_consumed = temp16 + 3; | ||
331 | output_struct->id = ACPI_RSTYPE_EXT_IRQ; | ||
332 | |||
333 | /* | ||
334 | * Point to the Byte3 | ||
335 | */ | ||
336 | buffer += 2; | ||
337 | temp8 = *buffer; | ||
338 | |||
339 | output_struct->data.extended_irq.producer_consumer = temp8 & 0x01; | ||
340 | |||
341 | /* | ||
342 | * Check for Interrupt Mode | ||
343 | * | ||
344 | * The definition of an Extended IRQ changed between ACPI spec v1.0b | ||
345 | * and ACPI spec 2.0 (section 6.4.3.6 in both). | ||
346 | * | ||
347 | * - Edge/Level are defined opposite in the table vs the headers | ||
348 | */ | ||
349 | output_struct->data.extended_irq.edge_level = | ||
350 | (temp8 & 0x2) ? ACPI_EDGE_SENSITIVE : ACPI_LEVEL_SENSITIVE; | ||
351 | |||
352 | /* | ||
353 | * Check Interrupt Polarity | ||
354 | */ | ||
355 | output_struct->data.extended_irq.active_high_low = (temp8 >> 2) & 0x1; | ||
356 | |||
357 | /* | ||
358 | * Check for sharable | ||
359 | */ | ||
360 | output_struct->data.extended_irq.shared_exclusive = (temp8 >> 3) & 0x01; | ||
361 | |||
362 | /* | ||
363 | * Point to Byte4 (IRQ Table length) | ||
364 | */ | ||
365 | buffer += 1; | ||
366 | temp8 = *buffer; | ||
367 | |||
368 | /* Must have at least one IRQ */ | ||
369 | |||
370 | if (temp8 < 1) { | ||
371 | return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH); | ||
372 | } | ||
373 | |||
374 | output_struct->data.extended_irq.number_of_interrupts = temp8; | ||
375 | |||
376 | /* | ||
377 | * Add any additional structure size to properly calculate | ||
378 | * the next pointer at the end of this function | ||
379 | */ | ||
380 | struct_size += (temp8 - 1) * 4; | ||
381 | |||
382 | /* | ||
383 | * Point to Byte5 (First IRQ Number) | ||
384 | */ | ||
385 | buffer += 1; | ||
386 | |||
387 | /* | ||
388 | * Cycle through every IRQ in the table | ||
389 | */ | ||
390 | for (index = 0; index < temp8; index++) { | ||
391 | ACPI_MOVE_32_TO_32 ( | ||
392 | &output_struct->data.extended_irq.interrupts[index], buffer); | ||
393 | |||
394 | /* Point to the next IRQ */ | ||
395 | |||
396 | buffer += 4; | ||
397 | } | ||
398 | |||
399 | /* | ||
400 | * This will leave us pointing to the Resource Source Index | ||
401 | * If it is present, then save it off and calculate the | ||
402 | * pointer to where the null terminated string goes: | ||
403 | * Each Interrupt takes 32-bits + the 5 bytes of the | ||
404 | * stream that are default. | ||
405 | * | ||
406 | * Note: Some resource descriptors will have an additional null, so | ||
407 | * we add 1 to the length. | ||
408 | */ | ||
409 | if (*bytes_consumed > | ||
410 | ((acpi_size) output_struct->data.extended_irq.number_of_interrupts * 4) + (5 + 1)) { | ||
411 | /* Dereference the Index */ | ||
412 | |||
413 | temp8 = *buffer; | ||
414 | output_struct->data.extended_irq.resource_source.index = (u32) temp8; | ||
415 | |||
416 | /* Point to the String */ | ||
417 | |||
418 | buffer += 1; | ||
419 | |||
420 | /* | ||
421 | * Point the String pointer to the end of this structure. | ||
422 | */ | ||
423 | output_struct->data.extended_irq.resource_source.string_ptr = | ||
424 | (char *)((char *) output_struct + struct_size); | ||
425 | |||
426 | temp_ptr = (u8 *) output_struct->data.extended_irq.resource_source.string_ptr; | ||
427 | |||
428 | /* Copy the string into the buffer */ | ||
429 | |||
430 | index = 0; | ||
431 | while (0x00 != *buffer) { | ||
432 | *temp_ptr = *buffer; | ||
433 | |||
434 | temp_ptr += 1; | ||
435 | buffer += 1; | ||
436 | index += 1; | ||
437 | } | ||
438 | |||
439 | /* | ||
440 | * Add the terminating null | ||
441 | */ | ||
442 | *temp_ptr = 0x00; | ||
443 | output_struct->data.extended_irq.resource_source.string_length = index + 1; | ||
444 | |||
445 | /* | ||
446 | * In order for the struct_size to fall on a 32-bit boundary, | ||
447 | * calculate the length of the string and expand the | ||
448 | * struct_size to the next 32-bit boundary. | ||
449 | */ | ||
450 | temp8 = (u8) (index + 1); | ||
451 | struct_size += ACPI_ROUND_UP_to_32_bITS (temp8); | ||
452 | } | ||
453 | else { | ||
454 | output_struct->data.extended_irq.resource_source.index = 0x00; | ||
455 | output_struct->data.extended_irq.resource_source.string_length = 0; | ||
456 | output_struct->data.extended_irq.resource_source.string_ptr = NULL; | ||
457 | } | ||
458 | |||
459 | /* | ||
460 | * Set the Length parameter | ||
461 | */ | ||
462 | output_struct->length = (u32) struct_size; | ||
463 | |||
464 | /* | ||
465 | * Return the final size of the structure | ||
466 | */ | ||
467 | *structure_size = struct_size; | ||
468 | return_ACPI_STATUS (AE_OK); | ||
469 | } | ||
470 | |||
471 | |||
472 | /******************************************************************************* | ||
473 | * | ||
474 | * FUNCTION: acpi_rs_extended_irq_stream | ||
475 | * | ||
476 | * PARAMETERS: linked_list - Pointer to the resource linked list | ||
477 | * output_buffer - Pointer to the user's return buffer | ||
478 | * bytes_consumed - Pointer to where the number of bytes | ||
479 | * used in the output_buffer is returned | ||
480 | * | ||
481 | * RETURN: Status | ||
482 | * | ||
483 | * DESCRIPTION: Take the linked list resource structure and fills in the | ||
484 | * the appropriate bytes in a byte stream | ||
485 | * | ||
486 | ******************************************************************************/ | ||
487 | |||
488 | acpi_status | ||
489 | acpi_rs_extended_irq_stream ( | ||
490 | struct acpi_resource *linked_list, | ||
491 | u8 **output_buffer, | ||
492 | acpi_size *bytes_consumed) | ||
493 | { | ||
494 | u8 *buffer = *output_buffer; | ||
495 | u16 *length_field; | ||
496 | u8 temp8 = 0; | ||
497 | u8 index; | ||
498 | char *temp_pointer = NULL; | ||
499 | |||
500 | |||
501 | ACPI_FUNCTION_TRACE ("rs_extended_irq_stream"); | ||
502 | |||
503 | |||
504 | /* | ||
505 | * The descriptor field is static | ||
506 | */ | ||
507 | *buffer = 0x89; | ||
508 | buffer += 1; | ||
509 | |||
510 | /* | ||
511 | * Set a pointer to the Length field - to be filled in later | ||
512 | */ | ||
513 | length_field = ACPI_CAST_PTR (u16, buffer); | ||
514 | buffer += 2; | ||
515 | |||
516 | /* | ||
517 | * Set the Interrupt vector flags | ||
518 | */ | ||
519 | temp8 = (u8)(linked_list->data.extended_irq.producer_consumer & 0x01); | ||
520 | temp8 |= ((linked_list->data.extended_irq.shared_exclusive & 0x01) << 3); | ||
521 | |||
522 | /* | ||
523 | * Set the Interrupt Mode | ||
524 | * | ||
525 | * The definition of an Extended IRQ changed between ACPI spec v1.0b | ||
526 | * and ACPI spec 2.0 (section 6.4.3.6 in both). This code does not | ||
527 | * implement the more restrictive definition of 1.0b | ||
528 | * | ||
529 | * - Edge/Level are defined opposite in the table vs the headers | ||
530 | */ | ||
531 | if (ACPI_EDGE_SENSITIVE == linked_list->data.extended_irq.edge_level) { | ||
532 | temp8 |= 0x2; | ||
533 | } | ||
534 | |||
535 | /* | ||
536 | * Set the Interrupt Polarity | ||
537 | */ | ||
538 | temp8 |= ((linked_list->data.extended_irq.active_high_low & 0x1) << 2); | ||
539 | |||
540 | *buffer = temp8; | ||
541 | buffer += 1; | ||
542 | |||
543 | /* | ||
544 | * Set the Interrupt table length | ||
545 | */ | ||
546 | temp8 = (u8) linked_list->data.extended_irq.number_of_interrupts; | ||
547 | |||
548 | *buffer = temp8; | ||
549 | buffer += 1; | ||
550 | |||
551 | for (index = 0; index < linked_list->data.extended_irq.number_of_interrupts; | ||
552 | index++) { | ||
553 | ACPI_MOVE_32_TO_32 (buffer, | ||
554 | &linked_list->data.extended_irq.interrupts[index]); | ||
555 | buffer += 4; | ||
556 | } | ||
557 | |||
558 | /* | ||
559 | * Resource Source Index and Resource Source are optional | ||
560 | */ | ||
561 | if (0 != linked_list->data.extended_irq.resource_source.string_length) { | ||
562 | *buffer = (u8) linked_list->data.extended_irq.resource_source.index; | ||
563 | buffer += 1; | ||
564 | |||
565 | temp_pointer = (char *) buffer; | ||
566 | |||
567 | /* | ||
568 | * Copy the string | ||
569 | */ | ||
570 | ACPI_STRCPY (temp_pointer, | ||
571 | linked_list->data.extended_irq.resource_source.string_ptr); | ||
572 | |||
573 | /* | ||
574 | * Buffer needs to be set to the length of the sting + one for the | ||
575 | * terminating null | ||
576 | */ | ||
577 | buffer += (acpi_size)(ACPI_STRLEN (linked_list->data.extended_irq.resource_source.string_ptr) + 1); | ||
578 | } | ||
579 | |||
580 | /* | ||
581 | * Return the number of bytes consumed in this operation | ||
582 | */ | ||
583 | *bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer); | ||
584 | |||
585 | /* | ||
586 | * Set the length field to the number of bytes consumed | ||
587 | * minus the header size (3 bytes) | ||
588 | */ | ||
589 | *length_field = (u16) (*bytes_consumed - 3); | ||
590 | return_ACPI_STATUS (AE_OK); | ||
591 | } | ||
592 | |||
diff --git a/drivers/acpi/resources/rslist.c b/drivers/acpi/resources/rslist.c new file mode 100644 index 000000000000..e49c1e030f99 --- /dev/null +++ b/drivers/acpi/resources/rslist.c | |||
@@ -0,0 +1,518 @@ | |||
1 | /******************************************************************************* | ||
2 | * | ||
3 | * Module Name: rslist - Linked list utilities | ||
4 | * | ||
5 | ******************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2005, R. Byron Moore | ||
9 | * All rights reserved. | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions, and the following disclaimer, | ||
16 | * without modification. | ||
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
18 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
19 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
20 | * including a substantially similar Disclaimer requirement for further | ||
21 | * binary redistribution. | ||
22 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
23 | * of any contributors may be used to endorse or promote products derived | ||
24 | * from this software without specific prior written permission. | ||
25 | * | ||
26 | * Alternatively, this software may be distributed under the terms of the | ||
27 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
28 | * Software Foundation. | ||
29 | * | ||
30 | * NO WARRANTY | ||
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
41 | * POSSIBILITY OF SUCH DAMAGES. | ||
42 | */ | ||
43 | |||
44 | |||
45 | #include <acpi/acpi.h> | ||
46 | #include <acpi/acresrc.h> | ||
47 | |||
48 | #define _COMPONENT ACPI_RESOURCES | ||
49 | ACPI_MODULE_NAME ("rslist") | ||
50 | |||
51 | |||
52 | /******************************************************************************* | ||
53 | * | ||
54 | * FUNCTION: acpi_rs_get_resource_type | ||
55 | * | ||
56 | * PARAMETERS: resource_start_byte - Byte 0 of a resource descriptor | ||
57 | * | ||
58 | * RETURN: The Resource Type (Name) with no extraneous bits | ||
59 | * | ||
60 | * DESCRIPTION: Extract the Resource Type/Name from the first byte of | ||
61 | * a resource descriptor. | ||
62 | * | ||
63 | ******************************************************************************/ | ||
64 | |||
65 | u8 | ||
66 | acpi_rs_get_resource_type ( | ||
67 | u8 resource_start_byte) | ||
68 | { | ||
69 | |||
70 | ACPI_FUNCTION_ENTRY (); | ||
71 | |||
72 | |||
73 | /* | ||
74 | * Determine if this is a small or large resource | ||
75 | */ | ||
76 | switch (resource_start_byte & ACPI_RDESC_TYPE_MASK) { | ||
77 | case ACPI_RDESC_TYPE_SMALL: | ||
78 | |||
79 | /* | ||
80 | * Small Resource Type -- Only bits 6:3 are valid | ||
81 | */ | ||
82 | return ((u8) (resource_start_byte & ACPI_RDESC_SMALL_MASK)); | ||
83 | |||
84 | |||
85 | case ACPI_RDESC_TYPE_LARGE: | ||
86 | |||
87 | /* | ||
88 | * Large Resource Type -- All bits are valid | ||
89 | */ | ||
90 | return (resource_start_byte); | ||
91 | |||
92 | |||
93 | default: | ||
94 | /* No other types of resource descriptor */ | ||
95 | break; | ||
96 | } | ||
97 | |||
98 | return (0xFF); | ||
99 | } | ||
100 | |||
101 | |||
102 | /******************************************************************************* | ||
103 | * | ||
104 | * FUNCTION: acpi_rs_byte_stream_to_list | ||
105 | * | ||
106 | * PARAMETERS: byte_stream_buffer - Pointer to the resource byte stream | ||
107 | * byte_stream_buffer_length - Length of byte_stream_buffer | ||
108 | * output_buffer - Pointer to the buffer that will | ||
109 | * contain the output structures | ||
110 | * | ||
111 | * RETURN: Status | ||
112 | * | ||
113 | * DESCRIPTION: Takes the resource byte stream and parses it, creating a | ||
114 | * linked list of resources in the caller's output buffer | ||
115 | * | ||
116 | ******************************************************************************/ | ||
117 | |||
118 | acpi_status | ||
119 | acpi_rs_byte_stream_to_list ( | ||
120 | u8 *byte_stream_buffer, | ||
121 | u32 byte_stream_buffer_length, | ||
122 | u8 *output_buffer) | ||
123 | { | ||
124 | acpi_status status; | ||
125 | acpi_size bytes_parsed = 0; | ||
126 | u8 resource_type = 0; | ||
127 | acpi_size bytes_consumed = 0; | ||
128 | u8 *buffer = output_buffer; | ||
129 | acpi_size structure_size = 0; | ||
130 | u8 end_tag_processed = FALSE; | ||
131 | struct acpi_resource *resource; | ||
132 | |||
133 | ACPI_FUNCTION_TRACE ("rs_byte_stream_to_list"); | ||
134 | |||
135 | |||
136 | while (bytes_parsed < byte_stream_buffer_length && | ||
137 | !end_tag_processed) { | ||
138 | /* | ||
139 | * The next byte in the stream is the resource type | ||
140 | */ | ||
141 | resource_type = acpi_rs_get_resource_type (*byte_stream_buffer); | ||
142 | |||
143 | switch (resource_type) { | ||
144 | case ACPI_RDESC_TYPE_MEMORY_24: | ||
145 | /* | ||
146 | * 24-Bit Memory Resource | ||
147 | */ | ||
148 | status = acpi_rs_memory24_resource (byte_stream_buffer, | ||
149 | &bytes_consumed, &buffer, &structure_size); | ||
150 | break; | ||
151 | |||
152 | |||
153 | case ACPI_RDESC_TYPE_LARGE_VENDOR: | ||
154 | /* | ||
155 | * Vendor Defined Resource | ||
156 | */ | ||
157 | status = acpi_rs_vendor_resource (byte_stream_buffer, | ||
158 | &bytes_consumed, &buffer, &structure_size); | ||
159 | break; | ||
160 | |||
161 | |||
162 | case ACPI_RDESC_TYPE_MEMORY_32: | ||
163 | /* | ||
164 | * 32-Bit Memory Range Resource | ||
165 | */ | ||
166 | status = acpi_rs_memory32_range_resource (byte_stream_buffer, | ||
167 | &bytes_consumed, &buffer, &structure_size); | ||
168 | break; | ||
169 | |||
170 | |||
171 | case ACPI_RDESC_TYPE_FIXED_MEMORY_32: | ||
172 | /* | ||
173 | * 32-Bit Fixed Memory Resource | ||
174 | */ | ||
175 | status = acpi_rs_fixed_memory32_resource (byte_stream_buffer, | ||
176 | &bytes_consumed, &buffer, &structure_size); | ||
177 | break; | ||
178 | |||
179 | |||
180 | case ACPI_RDESC_TYPE_QWORD_ADDRESS_SPACE: | ||
181 | case ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE: | ||
182 | /* | ||
183 | * 64-Bit Address Resource | ||
184 | */ | ||
185 | status = acpi_rs_address64_resource (byte_stream_buffer, | ||
186 | &bytes_consumed, &buffer, &structure_size); | ||
187 | break; | ||
188 | |||
189 | |||
190 | case ACPI_RDESC_TYPE_DWORD_ADDRESS_SPACE: | ||
191 | /* | ||
192 | * 32-Bit Address Resource | ||
193 | */ | ||
194 | status = acpi_rs_address32_resource (byte_stream_buffer, | ||
195 | &bytes_consumed, &buffer, &structure_size); | ||
196 | break; | ||
197 | |||
198 | |||
199 | case ACPI_RDESC_TYPE_WORD_ADDRESS_SPACE: | ||
200 | /* | ||
201 | * 16-Bit Address Resource | ||
202 | */ | ||
203 | status = acpi_rs_address16_resource (byte_stream_buffer, | ||
204 | &bytes_consumed, &buffer, &structure_size); | ||
205 | break; | ||
206 | |||
207 | |||
208 | case ACPI_RDESC_TYPE_EXTENDED_XRUPT: | ||
209 | /* | ||
210 | * Extended IRQ | ||
211 | */ | ||
212 | status = acpi_rs_extended_irq_resource (byte_stream_buffer, | ||
213 | &bytes_consumed, &buffer, &structure_size); | ||
214 | break; | ||
215 | |||
216 | |||
217 | case ACPI_RDESC_TYPE_IRQ_FORMAT: | ||
218 | /* | ||
219 | * IRQ Resource | ||
220 | */ | ||
221 | status = acpi_rs_irq_resource (byte_stream_buffer, | ||
222 | &bytes_consumed, &buffer, &structure_size); | ||
223 | break; | ||
224 | |||
225 | |||
226 | case ACPI_RDESC_TYPE_DMA_FORMAT: | ||
227 | /* | ||
228 | * DMA Resource | ||
229 | */ | ||
230 | status = acpi_rs_dma_resource (byte_stream_buffer, | ||
231 | &bytes_consumed, &buffer, &structure_size); | ||
232 | break; | ||
233 | |||
234 | |||
235 | case ACPI_RDESC_TYPE_START_DEPENDENT: | ||
236 | /* | ||
237 | * Start Dependent Functions Resource | ||
238 | */ | ||
239 | status = acpi_rs_start_depend_fns_resource (byte_stream_buffer, | ||
240 | &bytes_consumed, &buffer, &structure_size); | ||
241 | break; | ||
242 | |||
243 | |||
244 | case ACPI_RDESC_TYPE_END_DEPENDENT: | ||
245 | /* | ||
246 | * End Dependent Functions Resource | ||
247 | */ | ||
248 | status = acpi_rs_end_depend_fns_resource (byte_stream_buffer, | ||
249 | &bytes_consumed, &buffer, &structure_size); | ||
250 | break; | ||
251 | |||
252 | |||
253 | case ACPI_RDESC_TYPE_IO_PORT: | ||
254 | /* | ||
255 | * IO Port Resource | ||
256 | */ | ||
257 | status = acpi_rs_io_resource (byte_stream_buffer, | ||
258 | &bytes_consumed, &buffer, &structure_size); | ||
259 | break; | ||
260 | |||
261 | |||
262 | case ACPI_RDESC_TYPE_FIXED_IO_PORT: | ||
263 | /* | ||
264 | * Fixed IO Port Resource | ||
265 | */ | ||
266 | status = acpi_rs_fixed_io_resource (byte_stream_buffer, | ||
267 | &bytes_consumed, &buffer, &structure_size); | ||
268 | break; | ||
269 | |||
270 | |||
271 | case ACPI_RDESC_TYPE_SMALL_VENDOR: | ||
272 | /* | ||
273 | * Vendor Specific Resource | ||
274 | */ | ||
275 | status = acpi_rs_vendor_resource (byte_stream_buffer, | ||
276 | &bytes_consumed, &buffer, &structure_size); | ||
277 | break; | ||
278 | |||
279 | |||
280 | case ACPI_RDESC_TYPE_END_TAG: | ||
281 | /* | ||
282 | * End Tag | ||
283 | */ | ||
284 | end_tag_processed = TRUE; | ||
285 | status = acpi_rs_end_tag_resource (byte_stream_buffer, | ||
286 | &bytes_consumed, &buffer, &structure_size); | ||
287 | break; | ||
288 | |||
289 | |||
290 | default: | ||
291 | /* | ||
292 | * Invalid/Unknown resource type | ||
293 | */ | ||
294 | status = AE_AML_INVALID_RESOURCE_TYPE; | ||
295 | break; | ||
296 | } | ||
297 | |||
298 | if (ACPI_FAILURE (status)) { | ||
299 | return_ACPI_STATUS (status); | ||
300 | } | ||
301 | |||
302 | /* | ||
303 | * Update the return value and counter | ||
304 | */ | ||
305 | bytes_parsed += bytes_consumed; | ||
306 | |||
307 | /* | ||
308 | * Set the byte stream to point to the next resource | ||
309 | */ | ||
310 | byte_stream_buffer += bytes_consumed; | ||
311 | |||
312 | /* | ||
313 | * Set the Buffer to the next structure | ||
314 | */ | ||
315 | resource = ACPI_CAST_PTR (struct acpi_resource, buffer); | ||
316 | resource->length = (u32) ACPI_ALIGN_RESOURCE_SIZE (resource->length); | ||
317 | buffer += ACPI_ALIGN_RESOURCE_SIZE (structure_size); | ||
318 | |||
319 | } /* end while */ | ||
320 | |||
321 | /* | ||
322 | * Check the reason for exiting the while loop | ||
323 | */ | ||
324 | if (!end_tag_processed) { | ||
325 | return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG); | ||
326 | } | ||
327 | |||
328 | return_ACPI_STATUS (AE_OK); | ||
329 | } | ||
330 | |||
331 | |||
332 | /******************************************************************************* | ||
333 | * | ||
334 | * FUNCTION: acpi_rs_list_to_byte_stream | ||
335 | * | ||
336 | * PARAMETERS: linked_list - Pointer to the resource linked list | ||
337 | * byte_steam_size_needed - Calculated size of the byte stream | ||
338 | * needed from calling | ||
339 | * acpi_rs_get_byte_stream_length() | ||
340 | * The size of the output_buffer is | ||
341 | * guaranteed to be >= | ||
342 | * byte_stream_size_needed | ||
343 | * output_buffer - Pointer to the buffer that will | ||
344 | * contain the byte stream | ||
345 | * | ||
346 | * RETURN: Status | ||
347 | * | ||
348 | * DESCRIPTION: Takes the resource linked list and parses it, creating a | ||
349 | * byte stream of resources in the caller's output buffer | ||
350 | * | ||
351 | ******************************************************************************/ | ||
352 | |||
353 | acpi_status | ||
354 | acpi_rs_list_to_byte_stream ( | ||
355 | struct acpi_resource *linked_list, | ||
356 | acpi_size byte_stream_size_needed, | ||
357 | u8 *output_buffer) | ||
358 | { | ||
359 | acpi_status status; | ||
360 | u8 *buffer = output_buffer; | ||
361 | acpi_size bytes_consumed = 0; | ||
362 | u8 done = FALSE; | ||
363 | |||
364 | |||
365 | ACPI_FUNCTION_TRACE ("rs_list_to_byte_stream"); | ||
366 | |||
367 | |||
368 | while (!done) { | ||
369 | switch (linked_list->id) { | ||
370 | case ACPI_RSTYPE_IRQ: | ||
371 | /* | ||
372 | * IRQ Resource | ||
373 | */ | ||
374 | status = acpi_rs_irq_stream (linked_list, &buffer, &bytes_consumed); | ||
375 | break; | ||
376 | |||
377 | case ACPI_RSTYPE_DMA: | ||
378 | /* | ||
379 | * DMA Resource | ||
380 | */ | ||
381 | status = acpi_rs_dma_stream (linked_list, &buffer, &bytes_consumed); | ||
382 | break; | ||
383 | |||
384 | case ACPI_RSTYPE_START_DPF: | ||
385 | /* | ||
386 | * Start Dependent Functions Resource | ||
387 | */ | ||
388 | status = acpi_rs_start_depend_fns_stream (linked_list, | ||
389 | &buffer, &bytes_consumed); | ||
390 | break; | ||
391 | |||
392 | case ACPI_RSTYPE_END_DPF: | ||
393 | /* | ||
394 | * End Dependent Functions Resource | ||
395 | */ | ||
396 | status = acpi_rs_end_depend_fns_stream (linked_list, | ||
397 | &buffer, &bytes_consumed); | ||
398 | break; | ||
399 | |||
400 | case ACPI_RSTYPE_IO: | ||
401 | /* | ||
402 | * IO Port Resource | ||
403 | */ | ||
404 | status = acpi_rs_io_stream (linked_list, &buffer, &bytes_consumed); | ||
405 | break; | ||
406 | |||
407 | case ACPI_RSTYPE_FIXED_IO: | ||
408 | /* | ||
409 | * Fixed IO Port Resource | ||
410 | */ | ||
411 | status = acpi_rs_fixed_io_stream (linked_list, &buffer, &bytes_consumed); | ||
412 | break; | ||
413 | |||
414 | case ACPI_RSTYPE_VENDOR: | ||
415 | /* | ||
416 | * Vendor Defined Resource | ||
417 | */ | ||
418 | status = acpi_rs_vendor_stream (linked_list, &buffer, &bytes_consumed); | ||
419 | break; | ||
420 | |||
421 | case ACPI_RSTYPE_END_TAG: | ||
422 | /* | ||
423 | * End Tag | ||
424 | */ | ||
425 | status = acpi_rs_end_tag_stream (linked_list, &buffer, &bytes_consumed); | ||
426 | |||
427 | /* | ||
428 | * An End Tag indicates the end of the Resource Template | ||
429 | */ | ||
430 | done = TRUE; | ||
431 | break; | ||
432 | |||
433 | case ACPI_RSTYPE_MEM24: | ||
434 | /* | ||
435 | * 24-Bit Memory Resource | ||
436 | */ | ||
437 | status = acpi_rs_memory24_stream (linked_list, &buffer, &bytes_consumed); | ||
438 | break; | ||
439 | |||
440 | case ACPI_RSTYPE_MEM32: | ||
441 | /* | ||
442 | * 32-Bit Memory Range Resource | ||
443 | */ | ||
444 | status = acpi_rs_memory32_range_stream (linked_list, &buffer, | ||
445 | &bytes_consumed); | ||
446 | break; | ||
447 | |||
448 | case ACPI_RSTYPE_FIXED_MEM32: | ||
449 | /* | ||
450 | * 32-Bit Fixed Memory Resource | ||
451 | */ | ||
452 | status = acpi_rs_fixed_memory32_stream (linked_list, &buffer, | ||
453 | &bytes_consumed); | ||
454 | break; | ||
455 | |||
456 | case ACPI_RSTYPE_ADDRESS16: | ||
457 | /* | ||
458 | * 16-Bit Address Descriptor Resource | ||
459 | */ | ||
460 | status = acpi_rs_address16_stream (linked_list, &buffer, | ||
461 | &bytes_consumed); | ||
462 | break; | ||
463 | |||
464 | case ACPI_RSTYPE_ADDRESS32: | ||
465 | /* | ||
466 | * 32-Bit Address Descriptor Resource | ||
467 | */ | ||
468 | status = acpi_rs_address32_stream (linked_list, &buffer, | ||
469 | &bytes_consumed); | ||
470 | break; | ||
471 | |||
472 | case ACPI_RSTYPE_ADDRESS64: | ||
473 | /* | ||
474 | * 64-Bit Address Descriptor Resource | ||
475 | */ | ||
476 | status = acpi_rs_address64_stream (linked_list, &buffer, | ||
477 | &bytes_consumed); | ||
478 | break; | ||
479 | |||
480 | case ACPI_RSTYPE_EXT_IRQ: | ||
481 | /* | ||
482 | * Extended IRQ Resource | ||
483 | */ | ||
484 | status = acpi_rs_extended_irq_stream (linked_list, &buffer, | ||
485 | &bytes_consumed); | ||
486 | break; | ||
487 | |||
488 | default: | ||
489 | /* | ||
490 | * If we get here, everything is out of sync, | ||
491 | * so exit with an error | ||
492 | */ | ||
493 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid descriptor type (%X) in resource list\n", | ||
494 | linked_list->id)); | ||
495 | status = AE_BAD_DATA; | ||
496 | break; | ||
497 | |||
498 | } /* switch (linked_list->Id) */ | ||
499 | |||
500 | if (ACPI_FAILURE (status)) { | ||
501 | return_ACPI_STATUS (status); | ||
502 | } | ||
503 | |||
504 | /* | ||
505 | * Set the Buffer to point to the open byte | ||
506 | */ | ||
507 | buffer += bytes_consumed; | ||
508 | |||
509 | /* | ||
510 | * Point to the next object | ||
511 | */ | ||
512 | linked_list = ACPI_PTR_ADD (struct acpi_resource, | ||
513 | linked_list, linked_list->length); | ||
514 | } | ||
515 | |||
516 | return_ACPI_STATUS (AE_OK); | ||
517 | } | ||
518 | |||
diff --git a/drivers/acpi/resources/rsmemory.c b/drivers/acpi/resources/rsmemory.c new file mode 100644 index 000000000000..7c935aecf075 --- /dev/null +++ b/drivers/acpi/resources/rsmemory.c | |||
@@ -0,0 +1,566 @@ | |||
1 | /******************************************************************************* | ||
2 | * | ||
3 | * Module Name: rsmem24 - Memory resource descriptors | ||
4 | * | ||
5 | ******************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2005, R. Byron Moore | ||
9 | * All rights reserved. | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions, and the following disclaimer, | ||
16 | * without modification. | ||
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
18 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
19 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
20 | * including a substantially similar Disclaimer requirement for further | ||
21 | * binary redistribution. | ||
22 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
23 | * of any contributors may be used to endorse or promote products derived | ||
24 | * from this software without specific prior written permission. | ||
25 | * | ||
26 | * Alternatively, this software may be distributed under the terms of the | ||
27 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
28 | * Software Foundation. | ||
29 | * | ||
30 | * NO WARRANTY | ||
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
41 | * POSSIBILITY OF SUCH DAMAGES. | ||
42 | */ | ||
43 | |||
44 | |||
45 | #include <acpi/acpi.h> | ||
46 | #include <acpi/acresrc.h> | ||
47 | |||
48 | #define _COMPONENT ACPI_RESOURCES | ||
49 | ACPI_MODULE_NAME ("rsmemory") | ||
50 | |||
51 | |||
52 | /******************************************************************************* | ||
53 | * | ||
54 | * FUNCTION: acpi_rs_memory24_resource | ||
55 | * | ||
56 | * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte | ||
57 | * stream | ||
58 | * bytes_consumed - Pointer to where the number of bytes | ||
59 | * consumed the byte_stream_buffer is | ||
60 | * returned | ||
61 | * output_buffer - Pointer to the return data buffer | ||
62 | * structure_size - Pointer to where the number of bytes | ||
63 | * in the return data struct is returned | ||
64 | * | ||
65 | * RETURN: Status | ||
66 | * | ||
67 | * DESCRIPTION: Take the resource byte stream and fill out the appropriate | ||
68 | * structure pointed to by the output_buffer. Return the | ||
69 | * number of bytes consumed from the byte stream. | ||
70 | * | ||
71 | ******************************************************************************/ | ||
72 | |||
73 | acpi_status | ||
74 | acpi_rs_memory24_resource ( | ||
75 | u8 *byte_stream_buffer, | ||
76 | acpi_size *bytes_consumed, | ||
77 | u8 **output_buffer, | ||
78 | acpi_size *structure_size) | ||
79 | { | ||
80 | u8 *buffer = byte_stream_buffer; | ||
81 | struct acpi_resource *output_struct = (void *) *output_buffer; | ||
82 | u16 temp16 = 0; | ||
83 | u8 temp8 = 0; | ||
84 | acpi_size struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_mem24); | ||
85 | |||
86 | |||
87 | ACPI_FUNCTION_TRACE ("rs_memory24_resource"); | ||
88 | |||
89 | |||
90 | /* | ||
91 | * Point past the Descriptor to get the number of bytes consumed | ||
92 | */ | ||
93 | buffer += 1; | ||
94 | |||
95 | ACPI_MOVE_16_TO_16 (&temp16, buffer); | ||
96 | buffer += 2; | ||
97 | *bytes_consumed = (acpi_size) temp16 + 3; | ||
98 | output_struct->id = ACPI_RSTYPE_MEM24; | ||
99 | |||
100 | /* | ||
101 | * Check Byte 3 the Read/Write bit | ||
102 | */ | ||
103 | temp8 = *buffer; | ||
104 | buffer += 1; | ||
105 | output_struct->data.memory24.read_write_attribute = temp8 & 0x01; | ||
106 | |||
107 | /* | ||
108 | * Get min_base_address (Bytes 4-5) | ||
109 | */ | ||
110 | ACPI_MOVE_16_TO_16 (&temp16, buffer); | ||
111 | buffer += 2; | ||
112 | output_struct->data.memory24.min_base_address = temp16; | ||
113 | |||
114 | /* | ||
115 | * Get max_base_address (Bytes 6-7) | ||
116 | */ | ||
117 | ACPI_MOVE_16_TO_16 (&temp16, buffer); | ||
118 | buffer += 2; | ||
119 | output_struct->data.memory24.max_base_address = temp16; | ||
120 | |||
121 | /* | ||
122 | * Get Alignment (Bytes 8-9) | ||
123 | */ | ||
124 | ACPI_MOVE_16_TO_16 (&temp16, buffer); | ||
125 | buffer += 2; | ||
126 | output_struct->data.memory24.alignment = temp16; | ||
127 | |||
128 | /* | ||
129 | * Get range_length (Bytes 10-11) | ||
130 | */ | ||
131 | ACPI_MOVE_16_TO_16 (&temp16, buffer); | ||
132 | output_struct->data.memory24.range_length = temp16; | ||
133 | |||
134 | /* | ||
135 | * Set the Length parameter | ||
136 | */ | ||
137 | output_struct->length = (u32) struct_size; | ||
138 | |||
139 | /* | ||
140 | * Return the final size of the structure | ||
141 | */ | ||
142 | *structure_size = struct_size; | ||
143 | return_ACPI_STATUS (AE_OK); | ||
144 | } | ||
145 | |||
146 | |||
147 | /******************************************************************************* | ||
148 | * | ||
149 | * FUNCTION: acpi_rs_memory24_stream | ||
150 | * | ||
151 | * PARAMETERS: linked_list - Pointer to the resource linked list | ||
152 | * output_buffer - Pointer to the user's return buffer | ||
153 | * bytes_consumed - Pointer to where the number of bytes | ||
154 | * used in the output_buffer is returned | ||
155 | * | ||
156 | * RETURN: Status | ||
157 | * | ||
158 | * DESCRIPTION: Take the linked list resource structure and fills in the | ||
159 | * the appropriate bytes in a byte stream | ||
160 | * | ||
161 | ******************************************************************************/ | ||
162 | |||
163 | acpi_status | ||
164 | acpi_rs_memory24_stream ( | ||
165 | struct acpi_resource *linked_list, | ||
166 | u8 **output_buffer, | ||
167 | acpi_size *bytes_consumed) | ||
168 | { | ||
169 | u8 *buffer = *output_buffer; | ||
170 | u16 temp16 = 0; | ||
171 | u8 temp8 = 0; | ||
172 | |||
173 | |||
174 | ACPI_FUNCTION_TRACE ("rs_memory24_stream"); | ||
175 | |||
176 | |||
177 | /* | ||
178 | * The descriptor field is static | ||
179 | */ | ||
180 | *buffer = 0x81; | ||
181 | buffer += 1; | ||
182 | |||
183 | /* | ||
184 | * The length field is static | ||
185 | */ | ||
186 | temp16 = 0x09; | ||
187 | ACPI_MOVE_16_TO_16 (buffer, &temp16); | ||
188 | buffer += 2; | ||
189 | |||
190 | /* | ||
191 | * Set the Information Byte | ||
192 | */ | ||
193 | temp8 = (u8) (linked_list->data.memory24.read_write_attribute & 0x01); | ||
194 | *buffer = temp8; | ||
195 | buffer += 1; | ||
196 | |||
197 | /* | ||
198 | * Set the Range minimum base address | ||
199 | */ | ||
200 | ACPI_MOVE_32_TO_16 (buffer, &linked_list->data.memory24.min_base_address); | ||
201 | buffer += 2; | ||
202 | |||
203 | /* | ||
204 | * Set the Range maximum base address | ||
205 | */ | ||
206 | ACPI_MOVE_32_TO_16 (buffer, &linked_list->data.memory24.max_base_address); | ||
207 | buffer += 2; | ||
208 | |||
209 | /* | ||
210 | * Set the base alignment | ||
211 | */ | ||
212 | ACPI_MOVE_32_TO_16 (buffer, &linked_list->data.memory24.alignment); | ||
213 | buffer += 2; | ||
214 | |||
215 | /* | ||
216 | * Set the range length | ||
217 | */ | ||
218 | ACPI_MOVE_32_TO_16 (buffer, &linked_list->data.memory24.range_length); | ||
219 | buffer += 2; | ||
220 | |||
221 | /* | ||
222 | * Return the number of bytes consumed in this operation | ||
223 | */ | ||
224 | *bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer); | ||
225 | return_ACPI_STATUS (AE_OK); | ||
226 | } | ||
227 | |||
228 | |||
229 | /******************************************************************************* | ||
230 | * | ||
231 | * FUNCTION: acpi_rs_memory32_range_resource | ||
232 | * | ||
233 | * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte | ||
234 | * stream | ||
235 | * bytes_consumed - Pointer to where the number of bytes | ||
236 | * consumed the byte_stream_buffer is | ||
237 | * returned | ||
238 | * output_buffer - Pointer to the return data buffer | ||
239 | * structure_size - Pointer to where the number of bytes | ||
240 | * in the return data struct is returned | ||
241 | * | ||
242 | * RETURN: Status | ||
243 | * | ||
244 | * DESCRIPTION: Take the resource byte stream and fill out the appropriate | ||
245 | * structure pointed to by the output_buffer. Return the | ||
246 | * number of bytes consumed from the byte stream. | ||
247 | * | ||
248 | ******************************************************************************/ | ||
249 | |||
250 | acpi_status | ||
251 | acpi_rs_memory32_range_resource ( | ||
252 | u8 *byte_stream_buffer, | ||
253 | acpi_size *bytes_consumed, | ||
254 | u8 **output_buffer, | ||
255 | acpi_size *structure_size) | ||
256 | { | ||
257 | u8 *buffer = byte_stream_buffer; | ||
258 | struct acpi_resource *output_struct = (void *) *output_buffer; | ||
259 | u16 temp16 = 0; | ||
260 | u8 temp8 = 0; | ||
261 | acpi_size struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_mem32); | ||
262 | |||
263 | |||
264 | ACPI_FUNCTION_TRACE ("rs_memory32_range_resource"); | ||
265 | |||
266 | |||
267 | /* | ||
268 | * Point past the Descriptor to get the number of bytes consumed | ||
269 | */ | ||
270 | buffer += 1; | ||
271 | |||
272 | ACPI_MOVE_16_TO_16 (&temp16, buffer); | ||
273 | buffer += 2; | ||
274 | *bytes_consumed = (acpi_size) temp16 + 3; | ||
275 | |||
276 | output_struct->id = ACPI_RSTYPE_MEM32; | ||
277 | |||
278 | /* | ||
279 | * Point to the place in the output buffer where the data portion will | ||
280 | * begin. | ||
281 | * 1. Set the RESOURCE_DATA * Data to point to its own address, then | ||
282 | * 2. Set the pointer to the next address. | ||
283 | * | ||
284 | * NOTE: output_struct->Data is cast to u8, otherwise, this addition adds | ||
285 | * 4 * sizeof(RESOURCE_DATA) instead of 4 * sizeof(u8) | ||
286 | */ | ||
287 | |||
288 | /* | ||
289 | * Check Byte 3 the Read/Write bit | ||
290 | */ | ||
291 | temp8 = *buffer; | ||
292 | buffer += 1; | ||
293 | |||
294 | output_struct->data.memory32.read_write_attribute = temp8 & 0x01; | ||
295 | |||
296 | /* | ||
297 | * Get min_base_address (Bytes 4-7) | ||
298 | */ | ||
299 | ACPI_MOVE_32_TO_32 (&output_struct->data.memory32.min_base_address, buffer); | ||
300 | buffer += 4; | ||
301 | |||
302 | /* | ||
303 | * Get max_base_address (Bytes 8-11) | ||
304 | */ | ||
305 | ACPI_MOVE_32_TO_32 (&output_struct->data.memory32.max_base_address, buffer); | ||
306 | buffer += 4; | ||
307 | |||
308 | /* | ||
309 | * Get Alignment (Bytes 12-15) | ||
310 | */ | ||
311 | ACPI_MOVE_32_TO_32 (&output_struct->data.memory32.alignment, buffer); | ||
312 | buffer += 4; | ||
313 | |||
314 | /* | ||
315 | * Get range_length (Bytes 16-19) | ||
316 | */ | ||
317 | ACPI_MOVE_32_TO_32 (&output_struct->data.memory32.range_length, buffer); | ||
318 | |||
319 | /* | ||
320 | * Set the Length parameter | ||
321 | */ | ||
322 | output_struct->length = (u32) struct_size; | ||
323 | |||
324 | /* | ||
325 | * Return the final size of the structure | ||
326 | */ | ||
327 | *structure_size = struct_size; | ||
328 | return_ACPI_STATUS (AE_OK); | ||
329 | } | ||
330 | |||
331 | |||
332 | /******************************************************************************* | ||
333 | * | ||
334 | * FUNCTION: acpi_rs_fixed_memory32_resource | ||
335 | * | ||
336 | * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte | ||
337 | * stream | ||
338 | * bytes_consumed - Pointer to where the number of bytes | ||
339 | * consumed the byte_stream_buffer is | ||
340 | * returned | ||
341 | * output_buffer - Pointer to the return data buffer | ||
342 | * structure_size - Pointer to where the number of bytes | ||
343 | * in the return data struct is returned | ||
344 | * | ||
345 | * RETURN: Status | ||
346 | * | ||
347 | * DESCRIPTION: Take the resource byte stream and fill out the appropriate | ||
348 | * structure pointed to by the output_buffer. Return the | ||
349 | * number of bytes consumed from the byte stream. | ||
350 | * | ||
351 | ******************************************************************************/ | ||
352 | |||
353 | acpi_status | ||
354 | acpi_rs_fixed_memory32_resource ( | ||
355 | u8 *byte_stream_buffer, | ||
356 | acpi_size *bytes_consumed, | ||
357 | u8 **output_buffer, | ||
358 | acpi_size *structure_size) | ||
359 | { | ||
360 | u8 *buffer = byte_stream_buffer; | ||
361 | struct acpi_resource *output_struct = (void *) *output_buffer; | ||
362 | u16 temp16 = 0; | ||
363 | u8 temp8 = 0; | ||
364 | acpi_size struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_fixed_mem32); | ||
365 | |||
366 | |||
367 | ACPI_FUNCTION_TRACE ("rs_fixed_memory32_resource"); | ||
368 | |||
369 | |||
370 | /* | ||
371 | * Point past the Descriptor to get the number of bytes consumed | ||
372 | */ | ||
373 | buffer += 1; | ||
374 | ACPI_MOVE_16_TO_16 (&temp16, buffer); | ||
375 | |||
376 | buffer += 2; | ||
377 | *bytes_consumed = (acpi_size) temp16 + 3; | ||
378 | |||
379 | output_struct->id = ACPI_RSTYPE_FIXED_MEM32; | ||
380 | |||
381 | /* | ||
382 | * Check Byte 3 the Read/Write bit | ||
383 | */ | ||
384 | temp8 = *buffer; | ||
385 | buffer += 1; | ||
386 | output_struct->data.fixed_memory32.read_write_attribute = temp8 & 0x01; | ||
387 | |||
388 | /* | ||
389 | * Get range_base_address (Bytes 4-7) | ||
390 | */ | ||
391 | ACPI_MOVE_32_TO_32 (&output_struct->data.fixed_memory32.range_base_address, buffer); | ||
392 | buffer += 4; | ||
393 | |||
394 | /* | ||
395 | * Get range_length (Bytes 8-11) | ||
396 | */ | ||
397 | ACPI_MOVE_32_TO_32 (&output_struct->data.fixed_memory32.range_length, buffer); | ||
398 | |||
399 | /* | ||
400 | * Set the Length parameter | ||
401 | */ | ||
402 | output_struct->length = (u32) struct_size; | ||
403 | |||
404 | /* | ||
405 | * Return the final size of the structure | ||
406 | */ | ||
407 | *structure_size = struct_size; | ||
408 | return_ACPI_STATUS (AE_OK); | ||
409 | } | ||
410 | |||
411 | |||
412 | /******************************************************************************* | ||
413 | * | ||
414 | * FUNCTION: acpi_rs_memory32_range_stream | ||
415 | * | ||
416 | * PARAMETERS: linked_list - Pointer to the resource linked list | ||
417 | * output_buffer - Pointer to the user's return buffer | ||
418 | * bytes_consumed - Pointer to where the number of bytes | ||
419 | * used in the output_buffer is returned | ||
420 | * | ||
421 | * RETURN: Status | ||
422 | * | ||
423 | * DESCRIPTION: Take the linked list resource structure and fills in the | ||
424 | * the appropriate bytes in a byte stream | ||
425 | * | ||
426 | ******************************************************************************/ | ||
427 | |||
428 | acpi_status | ||
429 | acpi_rs_memory32_range_stream ( | ||
430 | struct acpi_resource *linked_list, | ||
431 | u8 **output_buffer, | ||
432 | acpi_size *bytes_consumed) | ||
433 | { | ||
434 | u8 *buffer = *output_buffer; | ||
435 | u16 temp16 = 0; | ||
436 | u8 temp8 = 0; | ||
437 | |||
438 | |||
439 | ACPI_FUNCTION_TRACE ("rs_memory32_range_stream"); | ||
440 | |||
441 | |||
442 | /* | ||
443 | * The descriptor field is static | ||
444 | */ | ||
445 | *buffer = 0x85; | ||
446 | buffer += 1; | ||
447 | |||
448 | /* | ||
449 | * The length field is static | ||
450 | */ | ||
451 | temp16 = 0x11; | ||
452 | |||
453 | ACPI_MOVE_16_TO_16 (buffer, &temp16); | ||
454 | buffer += 2; | ||
455 | |||
456 | /* | ||
457 | * Set the Information Byte | ||
458 | */ | ||
459 | temp8 = (u8) (linked_list->data.memory32.read_write_attribute & 0x01); | ||
460 | *buffer = temp8; | ||
461 | buffer += 1; | ||
462 | |||
463 | /* | ||
464 | * Set the Range minimum base address | ||
465 | */ | ||
466 | ACPI_MOVE_32_TO_32 (buffer, &linked_list->data.memory32.min_base_address); | ||
467 | buffer += 4; | ||
468 | |||
469 | /* | ||
470 | * Set the Range maximum base address | ||
471 | */ | ||
472 | ACPI_MOVE_32_TO_32 (buffer, &linked_list->data.memory32.max_base_address); | ||
473 | buffer += 4; | ||
474 | |||
475 | /* | ||
476 | * Set the base alignment | ||
477 | */ | ||
478 | ACPI_MOVE_32_TO_32 (buffer, &linked_list->data.memory32.alignment); | ||
479 | buffer += 4; | ||
480 | |||
481 | /* | ||
482 | * Set the range length | ||
483 | */ | ||
484 | ACPI_MOVE_32_TO_32 (buffer, &linked_list->data.memory32.range_length); | ||
485 | buffer += 4; | ||
486 | |||
487 | /* | ||
488 | * Return the number of bytes consumed in this operation | ||
489 | */ | ||
490 | *bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer); | ||
491 | return_ACPI_STATUS (AE_OK); | ||
492 | } | ||
493 | |||
494 | |||
495 | /******************************************************************************* | ||
496 | * | ||
497 | * FUNCTION: acpi_rs_fixed_memory32_stream | ||
498 | * | ||
499 | * PARAMETERS: linked_list - Pointer to the resource linked list | ||
500 | * output_buffer - Pointer to the user's return buffer | ||
501 | * bytes_consumed - Pointer to where the number of bytes | ||
502 | * used in the output_buffer is returned | ||
503 | * | ||
504 | * RETURN: Status | ||
505 | * | ||
506 | * DESCRIPTION: Take the linked list resource structure and fills in the | ||
507 | * the appropriate bytes in a byte stream | ||
508 | * | ||
509 | ******************************************************************************/ | ||
510 | |||
511 | acpi_status | ||
512 | acpi_rs_fixed_memory32_stream ( | ||
513 | struct acpi_resource *linked_list, | ||
514 | u8 **output_buffer, | ||
515 | acpi_size *bytes_consumed) | ||
516 | { | ||
517 | u8 *buffer = *output_buffer; | ||
518 | u16 temp16 = 0; | ||
519 | u8 temp8 = 0; | ||
520 | |||
521 | |||
522 | ACPI_FUNCTION_TRACE ("rs_fixed_memory32_stream"); | ||
523 | |||
524 | |||
525 | /* | ||
526 | * The descriptor field is static | ||
527 | */ | ||
528 | *buffer = 0x86; | ||
529 | buffer += 1; | ||
530 | |||
531 | /* | ||
532 | * The length field is static | ||
533 | */ | ||
534 | temp16 = 0x09; | ||
535 | |||
536 | ACPI_MOVE_16_TO_16 (buffer, &temp16); | ||
537 | buffer += 2; | ||
538 | |||
539 | /* | ||
540 | * Set the Information Byte | ||
541 | */ | ||
542 | temp8 = (u8) (linked_list->data.fixed_memory32.read_write_attribute & 0x01); | ||
543 | *buffer = temp8; | ||
544 | buffer += 1; | ||
545 | |||
546 | /* | ||
547 | * Set the Range base address | ||
548 | */ | ||
549 | ACPI_MOVE_32_TO_32 (buffer, | ||
550 | &linked_list->data.fixed_memory32.range_base_address); | ||
551 | buffer += 4; | ||
552 | |||
553 | /* | ||
554 | * Set the range length | ||
555 | */ | ||
556 | ACPI_MOVE_32_TO_32 (buffer, | ||
557 | &linked_list->data.fixed_memory32.range_length); | ||
558 | buffer += 4; | ||
559 | |||
560 | /* | ||
561 | * Return the number of bytes consumed in this operation | ||
562 | */ | ||
563 | *bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer); | ||
564 | return_ACPI_STATUS (AE_OK); | ||
565 | } | ||
566 | |||
diff --git a/drivers/acpi/resources/rsmisc.c b/drivers/acpi/resources/rsmisc.c new file mode 100644 index 000000000000..d16be44b5df7 --- /dev/null +++ b/drivers/acpi/resources/rsmisc.c | |||
@@ -0,0 +1,597 @@ | |||
1 | /******************************************************************************* | ||
2 | * | ||
3 | * Module Name: rsmisc - Miscellaneous resource descriptors | ||
4 | * | ||
5 | ******************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2005, R. Byron Moore | ||
9 | * All rights reserved. | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions, and the following disclaimer, | ||
16 | * without modification. | ||
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
18 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
19 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
20 | * including a substantially similar Disclaimer requirement for further | ||
21 | * binary redistribution. | ||
22 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
23 | * of any contributors may be used to endorse or promote products derived | ||
24 | * from this software without specific prior written permission. | ||
25 | * | ||
26 | * Alternatively, this software may be distributed under the terms of the | ||
27 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
28 | * Software Foundation. | ||
29 | * | ||
30 | * NO WARRANTY | ||
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
41 | * POSSIBILITY OF SUCH DAMAGES. | ||
42 | */ | ||
43 | |||
44 | |||
45 | #include <acpi/acpi.h> | ||
46 | #include <acpi/acresrc.h> | ||
47 | |||
48 | #define _COMPONENT ACPI_RESOURCES | ||
49 | ACPI_MODULE_NAME ("rsmisc") | ||
50 | |||
51 | |||
52 | /******************************************************************************* | ||
53 | * | ||
54 | * FUNCTION: acpi_rs_end_tag_resource | ||
55 | * | ||
56 | * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte | ||
57 | * stream | ||
58 | * bytes_consumed - Pointer to where the number of bytes | ||
59 | * consumed the byte_stream_buffer is | ||
60 | * returned | ||
61 | * output_buffer - Pointer to the return data buffer | ||
62 | * structure_size - Pointer to where the number of bytes | ||
63 | * in the return data struct is returned | ||
64 | * | ||
65 | * RETURN: Status | ||
66 | * | ||
67 | * DESCRIPTION: Take the resource byte stream and fill out the appropriate | ||
68 | * structure pointed to by the output_buffer. Return the | ||
69 | * number of bytes consumed from the byte stream. | ||
70 | * | ||
71 | ******************************************************************************/ | ||
72 | |||
73 | acpi_status | ||
74 | acpi_rs_end_tag_resource ( | ||
75 | u8 *byte_stream_buffer, | ||
76 | acpi_size *bytes_consumed, | ||
77 | u8 **output_buffer, | ||
78 | acpi_size *structure_size) | ||
79 | { | ||
80 | struct acpi_resource *output_struct = (void *) *output_buffer; | ||
81 | acpi_size struct_size = ACPI_RESOURCE_LENGTH; | ||
82 | |||
83 | |||
84 | ACPI_FUNCTION_TRACE ("rs_end_tag_resource"); | ||
85 | |||
86 | |||
87 | /* | ||
88 | * The number of bytes consumed is static | ||
89 | */ | ||
90 | *bytes_consumed = 2; | ||
91 | |||
92 | /* | ||
93 | * Fill out the structure | ||
94 | */ | ||
95 | output_struct->id = ACPI_RSTYPE_END_TAG; | ||
96 | |||
97 | /* | ||
98 | * Set the Length parameter | ||
99 | */ | ||
100 | output_struct->length = 0; | ||
101 | |||
102 | /* | ||
103 | * Return the final size of the structure | ||
104 | */ | ||
105 | *structure_size = struct_size; | ||
106 | return_ACPI_STATUS (AE_OK); | ||
107 | } | ||
108 | |||
109 | |||
110 | /******************************************************************************* | ||
111 | * | ||
112 | * FUNCTION: acpi_rs_end_tag_stream | ||
113 | * | ||
114 | * PARAMETERS: linked_list - Pointer to the resource linked list | ||
115 | * output_buffer - Pointer to the user's return buffer | ||
116 | * bytes_consumed - Pointer to where the number of bytes | ||
117 | * used in the output_buffer is returned | ||
118 | * | ||
119 | * RETURN: Status | ||
120 | * | ||
121 | * DESCRIPTION: Take the linked list resource structure and fills in the | ||
122 | * the appropriate bytes in a byte stream | ||
123 | * | ||
124 | ******************************************************************************/ | ||
125 | |||
126 | acpi_status | ||
127 | acpi_rs_end_tag_stream ( | ||
128 | struct acpi_resource *linked_list, | ||
129 | u8 **output_buffer, | ||
130 | acpi_size *bytes_consumed) | ||
131 | { | ||
132 | u8 *buffer = *output_buffer; | ||
133 | u8 temp8 = 0; | ||
134 | |||
135 | |||
136 | ACPI_FUNCTION_TRACE ("rs_end_tag_stream"); | ||
137 | |||
138 | |||
139 | /* | ||
140 | * The descriptor field is static | ||
141 | */ | ||
142 | *buffer = 0x79; | ||
143 | buffer += 1; | ||
144 | |||
145 | /* | ||
146 | * Set the Checksum - zero means that the resource data is treated as if | ||
147 | * the checksum operation succeeded (ACPI Spec 1.0b Section 6.4.2.8) | ||
148 | */ | ||
149 | temp8 = 0; | ||
150 | |||
151 | *buffer = temp8; | ||
152 | buffer += 1; | ||
153 | |||
154 | /* | ||
155 | * Return the number of bytes consumed in this operation | ||
156 | */ | ||
157 | *bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer); | ||
158 | return_ACPI_STATUS (AE_OK); | ||
159 | } | ||
160 | |||
161 | |||
162 | /******************************************************************************* | ||
163 | * | ||
164 | * FUNCTION: acpi_rs_vendor_resource | ||
165 | * | ||
166 | * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte | ||
167 | * stream | ||
168 | * bytes_consumed - Pointer to where the number of bytes | ||
169 | * consumed the byte_stream_buffer is | ||
170 | * returned | ||
171 | * output_buffer - Pointer to the return data buffer | ||
172 | * structure_size - Pointer to where the number of bytes | ||
173 | * in the return data struct is returned | ||
174 | * | ||
175 | * RETURN: Status | ||
176 | * | ||
177 | * DESCRIPTION: Take the resource byte stream and fill out the appropriate | ||
178 | * structure pointed to by the output_buffer. Return the | ||
179 | * number of bytes consumed from the byte stream. | ||
180 | * | ||
181 | ******************************************************************************/ | ||
182 | |||
183 | acpi_status | ||
184 | acpi_rs_vendor_resource ( | ||
185 | u8 *byte_stream_buffer, | ||
186 | acpi_size *bytes_consumed, | ||
187 | u8 **output_buffer, | ||
188 | acpi_size *structure_size) | ||
189 | { | ||
190 | u8 *buffer = byte_stream_buffer; | ||
191 | struct acpi_resource *output_struct = (void *) *output_buffer; | ||
192 | u16 temp16 = 0; | ||
193 | u8 temp8 = 0; | ||
194 | u8 index; | ||
195 | acpi_size struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_vendor); | ||
196 | |||
197 | |||
198 | ACPI_FUNCTION_TRACE ("rs_vendor_resource"); | ||
199 | |||
200 | |||
201 | /* | ||
202 | * Dereference the Descriptor to find if this is a large or small item. | ||
203 | */ | ||
204 | temp8 = *buffer; | ||
205 | |||
206 | if (temp8 & 0x80) { | ||
207 | /* | ||
208 | * Large Item, point to the length field | ||
209 | */ | ||
210 | buffer += 1; | ||
211 | |||
212 | /* Dereference */ | ||
213 | |||
214 | ACPI_MOVE_16_TO_16 (&temp16, buffer); | ||
215 | |||
216 | /* Calculate bytes consumed */ | ||
217 | |||
218 | *bytes_consumed = (acpi_size) temp16 + 3; | ||
219 | |||
220 | /* Point to the first vendor byte */ | ||
221 | |||
222 | buffer += 2; | ||
223 | } | ||
224 | else { | ||
225 | /* | ||
226 | * Small Item, dereference the size | ||
227 | */ | ||
228 | temp16 = (u8)(*buffer & 0x07); | ||
229 | |||
230 | /* Calculate bytes consumed */ | ||
231 | |||
232 | *bytes_consumed = (acpi_size) temp16 + 1; | ||
233 | |||
234 | /* Point to the first vendor byte */ | ||
235 | |||
236 | buffer += 1; | ||
237 | } | ||
238 | |||
239 | output_struct->id = ACPI_RSTYPE_VENDOR; | ||
240 | output_struct->data.vendor_specific.length = temp16; | ||
241 | |||
242 | for (index = 0; index < temp16; index++) { | ||
243 | output_struct->data.vendor_specific.reserved[index] = *buffer; | ||
244 | buffer += 1; | ||
245 | } | ||
246 | |||
247 | /* | ||
248 | * In order for the struct_size to fall on a 32-bit boundary, | ||
249 | * calculate the length of the vendor string and expand the | ||
250 | * struct_size to the next 32-bit boundary. | ||
251 | */ | ||
252 | struct_size += ACPI_ROUND_UP_to_32_bITS (temp16); | ||
253 | |||
254 | /* | ||
255 | * Set the Length parameter | ||
256 | */ | ||
257 | output_struct->length = (u32) struct_size; | ||
258 | |||
259 | /* | ||
260 | * Return the final size of the structure | ||
261 | */ | ||
262 | *structure_size = struct_size; | ||
263 | return_ACPI_STATUS (AE_OK); | ||
264 | } | ||
265 | |||
266 | |||
267 | /******************************************************************************* | ||
268 | * | ||
269 | * FUNCTION: acpi_rs_vendor_stream | ||
270 | * | ||
271 | * PARAMETERS: linked_list - Pointer to the resource linked list | ||
272 | * output_buffer - Pointer to the user's return buffer | ||
273 | * bytes_consumed - Pointer to where the number of bytes | ||
274 | * used in the output_buffer is returned | ||
275 | * | ||
276 | * RETURN: Status | ||
277 | * | ||
278 | * DESCRIPTION: Take the linked list resource structure and fills in the | ||
279 | * the appropriate bytes in a byte stream | ||
280 | * | ||
281 | ******************************************************************************/ | ||
282 | |||
283 | acpi_status | ||
284 | acpi_rs_vendor_stream ( | ||
285 | struct acpi_resource *linked_list, | ||
286 | u8 **output_buffer, | ||
287 | acpi_size *bytes_consumed) | ||
288 | { | ||
289 | u8 *buffer = *output_buffer; | ||
290 | u16 temp16 = 0; | ||
291 | u8 temp8 = 0; | ||
292 | u8 index; | ||
293 | |||
294 | |||
295 | ACPI_FUNCTION_TRACE ("rs_vendor_stream"); | ||
296 | |||
297 | |||
298 | /* | ||
299 | * Dereference the length to find if this is a large or small item. | ||
300 | */ | ||
301 | if(linked_list->data.vendor_specific.length > 7) { | ||
302 | /* | ||
303 | * Large Item, Set the descriptor field and length bytes | ||
304 | */ | ||
305 | *buffer = 0x84; | ||
306 | buffer += 1; | ||
307 | |||
308 | temp16 = (u16) linked_list->data.vendor_specific.length; | ||
309 | |||
310 | ACPI_MOVE_16_TO_16 (buffer, &temp16); | ||
311 | buffer += 2; | ||
312 | } | ||
313 | else { | ||
314 | /* | ||
315 | * Small Item, Set the descriptor field | ||
316 | */ | ||
317 | temp8 = 0x70; | ||
318 | temp8 |= (u8) linked_list->data.vendor_specific.length; | ||
319 | |||
320 | *buffer = temp8; | ||
321 | buffer += 1; | ||
322 | } | ||
323 | |||
324 | /* | ||
325 | * Loop through all of the Vendor Specific fields | ||
326 | */ | ||
327 | for (index = 0; index < linked_list->data.vendor_specific.length; index++) { | ||
328 | temp8 = linked_list->data.vendor_specific.reserved[index]; | ||
329 | |||
330 | *buffer = temp8; | ||
331 | buffer += 1; | ||
332 | } | ||
333 | |||
334 | /* | ||
335 | * Return the number of bytes consumed in this operation | ||
336 | */ | ||
337 | *bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer); | ||
338 | return_ACPI_STATUS (AE_OK); | ||
339 | } | ||
340 | |||
341 | |||
342 | /******************************************************************************* | ||
343 | * | ||
344 | * FUNCTION: acpi_rs_start_depend_fns_resource | ||
345 | * | ||
346 | * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte | ||
347 | * stream | ||
348 | * bytes_consumed - Pointer to where the number of bytes | ||
349 | * consumed the byte_stream_buffer is | ||
350 | * returned | ||
351 | * output_buffer - Pointer to the return data buffer | ||
352 | * structure_size - Pointer to where the number of bytes | ||
353 | * in the return data struct is returned | ||
354 | * | ||
355 | * RETURN: Status | ||
356 | * | ||
357 | * DESCRIPTION: Take the resource byte stream and fill out the appropriate | ||
358 | * structure pointed to by the output_buffer. Return the | ||
359 | * number of bytes consumed from the byte stream. | ||
360 | * | ||
361 | ******************************************************************************/ | ||
362 | |||
363 | acpi_status | ||
364 | acpi_rs_start_depend_fns_resource ( | ||
365 | u8 *byte_stream_buffer, | ||
366 | acpi_size *bytes_consumed, | ||
367 | u8 **output_buffer, | ||
368 | acpi_size *structure_size) | ||
369 | { | ||
370 | u8 *buffer = byte_stream_buffer; | ||
371 | struct acpi_resource *output_struct = (void *) *output_buffer; | ||
372 | u8 temp8 = 0; | ||
373 | acpi_size struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_start_dpf); | ||
374 | |||
375 | |||
376 | ACPI_FUNCTION_TRACE ("rs_start_depend_fns_resource"); | ||
377 | |||
378 | |||
379 | /* | ||
380 | * The number of bytes consumed are contained in the descriptor (Bits:0-1) | ||
381 | */ | ||
382 | temp8 = *buffer; | ||
383 | |||
384 | *bytes_consumed = (temp8 & 0x01) + 1; | ||
385 | |||
386 | output_struct->id = ACPI_RSTYPE_START_DPF; | ||
387 | |||
388 | /* | ||
389 | * Point to Byte 1 if it is used | ||
390 | */ | ||
391 | if (2 == *bytes_consumed) { | ||
392 | buffer += 1; | ||
393 | temp8 = *buffer; | ||
394 | |||
395 | /* | ||
396 | * Check Compatibility priority | ||
397 | */ | ||
398 | output_struct->data.start_dpf.compatibility_priority = temp8 & 0x03; | ||
399 | |||
400 | if (3 == output_struct->data.start_dpf.compatibility_priority) { | ||
401 | return_ACPI_STATUS (AE_AML_BAD_RESOURCE_VALUE); | ||
402 | } | ||
403 | |||
404 | /* | ||
405 | * Check Performance/Robustness preference | ||
406 | */ | ||
407 | output_struct->data.start_dpf.performance_robustness = (temp8 >> 2) & 0x03; | ||
408 | |||
409 | if (3 == output_struct->data.start_dpf.performance_robustness) { | ||
410 | return_ACPI_STATUS (AE_AML_BAD_RESOURCE_VALUE); | ||
411 | } | ||
412 | } | ||
413 | else { | ||
414 | output_struct->data.start_dpf.compatibility_priority = | ||
415 | ACPI_ACCEPTABLE_CONFIGURATION; | ||
416 | |||
417 | output_struct->data.start_dpf.performance_robustness = | ||
418 | ACPI_ACCEPTABLE_CONFIGURATION; | ||
419 | } | ||
420 | |||
421 | /* | ||
422 | * Set the Length parameter | ||
423 | */ | ||
424 | output_struct->length = (u32) struct_size; | ||
425 | |||
426 | /* | ||
427 | * Return the final size of the structure | ||
428 | */ | ||
429 | *structure_size = struct_size; | ||
430 | return_ACPI_STATUS (AE_OK); | ||
431 | } | ||
432 | |||
433 | |||
434 | /******************************************************************************* | ||
435 | * | ||
436 | * FUNCTION: acpi_rs_end_depend_fns_resource | ||
437 | * | ||
438 | * PARAMETERS: byte_stream_buffer - Pointer to the resource input byte | ||
439 | * stream | ||
440 | * bytes_consumed - Pointer to where the number of bytes | ||
441 | * consumed the byte_stream_buffer is | ||
442 | * returned | ||
443 | * output_buffer - Pointer to the return data buffer | ||
444 | * structure_size - Pointer to where the number of bytes | ||
445 | * in the return data struct is returned | ||
446 | * | ||
447 | * RETURN: Status | ||
448 | * | ||
449 | * DESCRIPTION: Take the resource byte stream and fill out the appropriate | ||
450 | * structure pointed to by the output_buffer. Return the | ||
451 | * number of bytes consumed from the byte stream. | ||
452 | * | ||
453 | ******************************************************************************/ | ||
454 | |||
455 | acpi_status | ||
456 | acpi_rs_end_depend_fns_resource ( | ||
457 | u8 *byte_stream_buffer, | ||
458 | acpi_size *bytes_consumed, | ||
459 | u8 **output_buffer, | ||
460 | acpi_size *structure_size) | ||
461 | { | ||
462 | struct acpi_resource *output_struct = (void *) *output_buffer; | ||
463 | acpi_size struct_size = ACPI_RESOURCE_LENGTH; | ||
464 | |||
465 | |||
466 | ACPI_FUNCTION_TRACE ("rs_end_depend_fns_resource"); | ||
467 | |||
468 | |||
469 | /* | ||
470 | * The number of bytes consumed is static | ||
471 | */ | ||
472 | *bytes_consumed = 1; | ||
473 | |||
474 | /* | ||
475 | * Fill out the structure | ||
476 | */ | ||
477 | output_struct->id = ACPI_RSTYPE_END_DPF; | ||
478 | |||
479 | /* | ||
480 | * Set the Length parameter | ||
481 | */ | ||
482 | output_struct->length = (u32) struct_size; | ||
483 | |||
484 | /* | ||
485 | * Return the final size of the structure | ||
486 | */ | ||
487 | *structure_size = struct_size; | ||
488 | return_ACPI_STATUS (AE_OK); | ||
489 | } | ||
490 | |||
491 | |||
492 | /******************************************************************************* | ||
493 | * | ||
494 | * FUNCTION: acpi_rs_start_depend_fns_stream | ||
495 | * | ||
496 | * PARAMETERS: linked_list - Pointer to the resource linked list | ||
497 | * output_buffer - Pointer to the user's return buffer | ||
498 | * bytes_consumed - u32 pointer that is filled with | ||
499 | * the number of bytes of the | ||
500 | * output_buffer used | ||
501 | * | ||
502 | * RETURN: Status | ||
503 | * | ||
504 | * DESCRIPTION: Take the linked list resource structure and fills in the | ||
505 | * the appropriate bytes in a byte stream | ||
506 | * | ||
507 | ******************************************************************************/ | ||
508 | |||
509 | acpi_status | ||
510 | acpi_rs_start_depend_fns_stream ( | ||
511 | struct acpi_resource *linked_list, | ||
512 | u8 **output_buffer, | ||
513 | acpi_size *bytes_consumed) | ||
514 | { | ||
515 | u8 *buffer = *output_buffer; | ||
516 | u8 temp8 = 0; | ||
517 | |||
518 | |||
519 | ACPI_FUNCTION_TRACE ("rs_start_depend_fns_stream"); | ||
520 | |||
521 | |||
522 | /* | ||
523 | * The descriptor field is set based upon whether a byte is needed | ||
524 | * to contain Priority data. | ||
525 | */ | ||
526 | if (ACPI_ACCEPTABLE_CONFIGURATION == | ||
527 | linked_list->data.start_dpf.compatibility_priority && | ||
528 | ACPI_ACCEPTABLE_CONFIGURATION == | ||
529 | linked_list->data.start_dpf.performance_robustness) { | ||
530 | *buffer = 0x30; | ||
531 | } | ||
532 | else { | ||
533 | *buffer = 0x31; | ||
534 | buffer += 1; | ||
535 | |||
536 | /* | ||
537 | * Set the Priority Byte Definition | ||
538 | */ | ||
539 | temp8 = 0; | ||
540 | temp8 = (u8) ((linked_list->data.start_dpf.performance_robustness & | ||
541 | 0x03) << 2); | ||
542 | temp8 |= (linked_list->data.start_dpf.compatibility_priority & | ||
543 | 0x03); | ||
544 | *buffer = temp8; | ||
545 | } | ||
546 | |||
547 | buffer += 1; | ||
548 | |||
549 | /* | ||
550 | * Return the number of bytes consumed in this operation | ||
551 | */ | ||
552 | *bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer); | ||
553 | return_ACPI_STATUS (AE_OK); | ||
554 | } | ||
555 | |||
556 | |||
557 | /******************************************************************************* | ||
558 | * | ||
559 | * FUNCTION: acpi_rs_end_depend_fns_stream | ||
560 | * | ||
561 | * PARAMETERS: linked_list - Pointer to the resource linked list | ||
562 | * output_buffer - Pointer to the user's return buffer | ||
563 | * bytes_consumed - Pointer to where the number of bytes | ||
564 | * used in the output_buffer is returned | ||
565 | * | ||
566 | * RETURN: Status | ||
567 | * | ||
568 | * DESCRIPTION: Take the linked list resource structure and fills in the | ||
569 | * the appropriate bytes in a byte stream | ||
570 | * | ||
571 | ******************************************************************************/ | ||
572 | |||
573 | acpi_status | ||
574 | acpi_rs_end_depend_fns_stream ( | ||
575 | struct acpi_resource *linked_list, | ||
576 | u8 **output_buffer, | ||
577 | acpi_size *bytes_consumed) | ||
578 | { | ||
579 | u8 *buffer = *output_buffer; | ||
580 | |||
581 | |||
582 | ACPI_FUNCTION_TRACE ("rs_end_depend_fns_stream"); | ||
583 | |||
584 | |||
585 | /* | ||
586 | * The descriptor field is static | ||
587 | */ | ||
588 | *buffer = 0x38; | ||
589 | buffer += 1; | ||
590 | |||
591 | /* | ||
592 | * Return the number of bytes consumed in this operation | ||
593 | */ | ||
594 | *bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer); | ||
595 | return_ACPI_STATUS (AE_OK); | ||
596 | } | ||
597 | |||
diff --git a/drivers/acpi/resources/rsutils.c b/drivers/acpi/resources/rsutils.c new file mode 100644 index 000000000000..ee9ce13c053d --- /dev/null +++ b/drivers/acpi/resources/rsutils.c | |||
@@ -0,0 +1,356 @@ | |||
1 | /******************************************************************************* | ||
2 | * | ||
3 | * Module Name: rsutils - Utilities for the resource manager | ||
4 | * | ||
5 | ******************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2005, R. Byron Moore | ||
9 | * All rights reserved. | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions, and the following disclaimer, | ||
16 | * without modification. | ||
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
18 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
19 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
20 | * including a substantially similar Disclaimer requirement for further | ||
21 | * binary redistribution. | ||
22 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
23 | * of any contributors may be used to endorse or promote products derived | ||
24 | * from this software without specific prior written permission. | ||
25 | * | ||
26 | * Alternatively, this software may be distributed under the terms of the | ||
27 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
28 | * Software Foundation. | ||
29 | * | ||
30 | * NO WARRANTY | ||
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
41 | * POSSIBILITY OF SUCH DAMAGES. | ||
42 | */ | ||
43 | |||
44 | |||
45 | #include <acpi/acpi.h> | ||
46 | #include <acpi/acnamesp.h> | ||
47 | #include <acpi/acresrc.h> | ||
48 | |||
49 | |||
50 | #define _COMPONENT ACPI_RESOURCES | ||
51 | ACPI_MODULE_NAME ("rsutils") | ||
52 | |||
53 | |||
54 | /******************************************************************************* | ||
55 | * | ||
56 | * FUNCTION: acpi_rs_get_prt_method_data | ||
57 | * | ||
58 | * PARAMETERS: Handle - a handle to the containing object | ||
59 | * ret_buffer - a pointer to a buffer structure for the | ||
60 | * results | ||
61 | * | ||
62 | * RETURN: Status | ||
63 | * | ||
64 | * DESCRIPTION: This function is called to get the _PRT value of an object | ||
65 | * contained in an object specified by the handle passed in | ||
66 | * | ||
67 | * If the function fails an appropriate status will be returned | ||
68 | * and the contents of the callers buffer is undefined. | ||
69 | * | ||
70 | ******************************************************************************/ | ||
71 | |||
72 | acpi_status | ||
73 | acpi_rs_get_prt_method_data ( | ||
74 | acpi_handle handle, | ||
75 | struct acpi_buffer *ret_buffer) | ||
76 | { | ||
77 | union acpi_operand_object *obj_desc; | ||
78 | acpi_status status; | ||
79 | |||
80 | |||
81 | ACPI_FUNCTION_TRACE ("rs_get_prt_method_data"); | ||
82 | |||
83 | |||
84 | /* Parameters guaranteed valid by caller */ | ||
85 | |||
86 | /* | ||
87 | * Execute the method, no parameters | ||
88 | */ | ||
89 | status = acpi_ut_evaluate_object (handle, "_PRT", ACPI_BTYPE_PACKAGE, &obj_desc); | ||
90 | if (ACPI_FAILURE (status)) { | ||
91 | return_ACPI_STATUS (status); | ||
92 | } | ||
93 | |||
94 | /* | ||
95 | * Create a resource linked list from the byte stream buffer that comes | ||
96 | * back from the _CRS method execution. | ||
97 | */ | ||
98 | status = acpi_rs_create_pci_routing_table (obj_desc, ret_buffer); | ||
99 | |||
100 | /* On exit, we must delete the object returned by evaluate_object */ | ||
101 | |||
102 | acpi_ut_remove_reference (obj_desc); | ||
103 | return_ACPI_STATUS (status); | ||
104 | } | ||
105 | |||
106 | |||
107 | /******************************************************************************* | ||
108 | * | ||
109 | * FUNCTION: acpi_rs_get_crs_method_data | ||
110 | * | ||
111 | * PARAMETERS: Handle - a handle to the containing object | ||
112 | * ret_buffer - a pointer to a buffer structure for the | ||
113 | * results | ||
114 | * | ||
115 | * RETURN: Status | ||
116 | * | ||
117 | * DESCRIPTION: This function is called to get the _CRS value of an object | ||
118 | * contained in an object specified by the handle passed in | ||
119 | * | ||
120 | * If the function fails an appropriate status will be returned | ||
121 | * and the contents of the callers buffer is undefined. | ||
122 | * | ||
123 | ******************************************************************************/ | ||
124 | |||
125 | acpi_status | ||
126 | acpi_rs_get_crs_method_data ( | ||
127 | acpi_handle handle, | ||
128 | struct acpi_buffer *ret_buffer) | ||
129 | { | ||
130 | union acpi_operand_object *obj_desc; | ||
131 | acpi_status status; | ||
132 | |||
133 | |||
134 | ACPI_FUNCTION_TRACE ("rs_get_crs_method_data"); | ||
135 | |||
136 | |||
137 | /* Parameters guaranteed valid by caller */ | ||
138 | |||
139 | /* | ||
140 | * Execute the method, no parameters | ||
141 | */ | ||
142 | status = acpi_ut_evaluate_object (handle, "_CRS", ACPI_BTYPE_BUFFER, &obj_desc); | ||
143 | if (ACPI_FAILURE (status)) { | ||
144 | return_ACPI_STATUS (status); | ||
145 | } | ||
146 | |||
147 | /* | ||
148 | * Make the call to create a resource linked list from the | ||
149 | * byte stream buffer that comes back from the _CRS method | ||
150 | * execution. | ||
151 | */ | ||
152 | status = acpi_rs_create_resource_list (obj_desc, ret_buffer); | ||
153 | |||
154 | /* on exit, we must delete the object returned by evaluate_object */ | ||
155 | |||
156 | acpi_ut_remove_reference (obj_desc); | ||
157 | return_ACPI_STATUS (status); | ||
158 | } | ||
159 | |||
160 | |||
161 | /******************************************************************************* | ||
162 | * | ||
163 | * FUNCTION: acpi_rs_get_prs_method_data | ||
164 | * | ||
165 | * PARAMETERS: Handle - a handle to the containing object | ||
166 | * ret_buffer - a pointer to a buffer structure for the | ||
167 | * results | ||
168 | * | ||
169 | * RETURN: Status | ||
170 | * | ||
171 | * DESCRIPTION: This function is called to get the _PRS value of an object | ||
172 | * contained in an object specified by the handle passed in | ||
173 | * | ||
174 | * If the function fails an appropriate status will be returned | ||
175 | * and the contents of the callers buffer is undefined. | ||
176 | * | ||
177 | ******************************************************************************/ | ||
178 | #ifdef ACPI_FUTURE_USAGE | ||
179 | acpi_status | ||
180 | acpi_rs_get_prs_method_data ( | ||
181 | acpi_handle handle, | ||
182 | struct acpi_buffer *ret_buffer) | ||
183 | { | ||
184 | union acpi_operand_object *obj_desc; | ||
185 | acpi_status status; | ||
186 | |||
187 | |||
188 | ACPI_FUNCTION_TRACE ("rs_get_prs_method_data"); | ||
189 | |||
190 | |||
191 | /* Parameters guaranteed valid by caller */ | ||
192 | |||
193 | /* | ||
194 | * Execute the method, no parameters | ||
195 | */ | ||
196 | status = acpi_ut_evaluate_object (handle, "_PRS", ACPI_BTYPE_BUFFER, &obj_desc); | ||
197 | if (ACPI_FAILURE (status)) { | ||
198 | return_ACPI_STATUS (status); | ||
199 | } | ||
200 | |||
201 | /* | ||
202 | * Make the call to create a resource linked list from the | ||
203 | * byte stream buffer that comes back from the _CRS method | ||
204 | * execution. | ||
205 | */ | ||
206 | status = acpi_rs_create_resource_list (obj_desc, ret_buffer); | ||
207 | |||
208 | /* on exit, we must delete the object returned by evaluate_object */ | ||
209 | |||
210 | acpi_ut_remove_reference (obj_desc); | ||
211 | return_ACPI_STATUS (status); | ||
212 | } | ||
213 | #endif /* ACPI_FUTURE_USAGE */ | ||
214 | |||
215 | |||
216 | /******************************************************************************* | ||
217 | * | ||
218 | * FUNCTION: acpi_rs_get_method_data | ||
219 | * | ||
220 | * PARAMETERS: Handle - a handle to the containing object | ||
221 | * ret_buffer - a pointer to a buffer structure for the | ||
222 | * results | ||
223 | * | ||
224 | * RETURN: Status | ||
225 | * | ||
226 | * DESCRIPTION: This function is called to get the _CRS or _PRS value of an | ||
227 | * object contained in an object specified by the handle passed in | ||
228 | * | ||
229 | * If the function fails an appropriate status will be returned | ||
230 | * and the contents of the callers buffer is undefined. | ||
231 | * | ||
232 | ******************************************************************************/ | ||
233 | |||
234 | acpi_status | ||
235 | acpi_rs_get_method_data ( | ||
236 | acpi_handle handle, | ||
237 | char *path, | ||
238 | struct acpi_buffer *ret_buffer) | ||
239 | { | ||
240 | union acpi_operand_object *obj_desc; | ||
241 | acpi_status status; | ||
242 | |||
243 | |||
244 | ACPI_FUNCTION_TRACE ("rs_get_method_data"); | ||
245 | |||
246 | |||
247 | /* Parameters guaranteed valid by caller */ | ||
248 | |||
249 | /* | ||
250 | * Execute the method, no parameters | ||
251 | */ | ||
252 | status = acpi_ut_evaluate_object (handle, path, ACPI_BTYPE_BUFFER, &obj_desc); | ||
253 | if (ACPI_FAILURE (status)) { | ||
254 | return_ACPI_STATUS (status); | ||
255 | } | ||
256 | |||
257 | /* | ||
258 | * Make the call to create a resource linked list from the | ||
259 | * byte stream buffer that comes back from the method | ||
260 | * execution. | ||
261 | */ | ||
262 | status = acpi_rs_create_resource_list (obj_desc, ret_buffer); | ||
263 | |||
264 | /* On exit, we must delete the object returned by evaluate_object */ | ||
265 | |||
266 | acpi_ut_remove_reference (obj_desc); | ||
267 | return_ACPI_STATUS (status); | ||
268 | } | ||
269 | |||
270 | /******************************************************************************* | ||
271 | * | ||
272 | * FUNCTION: acpi_rs_set_srs_method_data | ||
273 | * | ||
274 | * PARAMETERS: Handle - a handle to the containing object | ||
275 | * in_buffer - a pointer to a buffer structure of the | ||
276 | * parameter | ||
277 | * | ||
278 | * RETURN: Status | ||
279 | * | ||
280 | * DESCRIPTION: This function is called to set the _SRS of an object contained | ||
281 | * in an object specified by the handle passed in | ||
282 | * | ||
283 | * If the function fails an appropriate status will be returned | ||
284 | * and the contents of the callers buffer is undefined. | ||
285 | * | ||
286 | ******************************************************************************/ | ||
287 | |||
288 | acpi_status | ||
289 | acpi_rs_set_srs_method_data ( | ||
290 | acpi_handle handle, | ||
291 | struct acpi_buffer *in_buffer) | ||
292 | { | ||
293 | struct acpi_parameter_info info; | ||
294 | union acpi_operand_object *params[2]; | ||
295 | acpi_status status; | ||
296 | struct acpi_buffer buffer; | ||
297 | |||
298 | |||
299 | ACPI_FUNCTION_TRACE ("rs_set_srs_method_data"); | ||
300 | |||
301 | |||
302 | /* Parameters guaranteed valid by caller */ | ||
303 | |||
304 | /* | ||
305 | * The in_buffer parameter will point to a linked list of | ||
306 | * resource parameters. It needs to be formatted into a | ||
307 | * byte stream to be sent in as an input parameter to _SRS | ||
308 | * | ||
309 | * Convert the linked list into a byte stream | ||
310 | */ | ||
311 | buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; | ||
312 | status = acpi_rs_create_byte_stream (in_buffer->pointer, &buffer); | ||
313 | if (ACPI_FAILURE (status)) { | ||
314 | return_ACPI_STATUS (status); | ||
315 | } | ||
316 | |||
317 | /* | ||
318 | * Init the param object | ||
319 | */ | ||
320 | params[0] = acpi_ut_create_internal_object (ACPI_TYPE_BUFFER); | ||
321 | if (!params[0]) { | ||
322 | acpi_os_free (buffer.pointer); | ||
323 | return_ACPI_STATUS (AE_NO_MEMORY); | ||
324 | } | ||
325 | |||
326 | /* | ||
327 | * Set up the parameter object | ||
328 | */ | ||
329 | params[0]->buffer.length = (u32) buffer.length; | ||
330 | params[0]->buffer.pointer = buffer.pointer; | ||
331 | params[0]->common.flags = AOPOBJ_DATA_VALID; | ||
332 | params[1] = NULL; | ||
333 | |||
334 | info.node = handle; | ||
335 | info.parameters = params; | ||
336 | info.parameter_type = ACPI_PARAM_ARGS; | ||
337 | |||
338 | /* | ||
339 | * Execute the method, no return value | ||
340 | */ | ||
341 | status = acpi_ns_evaluate_relative ("_SRS", &info); | ||
342 | if (ACPI_SUCCESS (status)) { | ||
343 | /* Delete any return object (especially if implicit_return is enabled) */ | ||
344 | |||
345 | if (info.return_object) { | ||
346 | acpi_ut_remove_reference (info.return_object); | ||
347 | } | ||
348 | } | ||
349 | |||
350 | /* | ||
351 | * Clean up and return the status from acpi_ns_evaluate_relative | ||
352 | */ | ||
353 | acpi_ut_remove_reference (params[0]); | ||
354 | return_ACPI_STATUS (status); | ||
355 | } | ||
356 | |||
diff --git a/drivers/acpi/resources/rsxface.c b/drivers/acpi/resources/rsxface.c new file mode 100644 index 000000000000..a9cdcbeb3432 --- /dev/null +++ b/drivers/acpi/resources/rsxface.c | |||
@@ -0,0 +1,437 @@ | |||
1 | /******************************************************************************* | ||
2 | * | ||
3 | * Module Name: rsxface - Public interfaces to the resource manager | ||
4 | * | ||
5 | ******************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2005, R. Byron Moore | ||
9 | * All rights reserved. | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions, and the following disclaimer, | ||
16 | * without modification. | ||
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
18 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
19 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
20 | * including a substantially similar Disclaimer requirement for further | ||
21 | * binary redistribution. | ||
22 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
23 | * of any contributors may be used to endorse or promote products derived | ||
24 | * from this software without specific prior written permission. | ||
25 | * | ||
26 | * Alternatively, this software may be distributed under the terms of the | ||
27 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
28 | * Software Foundation. | ||
29 | * | ||
30 | * NO WARRANTY | ||
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
41 | * POSSIBILITY OF SUCH DAMAGES. | ||
42 | */ | ||
43 | |||
44 | #include <linux/module.h> | ||
45 | |||
46 | #include <acpi/acpi.h> | ||
47 | #include <acpi/acresrc.h> | ||
48 | |||
49 | #define _COMPONENT ACPI_RESOURCES | ||
50 | ACPI_MODULE_NAME ("rsxface") | ||
51 | |||
52 | |||
53 | /******************************************************************************* | ||
54 | * | ||
55 | * FUNCTION: acpi_get_irq_routing_table | ||
56 | * | ||
57 | * PARAMETERS: device_handle - a handle to the Bus device we are querying | ||
58 | * ret_buffer - a pointer to a buffer to receive the | ||
59 | * current resources for the device | ||
60 | * | ||
61 | * RETURN: Status | ||
62 | * | ||
63 | * DESCRIPTION: This function is called to get the IRQ routing table for a | ||
64 | * specific bus. The caller must first acquire a handle for the | ||
65 | * desired bus. The routine table is placed in the buffer pointed | ||
66 | * to by the ret_buffer variable parameter. | ||
67 | * | ||
68 | * If the function fails an appropriate status will be returned | ||
69 | * and the value of ret_buffer is undefined. | ||
70 | * | ||
71 | * This function attempts to execute the _PRT method contained in | ||
72 | * the object indicated by the passed device_handle. | ||
73 | * | ||
74 | ******************************************************************************/ | ||
75 | |||
76 | acpi_status | ||
77 | acpi_get_irq_routing_table ( | ||
78 | acpi_handle device_handle, | ||
79 | struct acpi_buffer *ret_buffer) | ||
80 | { | ||
81 | acpi_status status; | ||
82 | |||
83 | |||
84 | ACPI_FUNCTION_TRACE ("acpi_get_irq_routing_table "); | ||
85 | |||
86 | |||
87 | /* | ||
88 | * Must have a valid handle and buffer, So we have to have a handle | ||
89 | * and a return buffer structure, and if there is a non-zero buffer length | ||
90 | * we also need a valid pointer in the buffer. If it's a zero buffer length, | ||
91 | * we'll be returning the needed buffer size, so keep going. | ||
92 | */ | ||
93 | if (!device_handle) { | ||
94 | return_ACPI_STATUS (AE_BAD_PARAMETER); | ||
95 | } | ||
96 | |||
97 | status = acpi_ut_validate_buffer (ret_buffer); | ||
98 | if (ACPI_FAILURE (status)) { | ||
99 | return_ACPI_STATUS (status); | ||
100 | } | ||
101 | |||
102 | status = acpi_rs_get_prt_method_data (device_handle, ret_buffer); | ||
103 | return_ACPI_STATUS (status); | ||
104 | } | ||
105 | |||
106 | |||
107 | /******************************************************************************* | ||
108 | * | ||
109 | * FUNCTION: acpi_get_current_resources | ||
110 | * | ||
111 | * PARAMETERS: device_handle - a handle to the device object for the | ||
112 | * device we are querying | ||
113 | * ret_buffer - a pointer to a buffer to receive the | ||
114 | * current resources for the device | ||
115 | * | ||
116 | * RETURN: Status | ||
117 | * | ||
118 | * DESCRIPTION: This function is called to get the current resources for a | ||
119 | * specific device. The caller must first acquire a handle for | ||
120 | * the desired device. The resource data is placed in the buffer | ||
121 | * pointed to by the ret_buffer variable parameter. | ||
122 | * | ||
123 | * If the function fails an appropriate status will be returned | ||
124 | * and the value of ret_buffer is undefined. | ||
125 | * | ||
126 | * This function attempts to execute the _CRS method contained in | ||
127 | * the object indicated by the passed device_handle. | ||
128 | * | ||
129 | ******************************************************************************/ | ||
130 | |||
131 | acpi_status | ||
132 | acpi_get_current_resources ( | ||
133 | acpi_handle device_handle, | ||
134 | struct acpi_buffer *ret_buffer) | ||
135 | { | ||
136 | acpi_status status; | ||
137 | |||
138 | |||
139 | ACPI_FUNCTION_TRACE ("acpi_get_current_resources"); | ||
140 | |||
141 | |||
142 | /* | ||
143 | * Must have a valid handle and buffer, So we have to have a handle | ||
144 | * and a return buffer structure, and if there is a non-zero buffer length | ||
145 | * we also need a valid pointer in the buffer. If it's a zero buffer length, | ||
146 | * we'll be returning the needed buffer size, so keep going. | ||
147 | */ | ||
148 | if (!device_handle) { | ||
149 | return_ACPI_STATUS (AE_BAD_PARAMETER); | ||
150 | } | ||
151 | |||
152 | status = acpi_ut_validate_buffer (ret_buffer); | ||
153 | if (ACPI_FAILURE (status)) { | ||
154 | return_ACPI_STATUS (status); | ||
155 | } | ||
156 | |||
157 | status = acpi_rs_get_crs_method_data (device_handle, ret_buffer); | ||
158 | return_ACPI_STATUS (status); | ||
159 | } | ||
160 | EXPORT_SYMBOL(acpi_get_current_resources); | ||
161 | |||
162 | |||
163 | /******************************************************************************* | ||
164 | * | ||
165 | * FUNCTION: acpi_get_possible_resources | ||
166 | * | ||
167 | * PARAMETERS: device_handle - a handle to the device object for the | ||
168 | * device we are querying | ||
169 | * ret_buffer - a pointer to a buffer to receive the | ||
170 | * resources for the device | ||
171 | * | ||
172 | * RETURN: Status | ||
173 | * | ||
174 | * DESCRIPTION: This function is called to get a list of the possible resources | ||
175 | * for a specific device. The caller must first acquire a handle | ||
176 | * for the desired device. The resource data is placed in the | ||
177 | * buffer pointed to by the ret_buffer variable. | ||
178 | * | ||
179 | * If the function fails an appropriate status will be returned | ||
180 | * and the value of ret_buffer is undefined. | ||
181 | * | ||
182 | ******************************************************************************/ | ||
183 | #ifdef ACPI_FUTURE_USAGE | ||
184 | acpi_status | ||
185 | acpi_get_possible_resources ( | ||
186 | acpi_handle device_handle, | ||
187 | struct acpi_buffer *ret_buffer) | ||
188 | { | ||
189 | acpi_status status; | ||
190 | |||
191 | |||
192 | ACPI_FUNCTION_TRACE ("acpi_get_possible_resources"); | ||
193 | |||
194 | |||
195 | /* | ||
196 | * Must have a valid handle and buffer, So we have to have a handle | ||
197 | * and a return buffer structure, and if there is a non-zero buffer length | ||
198 | * we also need a valid pointer in the buffer. If it's a zero buffer length, | ||
199 | * we'll be returning the needed buffer size, so keep going. | ||
200 | */ | ||
201 | if (!device_handle) { | ||
202 | return_ACPI_STATUS (AE_BAD_PARAMETER); | ||
203 | } | ||
204 | |||
205 | status = acpi_ut_validate_buffer (ret_buffer); | ||
206 | if (ACPI_FAILURE (status)) { | ||
207 | return_ACPI_STATUS (status); | ||
208 | } | ||
209 | |||
210 | status = acpi_rs_get_prs_method_data (device_handle, ret_buffer); | ||
211 | return_ACPI_STATUS (status); | ||
212 | } | ||
213 | EXPORT_SYMBOL(acpi_get_possible_resources); | ||
214 | #endif /* ACPI_FUTURE_USAGE */ | ||
215 | |||
216 | |||
217 | /******************************************************************************* | ||
218 | * | ||
219 | * FUNCTION: acpi_walk_resources | ||
220 | * | ||
221 | * PARAMETERS: device_handle - a handle to the device object for the | ||
222 | * device we are querying | ||
223 | * Path - method name of the resources we want | ||
224 | * (METHOD_NAME__CRS or METHOD_NAME__PRS) | ||
225 | * user_function - called for each resource | ||
226 | * Context - passed to user_function | ||
227 | * | ||
228 | * RETURN: Status | ||
229 | * | ||
230 | * DESCRIPTION: Retrieves the current or possible resource list for the | ||
231 | * specified device. The user_function is called once for | ||
232 | * each resource in the list. | ||
233 | * | ||
234 | ******************************************************************************/ | ||
235 | |||
236 | acpi_status | ||
237 | acpi_walk_resources ( | ||
238 | acpi_handle device_handle, | ||
239 | char *path, | ||
240 | ACPI_WALK_RESOURCE_CALLBACK user_function, | ||
241 | void *context) | ||
242 | { | ||
243 | acpi_status status; | ||
244 | struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; | ||
245 | struct acpi_resource *resource; | ||
246 | struct acpi_resource *buffer_end; | ||
247 | |||
248 | |||
249 | ACPI_FUNCTION_TRACE ("acpi_walk_resources"); | ||
250 | |||
251 | |||
252 | if (!device_handle || | ||
253 | (ACPI_STRNCMP (path, METHOD_NAME__CRS, sizeof (METHOD_NAME__CRS)) && | ||
254 | ACPI_STRNCMP (path, METHOD_NAME__PRS, sizeof (METHOD_NAME__PRS)))) { | ||
255 | return_ACPI_STATUS (AE_BAD_PARAMETER); | ||
256 | } | ||
257 | |||
258 | status = acpi_rs_get_method_data (device_handle, path, &buffer); | ||
259 | if (ACPI_FAILURE (status)) { | ||
260 | return_ACPI_STATUS (status); | ||
261 | } | ||
262 | |||
263 | /* Setup pointers */ | ||
264 | |||
265 | resource = (struct acpi_resource *) buffer.pointer; | ||
266 | buffer_end = ACPI_CAST_PTR (struct acpi_resource, | ||
267 | ((u8 *) buffer.pointer + buffer.length)); | ||
268 | |||
269 | /* Walk the resource list */ | ||
270 | |||
271 | for (;;) { | ||
272 | if (!resource || resource->id == ACPI_RSTYPE_END_TAG) { | ||
273 | break; | ||
274 | } | ||
275 | |||
276 | status = user_function (resource, context); | ||
277 | |||
278 | switch (status) { | ||
279 | case AE_OK: | ||
280 | case AE_CTRL_DEPTH: | ||
281 | |||
282 | /* Just keep going */ | ||
283 | |||
284 | status = AE_OK; | ||
285 | break; | ||
286 | |||
287 | case AE_CTRL_TERMINATE: | ||
288 | |||
289 | /* Exit now, with OK stats */ | ||
290 | |||
291 | status = AE_OK; | ||
292 | goto cleanup; | ||
293 | |||
294 | default: | ||
295 | |||
296 | /* All others are valid exceptions */ | ||
297 | |||
298 | goto cleanup; | ||
299 | } | ||
300 | |||
301 | /* Get the next resource descriptor */ | ||
302 | |||
303 | resource = ACPI_NEXT_RESOURCE (resource); | ||
304 | |||
305 | /* Check for end-of-buffer */ | ||
306 | |||
307 | if (resource >= buffer_end) { | ||
308 | goto cleanup; | ||
309 | } | ||
310 | } | ||
311 | |||
312 | cleanup: | ||
313 | |||
314 | acpi_os_free (buffer.pointer); | ||
315 | return_ACPI_STATUS (status); | ||
316 | } | ||
317 | EXPORT_SYMBOL(acpi_walk_resources); | ||
318 | |||
319 | |||
320 | /******************************************************************************* | ||
321 | * | ||
322 | * FUNCTION: acpi_set_current_resources | ||
323 | * | ||
324 | * PARAMETERS: device_handle - a handle to the device object for the | ||
325 | * device we are changing the resources of | ||
326 | * in_buffer - a pointer to a buffer containing the | ||
327 | * resources to be set for the device | ||
328 | * | ||
329 | * RETURN: Status | ||
330 | * | ||
331 | * DESCRIPTION: This function is called to set the current resources for a | ||
332 | * specific device. The caller must first acquire a handle for | ||
333 | * the desired device. The resource data is passed to the routine | ||
334 | * the buffer pointed to by the in_buffer variable. | ||
335 | * | ||
336 | ******************************************************************************/ | ||
337 | |||
338 | acpi_status | ||
339 | acpi_set_current_resources ( | ||
340 | acpi_handle device_handle, | ||
341 | struct acpi_buffer *in_buffer) | ||
342 | { | ||
343 | acpi_status status; | ||
344 | |||
345 | |||
346 | ACPI_FUNCTION_TRACE ("acpi_set_current_resources"); | ||
347 | |||
348 | |||
349 | /* | ||
350 | * Must have a valid handle and buffer | ||
351 | */ | ||
352 | if ((!device_handle) || | ||
353 | (!in_buffer) || | ||
354 | (!in_buffer->pointer) || | ||
355 | (!in_buffer->length)) { | ||
356 | return_ACPI_STATUS (AE_BAD_PARAMETER); | ||
357 | } | ||
358 | |||
359 | status = acpi_rs_set_srs_method_data (device_handle, in_buffer); | ||
360 | return_ACPI_STATUS (status); | ||
361 | } | ||
362 | EXPORT_SYMBOL(acpi_set_current_resources); | ||
363 | |||
364 | |||
365 | #define ACPI_COPY_FIELD(out, in, field) ((out)->field = (in)->field) | ||
366 | #define ACPI_COPY_ADDRESS(out, in) \ | ||
367 | ACPI_COPY_FIELD(out, in, resource_type); \ | ||
368 | ACPI_COPY_FIELD(out, in, producer_consumer); \ | ||
369 | ACPI_COPY_FIELD(out, in, decode); \ | ||
370 | ACPI_COPY_FIELD(out, in, min_address_fixed); \ | ||
371 | ACPI_COPY_FIELD(out, in, max_address_fixed); \ | ||
372 | ACPI_COPY_FIELD(out, in, attribute); \ | ||
373 | ACPI_COPY_FIELD(out, in, granularity); \ | ||
374 | ACPI_COPY_FIELD(out, in, min_address_range); \ | ||
375 | ACPI_COPY_FIELD(out, in, max_address_range); \ | ||
376 | ACPI_COPY_FIELD(out, in, address_translation_offset); \ | ||
377 | ACPI_COPY_FIELD(out, in, address_length); \ | ||
378 | ACPI_COPY_FIELD(out, in, resource_source); | ||
379 | |||
380 | /****************************************************************************** | ||
381 | * | ||
382 | * FUNCTION: acpi_resource_to_address64 | ||
383 | * | ||
384 | * PARAMETERS: resource - Pointer to a resource | ||
385 | * out - Pointer to the users's return | ||
386 | * buffer (a struct | ||
387 | * struct acpi_resource_address64) | ||
388 | * | ||
389 | * RETURN: Status | ||
390 | * | ||
391 | * DESCRIPTION: If the resource is an address16, address32, or address64, | ||
392 | * copy it to the address64 return buffer. This saves the | ||
393 | * caller from having to duplicate code for different-sized | ||
394 | * addresses. | ||
395 | * | ||
396 | ******************************************************************************/ | ||
397 | |||
398 | acpi_status | ||
399 | acpi_resource_to_address64 ( | ||
400 | struct acpi_resource *resource, | ||
401 | struct acpi_resource_address64 *out) | ||
402 | { | ||
403 | struct acpi_resource_address16 *address16; | ||
404 | struct acpi_resource_address32 *address32; | ||
405 | |||
406 | |||
407 | switch (resource->id) { | ||
408 | case ACPI_RSTYPE_ADDRESS16: | ||
409 | |||
410 | address16 = (struct acpi_resource_address16 *) &resource->data; | ||
411 | ACPI_COPY_ADDRESS(out, address16); | ||
412 | break; | ||
413 | |||
414 | |||
415 | case ACPI_RSTYPE_ADDRESS32: | ||
416 | |||
417 | address32 = (struct acpi_resource_address32 *) &resource->data; | ||
418 | ACPI_COPY_ADDRESS(out, address32); | ||
419 | break; | ||
420 | |||
421 | |||
422 | case ACPI_RSTYPE_ADDRESS64: | ||
423 | |||
424 | /* Simple copy for 64 bit source */ | ||
425 | |||
426 | ACPI_MEMCPY (out, &resource->data, sizeof (struct acpi_resource_address64)); | ||
427 | break; | ||
428 | |||
429 | |||
430 | default: | ||
431 | return (AE_BAD_PARAMETER); | ||
432 | } | ||
433 | |||
434 | return (AE_OK); | ||
435 | } | ||
436 | EXPORT_SYMBOL(acpi_resource_to_address64); | ||
437 | |||