Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  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 are valid */
114 
115         if (temp8 > 2) {
116                 return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE);
117         }
118 
119         output_struct->data.address16.resource_type = temp8 & 0x03;
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 are valid */
500         if(temp8 > 2) {
501                 return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE);
502         }
503 
504         output_struct->data.address32.resource_type = temp8 & 0x03;
505 
506         /*
507          * Get the General Flags (Byte4)
508          */
509         buffer += 1;
510         temp8 = *buffer;
511 
512         /*
513          * Producer / Consumer
514          */
515         output_struct->data.address32.producer_consumer = temp8 & 0x01;
516 
517         /*
518          * Decode
519          */
520         output_struct->data.address32.decode = (temp8 >> 1) & 0x01;
521 
522         /*
523          * Min Address Fixed
524          */
525         output_struct->data.address32.min_address_fixed = (temp8 >> 2) & 0x01;
526 
527         /*
528          * Max Address Fixed
529          */
530         output_struct->data.address32.max_address_fixed = (temp8 >> 3) & 0x01;
531 
532         /*
533          * Get the Type Specific Flags (Byte5)
534          */
535         buffer += 1;
536         temp8 = *buffer;
537 
538         if (ACPI_MEMORY_RANGE == output_struct->data.address32.resource_type) {
539                 output_struct->data.address32.attribute.memory.read_write_attribute =
540                                 (u16) (temp8 & 0x01);
541 
542                 output_struct->data.address32.attribute.memory.cache_attribute =
543                                 (u16) ((temp8 >> 1) & 0x03);
544         }
545         else {
546                 if (ACPI_IO_RANGE == output_struct->data.address32.resource_type) {
547                         output_struct->data.address32.attribute.io.range_attribute =
548                                 (u16) (temp8 & 0x03);
549                         output_struct->data.address32.attribute.io.translation_attribute =
550                                 (u16) ((temp8 >> 4) & 0x03);
551                 }
552                 else {
553                         /* BUS_NUMBER_RANGE == output_struct->Data.Address32.resource_type */
554                         /* Nothing needs to be filled in */
555                 }
556         }
557 
558         /*
559          * Get Granularity (Bytes 6-9)
560          */
561         buffer += 1;
562         ACPI_MOVE_32_TO_32 (&output_struct->data.address32.granularity, buffer);
563 
564         /*
565          * Get min_address_range (Bytes 10-13)
566          */
567         buffer += 4;
568         ACPI_MOVE_32_TO_32 (&output_struct->data.address32.min_address_range, buffer);
569 
570         /*
571          * Get max_address_range (Bytes 14-17)
572          */
573         buffer += 4;
574         ACPI_MOVE_32_TO_32 (&output_struct->data.address32.max_address_range, buffer);
575 
576         /*
577          * Get address_translation_offset (Bytes 18-21)
578          */
579         buffer += 4;
580         ACPI_MOVE_32_TO_32 (&output_struct->data.address32.address_translation_offset, buffer);
581 
582         /*
583          * Get address_length (Bytes 22-25)
584          */
585         buffer += 4;
586         ACPI_MOVE_32_TO_32 (&output_struct->data.address32.address_length, buffer);
587 
588         /*
589          * Resource Source Index (if present)
590          */
591         buffer += 4;
592 
593         /*
594          * This will leave us pointing to the Resource Source Index
595          * If it is present, then save it off and calculate the
596          * pointer to where the null terminated string goes:
597          *
598          * Note: Some resource descriptors will have an additional null, so
599          * we add 1 to the length.
600          */
601         if (*bytes_consumed > (26 + 1)) {
602                 /* Dereference the Index */
603 
604                 temp8 = *buffer;
605                 output_struct->data.address32.resource_source.index =
606                                 (u32) temp8;
607 
608                 /* Point to the String */
609 
610                 buffer += 1;
611 
612                 /* Point the String pointer to the end of this structure */
613 
614                 output_struct->data.address32.resource_source.string_ptr =
615                                 (char *)((u8 *)output_struct + struct_size);
616 
617                 temp_ptr = (u8 *) output_struct->data.address32.resource_source.string_ptr;
618 
619                 /* Copy the string into the buffer */
620 
621                 index = 0;
622                 while (0x00 != *buffer) {
623                         *temp_ptr = *buffer;
624 
625                         temp_ptr += 1;
626                         buffer += 1;
627                         index += 1;
628                 }
629 
630                 /*
631                  * Add the terminating null
632                  */
633                 *temp_ptr = 0x00;
634                 output_struct->data.address32.resource_source.string_length = index + 1;
635 
636                 /*
637                  * In order for the struct_size to fall on a 32-bit boundary,
638                  * calculate the length of the string and expand the
639                  * struct_size to the next 32-bit boundary.
640                  */
641                 temp8 = (u8) (index + 1);
642                 struct_size += ACPI_ROUND_UP_to_32_bITS (temp8);
643         }
644         else {
645                 output_struct->data.address32.resource_source.index = 0x00;
646                 output_struct->data.address32.resource_source.string_length = 0;
647                 output_struct->data.address32.resource_source.string_ptr = NULL;
648         }
649 
650         /*
651          * Set the Length parameter
652          */
653         output_struct->length = (u32) struct_size;
654 
655         /*
656          * Return the final size of the structure
657          */
658         *structure_size = struct_size;
659         return_ACPI_STATUS (AE_OK);
660 }
661 
662 
663 /*******************************************************************************
664  *
665  * FUNCTION:    acpi_rs_address32_stream
666  *
667  * PARAMETERS:  linked_list             - Pointer to the resource linked list
668  *              output_buffer           - Pointer to the user's return buffer
669  *              bytes_consumed          - Pointer to where the number of bytes
670  *                                        used in the output_buffer is returned
671  *
672  * RETURN:      Status
673  *
674  * DESCRIPTION: Take the linked list resource structure and fills in the
675  *              the appropriate bytes in a byte stream
676  *
677  ******************************************************************************/
678 
679 acpi_status
680 acpi_rs_address32_stream (
681         struct acpi_resource            *linked_list,
682         u8                              **output_buffer,
683         acpi_size                       *bytes_consumed)
684 {
685         u8                              *buffer;
686         u16                             *length_field;
687         u8                              temp8;
688         char                            *temp_pointer;
689 
690 
691         ACPI_FUNCTION_TRACE ("rs_address32_stream");
692 
693 
694         buffer = *output_buffer;
695 
696         /*
697          * The descriptor field is static
698          */
699         *buffer = 0x87;
700         buffer += 1;
701 
702         /*
703          * Set a pointer to the Length field - to be filled in later
704          */
705         length_field = ACPI_CAST_PTR (u16, buffer);
706         buffer += 2;
707 
708         /*
709          * Set the Resource Type (Memory, Io, bus_number)
710          */
711         temp8 = (u8) (linked_list->data.address32.resource_type & 0x03);
712 
713         *buffer = temp8;
714         buffer += 1;
715 
716         /*
717          * Set the general flags
718          */
719         temp8 = (u8) (linked_list->data.address32.producer_consumer & 0x01);
720         temp8 |= (linked_list->data.address32.decode & 0x01) << 1;
721         temp8 |= (linked_list->data.address32.min_address_fixed & 0x01) << 2;
722         temp8 |= (linked_list->data.address32.max_address_fixed & 0x01) << 3;
723 
724         *buffer = temp8;
725         buffer += 1;
726 
727         /*
728          * Set the type specific flags
729          */
730         temp8 = 0;
731 
732         if (ACPI_MEMORY_RANGE == linked_list->data.address32.resource_type) {
733                 temp8 = (u8)
734                         (linked_list->data.address32.attribute.memory.read_write_attribute &
735                         0x01);
736 
737                 temp8 |=
738                         (linked_list->data.address32.attribute.memory.cache_attribute &
739                          0x03) << 1;
740         }
741         else if (ACPI_IO_RANGE == linked_list->data.address32.resource_type) {
742                 temp8 = (u8)
743                         (linked_list->data.address32.attribute.io.range_attribute &
744                          0x03);
745                 temp8 |=
746                         (linked_list->data.address32.attribute.io.translation_attribute &
747                          0x03) << 4;
748         }
749 
750         *buffer = temp8;
751         buffer += 1;
752 
753         /*
754          * Set the address space granularity
755          */
756         ACPI_MOVE_32_TO_32 (buffer, &linked_list->data.address32.granularity);
757         buffer += 4;
758 
759         /*
760          * Set the address range minimum
761          */
762         ACPI_MOVE_32_TO_32 (buffer, &linked_list->data.address32.min_address_range);
763         buffer += 4;
764 
765         /*
766          * Set the address range maximum
767          */
768         ACPI_MOVE_32_TO_32 (buffer, &linked_list->data.address32.max_address_range);
769         buffer += 4;
770 
771         /*
772          * Set the address translation offset
773          */
774         ACPI_MOVE_32_TO_32 (buffer, &linked_list->data.address32.address_translation_offset);
775         buffer += 4;
776 
777         /*
778          * Set the address length
779          */
780         ACPI_MOVE_32_TO_32 (buffer, &linked_list->data.address32.address_length);
781         buffer += 4;
782 
783         /*
784          * Resource Source Index and Resource Source are optional
785          */
786         if (0 != linked_list->data.address32.resource_source.string_length) {
787                 temp8 = (u8) linked_list->data.address32.resource_source.index;
788 
789                 *buffer = temp8;
790                 buffer += 1;
791 
792                 temp_pointer = (char *) buffer;
793 
794                 /*
795                  * Copy the string
796                  */
797                 ACPI_STRCPY (temp_pointer,
798                         linked_list->data.address32.resource_source.string_ptr);
799 
800                 /*
801                  * Buffer needs to be set to the length of the sting + one for the
802                  *  terminating null
803                  */
804                 buffer += (acpi_size)(ACPI_STRLEN (linked_list->data.address32.resource_source.string_ptr) + 1);
805         }
806 
807         /*
808          * Return the number of bytes consumed in this operation
809          */
810         *bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
811 
812         /*
813          * Set the length field to the number of bytes consumed
814          *  minus the header size (3 bytes)
815          */
816         *length_field = (u16) (*bytes_consumed - 3);
817         return_ACPI_STATUS (AE_OK);
818 }
819 
820 
821 /*******************************************************************************
822  *
823  * FUNCTION:    acpi_rs_address64_resource
824  *
825  * PARAMETERS:  byte_stream_buffer      - Pointer to the resource input byte
826  *                                        stream
827  *              bytes_consumed          - Pointer to where the number of bytes
828  *                                        consumed the byte_stream_buffer is
829  *                                        returned
830  *              output_buffer           - Pointer to the return data buffer
831  *              structure_size          - Pointer to where the number of bytes
832  *                                        in the return data struct is returned
833  *
834  * RETURN:      Status
835  *
836  * DESCRIPTION: Take the resource byte stream and fill out the appropriate
837  *              structure pointed to by the output_buffer. Return the
838  *              number of bytes consumed from the byte stream.
839  *
840  ******************************************************************************/
841 
842 acpi_status
843 acpi_rs_address64_resource (
844         u8                              *byte_stream_buffer,
845         acpi_size                       *bytes_consumed,
846         u8                              **output_buffer,
847         acpi_size                       *structure_size)
848 {
849         u8                              *buffer;
850         struct acpi_resource            *output_struct = (void *) *output_buffer;
851         u16                             temp16;
852         u8                              temp8;
853         u8                              *temp_ptr;
854         acpi_size                       struct_size;
855         u32                             index;
856 
857 
858         ACPI_FUNCTION_TRACE ("rs_address64_resource");
859 
860 
861         buffer = byte_stream_buffer;
862         struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_address64);
863 
864         /*
865          * Point past the Descriptor to get the number of bytes consumed
866          */
867         buffer += 1;
868         ACPI_MOVE_16_TO_16 (&temp16, buffer);
869 
870         /* Validate minimum descriptor length */
871 
872         if (temp16 < 43) {
873                 return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH);
874         }
875 
876         *bytes_consumed = temp16 + 3;
877         output_struct->id = ACPI_RSTYPE_ADDRESS64;
878 
879         /*
880          * Get the Resource Type (Byte3)
881          */
882         buffer += 2;
883         temp8 = *buffer;
884 
885         /* Values 0-2 are valid */
886 
887         if(temp8 > 2) {
888                 return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE);
889         }
890 
891         output_struct->data.address64.resource_type = temp8 & 0x03;
892 
893         /*
894          * Get the General Flags (Byte4)
895          */
896         buffer += 1;
897         temp8 = *buffer;
898 
899         /*
900          * Producer / Consumer
901          */
902         output_struct->data.address64.producer_consumer = temp8 & 0x01;
903 
904         /*
905          * Decode
906          */
907         output_struct->data.address64.decode = (temp8 >> 1) & 0x01;
908 
909         /*
910          * Min Address Fixed
911          */
912         output_struct->data.address64.min_address_fixed = (temp8 >> 2) & 0x01;
913 
914         /*
915          * Max Address Fixed
916          */
917         output_struct->data.address64.max_address_fixed = (temp8 >> 3) & 0x01;
918 
919         /*
920          * Get the Type Specific Flags (Byte5)
921          */
922         buffer += 1;
923         temp8 = *buffer;
924 
925         if (ACPI_MEMORY_RANGE == output_struct->data.address64.resource_type) {
926                 output_struct->data.address64.attribute.memory.read_write_attribute =
927                                 (u16) (temp8 & 0x01);
928 
929                 output_struct->data.address64.attribute.memory.cache_attribute =
930                                 (u16) ((temp8 >> 1) & 0x03);
931         }
932         else {
933                 if (ACPI_IO_RANGE == output_struct->data.address64.resource_type) {
934                         output_struct->data.address64.attribute.io.range_attribute =
935                                 (u16) (temp8 & 0x03);
936                         output_struct->data.address64.attribute.io.translation_attribute =
937                                 (u16) ((temp8 >> 4) & 0x03);
938                 }
939                 else {
940                         /* BUS_NUMBER_RANGE == output_struct->Data.Address64.resource_type */
941                         /* Nothing needs to be filled in */
942                 }
943         }
944 
945         /*
946          * Get Granularity (Bytes 6-13)
947          */
948         buffer += 1;
949         ACPI_MOVE_64_TO_64 (&output_struct->data.address64.granularity, buffer);
950 
951         /*
952          * Get min_address_range (Bytes 14-21)
953          */
954         buffer += 8;
955         ACPI_MOVE_64_TO_64 (&output_struct->data.address64.min_address_range, buffer);
956 
957         /*
958          * Get max_address_range (Bytes 22-29)
959          */
960         buffer += 8;
961         ACPI_MOVE_64_TO_64 (&output_struct->data.address64.max_address_range, buffer);
962 
963         /*
964          * Get address_translation_offset (Bytes 30-37)
965          */
966         buffer += 8;
967         ACPI_MOVE_64_TO_64 (&output_struct->data.address64.address_translation_offset, buffer);
968 
969         /*
970          * Get address_length (Bytes 38-45)
971          */
972         buffer += 8;
973         ACPI_MOVE_64_TO_64 (&output_struct->data.address64.address_length, buffer);
974 
975         /*
976          * Resource Source Index (if present)
977          */
978         buffer += 8;
979 
980         /*
981          * This will leave us pointing to the Resource Source Index
982          * If it is present, then save it off and calculate the
983          * pointer to where the null terminated string goes:
984          * Each Interrupt takes 32-bits + the 5 bytes of the
985          * stream that are default.
986          *
987          * Note: Some resource descriptors will have an additional null, so
988          * we add 1 to the length.
989          */
990         if (*bytes_consumed > (46 + 1)) {
991                 /* Dereference the Index */
992 
993                 temp8 = *buffer;
994                 output_struct->data.address64.resource_source.index =
995                                 (u32) temp8;
996 
997                 /* Point to the String */
998 
999                 buffer += 1;
1000 
1001                 /* Point the String pointer to the end of this structure */
1002 
1003                 output_struct->data.address64.resource_source.string_ptr =
1004                                 (char *)((u8 *)output_struct + struct_size);
1005 
1006                 temp_ptr = (u8 *) output_struct->data.address64.resource_source.string_ptr;
1007 
1008                 /* Copy the string into the buffer */
1009 
1010                 index = 0;
1011                 while (0x00 != *buffer) {
1012                         *temp_ptr = *buffer;
1013 
1014                         temp_ptr += 1;
1015                         buffer += 1;
1016                         index += 1;
1017                 }
1018 
1019                 /*
1020                  * Add the terminating null
1021                  */
1022                 *temp_ptr = 0x00;
1023                 output_struct->data.address64.resource_source.string_length = index + 1;
1024 
1025                 /*
1026                  * In order for the struct_size to fall on a 32-bit boundary,
1027                  * calculate the length of the string and expand the
1028                  * struct_size to the next 32-bit boundary.
1029                  */
1030                 temp8 = (u8) (index + 1);
1031                 struct_size += ACPI_ROUND_UP_to_32_bITS (temp8);
1032         }
1033         else {
1034                 output_struct->data.address64.resource_source.index = 0x00;
1035                 output_struct->data.address64.resource_source.string_length = 0;
1036                 output_struct->data.address64.resource_source.string_ptr = NULL;
1037         }
1038 
1039         /*
1040          * Set the Length parameter
1041          */
1042         output_struct->length = (u32) struct_size;
1043 
1044         /*
1045          * Return the final size of the structure
1046          */
1047         *structure_size = struct_size;
1048         return_ACPI_STATUS (AE_OK);
1049 }
1050 
1051 
1052 /*******************************************************************************
1053  *
1054  * FUNCTION:    acpi_rs_address64_stream
1055  *
1056  * PARAMETERS:  linked_list             - Pointer to the resource linked list
1057  *              output_buffer           - Pointer to the user's return buffer
1058  *              bytes_consumed          - Pointer to where the number of bytes
1059  *                                        used in the output_buffer is returned
1060  *
1061  * RETURN:      Status
1062  *
1063  * DESCRIPTION: Take the linked list resource structure and fills in the
1064  *              the appropriate bytes in a byte stream
1065  *
1066  ******************************************************************************/
1067 
1068 acpi_status
1069 acpi_rs_address64_stream (
1070         struct acpi_resource            *linked_list,
1071         u8                              **output_buffer,
1072         acpi_size                       *bytes_consumed)
1073 {
1074         u8                              *buffer;
1075         u16                             *length_field;
1076         u8                              temp8;
1077         char                            *temp_pointer;
1078 
1079 
1080         ACPI_FUNCTION_TRACE ("rs_address64_stream");
1081 
1082 
1083         buffer = *output_buffer;
1084 
1085         /*
1086          * The descriptor field is static
1087          */
1088         *buffer = 0x8A;
1089         buffer += 1;
1090 
1091         /*
1092          * Set a pointer to the Length field - to be filled in later
1093          */
1094         length_field = ACPI_CAST_PTR (u16, buffer);
1095         buffer += 2;
1096 
1097         /*
1098          * Set the Resource Type (Memory, Io, bus_number)
1099          */
1100         temp8 = (u8) (linked_list->data.address64.resource_type & 0x03);
1101 
1102         *buffer = temp8;
1103         buffer += 1;
1104 
1105         /*
1106          * Set the general flags
1107          */
1108         temp8 = (u8) (linked_list->data.address64.producer_consumer & 0x01);
1109         temp8 |= (linked_list->data.address64.decode & 0x01) << 1;
1110         temp8 |= (linked_list->data.address64.min_address_fixed & 0x01) << 2;
1111         temp8 |= (linked_list->data.address64.max_address_fixed & 0x01) << 3;
1112 
1113         *buffer = temp8;
1114         buffer += 1;
1115 
1116         /*
1117          * Set the type specific flags
1118          */
1119         temp8 = 0;
1120 
1121         if (ACPI_MEMORY_RANGE == linked_list->data.address64.resource_type) {
1122                 temp8 = (u8)
1123                         (linked_list->data.address64.attribute.memory.read_write_attribute &
1124                         0x01);
1125 
1126                 temp8 |=
1127                         (linked_list->data.address64.attribute.memory.cache_attribute &
1128                          0x03) << 1;
1129         }
1130         else if (ACPI_IO_RANGE == linked_list->data.address64.resource_type) {
1131                 temp8 = (u8)
1132                         (linked_list->data.address64.attribute.io.range_attribute &
1133                          0x03);
1134                 temp8 |=
1135                         (linked_list->data.address64.attribute.io.range_attribute &
1136                          0x03) << 4;
1137         }
1138 
1139         *buffer = temp8;
1140         buffer += 1;
1141 
1142         /*
1143          * Set the address space granularity
1144          */
1145         ACPI_MOVE_64_TO_64 (buffer, &linked_list->data.address64.granularity);
1146         buffer += 8;
1147 
1148         /*
1149          * Set the address range minimum
1150          */
1151         ACPI_MOVE_64_TO_64 (buffer, &linked_list->data.address64.min_address_range);
1152         buffer += 8;
1153 
1154         /*
1155          * Set the address range maximum
1156          */
1157         ACPI_MOVE_64_TO_64 (buffer, &linked_list->data.address64.max_address_range);
1158         buffer += 8;
1159 
1160         /*
1161          * Set the address translation offset
1162          */
1163         ACPI_MOVE_64_TO_64 (buffer, &linked_list->data.address64.address_translation_offset);
1164         buffer += 8;
1165 
1166         /*
1167          * Set the address length
1168          */
1169         ACPI_MOVE_64_TO_64 (buffer, &linked_list->data.address64.address_length);
1170         buffer += 8;
1171 
1172         /*
1173          * Resource Source Index and Resource Source are optional
1174          */
1175         if (0 != linked_list->data.address64.resource_source.string_length) {
1176                 temp8 = (u8) linked_list->data.address64.resource_source.index;
1177 
1178                 *buffer = temp8;
1179                 buffer += 1;
1180 
1181                 temp_pointer = (char *) buffer;
1182 
1183                 /*
1184                  * Copy the string
1185                  */
1186                 ACPI_STRCPY (temp_pointer, linked_list->data.address64.resource_source.string_ptr);
1187 
1188                 /*
1189                  * Buffer needs to be set to the length of the sting + one for the
1190                  * terminating null
1191                  */
1192                 buffer += (acpi_size)(ACPI_STRLEN (linked_list->data.address64.resource_source.string_ptr) + 1);
1193         }
1194 
1195         /*
1196          * Return the number of bytes consumed in this operation
1197          */
1198         *bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
1199 
1200         /*
1201          * Set the length field to the number of bytes consumed
1202          * minus the header size (3 bytes)
1203          */
1204         *length_field = (u16) (*bytes_consumed - 3);
1205         return_ACPI_STATUS (AE_OK);
1206 }
1207 
1208 
  This page was automatically generated by the LXR engine.