Pull release into acpica branch
[pandora-kernel.git] / drivers / acpi / resources / rsmisc.c
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 #include <acpi/acpi.h>
45 #include <acpi/acresrc.h>
46
47 #define _COMPONENT          ACPI_RESOURCES
48 ACPI_MODULE_NAME("rsmisc")
49
50 /*******************************************************************************
51  *
52  * FUNCTION:    acpi_rs_generic_register_resource
53  *
54  * PARAMETERS:  byte_stream_buffer      - Pointer to the resource input byte
55  *                                        stream
56  *              bytes_consumed          - Pointer to where the number of bytes
57  *                                        consumed the byte_stream_buffer is
58  *                                        returned
59  *              output_buffer           - Pointer to the return data buffer
60  *              structure_size          - Pointer to where the number of bytes
61  *                                        in the return data struct is returned
62  *
63  * RETURN:      Status
64  *
65  * DESCRIPTION: Take the resource byte stream and fill out the appropriate
66  *              structure pointed to by the output_buffer. Return the
67  *              number of bytes consumed from the byte stream.
68  *
69  ******************************************************************************/
70 acpi_status
71 acpi_rs_generic_register_resource(u8 * byte_stream_buffer,
72                                   acpi_size * bytes_consumed,
73                                   u8 ** output_buffer,
74                                   acpi_size * structure_size)
75 {
76         u8 *buffer = byte_stream_buffer;
77         struct acpi_resource *output_struct = (void *)*output_buffer;
78         u16 temp16;
79         u8 temp8;
80         acpi_size struct_size =
81             ACPI_SIZEOF_RESOURCE(struct acpi_resource_generic_reg);
82
83         ACPI_FUNCTION_TRACE("rs_generic_register_resource");
84
85         /* Byte 0 is the Descriptor Type */
86
87         buffer += 1;
88
89         /* Get the Descriptor Length field (Bytes 1-2) */
90
91         ACPI_MOVE_16_TO_16(&temp16, buffer);
92         buffer += 2;
93
94         /* Validate the descriptor length */
95
96         if (temp16 != 12) {
97                 return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH);
98         }
99
100         /* The number of bytes consumed is fixed (12 + 3) */
101
102         *bytes_consumed = 15;
103
104         /* Fill out the structure */
105
106         output_struct->type = ACPI_RSTYPE_GENERIC_REG;
107
108         /* Get space_id (Byte 3) */
109
110         temp8 = *buffer;
111         output_struct->data.generic_reg.space_id = temp8;
112         buffer += 1;
113
114         /* Get register_bit_width (Byte 4) */
115
116         temp8 = *buffer;
117         output_struct->data.generic_reg.bit_width = temp8;
118         buffer += 1;
119
120         /* Get register_bit_offset (Byte 5) */
121
122         temp8 = *buffer;
123         output_struct->data.generic_reg.bit_offset = temp8;
124         buffer += 1;
125
126         /* Get address_size (Byte 6) */
127
128         temp8 = *buffer;
129         output_struct->data.generic_reg.address_size = temp8;
130         buffer += 1;
131
132         /* Get register_address (Bytes 7-14) */
133
134         ACPI_MOVE_64_TO_64(&output_struct->data.generic_reg.address, buffer);
135
136         /* Set the Length parameter */
137
138         output_struct->length = (u32) struct_size;
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  * FUNCTION:    acpi_rs_generic_register_stream
149  *
150  * PARAMETERS:  Resource                - Pointer to the resource linked list
151  *              output_buffer           - Pointer to the user's return buffer
152  *              bytes_consumed          - Pointer to where the number of bytes
153  *                                        used in the output_buffer is returned
154  *
155  * RETURN:      Status
156  *
157  * DESCRIPTION: Take the linked list resource structure and fills in the
158  *              the appropriate bytes in a byte stream
159  *
160  ******************************************************************************/
161
162 acpi_status
163 acpi_rs_generic_register_stream(struct acpi_resource *resource,
164                                 u8 ** output_buffer, acpi_size * bytes_consumed)
165 {
166         u8 *buffer = *output_buffer;
167         u16 temp16;
168
169         ACPI_FUNCTION_TRACE("rs_generic_register_stream");
170
171         /* Set the Descriptor Type (Byte 0) */
172
173         *buffer = ACPI_RDESC_TYPE_GENERIC_REGISTER;
174         buffer += 1;
175
176         /* Set the Descriptor Length (Bytes 1-2) */
177
178         temp16 = 12;
179         ACPI_MOVE_16_TO_16(buffer, &temp16);
180         buffer += 2;
181
182         /* Set space_id (Byte 3) */
183
184         *buffer = (u8) resource->data.generic_reg.space_id;
185         buffer += 1;
186
187         /* Set register_bit_width (Byte 4) */
188
189         *buffer = (u8) resource->data.generic_reg.bit_width;
190         buffer += 1;
191
192         /* Set register_bit_offset (Byte 5) */
193
194         *buffer = (u8) resource->data.generic_reg.bit_offset;
195         buffer += 1;
196
197         /* Set address_size (Byte 6) */
198
199         *buffer = (u8) resource->data.generic_reg.address_size;
200         buffer += 1;
201
202         /* Set register_address (Bytes 7-14) */
203
204         ACPI_MOVE_64_TO_64(buffer, &resource->data.generic_reg.address);
205         buffer += 8;
206
207         /* Return the number of bytes consumed in this operation */
208
209         *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer);
210         return_ACPI_STATUS(AE_OK);
211 }
212
213 /*******************************************************************************
214  *
215  * FUNCTION:    acpi_rs_end_tag_resource
216  *
217  * PARAMETERS:  byte_stream_buffer      - Pointer to the resource input byte
218  *                                        stream
219  *              bytes_consumed          - Pointer to where the number of bytes
220  *                                        consumed the byte_stream_buffer is
221  *                                        returned
222  *              output_buffer           - Pointer to the return data buffer
223  *              structure_size          - Pointer to where the number of bytes
224  *                                        in the return data struct is returned
225  *
226  * RETURN:      Status
227  *
228  * DESCRIPTION: Take the resource byte stream and fill out the appropriate
229  *              structure pointed to by the output_buffer. Return the
230  *              number of bytes consumed from the byte stream.
231  *
232  ******************************************************************************/
233
234 acpi_status
235 acpi_rs_end_tag_resource(u8 * byte_stream_buffer,
236                          acpi_size * bytes_consumed,
237                          u8 ** output_buffer, acpi_size * structure_size)
238 {
239         struct acpi_resource *output_struct = (void *)*output_buffer;
240         acpi_size struct_size = ACPI_RESOURCE_LENGTH;
241
242         ACPI_FUNCTION_TRACE("rs_end_tag_resource");
243
244         /* The number of bytes consumed is static */
245
246         *bytes_consumed = 2;
247
248         /* Fill out the structure */
249
250         output_struct->type = ACPI_RSTYPE_END_TAG;
251
252         /* Set the Length parameter */
253
254         output_struct->length = 0;
255
256         /* Return the final size of the structure */
257
258         *structure_size = struct_size;
259         return_ACPI_STATUS(AE_OK);
260 }
261
262 /*******************************************************************************
263  *
264  * FUNCTION:    acpi_rs_end_tag_stream
265  *
266  * PARAMETERS:  Resource                - Pointer to the resource linked list
267  *              output_buffer           - Pointer to the user's return buffer
268  *              bytes_consumed          - Pointer to where the number of bytes
269  *                                        used in the output_buffer is returned
270  *
271  * RETURN:      Status
272  *
273  * DESCRIPTION: Take the linked list resource structure and fills in the
274  *              the appropriate bytes in a byte stream
275  *
276  ******************************************************************************/
277
278 acpi_status
279 acpi_rs_end_tag_stream(struct acpi_resource *resource,
280                        u8 ** output_buffer, acpi_size * bytes_consumed)
281 {
282         u8 *buffer = *output_buffer;
283         u8 temp8 = 0;
284
285         ACPI_FUNCTION_TRACE("rs_end_tag_stream");
286
287         /* The Descriptor Type field is static */
288
289         *buffer = ACPI_RDESC_TYPE_END_TAG | 0x01;
290         buffer += 1;
291
292         /*
293          * Set the Checksum - zero means that the resource data is treated as if
294          * the checksum operation succeeded (ACPI Spec 1.0b Section 6.4.2.8)
295          */
296         temp8 = 0;
297
298         *buffer = temp8;
299         buffer += 1;
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  * FUNCTION:    acpi_rs_vendor_resource
310  *
311  * PARAMETERS:  byte_stream_buffer      - Pointer to the resource input byte
312  *                                        stream
313  *              bytes_consumed          - Pointer to where the number of bytes
314  *                                        consumed the byte_stream_buffer is
315  *                                        returned
316  *              output_buffer           - Pointer to the return data buffer
317  *              structure_size          - Pointer to where the number of bytes
318  *                                        in the return data struct is returned
319  *
320  * RETURN:      Status
321  *
322  * DESCRIPTION: Take the resource byte stream and fill out the appropriate
323  *              structure pointed to by the output_buffer. Return the
324  *              number of bytes consumed from the byte stream.
325  *
326  ******************************************************************************/
327
328 acpi_status
329 acpi_rs_vendor_resource(u8 * byte_stream_buffer,
330                         acpi_size * bytes_consumed,
331                         u8 ** output_buffer, acpi_size * structure_size)
332 {
333         u8 *buffer = byte_stream_buffer;
334         struct acpi_resource *output_struct = (void *)*output_buffer;
335         u16 temp16 = 0;
336         u8 temp8 = 0;
337         u8 index;
338         acpi_size struct_size =
339             ACPI_SIZEOF_RESOURCE(struct acpi_resource_vendor);
340
341         ACPI_FUNCTION_TRACE("rs_vendor_resource");
342
343         /* Dereference the Descriptor to find if this is a large or small item. */
344
345         temp8 = *buffer;
346
347         if (temp8 & ACPI_RDESC_TYPE_LARGE) {
348                 /* Large Item, point to the length field */
349
350                 buffer += 1;
351
352                 /* Dereference */
353
354                 ACPI_MOVE_16_TO_16(&temp16, buffer);
355
356                 /* Calculate bytes consumed */
357
358                 *bytes_consumed = (acpi_size) temp16 + 3;
359
360                 /* Point to the first vendor byte */
361
362                 buffer += 2;
363         } else {
364                 /* Small Item, dereference the size */
365
366                 temp16 = (u8) (*buffer & 0x07);
367
368                 /* Calculate bytes consumed */
369
370                 *bytes_consumed = (acpi_size) temp16 + 1;
371
372                 /* Point to the first vendor byte */
373
374                 buffer += 1;
375         }
376
377         output_struct->type = ACPI_RSTYPE_VENDOR;
378         output_struct->data.vendor_specific.length = temp16;
379
380         for (index = 0; index < temp16; index++) {
381                 output_struct->data.vendor_specific.reserved[index] = *buffer;
382                 buffer += 1;
383         }
384
385         /*
386          * In order for the struct_size to fall on a 32-bit boundary,
387          * calculate the length of the vendor string and expand the
388          * struct_size to the next 32-bit boundary.
389          */
390         struct_size += ACPI_ROUND_UP_to_32_bITS(temp16);
391
392         /* Set the Length parameter */
393
394         output_struct->length = (u32) struct_size;
395
396         /* Return the final size of the structure */
397
398         *structure_size = struct_size;
399         return_ACPI_STATUS(AE_OK);
400 }
401
402 /*******************************************************************************
403  *
404  * FUNCTION:    acpi_rs_vendor_stream
405  *
406  * PARAMETERS:  Resource                - Pointer to the resource linked list
407  *              output_buffer           - Pointer to the user's return buffer
408  *              bytes_consumed          - Pointer to where the number of bytes
409  *                                        used in the output_buffer is returned
410  *
411  * RETURN:      Status
412  *
413  * DESCRIPTION: Take the linked list resource structure and fills in the
414  *              the appropriate bytes in a byte stream
415  *
416  ******************************************************************************/
417
418 acpi_status
419 acpi_rs_vendor_stream(struct acpi_resource *resource,
420                       u8 ** output_buffer, acpi_size * bytes_consumed)
421 {
422         u8 *buffer = *output_buffer;
423         u16 temp16 = 0;
424         u8 temp8 = 0;
425         u8 index;
426
427         ACPI_FUNCTION_TRACE("rs_vendor_stream");
428
429         /* Dereference the length to find if this is a large or small item. */
430
431         if (resource->data.vendor_specific.length > 7) {
432                 /* Large Item, Set the descriptor field and length bytes */
433
434                 *buffer = ACPI_RDESC_TYPE_LARGE_VENDOR;
435                 buffer += 1;
436
437                 temp16 = (u16) resource->data.vendor_specific.length;
438
439                 ACPI_MOVE_16_TO_16(buffer, &temp16);
440                 buffer += 2;
441         } else {
442                 /* Small Item, Set the descriptor field */
443
444                 temp8 = ACPI_RDESC_TYPE_SMALL_VENDOR;
445                 temp8 |= (u8) resource->data.vendor_specific.length;
446
447                 *buffer = temp8;
448                 buffer += 1;
449         }
450
451         /* Loop through all of the Vendor Specific fields */
452
453         for (index = 0; index < resource->data.vendor_specific.length; index++) {
454                 temp8 = resource->data.vendor_specific.reserved[index];
455
456                 *buffer = temp8;
457                 buffer += 1;
458         }
459
460         /* Return the number of bytes consumed in this operation */
461
462         *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer);
463         return_ACPI_STATUS(AE_OK);
464 }
465
466 /*******************************************************************************
467  *
468  * FUNCTION:    acpi_rs_start_depend_fns_resource
469  *
470  * PARAMETERS:  byte_stream_buffer      - Pointer to the resource input byte
471  *                                        stream
472  *              bytes_consumed          - Pointer to where the number of bytes
473  *                                        consumed the byte_stream_buffer is
474  *                                        returned
475  *              output_buffer           - Pointer to the return data buffer
476  *              structure_size          - Pointer to where the number of bytes
477  *                                        in the return data struct is returned
478  *
479  * RETURN:      Status
480  *
481  * DESCRIPTION: Take the resource byte stream and fill out the appropriate
482  *              structure pointed to by the output_buffer. Return the
483  *              number of bytes consumed from the byte stream.
484  *
485  ******************************************************************************/
486
487 acpi_status
488 acpi_rs_start_depend_fns_resource(u8 * byte_stream_buffer,
489                                   acpi_size * bytes_consumed,
490                                   u8 ** output_buffer,
491                                   acpi_size * structure_size)
492 {
493         u8 *buffer = byte_stream_buffer;
494         struct acpi_resource *output_struct = (void *)*output_buffer;
495         u8 temp8 = 0;
496         acpi_size struct_size =
497             ACPI_SIZEOF_RESOURCE(struct acpi_resource_start_dpf);
498
499         ACPI_FUNCTION_TRACE("rs_start_depend_fns_resource");
500
501         /* The number of bytes consumed are found in the descriptor (Bits:0-1) */
502
503         temp8 = *buffer;
504
505         *bytes_consumed = (temp8 & 0x01) + 1;
506
507         output_struct->type = ACPI_RSTYPE_START_DPF;
508
509         /* Point to Byte 1 if it is used */
510
511         if (2 == *bytes_consumed) {
512                 buffer += 1;
513                 temp8 = *buffer;
514
515                 /* Check Compatibility priority */
516
517                 output_struct->data.start_dpf.compatibility_priority =
518                     temp8 & 0x03;
519
520                 if (3 == output_struct->data.start_dpf.compatibility_priority) {
521                         return_ACPI_STATUS(AE_AML_BAD_RESOURCE_VALUE);
522                 }
523
524                 /* Check Performance/Robustness preference */
525
526                 output_struct->data.start_dpf.performance_robustness =
527                     (temp8 >> 2) & 0x03;
528
529                 if (3 == output_struct->data.start_dpf.performance_robustness) {
530                         return_ACPI_STATUS(AE_AML_BAD_RESOURCE_VALUE);
531                 }
532         } else {
533                 output_struct->data.start_dpf.compatibility_priority =
534                     ACPI_ACCEPTABLE_CONFIGURATION;
535
536                 output_struct->data.start_dpf.performance_robustness =
537                     ACPI_ACCEPTABLE_CONFIGURATION;
538         }
539
540         /* Set the Length parameter */
541
542         output_struct->length = (u32) struct_size;
543
544         /* Return the final size of the structure */
545
546         *structure_size = struct_size;
547         return_ACPI_STATUS(AE_OK);
548 }
549
550 /*******************************************************************************
551  *
552  * FUNCTION:    acpi_rs_end_depend_fns_resource
553  *
554  * PARAMETERS:  byte_stream_buffer      - Pointer to the resource input byte
555  *                                        stream
556  *              bytes_consumed          - Pointer to where the number of bytes
557  *                                        consumed the byte_stream_buffer is
558  *                                        returned
559  *              output_buffer           - Pointer to the return data buffer
560  *              structure_size          - Pointer to where the number of bytes
561  *                                        in the return data struct is returned
562  *
563  * RETURN:      Status
564  *
565  * DESCRIPTION: Take the resource byte stream and fill out the appropriate
566  *              structure pointed to by the output_buffer. Return the
567  *              number of bytes consumed from the byte stream.
568  *
569  ******************************************************************************/
570
571 acpi_status
572 acpi_rs_end_depend_fns_resource(u8 * byte_stream_buffer,
573                                 acpi_size * bytes_consumed,
574                                 u8 ** output_buffer, acpi_size * structure_size)
575 {
576         struct acpi_resource *output_struct = (void *)*output_buffer;
577         acpi_size struct_size = ACPI_RESOURCE_LENGTH;
578
579         ACPI_FUNCTION_TRACE("rs_end_depend_fns_resource");
580
581         /* The number of bytes consumed is static */
582
583         *bytes_consumed = 1;
584
585         /*  Fill out the structure */
586
587         output_struct->type = ACPI_RSTYPE_END_DPF;
588
589         /* Set the Length parameter */
590
591         output_struct->length = (u32) struct_size;
592
593         /* Return the final size of the structure */
594
595         *structure_size = struct_size;
596         return_ACPI_STATUS(AE_OK);
597 }
598
599 /*******************************************************************************
600  *
601  * FUNCTION:    acpi_rs_start_depend_fns_stream
602  *
603  * PARAMETERS:  Resource                - Pointer to the resource linked list
604  *              output_buffer           - Pointer to the user's return buffer
605  *              bytes_consumed          - u32 pointer that is filled with
606  *                                        the number of bytes of the
607  *                                        output_buffer used
608  *
609  * RETURN:      Status
610  *
611  * DESCRIPTION: Take the linked list resource structure and fills in the
612  *              the appropriate bytes in a byte stream
613  *
614  ******************************************************************************/
615
616 acpi_status
617 acpi_rs_start_depend_fns_stream(struct acpi_resource *resource,
618                                 u8 ** output_buffer, acpi_size * bytes_consumed)
619 {
620         u8 *buffer = *output_buffer;
621         u8 temp8 = 0;
622
623         ACPI_FUNCTION_TRACE("rs_start_depend_fns_stream");
624
625         /*
626          * The descriptor type field is set based upon whether a byte is needed
627          * to contain Priority data.
628          */
629         if (ACPI_ACCEPTABLE_CONFIGURATION ==
630             resource->data.start_dpf.compatibility_priority &&
631             ACPI_ACCEPTABLE_CONFIGURATION ==
632             resource->data.start_dpf.performance_robustness) {
633                 *buffer = ACPI_RDESC_TYPE_START_DEPENDENT;
634         } else {
635                 *buffer = ACPI_RDESC_TYPE_START_DEPENDENT | 0x01;
636                 buffer += 1;
637
638                 /* Set the Priority Byte Definition */
639
640                 temp8 = 0;
641                 temp8 = (u8) ((resource->data.start_dpf.performance_robustness &
642                                0x03) << 2);
643                 temp8 |= (resource->data.start_dpf.compatibility_priority &
644                           0x03);
645                 *buffer = temp8;
646         }
647
648         buffer += 1;
649
650         /* Return the number of bytes consumed in this operation */
651
652         *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer);
653         return_ACPI_STATUS(AE_OK);
654 }
655
656 /*******************************************************************************
657  *
658  * FUNCTION:    acpi_rs_end_depend_fns_stream
659  *
660  * PARAMETERS:  Resource                - Pointer to the resource linked list
661  *              output_buffer           - Pointer to the user's return buffer
662  *              bytes_consumed          - Pointer to where the number of bytes
663  *                                        used in the output_buffer is returned
664  *
665  * RETURN:      Status
666  *
667  * DESCRIPTION: Take the linked list resource structure and fills in the
668  *              the appropriate bytes in a byte stream
669  *
670  ******************************************************************************/
671
672 acpi_status
673 acpi_rs_end_depend_fns_stream(struct acpi_resource *resource,
674                               u8 ** output_buffer, acpi_size * bytes_consumed)
675 {
676         u8 *buffer = *output_buffer;
677
678         ACPI_FUNCTION_TRACE("rs_end_depend_fns_stream");
679
680         /* The Descriptor Type field is static */
681
682         *buffer = ACPI_RDESC_TYPE_END_DEPENDENT;
683         buffer += 1;
684
685         /* Return the number of bytes consumed in this operation */
686
687         *bytes_consumed = ACPI_PTR_DIFF(buffer, *output_buffer);
688         return_ACPI_STATUS(AE_OK);
689 }