ACPI: ACPICA 20060421
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / acpi / resources / rsxface.c
CommitLineData
1da177e4
LT
1/*******************************************************************************
2 *
3 * Module Name: rsxface - Public interfaces to the resource manager
4 *
5 ******************************************************************************/
6
7/*
4a90c7e8 8 * Copyright (C) 2000 - 2006, R. Byron Moore
1da177e4
LT
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
1da177e4
LT
44#include <acpi/acpi.h>
45#include <acpi/acresrc.h>
46
47#define _COMPONENT ACPI_RESOURCES
4be44fcd 48ACPI_MODULE_NAME("rsxface")
1da177e4 49
44f6c012 50/* Local macros for 16,32-bit to 64-bit conversion */
44f6c012
RM
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); \
0897831b 58 ACPI_COPY_FIELD(out, in, info); \
44f6c012 59 ACPI_COPY_FIELD(out, in, granularity); \
50eca3eb
BM
60 ACPI_COPY_FIELD(out, in, minimum); \
61 ACPI_COPY_FIELD(out, in, maximum); \
62 ACPI_COPY_FIELD(out, in, translation_offset); \
44f6c012
RM
63 ACPI_COPY_FIELD(out, in, address_length); \
64 ACPI_COPY_FIELD(out, in, resource_source);
c51a4de8
BM
65/* Local prototypes */
66static acpi_status
67acpi_rs_match_vendor_resource(struct acpi_resource *resource, void *context);
68
1da177e4
LT
69/*******************************************************************************
70 *
71 * FUNCTION: acpi_get_irq_routing_table
72 *
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
76 *
77 * RETURN: Status
78 *
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.
83 *
84 * If the function fails an appropriate status will be returned
85 * and the value of ret_buffer is undefined.
86 *
87 * This function attempts to execute the _PRT method contained in
88 * the object indicated by the passed device_handle.
89 *
90 ******************************************************************************/
c51a4de8 91
1da177e4 92acpi_status
4be44fcd
LB
93acpi_get_irq_routing_table(acpi_handle device_handle,
94 struct acpi_buffer *ret_buffer)
1da177e4 95{
4be44fcd 96 acpi_status status;
1da177e4 97
b229cf92 98 ACPI_FUNCTION_TRACE(acpi_get_irq_routing_table);
1da177e4
LT
99
100 /*
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.
105 */
106 if (!device_handle) {
4be44fcd 107 return_ACPI_STATUS(AE_BAD_PARAMETER);
1da177e4
LT
108 }
109
4be44fcd
LB
110 status = acpi_ut_validate_buffer(ret_buffer);
111 if (ACPI_FAILURE(status)) {
112 return_ACPI_STATUS(status);
1da177e4
LT
113 }
114
4be44fcd
LB
115 status = acpi_rs_get_prt_method_data(device_handle, ret_buffer);
116 return_ACPI_STATUS(status);
1da177e4
LT
117}
118
8313524a
BM
119ACPI_EXPORT_SYMBOL(acpi_get_irq_routing_table)
120
1da177e4
LT
121/*******************************************************************************
122 *
123 * FUNCTION: acpi_get_current_resources
124 *
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
129 *
130 * RETURN: Status
131 *
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.
136 *
137 * If the function fails an appropriate status will be returned
138 * and the value of ret_buffer is undefined.
139 *
140 * This function attempts to execute the _CRS method contained in
141 * the object indicated by the passed device_handle.
142 *
143 ******************************************************************************/
1da177e4 144acpi_status
4be44fcd
LB
145acpi_get_current_resources(acpi_handle device_handle,
146 struct acpi_buffer *ret_buffer)
1da177e4 147{
4be44fcd 148 acpi_status status;
1da177e4 149
b229cf92 150 ACPI_FUNCTION_TRACE(acpi_get_current_resources);
1da177e4
LT
151
152 /*
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.
157 */
158 if (!device_handle) {
4be44fcd 159 return_ACPI_STATUS(AE_BAD_PARAMETER);
1da177e4
LT
160 }
161
4be44fcd
LB
162 status = acpi_ut_validate_buffer(ret_buffer);
163 if (ACPI_FAILURE(status)) {
164 return_ACPI_STATUS(status);
1da177e4
LT
165 }
166
4be44fcd
LB
167 status = acpi_rs_get_crs_method_data(device_handle, ret_buffer);
168 return_ACPI_STATUS(status);
1da177e4 169}
1da177e4 170
8313524a 171ACPI_EXPORT_SYMBOL(acpi_get_current_resources)
1da177e4 172
8313524a 173#ifdef ACPI_FUTURE_USAGE
1da177e4
LT
174/*******************************************************************************
175 *
176 * FUNCTION: acpi_get_possible_resources
177 *
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
182 *
183 * RETURN: Status
184 *
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.
189 *
190 * If the function fails an appropriate status will be returned
191 * and the value of ret_buffer is undefined.
192 *
193 ******************************************************************************/
1da177e4 194acpi_status
4be44fcd
LB
195acpi_get_possible_resources(acpi_handle device_handle,
196 struct acpi_buffer *ret_buffer)
1da177e4 197{
4be44fcd 198 acpi_status status;
1da177e4 199
b229cf92 200 ACPI_FUNCTION_TRACE(acpi_get_possible_resources);
1da177e4
LT
201
202 /*
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.
207 */
208 if (!device_handle) {
4be44fcd 209 return_ACPI_STATUS(AE_BAD_PARAMETER);
1da177e4
LT
210 }
211
4be44fcd
LB
212 status = acpi_ut_validate_buffer(ret_buffer);
213 if (ACPI_FAILURE(status)) {
214 return_ACPI_STATUS(status);
1da177e4
LT
215 }
216
4be44fcd
LB
217 status = acpi_rs_get_prs_method_data(device_handle, ret_buffer);
218 return_ACPI_STATUS(status);
1da177e4 219}
1da177e4 220
8313524a 221ACPI_EXPORT_SYMBOL(acpi_get_possible_resources)
4be44fcd 222#endif /* ACPI_FUTURE_USAGE */
1da177e4
LT
223
224/*******************************************************************************
225 *
226 * FUNCTION: acpi_walk_resources
227 *
c51a4de8 228 * PARAMETERS: device_handle - Handle to the device object for the
1da177e4 229 * device we are querying
c51a4de8 230 * Name - Method name of the resources we want
1da177e4 231 * (METHOD_NAME__CRS or METHOD_NAME__PRS)
c51a4de8
BM
232 * user_function - Called for each resource
233 * Context - Passed to user_function
1da177e4
LT
234 *
235 * RETURN: Status
236 *
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.
240 *
241 ******************************************************************************/
1da177e4 242acpi_status
4be44fcd 243acpi_walk_resources(acpi_handle device_handle,
c51a4de8 244 char *name,
61686124 245 acpi_walk_resource_callback user_function, void *context)
1da177e4 246{
4be44fcd 247 acpi_status status;
c51a4de8 248 struct acpi_buffer buffer;
4be44fcd 249 struct acpi_resource *resource;
c51a4de8 250 struct acpi_resource *resource_end;
1da177e4 251
b229cf92 252 ACPI_FUNCTION_TRACE(acpi_walk_resources);
1da177e4 253
c51a4de8
BM
254 /* Parameter validation */
255
256 if (!device_handle || !user_function || !name ||
b229cf92
BM
257 (!ACPI_COMPARE_NAME(name, METHOD_NAME__CRS) &&
258 !ACPI_COMPARE_NAME(name, METHOD_NAME__PRS))) {
4be44fcd 259 return_ACPI_STATUS(AE_BAD_PARAMETER);
1da177e4
LT
260 }
261
c51a4de8
BM
262 /* Get the _CRS or _PRS resource list */
263
264 buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
265 status = acpi_rs_get_method_data(device_handle, name, &buffer);
4be44fcd
LB
266 if (ACPI_FAILURE(status)) {
267 return_ACPI_STATUS(status);
1da177e4
LT
268 }
269
c51a4de8 270 /* Buffer now contains the resource list */
1da177e4 271
c51a4de8
BM
272 resource = ACPI_CAST_PTR(struct acpi_resource, buffer.pointer);
273 resource_end =
274 ACPI_ADD_PTR(struct acpi_resource, buffer.pointer, buffer.length);
1da177e4 275
c51a4de8 276 /* Walk the resource list until the end_tag is found (or buffer end) */
1da177e4 277
c51a4de8 278 while (resource < resource_end) {
52fc0b02 279
c51a4de8
BM
280 /* Sanity check the resource */
281
282 if (resource->type > ACPI_RESOURCE_TYPE_MAX) {
283 status = AE_AML_INVALID_RESOURCE_TYPE;
1da177e4
LT
284 break;
285 }
286
c51a4de8 287 /* Invoke the user function, abort on any error returned */
1da177e4 288
c51a4de8
BM
289 status = user_function(resource, context);
290 if (ACPI_FAILURE(status)) {
291 if (status == AE_CTRL_TERMINATE) {
52fc0b02 292
c51a4de8 293 /* This is an OK termination by the user function */
1da177e4 294
c51a4de8
BM
295 status = AE_OK;
296 }
1da177e4 297 break;
c51a4de8 298 }
1da177e4 299
2ae41174
LB
300 /* end_tag indicates end-of-list */
301
302 if (resource->type == ACPI_RESOURCE_TYPE_END_TAG) {
303 break;
304 }
305
1da177e4
LT
306 /* Get the next resource descriptor */
307
c51a4de8
BM
308 resource =
309 ACPI_ADD_PTR(struct acpi_resource, resource,
310 resource->length);
1da177e4
LT
311 }
312
8313524a 313 ACPI_FREE(buffer.pointer);
4be44fcd 314 return_ACPI_STATUS(status);
1da177e4 315}
1da177e4 316
8313524a 317ACPI_EXPORT_SYMBOL(acpi_walk_resources)
1da177e4
LT
318
319/*******************************************************************************
320 *
321 * FUNCTION: acpi_set_current_resources
322 *
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
327 *
328 * RETURN: Status
329 *
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.
334 *
335 ******************************************************************************/
1da177e4 336acpi_status
4be44fcd
LB
337acpi_set_current_resources(acpi_handle device_handle,
338 struct acpi_buffer *in_buffer)
1da177e4 339{
4be44fcd 340 acpi_status status;
1da177e4 341
b229cf92 342 ACPI_FUNCTION_TRACE(acpi_set_current_resources);
1da177e4 343
44f6c012
RM
344 /* Must have a valid handle and buffer */
345
4be44fcd
LB
346 if ((!device_handle) ||
347 (!in_buffer) || (!in_buffer->pointer) || (!in_buffer->length)) {
348 return_ACPI_STATUS(AE_BAD_PARAMETER);
1da177e4
LT
349 }
350
4be44fcd
LB
351 status = acpi_rs_set_srs_method_data(device_handle, in_buffer);
352 return_ACPI_STATUS(status);
1da177e4 353}
1da177e4 354
8313524a 355ACPI_EXPORT_SYMBOL(acpi_set_current_resources)
1da177e4 356
1da177e4
LT
357/******************************************************************************
358 *
359 * FUNCTION: acpi_resource_to_address64
360 *
bda663d3
RM
361 * PARAMETERS: Resource - Pointer to a resource
362 * Out - Pointer to the users's return
1da177e4
LT
363 * buffer (a struct
364 * struct acpi_resource_address64)
365 *
366 * RETURN: Status
367 *
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.
372 *
373 ******************************************************************************/
1da177e4 374acpi_status
4be44fcd
LB
375acpi_resource_to_address64(struct acpi_resource *resource,
376 struct acpi_resource_address64 *out)
1da177e4 377{
4be44fcd
LB
378 struct acpi_resource_address16 *address16;
379 struct acpi_resource_address32 *address32;
1da177e4 380
c51a4de8
BM
381 if (!resource || !out) {
382 return (AE_BAD_PARAMETER);
383 }
384
385 /* Convert 16 or 32 address descriptor to 64 */
386
bda663d3 387 switch (resource->type) {
50eca3eb 388 case ACPI_RESOURCE_TYPE_ADDRESS16:
1da177e4 389
4be44fcd
LB
390 address16 = (struct acpi_resource_address16 *)&resource->data;
391 ACPI_COPY_ADDRESS(out, address16);
1da177e4
LT
392 break;
393
50eca3eb 394 case ACPI_RESOURCE_TYPE_ADDRESS32:
1da177e4 395
4be44fcd
LB
396 address32 = (struct acpi_resource_address32 *)&resource->data;
397 ACPI_COPY_ADDRESS(out, address32);
1da177e4
LT
398 break;
399
50eca3eb 400 case ACPI_RESOURCE_TYPE_ADDRESS64:
1da177e4
LT
401
402 /* Simple copy for 64 bit source */
403
4be44fcd
LB
404 ACPI_MEMCPY(out, &resource->data,
405 sizeof(struct acpi_resource_address64));
1da177e4
LT
406 break;
407
1da177e4
LT
408 default:
409 return (AE_BAD_PARAMETER);
410 }
411
412 return (AE_OK);
413}
4be44fcd 414
8313524a 415ACPI_EXPORT_SYMBOL(acpi_resource_to_address64)
c51a4de8
BM
416
417/*******************************************************************************
418 *
419 * FUNCTION: acpi_get_vendor_resource
420 *
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
427 *
428 * RETURN: Status
429 *
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.
433 *
434 ******************************************************************************/
c51a4de8
BM
435acpi_status
436acpi_get_vendor_resource(acpi_handle device_handle,
437 char *name,
438 struct acpi_vendor_uuid * uuid,
439 struct acpi_buffer * ret_buffer)
440{
441 struct acpi_vendor_walk_info info;
442 acpi_status status;
443
444 /* Other parameters are validated by acpi_walk_resources */
445
446 if (!uuid || !ret_buffer) {
447 return (AE_BAD_PARAMETER);
448 }
449
450 info.uuid = uuid;
451 info.buffer = ret_buffer;
452 info.status = AE_NOT_EXIST;
453
454 /* Walk the _CRS or _PRS resource list for this device */
455
456 status =
457 acpi_walk_resources(device_handle, name,
458 acpi_rs_match_vendor_resource, &info);
459 if (ACPI_FAILURE(status)) {
460 return (status);
461 }
462
463 return (info.status);
464}
465
8313524a
BM
466ACPI_EXPORT_SYMBOL(acpi_get_vendor_resource)
467
c51a4de8
BM
468/*******************************************************************************
469 *
470 * FUNCTION: acpi_rs_match_vendor_resource
471 *
61686124 472 * PARAMETERS: acpi_walk_resource_callback
c51a4de8
BM
473 *
474 * RETURN: Status
475 *
476 * DESCRIPTION: Match a vendor resource via the ACPI 3.0 UUID
477 *
478 ******************************************************************************/
c51a4de8
BM
479static acpi_status
480acpi_rs_match_vendor_resource(struct acpi_resource *resource, void *context)
481{
482 struct acpi_vendor_walk_info *info = context;
483 struct acpi_resource_vendor_typed *vendor;
484 struct acpi_buffer *buffer;
485 acpi_status status;
486
487 /* Ignore all descriptors except Vendor */
488
489 if (resource->type != ACPI_RESOURCE_TYPE_VENDOR) {
490 return (AE_OK);
491 }
492
493 vendor = &resource->data.vendor_typed;
494
495 /*
496 * For a valid match, these conditions must hold:
497 *
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
501 */
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);
506 }
507
508 /* Validate/Allocate/Clear caller buffer */
509
510 buffer = info->buffer;
511 status = acpi_ut_initialize_buffer(buffer, resource->length);
512 if (ACPI_FAILURE(status)) {
513 return (status);
514 }
515
516 /* Found the correct resource, copy and return it */
517
518 ACPI_MEMCPY(buffer->pointer, resource, resource->length);
519 buffer->length = resource->length;
520
521 /* Found the desired descriptor, terminate resource walk */
522
523 info->status = AE_OK;
524 return (AE_CTRL_TERMINATE);
525}
8313524a
BM
526
527ACPI_EXPORT_SYMBOL(acpi_rs_match_vendor_resource)