diff options
Diffstat (limited to 'drivers/acpi/resources/rsaddr.c')
-rw-r--r-- | drivers/acpi/resources/rsaddr.c | 1225 |
1 files changed, 1225 insertions, 0 deletions
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 | |||