1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2 /*******************************************************************************
4 * Module Name: rsxface - Public interfaces to the resource manager
6 ******************************************************************************/
8 #define EXPORT_ACPI_INTERFACES
10 #include <acpi/acpi.h>
15 #define _COMPONENT ACPI_RESOURCES
16 ACPI_MODULE_NAME("rsxface")
18 /* Local macros for 16,32-bit to 64-bit conversion */
19 #define ACPI_COPY_FIELD(out, in, field) ((out)->field = (in)->field)
20 #define ACPI_COPY_ADDRESS(out, in) \
21 ACPI_COPY_FIELD(out, in, resource_type); \
22 ACPI_COPY_FIELD(out, in, producer_consumer); \
23 ACPI_COPY_FIELD(out, in, decode); \
24 ACPI_COPY_FIELD(out, in, min_address_fixed); \
25 ACPI_COPY_FIELD(out, in, max_address_fixed); \
26 ACPI_COPY_FIELD(out, in, info); \
27 ACPI_COPY_FIELD(out, in, address.granularity); \
28 ACPI_COPY_FIELD(out, in, address.minimum); \
29 ACPI_COPY_FIELD(out, in, address.maximum); \
30 ACPI_COPY_FIELD(out, in, address.translation_offset); \
31 ACPI_COPY_FIELD(out, in, address.address_length); \
32 ACPI_COPY_FIELD(out, in, resource_source);
33 /* Local prototypes */
35 acpi_rs_match_vendor_resource(struct acpi_resource
*resource
, void *context
);
38 acpi_rs_validate_parameters(acpi_handle device_handle
,
39 struct acpi_buffer
*buffer
,
40 struct acpi_namespace_node
**return_node
);
42 /*******************************************************************************
44 * FUNCTION: acpi_rs_validate_parameters
46 * PARAMETERS: device_handle - Handle to a device
47 * buffer - Pointer to a data buffer
48 * return_node - Pointer to where the device node is returned
52 * DESCRIPTION: Common parameter validation for resource interfaces
54 ******************************************************************************/
57 acpi_rs_validate_parameters(acpi_handle device_handle
,
58 struct acpi_buffer
*buffer
,
59 struct acpi_namespace_node
**return_node
)
62 struct acpi_namespace_node
*node
;
64 ACPI_FUNCTION_TRACE(rs_validate_parameters
);
67 * Must have a valid handle to an ACPI device
70 return_ACPI_STATUS(AE_BAD_PARAMETER
);
73 node
= acpi_ns_validate_handle(device_handle
);
75 return_ACPI_STATUS(AE_BAD_PARAMETER
);
78 if (node
->type
!= ACPI_TYPE_DEVICE
) {
79 return_ACPI_STATUS(AE_TYPE
);
83 * Validate the user buffer object
85 * if there is a non-zero buffer length we also need a valid pointer in
86 * the buffer. If it's a zero buffer length, we'll be returning the
87 * needed buffer size (later), so keep going.
89 status
= acpi_ut_validate_buffer(buffer
);
90 if (ACPI_FAILURE(status
)) {
91 return_ACPI_STATUS(status
);
95 return_ACPI_STATUS(AE_OK
);
98 /*******************************************************************************
100 * FUNCTION: acpi_get_irq_routing_table
102 * PARAMETERS: device_handle - Handle to the Bus device we are querying
103 * ret_buffer - Pointer to a buffer to receive the
104 * current resources for the device
108 * DESCRIPTION: This function is called to get the IRQ routing table for a
109 * specific bus. The caller must first acquire a handle for the
110 * desired bus. The routine table is placed in the buffer pointed
111 * to by the ret_buffer variable parameter.
113 * If the function fails an appropriate status will be returned
114 * and the value of ret_buffer is undefined.
116 * This function attempts to execute the _PRT method contained in
117 * the object indicated by the passed device_handle.
119 ******************************************************************************/
122 acpi_get_irq_routing_table(acpi_handle device_handle
,
123 struct acpi_buffer
*ret_buffer
)
126 struct acpi_namespace_node
*node
;
128 ACPI_FUNCTION_TRACE(acpi_get_irq_routing_table
);
130 /* Validate parameters then dispatch to internal routine */
132 status
= acpi_rs_validate_parameters(device_handle
, ret_buffer
, &node
);
133 if (ACPI_FAILURE(status
)) {
134 return_ACPI_STATUS(status
);
137 status
= acpi_rs_get_prt_method_data(node
, ret_buffer
);
138 return_ACPI_STATUS(status
);
141 ACPI_EXPORT_SYMBOL(acpi_get_irq_routing_table
)
143 /*******************************************************************************
145 * FUNCTION: acpi_get_current_resources
147 * PARAMETERS: device_handle - Handle to the device object for the
148 * device we are querying
149 * ret_buffer - Pointer to a buffer to receive the
150 * current resources for the device
154 * DESCRIPTION: This function is called to get the current resources for a
155 * specific device. The caller must first acquire a handle for
156 * the desired device. The resource data is placed in the buffer
157 * pointed to by the ret_buffer variable parameter.
159 * If the function fails an appropriate status will be returned
160 * and the value of ret_buffer is undefined.
162 * This function attempts to execute the _CRS method contained in
163 * the object indicated by the passed device_handle.
165 ******************************************************************************/
167 acpi_get_current_resources(acpi_handle device_handle
,
168 struct acpi_buffer
*ret_buffer
)
171 struct acpi_namespace_node
*node
;
173 ACPI_FUNCTION_TRACE(acpi_get_current_resources
);
175 /* Validate parameters then dispatch to internal routine */
177 status
= acpi_rs_validate_parameters(device_handle
, ret_buffer
, &node
);
178 if (ACPI_FAILURE(status
)) {
179 return_ACPI_STATUS(status
);
182 status
= acpi_rs_get_crs_method_data(node
, ret_buffer
);
183 return_ACPI_STATUS(status
);
186 ACPI_EXPORT_SYMBOL(acpi_get_current_resources
)
188 /*******************************************************************************
190 * FUNCTION: acpi_get_possible_resources
192 * PARAMETERS: device_handle - Handle to the device object for the
193 * device we are querying
194 * ret_buffer - Pointer to a buffer to receive the
195 * resources for the device
199 * DESCRIPTION: This function is called to get a list of the possible resources
200 * for a specific device. The caller must first acquire a handle
201 * for the desired device. The resource data is placed in the
202 * buffer pointed to by the ret_buffer variable.
204 * If the function fails an appropriate status will be returned
205 * and the value of ret_buffer is undefined.
207 ******************************************************************************/
209 acpi_get_possible_resources(acpi_handle device_handle
,
210 struct acpi_buffer
*ret_buffer
)
213 struct acpi_namespace_node
*node
;
215 ACPI_FUNCTION_TRACE(acpi_get_possible_resources
);
217 /* Validate parameters then dispatch to internal routine */
219 status
= acpi_rs_validate_parameters(device_handle
, ret_buffer
, &node
);
220 if (ACPI_FAILURE(status
)) {
221 return_ACPI_STATUS(status
);
224 status
= acpi_rs_get_prs_method_data(node
, ret_buffer
);
225 return_ACPI_STATUS(status
);
228 ACPI_EXPORT_SYMBOL(acpi_get_possible_resources
)
230 /*******************************************************************************
232 * FUNCTION: acpi_set_current_resources
234 * PARAMETERS: device_handle - Handle to the device object for the
235 * device we are setting resources
236 * in_buffer - Pointer to a buffer containing the
237 * resources to be set for the device
241 * DESCRIPTION: This function is called to set the current resources for a
242 * specific device. The caller must first acquire a handle for
243 * the desired device. The resource data is passed to the routine
244 * the buffer pointed to by the in_buffer variable.
246 ******************************************************************************/
248 acpi_set_current_resources(acpi_handle device_handle
,
249 struct acpi_buffer
*in_buffer
)
252 struct acpi_namespace_node
*node
;
254 ACPI_FUNCTION_TRACE(acpi_set_current_resources
);
256 /* Validate the buffer, don't allow zero length */
258 if ((!in_buffer
) || (!in_buffer
->pointer
) || (!in_buffer
->length
)) {
259 return_ACPI_STATUS(AE_BAD_PARAMETER
);
262 /* Validate parameters then dispatch to internal routine */
264 status
= acpi_rs_validate_parameters(device_handle
, in_buffer
, &node
);
265 if (ACPI_FAILURE(status
)) {
266 return_ACPI_STATUS(status
);
269 status
= acpi_rs_set_srs_method_data(node
, in_buffer
);
270 return_ACPI_STATUS(status
);
273 ACPI_EXPORT_SYMBOL(acpi_set_current_resources
)
275 /*******************************************************************************
277 * FUNCTION: acpi_get_event_resources
279 * PARAMETERS: device_handle - Handle to the device object for the
280 * device we are getting resources
281 * in_buffer - Pointer to a buffer containing the
282 * resources to be set for the device
286 * DESCRIPTION: This function is called to get the event resources for a
287 * specific device. The caller must first acquire a handle for
288 * the desired device. The resource data is passed to the routine
289 * the buffer pointed to by the in_buffer variable. Uses the
292 ******************************************************************************/
294 acpi_get_event_resources(acpi_handle device_handle
,
295 struct acpi_buffer
*ret_buffer
)
298 struct acpi_namespace_node
*node
;
300 ACPI_FUNCTION_TRACE(acpi_get_event_resources
);
302 /* Validate parameters then dispatch to internal routine */
304 status
= acpi_rs_validate_parameters(device_handle
, ret_buffer
, &node
);
305 if (ACPI_FAILURE(status
)) {
306 return_ACPI_STATUS(status
);
309 status
= acpi_rs_get_aei_method_data(node
, ret_buffer
);
310 return_ACPI_STATUS(status
);
313 ACPI_EXPORT_SYMBOL(acpi_get_event_resources
)
315 /******************************************************************************
317 * FUNCTION: acpi_resource_to_address64
319 * PARAMETERS: resource - Pointer to a resource
320 * out - Pointer to the users's return buffer
321 * (a struct acpi_resource_address64)
325 * DESCRIPTION: If the resource is an address16, address32, or address64,
326 * copy it to the address64 return buffer. This saves the
327 * caller from having to duplicate code for different-sized
330 ******************************************************************************/
332 acpi_resource_to_address64(struct acpi_resource
*resource
,
333 struct acpi_resource_address64
*out
)
335 struct acpi_resource_address16
*address16
;
336 struct acpi_resource_address32
*address32
;
338 if (!resource
|| !out
) {
339 return (AE_BAD_PARAMETER
);
342 /* Convert 16 or 32 address descriptor to 64 */
344 switch (resource
->type
) {
345 case ACPI_RESOURCE_TYPE_ADDRESS16
:
348 ACPI_CAST_PTR(struct acpi_resource_address16
,
350 ACPI_COPY_ADDRESS(out
, address16
);
353 case ACPI_RESOURCE_TYPE_ADDRESS32
:
356 ACPI_CAST_PTR(struct acpi_resource_address32
,
358 ACPI_COPY_ADDRESS(out
, address32
);
361 case ACPI_RESOURCE_TYPE_ADDRESS64
:
363 /* Simple copy for 64 bit source */
365 memcpy(out
, &resource
->data
,
366 sizeof(struct acpi_resource_address64
));
371 return (AE_BAD_PARAMETER
);
377 ACPI_EXPORT_SYMBOL(acpi_resource_to_address64
)
379 /*******************************************************************************
381 * FUNCTION: acpi_get_vendor_resource
383 * PARAMETERS: device_handle - Handle for the parent device object
384 * name - Method name for the parent resource
385 * (METHOD_NAME__CRS or METHOD_NAME__PRS)
386 * uuid - Pointer to the UUID to be matched.
387 * includes both subtype and 16-byte UUID
388 * ret_buffer - Where the vendor resource is returned
392 * DESCRIPTION: Walk a resource template for the specified device to find a
393 * vendor-defined resource that matches the supplied UUID and
394 * UUID subtype. Returns a struct acpi_resource of type Vendor.
396 ******************************************************************************/
398 acpi_get_vendor_resource(acpi_handle device_handle
,
400 struct acpi_vendor_uuid
*uuid
,
401 struct acpi_buffer
*ret_buffer
)
403 struct acpi_vendor_walk_info info
;
406 /* Other parameters are validated by acpi_walk_resources */
408 if (!uuid
|| !ret_buffer
) {
409 return (AE_BAD_PARAMETER
);
413 info
.buffer
= ret_buffer
;
414 info
.status
= AE_NOT_EXIST
;
416 /* Walk the _CRS or _PRS resource list for this device */
419 acpi_walk_resources(device_handle
, name
,
420 acpi_rs_match_vendor_resource
, &info
);
421 if (ACPI_FAILURE(status
)) {
425 return (info
.status
);
428 ACPI_EXPORT_SYMBOL(acpi_get_vendor_resource
)
430 /*******************************************************************************
432 * FUNCTION: acpi_rs_match_vendor_resource
434 * PARAMETERS: acpi_walk_resource_callback
438 * DESCRIPTION: Match a vendor resource via the ACPI 3.0 UUID
440 ******************************************************************************/
442 acpi_rs_match_vendor_resource(struct acpi_resource
*resource
, void *context
)
444 struct acpi_vendor_walk_info
*info
= context
;
445 struct acpi_resource_vendor_typed
*vendor
;
446 struct acpi_buffer
*buffer
;
449 /* Ignore all descriptors except Vendor */
451 if (resource
->type
!= ACPI_RESOURCE_TYPE_VENDOR
) {
455 vendor
= &resource
->data
.vendor_typed
;
458 * For a valid match, these conditions must hold:
460 * 1) Length of descriptor data must be at least as long as a UUID struct
461 * 2) The UUID subtypes must match
462 * 3) The UUID data must match
464 if ((vendor
->byte_length
< (ACPI_UUID_LENGTH
+ 1)) ||
465 (vendor
->uuid_subtype
!= info
->uuid
->subtype
) ||
466 (memcmp(vendor
->uuid
, info
->uuid
->data
, ACPI_UUID_LENGTH
))) {
470 /* Validate/Allocate/Clear caller buffer */
472 buffer
= info
->buffer
;
473 status
= acpi_ut_initialize_buffer(buffer
, resource
->length
);
474 if (ACPI_FAILURE(status
)) {
478 /* Found the correct resource, copy and return it */
480 memcpy(buffer
->pointer
, resource
, resource
->length
);
481 buffer
->length
= resource
->length
;
483 /* Found the desired descriptor, terminate resource walk */
485 info
->status
= AE_OK
;
486 return (AE_CTRL_TERMINATE
);
489 /*******************************************************************************
491 * FUNCTION: acpi_walk_resource_buffer
493 * PARAMETERS: buffer - Formatted buffer returned by one of the
494 * various Get*Resource functions
495 * user_function - Called for each resource
496 * context - Passed to user_function
500 * DESCRIPTION: Walks the input resource template. The user_function is called
501 * once for each resource in the list.
503 ******************************************************************************/
506 acpi_walk_resource_buffer(struct acpi_buffer
*buffer
,
507 acpi_walk_resource_callback user_function
,
510 acpi_status status
= AE_OK
;
511 struct acpi_resource
*resource
;
512 struct acpi_resource
*resource_end
;
514 ACPI_FUNCTION_TRACE(acpi_walk_resource_buffer
);
516 /* Parameter validation */
518 if (!buffer
|| !buffer
->pointer
|| !user_function
) {
519 return_ACPI_STATUS(AE_BAD_PARAMETER
);
522 /* Buffer contains the resource list and length */
524 resource
= ACPI_CAST_PTR(struct acpi_resource
, buffer
->pointer
);
526 ACPI_ADD_PTR(struct acpi_resource
, buffer
->pointer
, buffer
->length
);
528 /* Walk the resource list until the end_tag is found (or buffer end) */
530 while (resource
< resource_end
) {
532 /* Sanity check the resource type */
534 if (resource
->type
> ACPI_RESOURCE_TYPE_MAX
) {
535 status
= AE_AML_INVALID_RESOURCE_TYPE
;
539 /* Sanity check the length. It must not be zero, or we loop forever */
541 if (!resource
->length
) {
542 return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH
);
545 /* Invoke the user function, abort on any error returned */
547 status
= user_function(resource
, context
);
548 if (ACPI_FAILURE(status
)) {
549 if (status
== AE_CTRL_TERMINATE
) {
551 /* This is an OK termination by the user function */
558 /* end_tag indicates end-of-list */
560 if (resource
->type
== ACPI_RESOURCE_TYPE_END_TAG
) {
564 /* Get the next resource descriptor */
566 resource
= ACPI_NEXT_RESOURCE(resource
);
569 return_ACPI_STATUS(status
);
572 ACPI_EXPORT_SYMBOL(acpi_walk_resource_buffer
)
574 /*******************************************************************************
576 * FUNCTION: acpi_walk_resources
578 * PARAMETERS: device_handle - Handle to the device object for the
579 * device we are querying
580 * name - Method name of the resources we want.
581 * (METHOD_NAME__CRS, METHOD_NAME__PRS, or
582 * METHOD_NAME__AEI or METHOD_NAME__DMA)
583 * user_function - Called for each resource
584 * context - Passed to user_function
588 * DESCRIPTION: Retrieves the current or possible resource list for the
589 * specified device. The user_function is called once for
590 * each resource in the list.
592 ******************************************************************************/
594 acpi_walk_resources(acpi_handle device_handle
,
596 acpi_walk_resource_callback user_function
, void *context
)
599 struct acpi_buffer buffer
;
601 ACPI_FUNCTION_TRACE(acpi_walk_resources
);
603 /* Parameter validation */
605 if (!device_handle
|| !user_function
|| !name
||
606 (!ACPI_COMPARE_NAME(name
, METHOD_NAME__CRS
) &&
607 !ACPI_COMPARE_NAME(name
, METHOD_NAME__PRS
) &&
608 !ACPI_COMPARE_NAME(name
, METHOD_NAME__AEI
) &&
609 !ACPI_COMPARE_NAME(name
, METHOD_NAME__DMA
))) {
610 return_ACPI_STATUS(AE_BAD_PARAMETER
);
613 /* Get the _CRS/_PRS/_AEI/_DMA resource list */
615 buffer
.length
= ACPI_ALLOCATE_LOCAL_BUFFER
;
616 status
= acpi_rs_get_method_data(device_handle
, name
, &buffer
);
617 if (ACPI_FAILURE(status
)) {
618 return_ACPI_STATUS(status
);
621 /* Walk the resource list and cleanup */
623 status
= acpi_walk_resource_buffer(&buffer
, user_function
, context
);
624 ACPI_FREE(buffer
.pointer
);
625 return_ACPI_STATUS(status
);
628 ACPI_EXPORT_SYMBOL(acpi_walk_resources
)