Merge /spare/repo/linux-2.6/
[pandora-kernel.git] / drivers / acpi / resources / rsxface.c
1 /*******************************************************************************
2  *
3  * Module Name: rsxface - Public interfaces to the resource manager
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 <linux/module.h>
45
46 #include <acpi/acpi.h>
47 #include <acpi/acresrc.h>
48
49 #define _COMPONENT          ACPI_RESOURCES
50 ACPI_MODULE_NAME("rsxface")
51
52 /* Local macros for 16,32-bit to 64-bit conversion */
53 #define ACPI_COPY_FIELD(out, in, field)  ((out)->field = (in)->field)
54 #define ACPI_COPY_ADDRESS(out, in)                      \
55         ACPI_COPY_FIELD(out, in, resource_type);             \
56         ACPI_COPY_FIELD(out, in, producer_consumer);         \
57         ACPI_COPY_FIELD(out, in, decode);                    \
58         ACPI_COPY_FIELD(out, in, min_address_fixed);         \
59         ACPI_COPY_FIELD(out, in, max_address_fixed);         \
60         ACPI_COPY_FIELD(out, in, attribute);                 \
61         ACPI_COPY_FIELD(out, in, granularity);               \
62         ACPI_COPY_FIELD(out, in, min_address_range);         \
63         ACPI_COPY_FIELD(out, in, max_address_range);         \
64         ACPI_COPY_FIELD(out, in, address_translation_offset); \
65         ACPI_COPY_FIELD(out, in, address_length);            \
66         ACPI_COPY_FIELD(out, in, resource_source);
67 /*******************************************************************************
68  *
69  * FUNCTION:    acpi_get_irq_routing_table
70  *
71  * PARAMETERS:  device_handle   - a handle to the Bus device we are querying
72  *              ret_buffer      - a pointer to a buffer to receive the
73  *                                current resources for the device
74  *
75  * RETURN:      Status
76  *
77  * DESCRIPTION: This function is called to get the IRQ routing table for a
78  *              specific bus.  The caller must first acquire a handle for the
79  *              desired bus.  The routine table is placed in the buffer pointed
80  *              to by the ret_buffer variable parameter.
81  *
82  *              If the function fails an appropriate status will be returned
83  *              and the value of ret_buffer is undefined.
84  *
85  *              This function attempts to execute the _PRT method contained in
86  *              the object indicated by the passed device_handle.
87  *
88  ******************************************************************************/
89 acpi_status
90 acpi_get_irq_routing_table(acpi_handle device_handle,
91                            struct acpi_buffer *ret_buffer)
92 {
93         acpi_status status;
94
95         ACPI_FUNCTION_TRACE("acpi_get_irq_routing_table ");
96
97         /*
98          * Must have a valid handle and buffer, So we have to have a handle
99          * and a return buffer structure, and if there is a non-zero buffer length
100          * we also need a valid pointer in the buffer. If it's a zero buffer length,
101          * we'll be returning the needed buffer size, so keep going.
102          */
103         if (!device_handle) {
104                 return_ACPI_STATUS(AE_BAD_PARAMETER);
105         }
106
107         status = acpi_ut_validate_buffer(ret_buffer);
108         if (ACPI_FAILURE(status)) {
109                 return_ACPI_STATUS(status);
110         }
111
112         status = acpi_rs_get_prt_method_data(device_handle, ret_buffer);
113         return_ACPI_STATUS(status);
114 }
115
116 /*******************************************************************************
117  *
118  * FUNCTION:    acpi_get_current_resources
119  *
120  * PARAMETERS:  device_handle   - a handle to the device object for the
121  *                                device we are querying
122  *              ret_buffer      - a pointer to a buffer to receive the
123  *                                current resources for the device
124  *
125  * RETURN:      Status
126  *
127  * DESCRIPTION: This function is called to get the current resources for a
128  *              specific device.  The caller must first acquire a handle for
129  *              the desired device.  The resource data is placed in the buffer
130  *              pointed to by the ret_buffer variable parameter.
131  *
132  *              If the function fails an appropriate status will be returned
133  *              and the value of ret_buffer is undefined.
134  *
135  *              This function attempts to execute the _CRS method contained in
136  *              the object indicated by the passed device_handle.
137  *
138  ******************************************************************************/
139
140 acpi_status
141 acpi_get_current_resources(acpi_handle device_handle,
142                            struct acpi_buffer *ret_buffer)
143 {
144         acpi_status status;
145
146         ACPI_FUNCTION_TRACE("acpi_get_current_resources");
147
148         /*
149          * Must have a valid handle and buffer, So we have to have a handle
150          * and a return buffer structure, and if there is a non-zero buffer length
151          * we also need a valid pointer in the buffer. If it's a zero buffer length,
152          * we'll be returning the needed buffer size, so keep going.
153          */
154         if (!device_handle) {
155                 return_ACPI_STATUS(AE_BAD_PARAMETER);
156         }
157
158         status = acpi_ut_validate_buffer(ret_buffer);
159         if (ACPI_FAILURE(status)) {
160                 return_ACPI_STATUS(status);
161         }
162
163         status = acpi_rs_get_crs_method_data(device_handle, ret_buffer);
164         return_ACPI_STATUS(status);
165 }
166
167 EXPORT_SYMBOL(acpi_get_current_resources);
168
169 /*******************************************************************************
170  *
171  * FUNCTION:    acpi_get_possible_resources
172  *
173  * PARAMETERS:  device_handle   - a handle to the device object for the
174  *                                device we are querying
175  *              ret_buffer      - a pointer to a buffer to receive the
176  *                                resources for the device
177  *
178  * RETURN:      Status
179  *
180  * DESCRIPTION: This function is called to get a list of the possible resources
181  *              for a specific device.  The caller must first acquire a handle
182  *              for the desired device.  The resource data is placed in the
183  *              buffer pointed to by the ret_buffer variable.
184  *
185  *              If the function fails an appropriate status will be returned
186  *              and the value of ret_buffer is undefined.
187  *
188  ******************************************************************************/
189
190 #ifdef ACPI_FUTURE_USAGE
191 acpi_status
192 acpi_get_possible_resources(acpi_handle device_handle,
193                             struct acpi_buffer *ret_buffer)
194 {
195         acpi_status status;
196
197         ACPI_FUNCTION_TRACE("acpi_get_possible_resources");
198
199         /*
200          * Must have a valid handle and buffer, So we have to have a handle
201          * and a return buffer structure, and if there is a non-zero buffer length
202          * we also need a valid pointer in the buffer. If it's a zero buffer length,
203          * we'll be returning the needed buffer size, so keep going.
204          */
205         if (!device_handle) {
206                 return_ACPI_STATUS(AE_BAD_PARAMETER);
207         }
208
209         status = acpi_ut_validate_buffer(ret_buffer);
210         if (ACPI_FAILURE(status)) {
211                 return_ACPI_STATUS(status);
212         }
213
214         status = acpi_rs_get_prs_method_data(device_handle, ret_buffer);
215         return_ACPI_STATUS(status);
216 }
217
218 EXPORT_SYMBOL(acpi_get_possible_resources);
219 #endif                          /*  ACPI_FUTURE_USAGE  */
220
221 /*******************************************************************************
222  *
223  * FUNCTION:    acpi_walk_resources
224  *
225  * PARAMETERS:  device_handle   - a handle to the device object for the
226  *                                device we are querying
227  *              Path            - method name of the resources we want
228  *                                (METHOD_NAME__CRS or METHOD_NAME__PRS)
229  *              user_function   - called for each resource
230  *              Context         - passed to user_function
231  *
232  * RETURN:      Status
233  *
234  * DESCRIPTION: Retrieves the current or possible resource list for the
235  *              specified device.  The user_function is called once for
236  *              each resource in the list.
237  *
238  ******************************************************************************/
239
240 acpi_status
241 acpi_walk_resources(acpi_handle device_handle,
242                     char *path,
243                     ACPI_WALK_RESOURCE_CALLBACK user_function, void *context)
244 {
245         acpi_status status;
246         struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
247         struct acpi_resource *resource;
248         struct acpi_resource *buffer_end;
249
250         ACPI_FUNCTION_TRACE("acpi_walk_resources");
251
252         if (!device_handle ||
253             (ACPI_STRNCMP(path, METHOD_NAME__CRS, sizeof(METHOD_NAME__CRS)) &&
254              ACPI_STRNCMP(path, METHOD_NAME__PRS, sizeof(METHOD_NAME__PRS)))) {
255                 return_ACPI_STATUS(AE_BAD_PARAMETER);
256         }
257
258         status = acpi_rs_get_method_data(device_handle, path, &buffer);
259         if (ACPI_FAILURE(status)) {
260                 return_ACPI_STATUS(status);
261         }
262
263         /* Setup pointers */
264
265         resource = (struct acpi_resource *)buffer.pointer;
266         buffer_end = ACPI_CAST_PTR(struct acpi_resource,
267                                    ((u8 *) buffer.pointer + buffer.length));
268
269         /* Walk the resource list */
270
271         for (;;) {
272                 if (!resource || resource->id == ACPI_RSTYPE_END_TAG) {
273                         break;
274                 }
275
276                 status = user_function(resource, context);
277
278                 switch (status) {
279                 case AE_OK:
280                 case AE_CTRL_DEPTH:
281
282                         /* Just keep going */
283
284                         status = AE_OK;
285                         break;
286
287                 case AE_CTRL_TERMINATE:
288
289                         /* Exit now, with OK stats */
290
291                         status = AE_OK;
292                         goto cleanup;
293
294                 default:
295
296                         /* All others are valid exceptions */
297
298                         goto cleanup;
299                 }
300
301                 /* Get the next resource descriptor */
302
303                 resource = ACPI_NEXT_RESOURCE(resource);
304
305                 /* Check for end-of-buffer */
306
307                 if (resource >= buffer_end) {
308                         goto cleanup;
309                 }
310         }
311
312       cleanup:
313
314         acpi_os_free(buffer.pointer);
315         return_ACPI_STATUS(status);
316 }
317
318 EXPORT_SYMBOL(acpi_walk_resources);
319
320 /*******************************************************************************
321  *
322  * FUNCTION:    acpi_set_current_resources
323  *
324  * PARAMETERS:  device_handle   - a handle to the device object for the
325  *                                device we are changing the resources of
326  *              in_buffer       - a pointer to a buffer containing the
327  *                                resources to be set for the device
328  *
329  * RETURN:      Status
330  *
331  * DESCRIPTION: This function is called to set the current resources for a
332  *              specific device.  The caller must first acquire a handle for
333  *              the desired device.  The resource data is passed to the routine
334  *              the buffer pointed to by the in_buffer variable.
335  *
336  ******************************************************************************/
337
338 acpi_status
339 acpi_set_current_resources(acpi_handle device_handle,
340                            struct acpi_buffer *in_buffer)
341 {
342         acpi_status status;
343
344         ACPI_FUNCTION_TRACE("acpi_set_current_resources");
345
346         /* Must have a valid handle and buffer */
347
348         if ((!device_handle) ||
349             (!in_buffer) || (!in_buffer->pointer) || (!in_buffer->length)) {
350                 return_ACPI_STATUS(AE_BAD_PARAMETER);
351         }
352
353         status = acpi_rs_set_srs_method_data(device_handle, in_buffer);
354         return_ACPI_STATUS(status);
355 }
356
357 EXPORT_SYMBOL(acpi_set_current_resources);
358
359 /******************************************************************************
360  *
361  * FUNCTION:    acpi_resource_to_address64
362  *
363  * PARAMETERS:  resource                - Pointer to a resource
364  *              out                     - Pointer to the users's return
365  *                                        buffer (a struct
366  *                                        struct acpi_resource_address64)
367  *
368  * RETURN:      Status
369  *
370  * DESCRIPTION: If the resource is an address16, address32, or address64,
371  *              copy it to the address64 return buffer.  This saves the
372  *              caller from having to duplicate code for different-sized
373  *              addresses.
374  *
375  ******************************************************************************/
376
377 acpi_status
378 acpi_resource_to_address64(struct acpi_resource *resource,
379                            struct acpi_resource_address64 *out)
380 {
381         struct acpi_resource_address16 *address16;
382         struct acpi_resource_address32 *address32;
383
384         switch (resource->id) {
385         case ACPI_RSTYPE_ADDRESS16:
386
387                 address16 = (struct acpi_resource_address16 *)&resource->data;
388                 ACPI_COPY_ADDRESS(out, address16);
389                 break;
390
391         case ACPI_RSTYPE_ADDRESS32:
392
393                 address32 = (struct acpi_resource_address32 *)&resource->data;
394                 ACPI_COPY_ADDRESS(out, address32);
395                 break;
396
397         case ACPI_RSTYPE_ADDRESS64:
398
399                 /* Simple copy for 64 bit source */
400
401                 ACPI_MEMCPY(out, &resource->data,
402                             sizeof(struct acpi_resource_address64));
403                 break;
404
405         default:
406                 return (AE_BAD_PARAMETER);
407         }
408
409         return (AE_OK);
410 }
411
412 EXPORT_SYMBOL(acpi_resource_to_address64);