ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / drivers / acpi / resources / rsmisc.c
1 /*******************************************************************************
2  *
3  * Module Name: rsmisc - Miscellaneous resource descriptors
4  *
5  ******************************************************************************/
6
7 /*
8  * Copyright (C) 2000 - 2004, R. Byron Moore
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions, and the following disclaimer,
16  *    without modification.
17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18  *    substantially similar to the "NO WARRANTY" disclaimer below
19  *    ("Disclaimer") and any redistribution must be conditioned upon
20  *    including a substantially similar Disclaimer requirement for further
21  *    binary redistribution.
22  * 3. Neither the names of the above-listed copyright holders nor the names
23  *    of any contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * Alternatively, this software may be distributed under the terms of the
27  * GNU General Public License ("GPL") version 2 as published by the Free
28  * Software Foundation.
29  *
30  * NO WARRANTY
31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41  * POSSIBILITY OF SUCH DAMAGES.
42  */
43
44
45 #include <acpi/acpi.h>
46 #include <acpi/acresrc.h>
47
48 #define _COMPONENT          ACPI_RESOURCES
49          ACPI_MODULE_NAME    ("rsmisc")
50
51
52 /*******************************************************************************
53  *
54  * FUNCTION:    acpi_rs_end_tag_resource
55  *
56  * PARAMETERS:  byte_stream_buffer      - Pointer to the resource input byte
57  *                                        stream
58  *              bytes_consumed          - Pointer to where the number of bytes
59  *                                        consumed the byte_stream_buffer is
60  *                                        returned
61  *              output_buffer           - Pointer to the return data buffer
62  *              structure_size          - Pointer to where the number of bytes
63  *                                        in the return data struct is returned
64  *
65  * RETURN:      Status
66  *
67  * DESCRIPTION: Take the resource byte stream and fill out the appropriate
68  *              structure pointed to by the output_buffer. Return the
69  *              number of bytes consumed from the byte stream.
70  *
71  ******************************************************************************/
72
73 acpi_status
74 acpi_rs_end_tag_resource (
75         u8                              *byte_stream_buffer,
76         acpi_size                       *bytes_consumed,
77         u8                              **output_buffer,
78         acpi_size                       *structure_size)
79 {
80         struct acpi_resource            *output_struct = (void *) *output_buffer;
81         acpi_size                       struct_size = ACPI_RESOURCE_LENGTH;
82
83
84         ACPI_FUNCTION_TRACE ("rs_end_tag_resource");
85
86
87         /*
88          * The number of bytes consumed is static
89          */
90         *bytes_consumed = 2;
91
92         /*
93          *  Fill out the structure
94          */
95         output_struct->id = ACPI_RSTYPE_END_TAG;
96
97         /*
98          * Set the Length parameter
99          */
100         output_struct->length = 0;
101
102         /*
103          * Return the final size of the structure
104          */
105         *structure_size = struct_size;
106         return_ACPI_STATUS (AE_OK);
107 }
108
109
110 /*******************************************************************************
111  *
112  * FUNCTION:    acpi_rs_end_tag_stream
113  *
114  * PARAMETERS:  linked_list             - Pointer to the resource linked list
115  *              output_buffer           - Pointer to the user's return buffer
116  *              bytes_consumed          - Pointer to where the number of bytes
117  *                                        used in the output_buffer is returned
118  *
119  * RETURN:      Status
120  *
121  * DESCRIPTION: Take the linked list resource structure and fills in the
122  *              the appropriate bytes in a byte stream
123  *
124  ******************************************************************************/
125
126 acpi_status
127 acpi_rs_end_tag_stream (
128         struct acpi_resource            *linked_list,
129         u8                              **output_buffer,
130         acpi_size                       *bytes_consumed)
131 {
132         u8                              *buffer = *output_buffer;
133         u8                              temp8 = 0;
134
135
136         ACPI_FUNCTION_TRACE ("rs_end_tag_stream");
137
138
139         /*
140          * The descriptor field is static
141          */
142         *buffer = 0x79;
143         buffer += 1;
144
145         /*
146          * Set the Checksum - zero means that the resource data is treated as if
147          * the checksum operation succeeded (ACPI Spec 1.0b Section 6.4.2.8)
148          */
149         temp8 = 0;
150
151         *buffer = temp8;
152         buffer += 1;
153
154         /*
155          * Return the number of bytes consumed in this operation
156          */
157         *bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
158         return_ACPI_STATUS (AE_OK);
159 }
160
161
162 /*******************************************************************************
163  *
164  * FUNCTION:    acpi_rs_vendor_resource
165  *
166  * PARAMETERS:  byte_stream_buffer      - Pointer to the resource input byte
167  *                                        stream
168  *              bytes_consumed          - Pointer to where the number of bytes
169  *                                        consumed the byte_stream_buffer is
170  *                                        returned
171  *              output_buffer           - Pointer to the return data buffer
172  *              structure_size          - Pointer to where the number of bytes
173  *                                        in the return data struct is returned
174  *
175  * RETURN:      Status
176  *
177  * DESCRIPTION: Take the resource byte stream and fill out the appropriate
178  *              structure pointed to by the output_buffer. Return the
179  *              number of bytes consumed from the byte stream.
180  *
181  ******************************************************************************/
182
183 acpi_status
184 acpi_rs_vendor_resource (
185         u8                              *byte_stream_buffer,
186         acpi_size                       *bytes_consumed,
187         u8                              **output_buffer,
188         acpi_size                       *structure_size)
189 {
190         u8                              *buffer = byte_stream_buffer;
191         struct acpi_resource            *output_struct = (void *) *output_buffer;
192         u16                             temp16 = 0;
193         u8                              temp8 = 0;
194         u8                              index;
195         acpi_size                       struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_vendor);
196
197
198         ACPI_FUNCTION_TRACE ("rs_vendor_resource");
199
200
201         /*
202          * Dereference the Descriptor to find if this is a large or small item.
203          */
204         temp8 = *buffer;
205
206         if (temp8 & 0x80) {
207                 /*
208                  * Large Item, point to the length field
209                  */
210                 buffer += 1;
211
212                 /* Dereference */
213
214                 ACPI_MOVE_16_TO_16 (&temp16, buffer);
215
216                 /* Calculate bytes consumed */
217
218                 *bytes_consumed = (acpi_size) temp16 + 3;
219
220                 /* Point to the first vendor byte */
221
222                 buffer += 2;
223         }
224         else {
225                 /*
226                  * Small Item, dereference the size
227                  */
228                 temp16 = (u8)(*buffer & 0x07);
229
230                 /* Calculate bytes consumed */
231
232                 *bytes_consumed = (acpi_size) temp16 + 1;
233
234                 /* Point to the first vendor byte */
235
236                 buffer += 1;
237         }
238
239         output_struct->id = ACPI_RSTYPE_VENDOR;
240         output_struct->data.vendor_specific.length = temp16;
241
242         for (index = 0; index < temp16; index++) {
243                 output_struct->data.vendor_specific.reserved[index] = *buffer;
244                 buffer += 1;
245         }
246
247         /*
248          * In order for the struct_size to fall on a 32-bit boundary,
249          * calculate the length of the vendor string and expand the
250          * struct_size to the next 32-bit boundary.
251          */
252         struct_size += ACPI_ROUND_UP_to_32_bITS (temp16);
253
254         /*
255          * Set the Length parameter
256          */
257         output_struct->length = (u32) struct_size;
258
259         /*
260          * Return the final size of the structure
261          */
262         *structure_size = struct_size;
263         return_ACPI_STATUS (AE_OK);
264 }
265
266
267 /*******************************************************************************
268  *
269  * FUNCTION:    acpi_rs_vendor_stream
270  *
271  * PARAMETERS:  linked_list             - Pointer to the resource linked list
272  *              output_buffer           - Pointer to the user's return buffer
273  *              bytes_consumed          - Pointer to where the number of bytes
274  *                                        used in the output_buffer is returned
275  *
276  * RETURN:      Status
277  *
278  * DESCRIPTION: Take the linked list resource structure and fills in the
279  *              the appropriate bytes in a byte stream
280  *
281  ******************************************************************************/
282
283 acpi_status
284 acpi_rs_vendor_stream (
285         struct acpi_resource            *linked_list,
286         u8                              **output_buffer,
287         acpi_size                       *bytes_consumed)
288 {
289         u8                              *buffer = *output_buffer;
290         u16                             temp16 = 0;
291         u8                              temp8 = 0;
292         u8                              index;
293
294
295         ACPI_FUNCTION_TRACE ("rs_vendor_stream");
296
297
298         /*
299          * Dereference the length to find if this is a large or small item.
300          */
301         if(linked_list->data.vendor_specific.length > 7) {
302                 /*
303                  * Large Item, Set the descriptor field and length bytes
304                  */
305                 *buffer = 0x84;
306                 buffer += 1;
307
308                 temp16 = (u16) linked_list->data.vendor_specific.length;
309
310                 ACPI_MOVE_16_TO_16 (buffer, &temp16);
311                 buffer += 2;
312         }
313         else {
314                 /*
315                  * Small Item, Set the descriptor field
316                  */
317                 temp8 = 0x70;
318                 temp8 |= (u8) linked_list->data.vendor_specific.length;
319
320                 *buffer = temp8;
321                 buffer += 1;
322         }
323
324         /*
325          * Loop through all of the Vendor Specific fields
326          */
327         for (index = 0; index < linked_list->data.vendor_specific.length; index++) {
328                 temp8 = linked_list->data.vendor_specific.reserved[index];
329
330                 *buffer = temp8;
331                 buffer += 1;
332         }
333
334         /*
335          * Return the number of bytes consumed in this operation
336          */
337         *bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
338         return_ACPI_STATUS (AE_OK);
339 }
340
341
342 /*******************************************************************************
343  *
344  * FUNCTION:    acpi_rs_start_depend_fns_resource
345  *
346  * PARAMETERS:  byte_stream_buffer      - Pointer to the resource input byte
347  *                                        stream
348  *              bytes_consumed          - Pointer to where the number of bytes
349  *                                        consumed the byte_stream_buffer is
350  *                                        returned
351  *              output_buffer           - Pointer to the return data buffer
352  *              structure_size          - Pointer to where the number of bytes
353  *                                        in the return data struct is returned
354  *
355  * RETURN:      Status
356  *
357  * DESCRIPTION: Take the resource byte stream and fill out the appropriate
358  *              structure pointed to by the output_buffer. Return the
359  *              number of bytes consumed from the byte stream.
360  *
361  ******************************************************************************/
362
363 acpi_status
364 acpi_rs_start_depend_fns_resource (
365         u8                              *byte_stream_buffer,
366         acpi_size                       *bytes_consumed,
367         u8                              **output_buffer,
368         acpi_size                       *structure_size)
369 {
370         u8                              *buffer = byte_stream_buffer;
371         struct acpi_resource            *output_struct = (void *) *output_buffer;
372         u8                              temp8 = 0;
373         acpi_size                       struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_start_dpf);
374
375
376         ACPI_FUNCTION_TRACE ("rs_start_depend_fns_resource");
377
378
379         /*
380          * The number of bytes consumed are contained in the descriptor (Bits:0-1)
381          */
382         temp8 = *buffer;
383
384         *bytes_consumed = (temp8 & 0x01) + 1;
385
386         output_struct->id = ACPI_RSTYPE_START_DPF;
387
388         /*
389          * Point to Byte 1 if it is used
390          */
391         if (2 == *bytes_consumed) {
392                 buffer += 1;
393                 temp8 = *buffer;
394
395                 /*
396                  * Check Compatibility priority
397                  */
398                 output_struct->data.start_dpf.compatibility_priority = temp8 & 0x03;
399
400                 if (3 == output_struct->data.start_dpf.compatibility_priority) {
401                         return_ACPI_STATUS (AE_AML_BAD_RESOURCE_VALUE);
402                 }
403
404                 /*
405                  * Check Performance/Robustness preference
406                  */
407                 output_struct->data.start_dpf.performance_robustness = (temp8 >> 2) & 0x03;
408
409                 if (3 == output_struct->data.start_dpf.performance_robustness) {
410                         return_ACPI_STATUS (AE_AML_BAD_RESOURCE_VALUE);
411                 }
412         }
413         else {
414                 output_struct->data.start_dpf.compatibility_priority =
415                                 ACPI_ACCEPTABLE_CONFIGURATION;
416
417                 output_struct->data.start_dpf.performance_robustness =
418                                 ACPI_ACCEPTABLE_CONFIGURATION;
419         }
420
421         /*
422          * Set the Length parameter
423          */
424         output_struct->length = (u32) struct_size;
425
426         /*
427          * Return the final size of the structure
428          */
429         *structure_size = struct_size;
430         return_ACPI_STATUS (AE_OK);
431 }
432
433
434 /*******************************************************************************
435  *
436  * FUNCTION:    acpi_rs_end_depend_fns_resource
437  *
438  * PARAMETERS:  byte_stream_buffer      - Pointer to the resource input byte
439  *                                        stream
440  *              bytes_consumed          - Pointer to where the number of bytes
441  *                                        consumed the byte_stream_buffer is
442  *                                        returned
443  *              output_buffer           - Pointer to the return data buffer
444  *              structure_size          - Pointer to where the number of bytes
445  *                                        in the return data struct is returned
446  *
447  * RETURN:      Status
448  *
449  * DESCRIPTION: Take the resource byte stream and fill out the appropriate
450  *              structure pointed to by the output_buffer. Return the
451  *              number of bytes consumed from the byte stream.
452  *
453  ******************************************************************************/
454
455 acpi_status
456 acpi_rs_end_depend_fns_resource (
457         u8                              *byte_stream_buffer,
458         acpi_size                       *bytes_consumed,
459         u8                              **output_buffer,
460         acpi_size                       *structure_size)
461 {
462         struct acpi_resource            *output_struct = (void *) *output_buffer;
463         acpi_size                       struct_size = ACPI_RESOURCE_LENGTH;
464
465
466         ACPI_FUNCTION_TRACE ("rs_end_depend_fns_resource");
467
468
469         /*
470          * The number of bytes consumed is static
471          */
472         *bytes_consumed = 1;
473
474         /*
475          *  Fill out the structure
476          */
477         output_struct->id = ACPI_RSTYPE_END_DPF;
478
479         /*
480          * Set the Length parameter
481          */
482         output_struct->length = (u32) struct_size;
483
484         /*
485          * Return the final size of the structure
486          */
487         *structure_size = struct_size;
488         return_ACPI_STATUS (AE_OK);
489 }
490
491
492 /*******************************************************************************
493  *
494  * FUNCTION:    acpi_rs_start_depend_fns_stream
495  *
496  * PARAMETERS:  linked_list             - Pointer to the resource linked list
497  *              output_buffer           - Pointer to the user's return buffer
498  *              bytes_consumed          - u32 pointer that is filled with
499  *                                        the number of bytes of the
500  *                                        output_buffer used
501  *
502  * RETURN:      Status
503  *
504  * DESCRIPTION: Take the linked list resource structure and fills in the
505  *              the appropriate bytes in a byte stream
506  *
507  ******************************************************************************/
508
509 acpi_status
510 acpi_rs_start_depend_fns_stream (
511         struct acpi_resource            *linked_list,
512         u8                              **output_buffer,
513         acpi_size                       *bytes_consumed)
514 {
515         u8                              *buffer = *output_buffer;
516         u8                              temp8 = 0;
517
518
519         ACPI_FUNCTION_TRACE ("rs_start_depend_fns_stream");
520
521
522         /*
523          * The descriptor field is set based upon whether a byte is needed
524          * to contain Priority data.
525          */
526         if (ACPI_ACCEPTABLE_CONFIGURATION ==
527                         linked_list->data.start_dpf.compatibility_priority &&
528                 ACPI_ACCEPTABLE_CONFIGURATION ==
529                         linked_list->data.start_dpf.performance_robustness) {
530                 *buffer = 0x30;
531         }
532         else {
533                 *buffer = 0x31;
534                 buffer += 1;
535
536                 /*
537                  * Set the Priority Byte Definition
538                  */
539                 temp8 = 0;
540                 temp8 = (u8) ((linked_list->data.start_dpf.performance_robustness &
541                                    0x03) << 2);
542                 temp8 |= (linked_list->data.start_dpf.compatibility_priority &
543                                    0x03);
544                 *buffer = temp8;
545         }
546
547         buffer += 1;
548
549         /*
550          * Return the number of bytes consumed in this operation
551          */
552         *bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
553         return_ACPI_STATUS (AE_OK);
554 }
555
556
557 /*******************************************************************************
558  *
559  * FUNCTION:    acpi_rs_end_depend_fns_stream
560  *
561  * PARAMETERS:  linked_list             - Pointer to the resource linked list
562  *              output_buffer           - Pointer to the user's return buffer
563  *              bytes_consumed          - Pointer to where the number of bytes
564  *                                        used in the output_buffer is returned
565  *
566  * RETURN:      Status
567  *
568  * DESCRIPTION: Take the linked list resource structure and fills in the
569  *              the appropriate bytes in a byte stream
570  *
571  ******************************************************************************/
572
573 acpi_status
574 acpi_rs_end_depend_fns_stream (
575         struct acpi_resource            *linked_list,
576         u8                              **output_buffer,
577         acpi_size                       *bytes_consumed)
578 {
579         u8                              *buffer = *output_buffer;
580
581
582         ACPI_FUNCTION_TRACE ("rs_end_depend_fns_stream");
583
584
585         /*
586          * The descriptor field is static
587          */
588         *buffer = 0x38;
589         buffer += 1;
590
591         /*
592          * Return the number of bytes consumed in this operation
593          */
594         *bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
595         return_ACPI_STATUS (AE_OK);
596 }
597