diff options
Diffstat (limited to 'drivers/acpi/acpica/rsxface.c')
-rw-r--r-- | drivers/acpi/acpica/rsxface.c | 571 |
1 files changed, 571 insertions, 0 deletions
diff --git a/drivers/acpi/acpica/rsxface.c b/drivers/acpi/acpica/rsxface.c new file mode 100644 index 000000000000..0a274356b23e --- /dev/null +++ b/drivers/acpi/acpica/rsxface.c | |||
@@ -0,0 +1,571 @@ | |||
1 | /******************************************************************************* | ||
2 | * | ||
3 | * Module Name: rsxface - Public interfaces to the resource manager | ||
4 | * | ||
5 | ******************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2008, Intel Corp. | ||
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/accommon.h> | ||
46 | #include <acpi/acresrc.h> | ||
47 | #include <acpi/acnamesp.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, info); \ | ||
61 | ACPI_COPY_FIELD(out, in, granularity); \ | ||
62 | ACPI_COPY_FIELD(out, in, minimum); \ | ||
63 | ACPI_COPY_FIELD(out, in, maximum); \ | ||
64 | ACPI_COPY_FIELD(out, in, translation_offset); \ | ||
65 | ACPI_COPY_FIELD(out, in, address_length); \ | ||
66 | ACPI_COPY_FIELD(out, in, resource_source); | ||
67 | /* Local prototypes */ | ||
68 | static acpi_status | ||
69 | acpi_rs_match_vendor_resource(struct acpi_resource *resource, void *context); | ||
70 | |||
71 | static acpi_status | ||
72 | acpi_rs_validate_parameters(acpi_handle device_handle, | ||
73 | struct acpi_buffer *buffer, | ||
74 | struct acpi_namespace_node **return_node); | ||
75 | |||
76 | /******************************************************************************* | ||
77 | * | ||
78 | * FUNCTION: acpi_rs_validate_parameters | ||
79 | * | ||
80 | * PARAMETERS: device_handle - Handle to a device | ||
81 | * Buffer - Pointer to a data buffer | ||
82 | * return_node - Pointer to where the device node is returned | ||
83 | * | ||
84 | * RETURN: Status | ||
85 | * | ||
86 | * DESCRIPTION: Common parameter validation for resource interfaces | ||
87 | * | ||
88 | ******************************************************************************/ | ||
89 | |||
90 | static acpi_status | ||
91 | acpi_rs_validate_parameters(acpi_handle device_handle, | ||
92 | struct acpi_buffer *buffer, | ||
93 | struct acpi_namespace_node **return_node) | ||
94 | { | ||
95 | acpi_status status; | ||
96 | struct acpi_namespace_node *node; | ||
97 | |||
98 | ACPI_FUNCTION_TRACE(rs_validate_parameters); | ||
99 | |||
100 | /* | ||
101 | * Must have a valid handle to an ACPI device | ||
102 | */ | ||
103 | if (!device_handle) { | ||
104 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
105 | } | ||
106 | |||
107 | node = acpi_ns_map_handle_to_node(device_handle); | ||
108 | if (!node) { | ||
109 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
110 | } | ||
111 | |||
112 | if (node->type != ACPI_TYPE_DEVICE) { | ||
113 | return_ACPI_STATUS(AE_TYPE); | ||
114 | } | ||
115 | |||
116 | /* | ||
117 | * Validate the user buffer object | ||
118 | * | ||
119 | * if there is a non-zero buffer length we also need a valid pointer in | ||
120 | * the buffer. If it's a zero buffer length, we'll be returning the | ||
121 | * needed buffer size (later), so keep going. | ||
122 | */ | ||
123 | status = acpi_ut_validate_buffer(buffer); | ||
124 | if (ACPI_FAILURE(status)) { | ||
125 | return_ACPI_STATUS(status); | ||
126 | } | ||
127 | |||
128 | *return_node = node; | ||
129 | return_ACPI_STATUS(AE_OK); | ||
130 | } | ||
131 | |||
132 | /******************************************************************************* | ||
133 | * | ||
134 | * FUNCTION: acpi_get_irq_routing_table | ||
135 | * | ||
136 | * PARAMETERS: device_handle - Handle to the Bus device we are querying | ||
137 | * ret_buffer - Pointer to a buffer to receive the | ||
138 | * current resources for the device | ||
139 | * | ||
140 | * RETURN: Status | ||
141 | * | ||
142 | * DESCRIPTION: This function is called to get the IRQ routing table for a | ||
143 | * specific bus. The caller must first acquire a handle for the | ||
144 | * desired bus. The routine table is placed in the buffer pointed | ||
145 | * to by the ret_buffer variable parameter. | ||
146 | * | ||
147 | * If the function fails an appropriate status will be returned | ||
148 | * and the value of ret_buffer is undefined. | ||
149 | * | ||
150 | * This function attempts to execute the _PRT method contained in | ||
151 | * the object indicated by the passed device_handle. | ||
152 | * | ||
153 | ******************************************************************************/ | ||
154 | |||
155 | acpi_status | ||
156 | acpi_get_irq_routing_table(acpi_handle device_handle, | ||
157 | struct acpi_buffer *ret_buffer) | ||
158 | { | ||
159 | acpi_status status; | ||
160 | struct acpi_namespace_node *node; | ||
161 | |||
162 | ACPI_FUNCTION_TRACE(acpi_get_irq_routing_table); | ||
163 | |||
164 | /* Validate parameters then dispatch to internal routine */ | ||
165 | |||
166 | status = acpi_rs_validate_parameters(device_handle, ret_buffer, &node); | ||
167 | if (ACPI_FAILURE(status)) { | ||
168 | return_ACPI_STATUS(status); | ||
169 | } | ||
170 | |||
171 | status = acpi_rs_get_prt_method_data(node, ret_buffer); | ||
172 | return_ACPI_STATUS(status); | ||
173 | } | ||
174 | |||
175 | ACPI_EXPORT_SYMBOL(acpi_get_irq_routing_table) | ||
176 | |||
177 | /******************************************************************************* | ||
178 | * | ||
179 | * FUNCTION: acpi_get_current_resources | ||
180 | * | ||
181 | * PARAMETERS: device_handle - Handle to the device object for the | ||
182 | * device we are querying | ||
183 | * ret_buffer - Pointer to a buffer to receive the | ||
184 | * current resources for the device | ||
185 | * | ||
186 | * RETURN: Status | ||
187 | * | ||
188 | * DESCRIPTION: This function is called to get the current resources for a | ||
189 | * specific device. The caller must first acquire a handle for | ||
190 | * the desired device. The resource data is placed in the buffer | ||
191 | * pointed to by the ret_buffer variable parameter. | ||
192 | * | ||
193 | * If the function fails an appropriate status will be returned | ||
194 | * and the value of ret_buffer is undefined. | ||
195 | * | ||
196 | * This function attempts to execute the _CRS method contained in | ||
197 | * the object indicated by the passed device_handle. | ||
198 | * | ||
199 | ******************************************************************************/ | ||
200 | acpi_status | ||
201 | acpi_get_current_resources(acpi_handle device_handle, | ||
202 | struct acpi_buffer *ret_buffer) | ||
203 | { | ||
204 | acpi_status status; | ||
205 | struct acpi_namespace_node *node; | ||
206 | |||
207 | ACPI_FUNCTION_TRACE(acpi_get_current_resources); | ||
208 | |||
209 | /* Validate parameters then dispatch to internal routine */ | ||
210 | |||
211 | status = acpi_rs_validate_parameters(device_handle, ret_buffer, &node); | ||
212 | if (ACPI_FAILURE(status)) { | ||
213 | return_ACPI_STATUS(status); | ||
214 | } | ||
215 | |||
216 | status = acpi_rs_get_crs_method_data(node, ret_buffer); | ||
217 | return_ACPI_STATUS(status); | ||
218 | } | ||
219 | |||
220 | ACPI_EXPORT_SYMBOL(acpi_get_current_resources) | ||
221 | #ifdef ACPI_FUTURE_USAGE | ||
222 | /******************************************************************************* | ||
223 | * | ||
224 | * FUNCTION: acpi_get_possible_resources | ||
225 | * | ||
226 | * PARAMETERS: device_handle - Handle to the device object for the | ||
227 | * device we are querying | ||
228 | * ret_buffer - Pointer to a buffer to receive the | ||
229 | * resources for the device | ||
230 | * | ||
231 | * RETURN: Status | ||
232 | * | ||
233 | * DESCRIPTION: This function is called to get a list of the possible resources | ||
234 | * for a specific device. The caller must first acquire a handle | ||
235 | * for the desired device. The resource data is placed in the | ||
236 | * buffer pointed to by the ret_buffer variable. | ||
237 | * | ||
238 | * If the function fails an appropriate status will be returned | ||
239 | * and the value of ret_buffer is undefined. | ||
240 | * | ||
241 | ******************************************************************************/ | ||
242 | acpi_status | ||
243 | acpi_get_possible_resources(acpi_handle device_handle, | ||
244 | struct acpi_buffer *ret_buffer) | ||
245 | { | ||
246 | acpi_status status; | ||
247 | struct acpi_namespace_node *node; | ||
248 | |||
249 | ACPI_FUNCTION_TRACE(acpi_get_possible_resources); | ||
250 | |||
251 | /* Validate parameters then dispatch to internal routine */ | ||
252 | |||
253 | status = acpi_rs_validate_parameters(device_handle, ret_buffer, &node); | ||
254 | if (ACPI_FAILURE(status)) { | ||
255 | return_ACPI_STATUS(status); | ||
256 | } | ||
257 | |||
258 | status = acpi_rs_get_prs_method_data(node, ret_buffer); | ||
259 | return_ACPI_STATUS(status); | ||
260 | } | ||
261 | |||
262 | ACPI_EXPORT_SYMBOL(acpi_get_possible_resources) | ||
263 | #endif /* ACPI_FUTURE_USAGE */ | ||
264 | /******************************************************************************* | ||
265 | * | ||
266 | * FUNCTION: acpi_set_current_resources | ||
267 | * | ||
268 | * PARAMETERS: device_handle - Handle to the device object for the | ||
269 | * device we are setting resources | ||
270 | * in_buffer - Pointer to a buffer containing the | ||
271 | * resources to be set for the device | ||
272 | * | ||
273 | * RETURN: Status | ||
274 | * | ||
275 | * DESCRIPTION: This function is called to set the current resources for a | ||
276 | * specific device. The caller must first acquire a handle for | ||
277 | * the desired device. The resource data is passed to the routine | ||
278 | * the buffer pointed to by the in_buffer variable. | ||
279 | * | ||
280 | ******************************************************************************/ | ||
281 | acpi_status | ||
282 | acpi_set_current_resources(acpi_handle device_handle, | ||
283 | struct acpi_buffer *in_buffer) | ||
284 | { | ||
285 | acpi_status status; | ||
286 | struct acpi_namespace_node *node; | ||
287 | |||
288 | ACPI_FUNCTION_TRACE(acpi_set_current_resources); | ||
289 | |||
290 | /* Validate the buffer, don't allow zero length */ | ||
291 | |||
292 | if ((!in_buffer) || (!in_buffer->pointer) || (!in_buffer->length)) { | ||
293 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
294 | } | ||
295 | |||
296 | /* Validate parameters then dispatch to internal routine */ | ||
297 | |||
298 | status = acpi_rs_validate_parameters(device_handle, in_buffer, &node); | ||
299 | if (ACPI_FAILURE(status)) { | ||
300 | return_ACPI_STATUS(status); | ||
301 | } | ||
302 | |||
303 | status = acpi_rs_set_srs_method_data(node, in_buffer); | ||
304 | return_ACPI_STATUS(status); | ||
305 | } | ||
306 | |||
307 | ACPI_EXPORT_SYMBOL(acpi_set_current_resources) | ||
308 | |||
309 | /****************************************************************************** | ||
310 | * | ||
311 | * FUNCTION: acpi_resource_to_address64 | ||
312 | * | ||
313 | * PARAMETERS: Resource - Pointer to a resource | ||
314 | * Out - Pointer to the users's return buffer | ||
315 | * (a struct acpi_resource_address64) | ||
316 | * | ||
317 | * RETURN: Status | ||
318 | * | ||
319 | * DESCRIPTION: If the resource is an address16, address32, or address64, | ||
320 | * copy it to the address64 return buffer. This saves the | ||
321 | * caller from having to duplicate code for different-sized | ||
322 | * addresses. | ||
323 | * | ||
324 | ******************************************************************************/ | ||
325 | acpi_status | ||
326 | acpi_resource_to_address64(struct acpi_resource *resource, | ||
327 | struct acpi_resource_address64 *out) | ||
328 | { | ||
329 | struct acpi_resource_address16 *address16; | ||
330 | struct acpi_resource_address32 *address32; | ||
331 | |||
332 | if (!resource || !out) { | ||
333 | return (AE_BAD_PARAMETER); | ||
334 | } | ||
335 | |||
336 | /* Convert 16 or 32 address descriptor to 64 */ | ||
337 | |||
338 | switch (resource->type) { | ||
339 | case ACPI_RESOURCE_TYPE_ADDRESS16: | ||
340 | |||
341 | address16 = (struct acpi_resource_address16 *)&resource->data; | ||
342 | ACPI_COPY_ADDRESS(out, address16); | ||
343 | break; | ||
344 | |||
345 | case ACPI_RESOURCE_TYPE_ADDRESS32: | ||
346 | |||
347 | address32 = (struct acpi_resource_address32 *)&resource->data; | ||
348 | ACPI_COPY_ADDRESS(out, address32); | ||
349 | break; | ||
350 | |||
351 | case ACPI_RESOURCE_TYPE_ADDRESS64: | ||
352 | |||
353 | /* Simple copy for 64 bit source */ | ||
354 | |||
355 | ACPI_MEMCPY(out, &resource->data, | ||
356 | sizeof(struct acpi_resource_address64)); | ||
357 | break; | ||
358 | |||
359 | default: | ||
360 | return (AE_BAD_PARAMETER); | ||
361 | } | ||
362 | |||
363 | return (AE_OK); | ||
364 | } | ||
365 | |||
366 | ACPI_EXPORT_SYMBOL(acpi_resource_to_address64) | ||
367 | |||
368 | /******************************************************************************* | ||
369 | * | ||
370 | * FUNCTION: acpi_get_vendor_resource | ||
371 | * | ||
372 | * PARAMETERS: device_handle - Handle for the parent device object | ||
373 | * Name - Method name for the parent resource | ||
374 | * (METHOD_NAME__CRS or METHOD_NAME__PRS) | ||
375 | * Uuid - Pointer to the UUID to be matched. | ||
376 | * includes both subtype and 16-byte UUID | ||
377 | * ret_buffer - Where the vendor resource is returned | ||
378 | * | ||
379 | * RETURN: Status | ||
380 | * | ||
381 | * DESCRIPTION: Walk a resource template for the specified evice to find a | ||
382 | * vendor-defined resource that matches the supplied UUID and | ||
383 | * UUID subtype. Returns a struct acpi_resource of type Vendor. | ||
384 | * | ||
385 | ******************************************************************************/ | ||
386 | acpi_status | ||
387 | acpi_get_vendor_resource(acpi_handle device_handle, | ||
388 | char *name, | ||
389 | struct acpi_vendor_uuid * uuid, | ||
390 | struct acpi_buffer * ret_buffer) | ||
391 | { | ||
392 | struct acpi_vendor_walk_info info; | ||
393 | acpi_status status; | ||
394 | |||
395 | /* Other parameters are validated by acpi_walk_resources */ | ||
396 | |||
397 | if (!uuid || !ret_buffer) { | ||
398 | return (AE_BAD_PARAMETER); | ||
399 | } | ||
400 | |||
401 | info.uuid = uuid; | ||
402 | info.buffer = ret_buffer; | ||
403 | info.status = AE_NOT_EXIST; | ||
404 | |||
405 | /* Walk the _CRS or _PRS resource list for this device */ | ||
406 | |||
407 | status = | ||
408 | acpi_walk_resources(device_handle, name, | ||
409 | acpi_rs_match_vendor_resource, &info); | ||
410 | if (ACPI_FAILURE(status)) { | ||
411 | return (status); | ||
412 | } | ||
413 | |||
414 | return (info.status); | ||
415 | } | ||
416 | |||
417 | ACPI_EXPORT_SYMBOL(acpi_get_vendor_resource) | ||
418 | |||
419 | /******************************************************************************* | ||
420 | * | ||
421 | * FUNCTION: acpi_rs_match_vendor_resource | ||
422 | * | ||
423 | * PARAMETERS: acpi_walk_resource_callback | ||
424 | * | ||
425 | * RETURN: Status | ||
426 | * | ||
427 | * DESCRIPTION: Match a vendor resource via the ACPI 3.0 UUID | ||
428 | * | ||
429 | ******************************************************************************/ | ||
430 | static acpi_status | ||
431 | acpi_rs_match_vendor_resource(struct acpi_resource *resource, void *context) | ||
432 | { | ||
433 | struct acpi_vendor_walk_info *info = context; | ||
434 | struct acpi_resource_vendor_typed *vendor; | ||
435 | struct acpi_buffer *buffer; | ||
436 | acpi_status status; | ||
437 | |||
438 | /* Ignore all descriptors except Vendor */ | ||
439 | |||
440 | if (resource->type != ACPI_RESOURCE_TYPE_VENDOR) { | ||
441 | return (AE_OK); | ||
442 | } | ||
443 | |||
444 | vendor = &resource->data.vendor_typed; | ||
445 | |||
446 | /* | ||
447 | * For a valid match, these conditions must hold: | ||
448 | * | ||
449 | * 1) Length of descriptor data must be at least as long as a UUID struct | ||
450 | * 2) The UUID subtypes must match | ||
451 | * 3) The UUID data must match | ||
452 | */ | ||
453 | if ((vendor->byte_length < (ACPI_UUID_LENGTH + 1)) || | ||
454 | (vendor->uuid_subtype != info->uuid->subtype) || | ||
455 | (ACPI_MEMCMP(vendor->uuid, info->uuid->data, ACPI_UUID_LENGTH))) { | ||
456 | return (AE_OK); | ||
457 | } | ||
458 | |||
459 | /* Validate/Allocate/Clear caller buffer */ | ||
460 | |||
461 | buffer = info->buffer; | ||
462 | status = acpi_ut_initialize_buffer(buffer, resource->length); | ||
463 | if (ACPI_FAILURE(status)) { | ||
464 | return (status); | ||
465 | } | ||
466 | |||
467 | /* Found the correct resource, copy and return it */ | ||
468 | |||
469 | ACPI_MEMCPY(buffer->pointer, resource, resource->length); | ||
470 | buffer->length = resource->length; | ||
471 | |||
472 | /* Found the desired descriptor, terminate resource walk */ | ||
473 | |||
474 | info->status = AE_OK; | ||
475 | return (AE_CTRL_TERMINATE); | ||
476 | } | ||
477 | |||
478 | /******************************************************************************* | ||
479 | * | ||
480 | * FUNCTION: acpi_walk_resources | ||
481 | * | ||
482 | * PARAMETERS: device_handle - Handle to the device object for the | ||
483 | * device we are querying | ||
484 | * Name - Method name of the resources we want | ||
485 | * (METHOD_NAME__CRS or METHOD_NAME__PRS) | ||
486 | * user_function - Called for each resource | ||
487 | * Context - Passed to user_function | ||
488 | * | ||
489 | * RETURN: Status | ||
490 | * | ||
491 | * DESCRIPTION: Retrieves the current or possible resource list for the | ||
492 | * specified device. The user_function is called once for | ||
493 | * each resource in the list. | ||
494 | * | ||
495 | ******************************************************************************/ | ||
496 | acpi_status | ||
497 | acpi_walk_resources(acpi_handle device_handle, | ||
498 | char *name, | ||
499 | acpi_walk_resource_callback user_function, void *context) | ||
500 | { | ||
501 | acpi_status status; | ||
502 | struct acpi_buffer buffer; | ||
503 | struct acpi_resource *resource; | ||
504 | struct acpi_resource *resource_end; | ||
505 | |||
506 | ACPI_FUNCTION_TRACE(acpi_walk_resources); | ||
507 | |||
508 | /* Parameter validation */ | ||
509 | |||
510 | if (!device_handle || !user_function || !name || | ||
511 | (!ACPI_COMPARE_NAME(name, METHOD_NAME__CRS) && | ||
512 | !ACPI_COMPARE_NAME(name, METHOD_NAME__PRS))) { | ||
513 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
514 | } | ||
515 | |||
516 | /* Get the _CRS or _PRS resource list */ | ||
517 | |||
518 | buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; | ||
519 | status = acpi_rs_get_method_data(device_handle, name, &buffer); | ||
520 | if (ACPI_FAILURE(status)) { | ||
521 | return_ACPI_STATUS(status); | ||
522 | } | ||
523 | |||
524 | /* Buffer now contains the resource list */ | ||
525 | |||
526 | resource = ACPI_CAST_PTR(struct acpi_resource, buffer.pointer); | ||
527 | resource_end = | ||
528 | ACPI_ADD_PTR(struct acpi_resource, buffer.pointer, buffer.length); | ||
529 | |||
530 | /* Walk the resource list until the end_tag is found (or buffer end) */ | ||
531 | |||
532 | while (resource < resource_end) { | ||
533 | |||
534 | /* Sanity check the resource */ | ||
535 | |||
536 | if (resource->type > ACPI_RESOURCE_TYPE_MAX) { | ||
537 | status = AE_AML_INVALID_RESOURCE_TYPE; | ||
538 | break; | ||
539 | } | ||
540 | |||
541 | /* Invoke the user function, abort on any error returned */ | ||
542 | |||
543 | status = user_function(resource, context); | ||
544 | if (ACPI_FAILURE(status)) { | ||
545 | if (status == AE_CTRL_TERMINATE) { | ||
546 | |||
547 | /* This is an OK termination by the user function */ | ||
548 | |||
549 | status = AE_OK; | ||
550 | } | ||
551 | break; | ||
552 | } | ||
553 | |||
554 | /* end_tag indicates end-of-list */ | ||
555 | |||
556 | if (resource->type == ACPI_RESOURCE_TYPE_END_TAG) { | ||
557 | break; | ||
558 | } | ||
559 | |||
560 | /* Get the next resource descriptor */ | ||
561 | |||
562 | resource = | ||
563 | ACPI_ADD_PTR(struct acpi_resource, resource, | ||
564 | resource->length); | ||
565 | } | ||
566 | |||
567 | ACPI_FREE(buffer.pointer); | ||
568 | return_ACPI_STATUS(status); | ||
569 | } | ||
570 | |||
571 | ACPI_EXPORT_SYMBOL(acpi_walk_resources) | ||