ACPI: ACPICA 20060421
[linux-2.6/btrfs-unstable.git] / drivers / acpi / resources / rsxface.c
blob8c1628c12cc8b66eca40047ca48f56e4cb57063f
1 /*******************************************************************************
3 * Module Name: rsxface - Public interfaces to the resource manager
5 ******************************************************************************/
7 /*
8 * Copyright (C) 2000 - 2006, R. Byron Moore
9 * All rights reserved.
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.
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.
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.
44 #include <acpi/acpi.h>
45 #include <acpi/acresrc.h>
47 #define _COMPONENT ACPI_RESOURCES
48 ACPI_MODULE_NAME("rsxface")
50 /* Local macros for 16,32-bit to 64-bit conversion */
51 #define ACPI_COPY_FIELD(out, in, field) ((out)->field = (in)->field)
52 #define ACPI_COPY_ADDRESS(out, in) \
53 ACPI_COPY_FIELD(out, in, resource_type); \
54 ACPI_COPY_FIELD(out, in, producer_consumer); \
55 ACPI_COPY_FIELD(out, in, decode); \
56 ACPI_COPY_FIELD(out, in, min_address_fixed); \
57 ACPI_COPY_FIELD(out, in, max_address_fixed); \
58 ACPI_COPY_FIELD(out, in, info); \
59 ACPI_COPY_FIELD(out, in, granularity); \
60 ACPI_COPY_FIELD(out, in, minimum); \
61 ACPI_COPY_FIELD(out, in, maximum); \
62 ACPI_COPY_FIELD(out, in, translation_offset); \
63 ACPI_COPY_FIELD(out, in, address_length); \
64 ACPI_COPY_FIELD(out, in, resource_source);
65 /* Local prototypes */
66 static acpi_status
67 acpi_rs_match_vendor_resource(struct acpi_resource *resource, void *context);
69 /*******************************************************************************
71 * FUNCTION: acpi_get_irq_routing_table
73 * PARAMETERS: device_handle - a handle to the Bus device we are querying
74 * ret_buffer - a pointer to a buffer to receive the
75 * current resources for the device
77 * RETURN: Status
79 * DESCRIPTION: This function is called to get the IRQ routing table for a
80 * specific bus. The caller must first acquire a handle for the
81 * desired bus. The routine table is placed in the buffer pointed
82 * to by the ret_buffer variable parameter.
84 * If the function fails an appropriate status will be returned
85 * and the value of ret_buffer is undefined.
87 * This function attempts to execute the _PRT method contained in
88 * the object indicated by the passed device_handle.
90 ******************************************************************************/
92 acpi_status
93 acpi_get_irq_routing_table(acpi_handle device_handle,
94 struct acpi_buffer *ret_buffer)
96 acpi_status status;
98 ACPI_FUNCTION_TRACE(acpi_get_irq_routing_table);
101 * Must have a valid handle and buffer, So we have to have a handle
102 * and a return buffer structure, and if there is a non-zero buffer length
103 * we also need a valid pointer in the buffer. If it's a zero buffer length,
104 * we'll be returning the needed buffer size, so keep going.
106 if (!device_handle) {
107 return_ACPI_STATUS(AE_BAD_PARAMETER);
110 status = acpi_ut_validate_buffer(ret_buffer);
111 if (ACPI_FAILURE(status)) {
112 return_ACPI_STATUS(status);
115 status = acpi_rs_get_prt_method_data(device_handle, ret_buffer);
116 return_ACPI_STATUS(status);
119 ACPI_EXPORT_SYMBOL(acpi_get_irq_routing_table)
121 /*******************************************************************************
123 * FUNCTION: acpi_get_current_resources
125 * PARAMETERS: device_handle - a handle to the device object for the
126 * device we are querying
127 * ret_buffer - a pointer to a buffer to receive the
128 * current resources for the device
130 * RETURN: Status
132 * DESCRIPTION: This function is called to get the current resources for a
133 * specific device. The caller must first acquire a handle for
134 * the desired device. The resource data is placed in the buffer
135 * pointed to by the ret_buffer variable parameter.
137 * If the function fails an appropriate status will be returned
138 * and the value of ret_buffer is undefined.
140 * This function attempts to execute the _CRS method contained in
141 * the object indicated by the passed device_handle.
143 ******************************************************************************/
144 acpi_status
145 acpi_get_current_resources(acpi_handle device_handle,
146 struct acpi_buffer *ret_buffer)
148 acpi_status status;
150 ACPI_FUNCTION_TRACE(acpi_get_current_resources);
153 * Must have a valid handle and buffer, So we have to have a handle
154 * and a return buffer structure, and if there is a non-zero buffer length
155 * we also need a valid pointer in the buffer. If it's a zero buffer length,
156 * we'll be returning the needed buffer size, so keep going.
158 if (!device_handle) {
159 return_ACPI_STATUS(AE_BAD_PARAMETER);
162 status = acpi_ut_validate_buffer(ret_buffer);
163 if (ACPI_FAILURE(status)) {
164 return_ACPI_STATUS(status);
167 status = acpi_rs_get_crs_method_data(device_handle, ret_buffer);
168 return_ACPI_STATUS(status);
171 ACPI_EXPORT_SYMBOL(acpi_get_current_resources)
173 #ifdef ACPI_FUTURE_USAGE
174 /*******************************************************************************
176 * FUNCTION: acpi_get_possible_resources
178 * PARAMETERS: device_handle - a handle to the device object for the
179 * device we are querying
180 * ret_buffer - a pointer to a buffer to receive the
181 * resources for the device
183 * RETURN: Status
185 * DESCRIPTION: This function is called to get a list of the possible resources
186 * for a specific device. The caller must first acquire a handle
187 * for the desired device. The resource data is placed in the
188 * buffer pointed to by the ret_buffer variable.
190 * If the function fails an appropriate status will be returned
191 * and the value of ret_buffer is undefined.
193 ******************************************************************************/
194 acpi_status
195 acpi_get_possible_resources(acpi_handle device_handle,
196 struct acpi_buffer *ret_buffer)
198 acpi_status status;
200 ACPI_FUNCTION_TRACE(acpi_get_possible_resources);
203 * Must have a valid handle and buffer, So we have to have a handle
204 * and a return buffer structure, and if there is a non-zero buffer length
205 * we also need a valid pointer in the buffer. If it's a zero buffer length,
206 * we'll be returning the needed buffer size, so keep going.
208 if (!device_handle) {
209 return_ACPI_STATUS(AE_BAD_PARAMETER);
212 status = acpi_ut_validate_buffer(ret_buffer);
213 if (ACPI_FAILURE(status)) {
214 return_ACPI_STATUS(status);
217 status = acpi_rs_get_prs_method_data(device_handle, ret_buffer);
218 return_ACPI_STATUS(status);
221 ACPI_EXPORT_SYMBOL(acpi_get_possible_resources)
222 #endif /* ACPI_FUTURE_USAGE */
224 /*******************************************************************************
226 * FUNCTION: acpi_walk_resources
228 * PARAMETERS: device_handle - Handle to the device object for the
229 * device we are querying
230 * Name - Method name of the resources we want
231 * (METHOD_NAME__CRS or METHOD_NAME__PRS)
232 * user_function - Called for each resource
233 * Context - Passed to user_function
235 * RETURN: Status
237 * DESCRIPTION: Retrieves the current or possible resource list for the
238 * specified device. The user_function is called once for
239 * each resource in the list.
241 ******************************************************************************/
242 acpi_status
243 acpi_walk_resources(acpi_handle device_handle,
244 char *name,
245 acpi_walk_resource_callback user_function, void *context)
247 acpi_status status;
248 struct acpi_buffer buffer;
249 struct acpi_resource *resource;
250 struct acpi_resource *resource_end;
252 ACPI_FUNCTION_TRACE(acpi_walk_resources);
254 /* Parameter validation */
256 if (!device_handle || !user_function || !name ||
257 (!ACPI_COMPARE_NAME(name, METHOD_NAME__CRS) &&
258 !ACPI_COMPARE_NAME(name, METHOD_NAME__PRS))) {
259 return_ACPI_STATUS(AE_BAD_PARAMETER);
262 /* Get the _CRS or _PRS resource list */
264 buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
265 status = acpi_rs_get_method_data(device_handle, name, &buffer);
266 if (ACPI_FAILURE(status)) {
267 return_ACPI_STATUS(status);
270 /* Buffer now contains the resource list */
272 resource = ACPI_CAST_PTR(struct acpi_resource, buffer.pointer);
273 resource_end =
274 ACPI_ADD_PTR(struct acpi_resource, buffer.pointer, buffer.length);
276 /* Walk the resource list until the end_tag is found (or buffer end) */
278 while (resource < resource_end) {
280 /* Sanity check the resource */
282 if (resource->type > ACPI_RESOURCE_TYPE_MAX) {
283 status = AE_AML_INVALID_RESOURCE_TYPE;
284 break;
287 /* Invoke the user function, abort on any error returned */
289 status = user_function(resource, context);
290 if (ACPI_FAILURE(status)) {
291 if (status == AE_CTRL_TERMINATE) {
293 /* This is an OK termination by the user function */
295 status = AE_OK;
297 break;
300 /* end_tag indicates end-of-list */
302 if (resource->type == ACPI_RESOURCE_TYPE_END_TAG) {
303 break;
306 /* Get the next resource descriptor */
308 resource =
309 ACPI_ADD_PTR(struct acpi_resource, resource,
310 resource->length);
313 ACPI_FREE(buffer.pointer);
314 return_ACPI_STATUS(status);
317 ACPI_EXPORT_SYMBOL(acpi_walk_resources)
319 /*******************************************************************************
321 * FUNCTION: acpi_set_current_resources
323 * PARAMETERS: device_handle - a handle to the device object for the
324 * device we are changing the resources of
325 * in_buffer - a pointer to a buffer containing the
326 * resources to be set for the device
328 * RETURN: Status
330 * DESCRIPTION: This function is called to set the current resources for a
331 * specific device. The caller must first acquire a handle for
332 * the desired device. The resource data is passed to the routine
333 * the buffer pointed to by the in_buffer variable.
335 ******************************************************************************/
336 acpi_status
337 acpi_set_current_resources(acpi_handle device_handle,
338 struct acpi_buffer *in_buffer)
340 acpi_status status;
342 ACPI_FUNCTION_TRACE(acpi_set_current_resources);
344 /* Must have a valid handle and buffer */
346 if ((!device_handle) ||
347 (!in_buffer) || (!in_buffer->pointer) || (!in_buffer->length)) {
348 return_ACPI_STATUS(AE_BAD_PARAMETER);
351 status = acpi_rs_set_srs_method_data(device_handle, in_buffer);
352 return_ACPI_STATUS(status);
355 ACPI_EXPORT_SYMBOL(acpi_set_current_resources)
357 /******************************************************************************
359 * FUNCTION: acpi_resource_to_address64
361 * PARAMETERS: Resource - Pointer to a resource
362 * Out - Pointer to the users's return
363 * buffer (a struct
364 * struct acpi_resource_address64)
366 * RETURN: Status
368 * DESCRIPTION: If the resource is an address16, address32, or address64,
369 * copy it to the address64 return buffer. This saves the
370 * caller from having to duplicate code for different-sized
371 * addresses.
373 ******************************************************************************/
374 acpi_status
375 acpi_resource_to_address64(struct acpi_resource *resource,
376 struct acpi_resource_address64 *out)
378 struct acpi_resource_address16 *address16;
379 struct acpi_resource_address32 *address32;
381 if (!resource || !out) {
382 return (AE_BAD_PARAMETER);
385 /* Convert 16 or 32 address descriptor to 64 */
387 switch (resource->type) {
388 case ACPI_RESOURCE_TYPE_ADDRESS16:
390 address16 = (struct acpi_resource_address16 *)&resource->data;
391 ACPI_COPY_ADDRESS(out, address16);
392 break;
394 case ACPI_RESOURCE_TYPE_ADDRESS32:
396 address32 = (struct acpi_resource_address32 *)&resource->data;
397 ACPI_COPY_ADDRESS(out, address32);
398 break;
400 case ACPI_RESOURCE_TYPE_ADDRESS64:
402 /* Simple copy for 64 bit source */
404 ACPI_MEMCPY(out, &resource->data,
405 sizeof(struct acpi_resource_address64));
406 break;
408 default:
409 return (AE_BAD_PARAMETER);
412 return (AE_OK);
415 ACPI_EXPORT_SYMBOL(acpi_resource_to_address64)
417 /*******************************************************************************
419 * FUNCTION: acpi_get_vendor_resource
421 * PARAMETERS: device_handle - Handle for the parent device object
422 * Name - Method name for the parent resource
423 * (METHOD_NAME__CRS or METHOD_NAME__PRS)
424 * Uuid - Pointer to the UUID to be matched.
425 * includes both subtype and 16-byte UUID
426 * ret_buffer - Where the vendor resource is returned
428 * RETURN: Status
430 * DESCRIPTION: Walk a resource template for the specified evice to find a
431 * vendor-defined resource that matches the supplied UUID and
432 * UUID subtype. Returns a struct acpi_resource of type Vendor.
434 ******************************************************************************/
435 acpi_status
436 acpi_get_vendor_resource(acpi_handle device_handle,
437 char *name,
438 struct acpi_vendor_uuid * uuid,
439 struct acpi_buffer * ret_buffer)
441 struct acpi_vendor_walk_info info;
442 acpi_status status;
444 /* Other parameters are validated by acpi_walk_resources */
446 if (!uuid || !ret_buffer) {
447 return (AE_BAD_PARAMETER);
450 info.uuid = uuid;
451 info.buffer = ret_buffer;
452 info.status = AE_NOT_EXIST;
454 /* Walk the _CRS or _PRS resource list for this device */
456 status =
457 acpi_walk_resources(device_handle, name,
458 acpi_rs_match_vendor_resource, &info);
459 if (ACPI_FAILURE(status)) {
460 return (status);
463 return (info.status);
466 ACPI_EXPORT_SYMBOL(acpi_get_vendor_resource)
468 /*******************************************************************************
470 * FUNCTION: acpi_rs_match_vendor_resource
472 * PARAMETERS: acpi_walk_resource_callback
474 * RETURN: Status
476 * DESCRIPTION: Match a vendor resource via the ACPI 3.0 UUID
478 ******************************************************************************/
479 static acpi_status
480 acpi_rs_match_vendor_resource(struct acpi_resource *resource, void *context)
482 struct acpi_vendor_walk_info *info = context;
483 struct acpi_resource_vendor_typed *vendor;
484 struct acpi_buffer *buffer;
485 acpi_status status;
487 /* Ignore all descriptors except Vendor */
489 if (resource->type != ACPI_RESOURCE_TYPE_VENDOR) {
490 return (AE_OK);
493 vendor = &resource->data.vendor_typed;
496 * For a valid match, these conditions must hold:
498 * 1) Length of descriptor data must be at least as long as a UUID struct
499 * 2) The UUID subtypes must match
500 * 3) The UUID data must match
502 if ((vendor->byte_length < (ACPI_UUID_LENGTH + 1)) ||
503 (vendor->uuid_subtype != info->uuid->subtype) ||
504 (ACPI_MEMCMP(vendor->uuid, info->uuid->data, ACPI_UUID_LENGTH))) {
505 return (AE_OK);
508 /* Validate/Allocate/Clear caller buffer */
510 buffer = info->buffer;
511 status = acpi_ut_initialize_buffer(buffer, resource->length);
512 if (ACPI_FAILURE(status)) {
513 return (status);
516 /* Found the correct resource, copy and return it */
518 ACPI_MEMCPY(buffer->pointer, resource, resource->length);
519 buffer->length = resource->length;
521 /* Found the desired descriptor, terminate resource walk */
523 info->status = AE_OK;
524 return (AE_CTRL_TERMINATE);
527 ACPI_EXPORT_SYMBOL(acpi_rs_match_vendor_resource)