[ACPI] ACPICA 20050930
[linux-2.6-block.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_get_generic_reg
53  *
54  * PARAMETERS:  Aml                 - Pointer to the AML resource descriptor
55  *              aml_resource_length - Length of the resource from the AML header
56  *              Resource            - Where the internal resource is returned
57  *
58  * RETURN:      Status
59  *
60  * DESCRIPTION: Convert a raw AML resource descriptor to the corresponding
61  *              internal resource descriptor, simplifying bitflags and handling
62  *              alignment and endian issues if necessary.
63  *
64  ******************************************************************************/
65 acpi_status
66 acpi_rs_get_generic_reg(union aml_resource *aml,
67                         u16 aml_resource_length, struct acpi_resource *resource)
68 {
69         ACPI_FUNCTION_TRACE("rs_get_generic_reg");
70
71         /*
72          * Get the following fields from the AML descriptor:
73          * Address Space ID
74          * Register Bit Width
75          * Register Bit Offset
76          * Access Size
77          * Register Address
78          */
79         resource->data.generic_reg.space_id = aml->generic_reg.address_space_id;
80         resource->data.generic_reg.bit_width = aml->generic_reg.bit_width;
81         resource->data.generic_reg.bit_offset = aml->generic_reg.bit_offset;
82         resource->data.generic_reg.access_size = aml->generic_reg.access_size;
83         ACPI_MOVE_64_TO_64(&resource->data.generic_reg.address,
84                            &aml->generic_reg.address);
85
86         /* Complete the resource header */
87
88         resource->type = ACPI_RESOURCE_TYPE_GENERIC_REGISTER;
89         resource->length =
90             ACPI_SIZEOF_RESOURCE(struct acpi_resource_generic_register);
91         return_ACPI_STATUS(AE_OK);
92 }
93
94 /*******************************************************************************
95  *
96  * FUNCTION:    acpi_rs_set_generic_reg
97  *
98  * PARAMETERS:  Resource            - Pointer to the resource descriptor
99  *              Aml                 - Where the AML descriptor is returned
100  *
101  * RETURN:      Status
102  *
103  * DESCRIPTION: Convert an internal resource descriptor to the corresponding
104  *              external AML resource descriptor.
105  *
106  ******************************************************************************/
107
108 acpi_status
109 acpi_rs_set_generic_reg(struct acpi_resource *resource, union aml_resource *aml)
110 {
111         ACPI_FUNCTION_TRACE("rs_set_generic_reg");
112
113         /*
114          * Set the following fields in the AML descriptor:
115          * Address Space ID
116          * Register Bit Width
117          * Register Bit Offset
118          * Access Size
119          * Register Address
120          */
121         aml->generic_reg.address_space_id =
122             (u8) resource->data.generic_reg.space_id;
123         aml->generic_reg.bit_width = (u8) resource->data.generic_reg.bit_width;
124         aml->generic_reg.bit_offset =
125             (u8) resource->data.generic_reg.bit_offset;
126         aml->generic_reg.access_size =
127             (u8) resource->data.generic_reg.access_size;
128         ACPI_MOVE_64_TO_64(&aml->generic_reg.address,
129                            &resource->data.generic_reg.address);
130
131         /* Complete the AML descriptor header */
132
133         acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_GENERIC_REGISTER,
134                                     sizeof(struct
135                                            aml_resource_generic_register), aml);
136         return_ACPI_STATUS(AE_OK);
137 }
138
139 /*******************************************************************************
140  *
141  * FUNCTION:    acpi_rs_get_vendor
142  *
143  * PARAMETERS:  Aml                 - Pointer to the AML resource descriptor
144  *              aml_resource_length - Length of the resource from the AML header
145  *              Resource            - Where the internal resource is returned
146  *
147  * RETURN:      Status
148  *
149  * DESCRIPTION: Convert a raw AML resource descriptor to the corresponding
150  *              internal resource descriptor, simplifying bitflags and handling
151  *              alignment and endian issues if necessary.
152  *
153  ******************************************************************************/
154
155 acpi_status
156 acpi_rs_get_vendor(union aml_resource *aml,
157                    u16 aml_resource_length, struct acpi_resource *resource)
158 {
159         u8 *aml_byte_data;
160
161         ACPI_FUNCTION_TRACE("rs_get_vendor");
162
163         /* Determine if this is a large or small vendor specific item */
164
165         if (aml->large_header.descriptor_type & ACPI_RESOURCE_NAME_LARGE) {
166                 /* Large item, Point to the first vendor byte */
167
168                 aml_byte_data =
169                     ((u8 *) aml) + sizeof(struct aml_resource_large_header);
170         } else {
171                 /* Small item, Point to the first vendor byte */
172
173                 aml_byte_data =
174                     ((u8 *) aml) + sizeof(struct aml_resource_small_header);
175         }
176
177         /* Copy the vendor-specific bytes */
178
179         ACPI_MEMCPY(resource->data.vendor.byte_data,
180                     aml_byte_data, aml_resource_length);
181         resource->data.vendor.byte_length = aml_resource_length;
182
183         /*
184          * In order for the struct_size to fall on a 32-bit boundary,
185          * calculate the length of the vendor string and expand the
186          * struct_size to the next 32-bit boundary.
187          */
188         resource->type = ACPI_RESOURCE_TYPE_VENDOR;
189         resource->length = ACPI_SIZEOF_RESOURCE(struct acpi_resource_vendor) +
190             ACPI_ROUND_UP_to_32_bITS(aml_resource_length);
191         return_ACPI_STATUS(AE_OK);
192 }
193
194 /*******************************************************************************
195  *
196  * FUNCTION:    acpi_rs_set_vendor
197  *
198  * PARAMETERS:  Resource            - Pointer to the resource descriptor
199  *              Aml                 - Where the AML descriptor is returned
200  *
201  * RETURN:      Status
202  *
203  * DESCRIPTION: Convert an internal resource descriptor to the corresponding
204  *              external AML resource descriptor.
205  *
206  ******************************************************************************/
207
208 acpi_status
209 acpi_rs_set_vendor(struct acpi_resource *resource, union aml_resource *aml)
210 {
211         u32 resource_length;
212         u8 *source;
213         u8 *destination;
214
215         ACPI_FUNCTION_TRACE("rs_set_vendor");
216
217         resource_length = resource->data.vendor.byte_length;
218         source = ACPI_CAST_PTR(u8, resource->data.vendor.byte_data);
219
220         /* Length determines if this is a large or small resource */
221
222         if (resource_length > 7) {
223                 /* Large item, get pointer to the data part of the descriptor */
224
225                 destination =
226                     ((u8 *) aml) + sizeof(struct aml_resource_large_header);
227
228                 /* Complete the AML descriptor header */
229
230                 acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_VENDOR_LARGE,
231                                             (u32) (resource_length +
232                                                    sizeof(struct
233                                                           aml_resource_large_header)),
234                                             aml);
235         } else {
236                 /* Small item, get pointer to the data part of the descriptor */
237
238                 destination =
239                     ((u8 *) aml) + sizeof(struct aml_resource_small_header);
240
241                 /* Complete the AML descriptor header */
242
243                 acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_VENDOR_SMALL,
244                                             (u32) (resource_length +
245                                                    sizeof(struct
246                                                           aml_resource_small_header)),
247                                             aml);
248         }
249
250         /* Copy the vendor-specific bytes */
251
252         ACPI_MEMCPY(destination, source, resource_length);
253         return_ACPI_STATUS(AE_OK);
254 }
255
256 /*******************************************************************************
257  *
258  * FUNCTION:    acpi_rs_get_start_dpf
259  *
260  * PARAMETERS:  Aml                 - Pointer to the AML resource descriptor
261  *              aml_resource_length - Length of the resource from the AML header
262  *              Resource            - Where the internal resource is returned
263  *
264  * RETURN:      Status
265  *
266  * DESCRIPTION: Convert a raw AML resource descriptor to the corresponding
267  *              internal resource descriptor, simplifying bitflags and handling
268  *              alignment and endian issues if necessary.
269  *
270  ******************************************************************************/
271
272 acpi_status
273 acpi_rs_get_start_dpf(union aml_resource *aml,
274                       u16 aml_resource_length, struct acpi_resource *resource)
275 {
276         ACPI_FUNCTION_TRACE("rs_get_start_dpf");
277
278         /* Get the flags byte if present */
279
280         if (aml_resource_length == 1) {
281                 /* Get the Compatibility priority */
282
283                 resource->data.start_dpf.compatibility_priority =
284                     (aml->start_dpf.flags & 0x03);
285
286                 if (resource->data.start_dpf.compatibility_priority >= 3) {
287                         return_ACPI_STATUS(AE_AML_BAD_RESOURCE_VALUE);
288                 }
289
290                 /* Get the Performance/Robustness preference */
291
292                 resource->data.start_dpf.performance_robustness =
293                     ((aml->start_dpf.flags >> 2) & 0x03);
294
295                 if (resource->data.start_dpf.performance_robustness >= 3) {
296                         return_ACPI_STATUS(AE_AML_BAD_RESOURCE_VALUE);
297                 }
298         } else {
299                 /* start_dependent_no_pri(), no flags byte, set defaults */
300
301                 resource->data.start_dpf.compatibility_priority =
302                     ACPI_ACCEPTABLE_CONFIGURATION;
303
304                 resource->data.start_dpf.performance_robustness =
305                     ACPI_ACCEPTABLE_CONFIGURATION;
306         }
307
308         /* Complete the resource header */
309
310         resource->type = ACPI_RESOURCE_TYPE_START_DEPENDENT;
311         resource->length =
312             ACPI_SIZEOF_RESOURCE(struct acpi_resource_start_dependent);
313         return_ACPI_STATUS(AE_OK);
314 }
315
316 /*******************************************************************************
317  *
318  * FUNCTION:    acpi_rs_set_start_dpf
319  *
320  * PARAMETERS:  Resource            - Pointer to the resource descriptor
321  *              Aml                 - Where the AML descriptor is returned
322  *
323  * RETURN:      Status
324  *
325  * DESCRIPTION: Convert an internal resource descriptor to the corresponding
326  *              external AML resource descriptor.
327  *
328  ******************************************************************************/
329
330 acpi_status
331 acpi_rs_set_start_dpf(struct acpi_resource *resource, union aml_resource *aml)
332 {
333         ACPI_FUNCTION_TRACE("rs_set_start_dpf");
334
335         /*
336          * The descriptor type field is set based upon whether a byte is needed
337          * to contain Priority data.
338          */
339         if (ACPI_ACCEPTABLE_CONFIGURATION ==
340             resource->data.start_dpf.compatibility_priority &&
341             ACPI_ACCEPTABLE_CONFIGURATION ==
342             resource->data.start_dpf.performance_robustness) {
343                 acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_START_DEPENDENT,
344                                             sizeof(struct
345                                                    aml_resource_start_dependent_noprio),
346                                             aml);
347         } else {
348                 acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_START_DEPENDENT,
349                                             sizeof(struct
350                                                    aml_resource_start_dependent),
351                                             aml);
352
353                 /* Set the Flags byte */
354
355                 aml->start_dpf.flags = (u8)
356                     (((resource->data.start_dpf.
357                        performance_robustness & 0x03) << 2) | (resource->data.
358                                                                start_dpf.
359                                                                compatibility_priority
360                                                                & 0x03));
361         }
362         return_ACPI_STATUS(AE_OK);
363 }
364
365 /*******************************************************************************
366  *
367  * FUNCTION:    acpi_rs_get_end_dpf
368  *
369  * PARAMETERS:  Aml                 - Pointer to the AML resource descriptor
370  *              aml_resource_length - Length of the resource from the AML header
371  *              Resource            - Where the internal resource is returned
372  *
373  * RETURN:      Status
374  *
375  * DESCRIPTION: Convert a raw AML resource descriptor to the corresponding
376  *              internal resource descriptor, simplifying bitflags and handling
377  *              alignment and endian issues if necessary.
378  *
379  ******************************************************************************/
380
381 acpi_status
382 acpi_rs_get_end_dpf(union aml_resource *aml,
383                     u16 aml_resource_length, struct acpi_resource *resource)
384 {
385         ACPI_FUNCTION_TRACE("rs_get_end_dpf");
386
387         /* Complete the resource header */
388
389         resource->type = ACPI_RESOURCE_TYPE_END_DEPENDENT;
390         resource->length = (u32) ACPI_RESOURCE_LENGTH;
391         return_ACPI_STATUS(AE_OK);
392 }
393
394 /*******************************************************************************
395  *
396  * FUNCTION:    acpi_rs_set_end_dpf
397  *
398  * PARAMETERS:  Resource            - Pointer to the resource descriptor
399  *              Aml                 - Where the AML descriptor is returned
400  *
401  * RETURN:      Status
402  *
403  * DESCRIPTION: Convert an internal resource descriptor to the corresponding
404  *              external AML resource descriptor.
405  *
406  ******************************************************************************/
407
408 acpi_status
409 acpi_rs_set_end_dpf(struct acpi_resource *resource, union aml_resource *aml)
410 {
411         ACPI_FUNCTION_TRACE("rs_set_end_dpf");
412
413         /* Complete the AML descriptor header */
414
415         acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_END_DEPENDENT,
416                                     sizeof(struct aml_resource_end_dependent),
417                                     aml);
418         return_ACPI_STATUS(AE_OK);
419 }
420
421 /*******************************************************************************
422  *
423  * FUNCTION:    acpi_rs_get_end_tag
424  *
425  * PARAMETERS:  Aml                 - Pointer to the AML resource descriptor
426  *              aml_resource_length - Length of the resource from the AML header
427  *              Resource            - Where the internal resource is returned
428  *
429  * RETURN:      Status
430  *
431  * DESCRIPTION: Convert a raw AML resource descriptor to the corresponding
432  *              internal resource descriptor, simplifying bitflags and handling
433  *              alignment and endian issues if necessary.
434  *
435  ******************************************************************************/
436
437 acpi_status
438 acpi_rs_get_end_tag(union aml_resource *aml,
439                     u16 aml_resource_length, struct acpi_resource *resource)
440 {
441         ACPI_FUNCTION_TRACE("rs_get_end_tag");
442
443         /* Complete the resource header */
444
445         resource->type = ACPI_RESOURCE_TYPE_END_TAG;
446         resource->length = ACPI_RESOURCE_LENGTH;
447         return_ACPI_STATUS(AE_OK);
448 }
449
450 /*******************************************************************************
451  *
452  * FUNCTION:    acpi_rs_set_end_tag
453  *
454  * PARAMETERS:  Resource            - Pointer to the resource descriptor
455  *              Aml                 - Where the AML descriptor is returned
456  *
457  * RETURN:      Status
458  *
459  * DESCRIPTION: Convert an internal resource descriptor to the corresponding
460  *              external AML resource descriptor.
461  *
462  ******************************************************************************/
463
464 acpi_status
465 acpi_rs_set_end_tag(struct acpi_resource *resource, union aml_resource *aml)
466 {
467         ACPI_FUNCTION_TRACE("rs_set_end_tag");
468
469         /*
470          * Set the Checksum - zero means that the resource data is treated as if
471          * the checksum operation succeeded (ACPI Spec 1.0b Section 6.4.2.8)
472          */
473         aml->end_tag.checksum = 0;
474
475         /* Complete the AML descriptor header */
476
477         acpi_rs_set_resource_header(ACPI_RESOURCE_NAME_END_TAG,
478                                     sizeof(struct aml_resource_end_tag), aml);
479         return_ACPI_STATUS(AE_OK);
480 }