Linux-libre 4.19.8-gnu
[librecmc/linux-libre.git] / drivers / acpi / acpica / rsxface.c
1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2 /*******************************************************************************
3  *
4  * Module Name: rsxface - Public interfaces to the resource manager
5  *
6  ******************************************************************************/
7
8 #define EXPORT_ACPI_INTERFACES
9
10 #include <acpi/acpi.h>
11 #include "accommon.h"
12 #include "acresrc.h"
13 #include "acnamesp.h"
14
15 #define _COMPONENT          ACPI_RESOURCES
16 ACPI_MODULE_NAME("rsxface")
17
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 */
34 static acpi_status
35 acpi_rs_match_vendor_resource(struct acpi_resource *resource, void *context);
36
37 static acpi_status
38 acpi_rs_validate_parameters(acpi_handle device_handle,
39                             struct acpi_buffer *buffer,
40                             struct acpi_namespace_node **return_node);
41
42 /*******************************************************************************
43  *
44  * FUNCTION:    acpi_rs_validate_parameters
45  *
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
49  *
50  * RETURN:      Status
51  *
52  * DESCRIPTION: Common parameter validation for resource interfaces
53  *
54  ******************************************************************************/
55
56 static acpi_status
57 acpi_rs_validate_parameters(acpi_handle device_handle,
58                             struct acpi_buffer *buffer,
59                             struct acpi_namespace_node **return_node)
60 {
61         acpi_status status;
62         struct acpi_namespace_node *node;
63
64         ACPI_FUNCTION_TRACE(rs_validate_parameters);
65
66         /*
67          * Must have a valid handle to an ACPI device
68          */
69         if (!device_handle) {
70                 return_ACPI_STATUS(AE_BAD_PARAMETER);
71         }
72
73         node = acpi_ns_validate_handle(device_handle);
74         if (!node) {
75                 return_ACPI_STATUS(AE_BAD_PARAMETER);
76         }
77
78         if (node->type != ACPI_TYPE_DEVICE) {
79                 return_ACPI_STATUS(AE_TYPE);
80         }
81
82         /*
83          * Validate the user buffer object
84          *
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.
88          */
89         status = acpi_ut_validate_buffer(buffer);
90         if (ACPI_FAILURE(status)) {
91                 return_ACPI_STATUS(status);
92         }
93
94         *return_node = node;
95         return_ACPI_STATUS(AE_OK);
96 }
97
98 /*******************************************************************************
99  *
100  * FUNCTION:    acpi_get_irq_routing_table
101  *
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
105  *
106  * RETURN:      Status
107  *
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.
112  *
113  *              If the function fails an appropriate status will be returned
114  *              and the value of ret_buffer is undefined.
115  *
116  *              This function attempts to execute the _PRT method contained in
117  *              the object indicated by the passed device_handle.
118  *
119  ******************************************************************************/
120
121 acpi_status
122 acpi_get_irq_routing_table(acpi_handle device_handle,
123                            struct acpi_buffer *ret_buffer)
124 {
125         acpi_status status;
126         struct acpi_namespace_node *node;
127
128         ACPI_FUNCTION_TRACE(acpi_get_irq_routing_table);
129
130         /* Validate parameters then dispatch to internal routine */
131
132         status = acpi_rs_validate_parameters(device_handle, ret_buffer, &node);
133         if (ACPI_FAILURE(status)) {
134                 return_ACPI_STATUS(status);
135         }
136
137         status = acpi_rs_get_prt_method_data(node, ret_buffer);
138         return_ACPI_STATUS(status);
139 }
140
141 ACPI_EXPORT_SYMBOL(acpi_get_irq_routing_table)
142
143 /*******************************************************************************
144  *
145  * FUNCTION:    acpi_get_current_resources
146  *
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
151  *
152  * RETURN:      Status
153  *
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.
158  *
159  *              If the function fails an appropriate status will be returned
160  *              and the value of ret_buffer is undefined.
161  *
162  *              This function attempts to execute the _CRS method contained in
163  *              the object indicated by the passed device_handle.
164  *
165  ******************************************************************************/
166 acpi_status
167 acpi_get_current_resources(acpi_handle device_handle,
168                            struct acpi_buffer *ret_buffer)
169 {
170         acpi_status status;
171         struct acpi_namespace_node *node;
172
173         ACPI_FUNCTION_TRACE(acpi_get_current_resources);
174
175         /* Validate parameters then dispatch to internal routine */
176
177         status = acpi_rs_validate_parameters(device_handle, ret_buffer, &node);
178         if (ACPI_FAILURE(status)) {
179                 return_ACPI_STATUS(status);
180         }
181
182         status = acpi_rs_get_crs_method_data(node, ret_buffer);
183         return_ACPI_STATUS(status);
184 }
185
186 ACPI_EXPORT_SYMBOL(acpi_get_current_resources)
187
188 /*******************************************************************************
189  *
190  * FUNCTION:    acpi_get_possible_resources
191  *
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
196  *
197  * RETURN:      Status
198  *
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.
203  *
204  *              If the function fails an appropriate status will be returned
205  *              and the value of ret_buffer is undefined.
206  *
207  ******************************************************************************/
208 acpi_status
209 acpi_get_possible_resources(acpi_handle device_handle,
210                             struct acpi_buffer *ret_buffer)
211 {
212         acpi_status status;
213         struct acpi_namespace_node *node;
214
215         ACPI_FUNCTION_TRACE(acpi_get_possible_resources);
216
217         /* Validate parameters then dispatch to internal routine */
218
219         status = acpi_rs_validate_parameters(device_handle, ret_buffer, &node);
220         if (ACPI_FAILURE(status)) {
221                 return_ACPI_STATUS(status);
222         }
223
224         status = acpi_rs_get_prs_method_data(node, ret_buffer);
225         return_ACPI_STATUS(status);
226 }
227
228 ACPI_EXPORT_SYMBOL(acpi_get_possible_resources)
229
230 /*******************************************************************************
231  *
232  * FUNCTION:    acpi_set_current_resources
233  *
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
238  *
239  * RETURN:      Status
240  *
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.
245  *
246  ******************************************************************************/
247 acpi_status
248 acpi_set_current_resources(acpi_handle device_handle,
249                            struct acpi_buffer *in_buffer)
250 {
251         acpi_status status;
252         struct acpi_namespace_node *node;
253
254         ACPI_FUNCTION_TRACE(acpi_set_current_resources);
255
256         /* Validate the buffer, don't allow zero length */
257
258         if ((!in_buffer) || (!in_buffer->pointer) || (!in_buffer->length)) {
259                 return_ACPI_STATUS(AE_BAD_PARAMETER);
260         }
261
262         /* Validate parameters then dispatch to internal routine */
263
264         status = acpi_rs_validate_parameters(device_handle, in_buffer, &node);
265         if (ACPI_FAILURE(status)) {
266                 return_ACPI_STATUS(status);
267         }
268
269         status = acpi_rs_set_srs_method_data(node, in_buffer);
270         return_ACPI_STATUS(status);
271 }
272
273 ACPI_EXPORT_SYMBOL(acpi_set_current_resources)
274
275 /*******************************************************************************
276  *
277  * FUNCTION:    acpi_get_event_resources
278  *
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
283  *
284  * RETURN:      Status
285  *
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
290  *              _AEI method.
291  *
292  ******************************************************************************/
293 acpi_status
294 acpi_get_event_resources(acpi_handle device_handle,
295                          struct acpi_buffer *ret_buffer)
296 {
297         acpi_status status;
298         struct acpi_namespace_node *node;
299
300         ACPI_FUNCTION_TRACE(acpi_get_event_resources);
301
302         /* Validate parameters then dispatch to internal routine */
303
304         status = acpi_rs_validate_parameters(device_handle, ret_buffer, &node);
305         if (ACPI_FAILURE(status)) {
306                 return_ACPI_STATUS(status);
307         }
308
309         status = acpi_rs_get_aei_method_data(node, ret_buffer);
310         return_ACPI_STATUS(status);
311 }
312
313 ACPI_EXPORT_SYMBOL(acpi_get_event_resources)
314
315 /******************************************************************************
316  *
317  * FUNCTION:    acpi_resource_to_address64
318  *
319  * PARAMETERS:  resource        - Pointer to a resource
320  *              out             - Pointer to the users's return buffer
321  *                                (a struct acpi_resource_address64)
322  *
323  * RETURN:      Status
324  *
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
328  *              addresses.
329  *
330  ******************************************************************************/
331 acpi_status
332 acpi_resource_to_address64(struct acpi_resource *resource,
333                            struct acpi_resource_address64 *out)
334 {
335         struct acpi_resource_address16 *address16;
336         struct acpi_resource_address32 *address32;
337
338         if (!resource || !out) {
339                 return (AE_BAD_PARAMETER);
340         }
341
342         /* Convert 16 or 32 address descriptor to 64 */
343
344         switch (resource->type) {
345         case ACPI_RESOURCE_TYPE_ADDRESS16:
346
347                 address16 =
348                     ACPI_CAST_PTR(struct acpi_resource_address16,
349                                   &resource->data);
350                 ACPI_COPY_ADDRESS(out, address16);
351                 break;
352
353         case ACPI_RESOURCE_TYPE_ADDRESS32:
354
355                 address32 =
356                     ACPI_CAST_PTR(struct acpi_resource_address32,
357                                   &resource->data);
358                 ACPI_COPY_ADDRESS(out, address32);
359                 break;
360
361         case ACPI_RESOURCE_TYPE_ADDRESS64:
362
363                 /* Simple copy for 64 bit source */
364
365                 memcpy(out, &resource->data,
366                        sizeof(struct acpi_resource_address64));
367                 break;
368
369         default:
370
371                 return (AE_BAD_PARAMETER);
372         }
373
374         return (AE_OK);
375 }
376
377 ACPI_EXPORT_SYMBOL(acpi_resource_to_address64)
378
379 /*******************************************************************************
380  *
381  * FUNCTION:    acpi_get_vendor_resource
382  *
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
389  *
390  * RETURN:      Status
391  *
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.
395  *
396  ******************************************************************************/
397 acpi_status
398 acpi_get_vendor_resource(acpi_handle device_handle,
399                          char *name,
400                          struct acpi_vendor_uuid *uuid,
401                          struct acpi_buffer *ret_buffer)
402 {
403         struct acpi_vendor_walk_info info;
404         acpi_status status;
405
406         /* Other parameters are validated by acpi_walk_resources */
407
408         if (!uuid || !ret_buffer) {
409                 return (AE_BAD_PARAMETER);
410         }
411
412         info.uuid = uuid;
413         info.buffer = ret_buffer;
414         info.status = AE_NOT_EXIST;
415
416         /* Walk the _CRS or _PRS resource list for this device */
417
418         status =
419             acpi_walk_resources(device_handle, name,
420                                 acpi_rs_match_vendor_resource, &info);
421         if (ACPI_FAILURE(status)) {
422                 return (status);
423         }
424
425         return (info.status);
426 }
427
428 ACPI_EXPORT_SYMBOL(acpi_get_vendor_resource)
429
430 /*******************************************************************************
431  *
432  * FUNCTION:    acpi_rs_match_vendor_resource
433  *
434  * PARAMETERS:  acpi_walk_resource_callback
435  *
436  * RETURN:      Status
437  *
438  * DESCRIPTION: Match a vendor resource via the ACPI 3.0 UUID
439  *
440  ******************************************************************************/
441 static acpi_status
442 acpi_rs_match_vendor_resource(struct acpi_resource *resource, void *context)
443 {
444         struct acpi_vendor_walk_info *info = context;
445         struct acpi_resource_vendor_typed *vendor;
446         struct acpi_buffer *buffer;
447         acpi_status status;
448
449         /* Ignore all descriptors except Vendor */
450
451         if (resource->type != ACPI_RESOURCE_TYPE_VENDOR) {
452                 return (AE_OK);
453         }
454
455         vendor = &resource->data.vendor_typed;
456
457         /*
458          * For a valid match, these conditions must hold:
459          *
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
463          */
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))) {
467                 return (AE_OK);
468         }
469
470         /* Validate/Allocate/Clear caller buffer */
471
472         buffer = info->buffer;
473         status = acpi_ut_initialize_buffer(buffer, resource->length);
474         if (ACPI_FAILURE(status)) {
475                 return (status);
476         }
477
478         /* Found the correct resource, copy and return it */
479
480         memcpy(buffer->pointer, resource, resource->length);
481         buffer->length = resource->length;
482
483         /* Found the desired descriptor, terminate resource walk */
484
485         info->status = AE_OK;
486         return (AE_CTRL_TERMINATE);
487 }
488
489 /*******************************************************************************
490  *
491  * FUNCTION:    acpi_walk_resource_buffer
492  *
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
497  *
498  * RETURN:      Status
499  *
500  * DESCRIPTION: Walks the input resource template. The user_function is called
501  *              once for each resource in the list.
502  *
503  ******************************************************************************/
504
505 acpi_status
506 acpi_walk_resource_buffer(struct acpi_buffer *buffer,
507                           acpi_walk_resource_callback user_function,
508                           void *context)
509 {
510         acpi_status status = AE_OK;
511         struct acpi_resource *resource;
512         struct acpi_resource *resource_end;
513
514         ACPI_FUNCTION_TRACE(acpi_walk_resource_buffer);
515
516         /* Parameter validation */
517
518         if (!buffer || !buffer->pointer || !user_function) {
519                 return_ACPI_STATUS(AE_BAD_PARAMETER);
520         }
521
522         /* Buffer contains the resource list and length */
523
524         resource = ACPI_CAST_PTR(struct acpi_resource, buffer->pointer);
525         resource_end =
526             ACPI_ADD_PTR(struct acpi_resource, buffer->pointer, buffer->length);
527
528         /* Walk the resource list until the end_tag is found (or buffer end) */
529
530         while (resource < resource_end) {
531
532                 /* Sanity check the resource type */
533
534                 if (resource->type > ACPI_RESOURCE_TYPE_MAX) {
535                         status = AE_AML_INVALID_RESOURCE_TYPE;
536                         break;
537                 }
538
539                 /* Sanity check the length. It must not be zero, or we loop forever */
540
541                 if (!resource->length) {
542                         return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH);
543                 }
544
545                 /* Invoke the user function, abort on any error returned */
546
547                 status = user_function(resource, context);
548                 if (ACPI_FAILURE(status)) {
549                         if (status == AE_CTRL_TERMINATE) {
550
551                                 /* This is an OK termination by the user function */
552
553                                 status = AE_OK;
554                         }
555                         break;
556                 }
557
558                 /* end_tag indicates end-of-list */
559
560                 if (resource->type == ACPI_RESOURCE_TYPE_END_TAG) {
561                         break;
562                 }
563
564                 /* Get the next resource descriptor */
565
566                 resource = ACPI_NEXT_RESOURCE(resource);
567         }
568
569         return_ACPI_STATUS(status);
570 }
571
572 ACPI_EXPORT_SYMBOL(acpi_walk_resource_buffer)
573
574 /*******************************************************************************
575  *
576  * FUNCTION:    acpi_walk_resources
577  *
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
585  *
586  * RETURN:      Status
587  *
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.
591  *
592  ******************************************************************************/
593 acpi_status
594 acpi_walk_resources(acpi_handle device_handle,
595                     char *name,
596                     acpi_walk_resource_callback user_function, void *context)
597 {
598         acpi_status status;
599         struct acpi_buffer buffer;
600
601         ACPI_FUNCTION_TRACE(acpi_walk_resources);
602
603         /* Parameter validation */
604
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);
611         }
612
613         /* Get the _CRS/_PRS/_AEI/_DMA resource list */
614
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);
619         }
620
621         /* Walk the resource list and cleanup */
622
623         status = acpi_walk_resource_buffer(&buffer, user_function, context);
624         ACPI_FREE(buffer.pointer);
625         return_ACPI_STATUS(status);
626 }
627
628 ACPI_EXPORT_SYMBOL(acpi_walk_resources)