]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - sys/contrib/dev/acpica/resources/rsxface.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / sys / contrib / dev / acpica / resources / rsxface.c
1 /*******************************************************************************
2  *
3  * Module Name: rsxface - Public interfaces to the resource manager
4  *
5  ******************************************************************************/
6
7 /*
8  * Copyright (C) 2000 - 2011, 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
45 #define __RSXFACE_C__
46
47 #include <contrib/dev/acpica/include/acpi.h>
48 #include <contrib/dev/acpica/include/accommon.h>
49 #include <contrib/dev/acpica/include/acresrc.h>
50 #include <contrib/dev/acpica/include/acnamesp.h>
51
52 #define _COMPONENT          ACPI_RESOURCES
53         ACPI_MODULE_NAME    ("rsxface")
54
55 /* Local macros for 16,32-bit to 64-bit conversion */
56
57 #define ACPI_COPY_FIELD(Out, In, Field)  ((Out)->Field = (In)->Field)
58 #define ACPI_COPY_ADDRESS(Out, In)                      \
59     ACPI_COPY_FIELD(Out, In, ResourceType);              \
60     ACPI_COPY_FIELD(Out, In, ProducerConsumer);          \
61     ACPI_COPY_FIELD(Out, In, Decode);                    \
62     ACPI_COPY_FIELD(Out, In, MinAddressFixed);           \
63     ACPI_COPY_FIELD(Out, In, MaxAddressFixed);           \
64     ACPI_COPY_FIELD(Out, In, Info);                      \
65     ACPI_COPY_FIELD(Out, In, Granularity);               \
66     ACPI_COPY_FIELD(Out, In, Minimum);                   \
67     ACPI_COPY_FIELD(Out, In, Maximum);                   \
68     ACPI_COPY_FIELD(Out, In, TranslationOffset);         \
69     ACPI_COPY_FIELD(Out, In, AddressLength);             \
70     ACPI_COPY_FIELD(Out, In, ResourceSource);
71
72
73 /* Local prototypes */
74
75 static ACPI_STATUS
76 AcpiRsMatchVendorResource (
77     ACPI_RESOURCE           *Resource,
78     void                    *Context);
79
80 static ACPI_STATUS
81 AcpiRsValidateParameters (
82     ACPI_HANDLE             DeviceHandle,
83     ACPI_BUFFER             *Buffer,
84     ACPI_NAMESPACE_NODE     **ReturnNode);
85
86
87 /*******************************************************************************
88  *
89  * FUNCTION:    AcpiRsValidateParameters
90  *
91  * PARAMETERS:  DeviceHandle    - Handle to a device
92  *              Buffer          - Pointer to a data buffer
93  *              ReturnNode      - Pointer to where the device node is returned
94  *
95  * RETURN:      Status
96  *
97  * DESCRIPTION: Common parameter validation for resource interfaces
98  *
99  ******************************************************************************/
100
101 static ACPI_STATUS
102 AcpiRsValidateParameters (
103     ACPI_HANDLE             DeviceHandle,
104     ACPI_BUFFER             *Buffer,
105     ACPI_NAMESPACE_NODE     **ReturnNode)
106 {
107     ACPI_STATUS             Status;
108     ACPI_NAMESPACE_NODE     *Node;
109
110
111     ACPI_FUNCTION_TRACE (RsValidateParameters);
112
113
114     /*
115      * Must have a valid handle to an ACPI device
116      */
117     if (!DeviceHandle)
118     {
119         return_ACPI_STATUS (AE_BAD_PARAMETER);
120     }
121
122     Node = AcpiNsValidateHandle (DeviceHandle);
123     if (!Node)
124     {
125         return_ACPI_STATUS (AE_BAD_PARAMETER);
126     }
127
128     if (Node->Type != ACPI_TYPE_DEVICE)
129     {
130         return_ACPI_STATUS (AE_TYPE);
131     }
132
133     /*
134      * Validate the user buffer object
135      *
136      * if there is a non-zero buffer length we also need a valid pointer in
137      * the buffer. If it's a zero buffer length, we'll be returning the
138      * needed buffer size (later), so keep going.
139      */
140     Status = AcpiUtValidateBuffer (Buffer);
141     if (ACPI_FAILURE (Status))
142     {
143         return_ACPI_STATUS (Status);
144     }
145
146     *ReturnNode = Node;
147     return_ACPI_STATUS (AE_OK);
148 }
149
150
151 /*******************************************************************************
152  *
153  * FUNCTION:    AcpiGetIrqRoutingTable
154  *
155  * PARAMETERS:  DeviceHandle    - Handle to the Bus device we are querying
156  *              RetBuffer       - Pointer to a buffer to receive the
157  *                                current resources for the device
158  *
159  * RETURN:      Status
160  *
161  * DESCRIPTION: This function is called to get the IRQ routing table for a
162  *              specific bus. The caller must first acquire a handle for the
163  *              desired bus. The routine table is placed in the buffer pointed
164  *              to by the RetBuffer variable parameter.
165  *
166  *              If the function fails an appropriate status will be returned
167  *              and the value of RetBuffer is undefined.
168  *
169  *              This function attempts to execute the _PRT method contained in
170  *              the object indicated by the passed DeviceHandle.
171  *
172  ******************************************************************************/
173
174 ACPI_STATUS
175 AcpiGetIrqRoutingTable  (
176     ACPI_HANDLE             DeviceHandle,
177     ACPI_BUFFER             *RetBuffer)
178 {
179     ACPI_STATUS             Status;
180     ACPI_NAMESPACE_NODE     *Node;
181
182
183     ACPI_FUNCTION_TRACE (AcpiGetIrqRoutingTable);
184
185
186     /* Validate parameters then dispatch to internal routine */
187
188     Status = AcpiRsValidateParameters (DeviceHandle, RetBuffer, &Node);
189     if (ACPI_FAILURE (Status))
190     {
191         return_ACPI_STATUS (Status);
192     }
193
194     Status = AcpiRsGetPrtMethodData (Node, RetBuffer);
195     return_ACPI_STATUS (Status);
196 }
197
198 ACPI_EXPORT_SYMBOL (AcpiGetIrqRoutingTable)
199
200
201 /*******************************************************************************
202  *
203  * FUNCTION:    AcpiGetCurrentResources
204  *
205  * PARAMETERS:  DeviceHandle    - Handle to the device object for the
206  *                                device we are querying
207  *              RetBuffer       - Pointer to a buffer to receive the
208  *                                current resources for the device
209  *
210  * RETURN:      Status
211  *
212  * DESCRIPTION: This function is called to get the current resources for a
213  *              specific device. The caller must first acquire a handle for
214  *              the desired device. The resource data is placed in the buffer
215  *              pointed to by the RetBuffer variable parameter.
216  *
217  *              If the function fails an appropriate status will be returned
218  *              and the value of RetBuffer is undefined.
219  *
220  *              This function attempts to execute the _CRS method contained in
221  *              the object indicated by the passed DeviceHandle.
222  *
223  ******************************************************************************/
224
225 ACPI_STATUS
226 AcpiGetCurrentResources (
227     ACPI_HANDLE             DeviceHandle,
228     ACPI_BUFFER             *RetBuffer)
229 {
230     ACPI_STATUS             Status;
231     ACPI_NAMESPACE_NODE     *Node;
232
233
234     ACPI_FUNCTION_TRACE (AcpiGetCurrentResources);
235
236
237     /* Validate parameters then dispatch to internal routine */
238
239     Status = AcpiRsValidateParameters (DeviceHandle, RetBuffer, &Node);
240     if (ACPI_FAILURE (Status))
241     {
242         return_ACPI_STATUS (Status);
243     }
244
245     Status = AcpiRsGetCrsMethodData (Node, RetBuffer);
246     return_ACPI_STATUS (Status);
247 }
248
249 ACPI_EXPORT_SYMBOL (AcpiGetCurrentResources)
250
251
252 /*******************************************************************************
253  *
254  * FUNCTION:    AcpiGetPossibleResources
255  *
256  * PARAMETERS:  DeviceHandle    - Handle to the device object for the
257  *                                device we are querying
258  *              RetBuffer       - Pointer to a buffer to receive the
259  *                                resources for the device
260  *
261  * RETURN:      Status
262  *
263  * DESCRIPTION: This function is called to get a list of the possible resources
264  *              for a specific device. The caller must first acquire a handle
265  *              for the desired device. The resource data is placed in the
266  *              buffer pointed to by the RetBuffer variable.
267  *
268  *              If the function fails an appropriate status will be returned
269  *              and the value of RetBuffer is undefined.
270  *
271  ******************************************************************************/
272
273 ACPI_STATUS
274 AcpiGetPossibleResources (
275     ACPI_HANDLE             DeviceHandle,
276     ACPI_BUFFER             *RetBuffer)
277 {
278     ACPI_STATUS             Status;
279     ACPI_NAMESPACE_NODE     *Node;
280
281
282     ACPI_FUNCTION_TRACE (AcpiGetPossibleResources);
283
284
285     /* Validate parameters then dispatch to internal routine */
286
287     Status = AcpiRsValidateParameters (DeviceHandle, RetBuffer, &Node);
288     if (ACPI_FAILURE (Status))
289     {
290         return_ACPI_STATUS (Status);
291     }
292
293     Status = AcpiRsGetPrsMethodData (Node, RetBuffer);
294     return_ACPI_STATUS (Status);
295 }
296
297 ACPI_EXPORT_SYMBOL (AcpiGetPossibleResources)
298
299
300 /*******************************************************************************
301  *
302  * FUNCTION:    AcpiSetCurrentResources
303  *
304  * PARAMETERS:  DeviceHandle    - Handle to the device object for the
305  *                                device we are setting resources
306  *              InBuffer        - Pointer to a buffer containing the
307  *                                resources to be set for the device
308  *
309  * RETURN:      Status
310  *
311  * DESCRIPTION: This function is called to set the current resources for a
312  *              specific device. The caller must first acquire a handle for
313  *              the desired device. The resource data is passed to the routine
314  *              the buffer pointed to by the InBuffer variable.
315  *
316  ******************************************************************************/
317
318 ACPI_STATUS
319 AcpiSetCurrentResources (
320     ACPI_HANDLE             DeviceHandle,
321     ACPI_BUFFER             *InBuffer)
322 {
323     ACPI_STATUS             Status;
324     ACPI_NAMESPACE_NODE     *Node;
325
326
327     ACPI_FUNCTION_TRACE (AcpiSetCurrentResources);
328
329
330     /* Validate the buffer, don't allow zero length */
331
332     if ((!InBuffer) ||
333         (!InBuffer->Pointer) ||
334         (!InBuffer->Length))
335     {
336         return_ACPI_STATUS (AE_BAD_PARAMETER);
337     }
338
339     /* Validate parameters then dispatch to internal routine */
340
341     Status = AcpiRsValidateParameters (DeviceHandle, InBuffer, &Node);
342     if (ACPI_FAILURE (Status))
343     {
344         return_ACPI_STATUS (Status);
345     }
346
347     Status = AcpiRsSetSrsMethodData (Node, InBuffer);
348     return_ACPI_STATUS (Status);
349 }
350
351 ACPI_EXPORT_SYMBOL (AcpiSetCurrentResources)
352
353
354 /******************************************************************************
355  *
356  * FUNCTION:    AcpiResourceToAddress64
357  *
358  * PARAMETERS:  Resource        - Pointer to a resource
359  *              Out             - Pointer to the users's return buffer
360  *                                (a struct acpi_resource_address64)
361  *
362  * RETURN:      Status
363  *
364  * DESCRIPTION: If the resource is an address16, address32, or address64,
365  *              copy it to the address64 return buffer. This saves the
366  *              caller from having to duplicate code for different-sized
367  *              addresses.
368  *
369  ******************************************************************************/
370
371 ACPI_STATUS
372 AcpiResourceToAddress64 (
373     ACPI_RESOURCE               *Resource,
374     ACPI_RESOURCE_ADDRESS64     *Out)
375 {
376     ACPI_RESOURCE_ADDRESS16     *Address16;
377     ACPI_RESOURCE_ADDRESS32     *Address32;
378
379
380     if (!Resource || !Out)
381     {
382         return (AE_BAD_PARAMETER);
383     }
384
385     /* Convert 16 or 32 address descriptor to 64 */
386
387     switch (Resource->Type)
388     {
389     case ACPI_RESOURCE_TYPE_ADDRESS16:
390
391         Address16 = ACPI_CAST_PTR (ACPI_RESOURCE_ADDRESS16, &Resource->Data);
392         ACPI_COPY_ADDRESS (Out, Address16);
393         break;
394
395     case ACPI_RESOURCE_TYPE_ADDRESS32:
396
397         Address32 = ACPI_CAST_PTR (ACPI_RESOURCE_ADDRESS32, &Resource->Data);
398         ACPI_COPY_ADDRESS (Out, Address32);
399         break;
400
401     case ACPI_RESOURCE_TYPE_ADDRESS64:
402
403         /* Simple copy for 64 bit source */
404
405         ACPI_MEMCPY (Out, &Resource->Data, sizeof (ACPI_RESOURCE_ADDRESS64));
406         break;
407
408     default:
409         return (AE_BAD_PARAMETER);
410     }
411
412     return (AE_OK);
413 }
414
415 ACPI_EXPORT_SYMBOL (AcpiResourceToAddress64)
416
417
418 /*******************************************************************************
419  *
420  * FUNCTION:    AcpiGetVendorResource
421  *
422  * PARAMETERS:  DeviceHandle    - Handle for the parent device object
423  *              Name            - Method name for the parent resource
424  *                                (METHOD_NAME__CRS or METHOD_NAME__PRS)
425  *              Uuid            - Pointer to the UUID to be matched.
426  *                                includes both subtype and 16-byte UUID
427  *              RetBuffer       - Where the vendor resource is returned
428  *
429  * RETURN:      Status
430  *
431  * DESCRIPTION: Walk a resource template for the specified evice to find a
432  *              vendor-defined resource that matches the supplied UUID and
433  *              UUID subtype. Returns a ACPI_RESOURCE of type Vendor.
434  *
435  ******************************************************************************/
436
437 ACPI_STATUS
438 AcpiGetVendorResource (
439     ACPI_HANDLE             DeviceHandle,
440     char                    *Name,
441     ACPI_VENDOR_UUID        *Uuid,
442     ACPI_BUFFER             *RetBuffer)
443 {
444     ACPI_VENDOR_WALK_INFO   Info;
445     ACPI_STATUS             Status;
446
447
448     /* Other parameters are validated by AcpiWalkResources */
449
450     if (!Uuid || !RetBuffer)
451     {
452         return (AE_BAD_PARAMETER);
453     }
454
455     Info.Uuid = Uuid;
456     Info.Buffer = RetBuffer;
457     Info.Status = AE_NOT_EXIST;
458
459     /* Walk the _CRS or _PRS resource list for this device */
460
461     Status = AcpiWalkResources (DeviceHandle, Name, AcpiRsMatchVendorResource,
462                 &Info);
463     if (ACPI_FAILURE (Status))
464     {
465         return (Status);
466     }
467
468     return (Info.Status);
469 }
470
471 ACPI_EXPORT_SYMBOL (AcpiGetVendorResource)
472
473
474 /*******************************************************************************
475  *
476  * FUNCTION:    AcpiRsMatchVendorResource
477  *
478  * PARAMETERS:  ACPI_WALK_RESOURCE_CALLBACK
479  *
480  * RETURN:      Status
481  *
482  * DESCRIPTION: Match a vendor resource via the ACPI 3.0 UUID
483  *
484  ******************************************************************************/
485
486 static ACPI_STATUS
487 AcpiRsMatchVendorResource (
488     ACPI_RESOURCE           *Resource,
489     void                    *Context)
490 {
491     ACPI_VENDOR_WALK_INFO       *Info = Context;
492     ACPI_RESOURCE_VENDOR_TYPED  *Vendor;
493     ACPI_BUFFER                 *Buffer;
494     ACPI_STATUS                 Status;
495
496
497     /* Ignore all descriptors except Vendor */
498
499     if (Resource->Type != ACPI_RESOURCE_TYPE_VENDOR)
500     {
501         return (AE_OK);
502     }
503
504     Vendor = &Resource->Data.VendorTyped;
505
506     /*
507      * For a valid match, these conditions must hold:
508      *
509      * 1) Length of descriptor data must be at least as long as a UUID struct
510      * 2) The UUID subtypes must match
511      * 3) The UUID data must match
512      */
513     if ((Vendor->ByteLength < (ACPI_UUID_LENGTH + 1)) ||
514         (Vendor->UuidSubtype != Info->Uuid->Subtype)  ||
515         (ACPI_MEMCMP (Vendor->Uuid, Info->Uuid->Data, ACPI_UUID_LENGTH)))
516     {
517         return (AE_OK);
518     }
519
520     /* Validate/Allocate/Clear caller buffer */
521
522     Buffer = Info->Buffer;
523     Status = AcpiUtInitializeBuffer (Buffer, Resource->Length);
524     if (ACPI_FAILURE (Status))
525     {
526         return (Status);
527     }
528
529     /* Found the correct resource, copy and return it */
530
531     ACPI_MEMCPY (Buffer->Pointer, Resource, Resource->Length);
532     Buffer->Length = Resource->Length;
533
534     /* Found the desired descriptor, terminate resource walk */
535
536     Info->Status = AE_OK;
537     return (AE_CTRL_TERMINATE);
538 }
539
540
541 /*******************************************************************************
542  *
543  * FUNCTION:    AcpiWalkResources
544  *
545  * PARAMETERS:  DeviceHandle    - Handle to the device object for the
546  *                                device we are querying
547  *              Name            - Method name of the resources we want
548  *                                (METHOD_NAME__CRS or METHOD_NAME__PRS)
549  *              UserFunction    - Called for each resource
550  *              Context         - Passed to UserFunction
551  *
552  * RETURN:      Status
553  *
554  * DESCRIPTION: Retrieves the current or possible resource list for the
555  *              specified device. The UserFunction is called once for
556  *              each resource in the list.
557  *
558  ******************************************************************************/
559
560 ACPI_STATUS
561 AcpiWalkResources (
562     ACPI_HANDLE                 DeviceHandle,
563     char                        *Name,
564     ACPI_WALK_RESOURCE_CALLBACK UserFunction,
565     void                        *Context)
566 {
567     ACPI_STATUS                 Status;
568     ACPI_BUFFER                 Buffer;
569     ACPI_RESOURCE               *Resource;
570     ACPI_RESOURCE               *ResourceEnd;
571
572
573     ACPI_FUNCTION_TRACE (AcpiWalkResources);
574
575
576     /* Parameter validation */
577
578     if (!DeviceHandle || !UserFunction || !Name ||
579         (!ACPI_COMPARE_NAME (Name, METHOD_NAME__CRS) &&
580          !ACPI_COMPARE_NAME (Name, METHOD_NAME__PRS)))
581     {
582         return_ACPI_STATUS (AE_BAD_PARAMETER);
583     }
584
585     /* Get the _CRS or _PRS resource list */
586
587     Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
588     Status = AcpiRsGetMethodData (DeviceHandle, Name, &Buffer);
589     if (ACPI_FAILURE (Status))
590     {
591         return_ACPI_STATUS (Status);
592     }
593
594     /* Buffer now contains the resource list */
595
596     Resource = ACPI_CAST_PTR (ACPI_RESOURCE, Buffer.Pointer);
597     ResourceEnd = ACPI_ADD_PTR (ACPI_RESOURCE, Buffer.Pointer, Buffer.Length);
598
599     /* Walk the resource list until the EndTag is found (or buffer end) */
600
601     while (Resource < ResourceEnd)
602     {
603         /* Sanity check the resource */
604
605         if (Resource->Type > ACPI_RESOURCE_TYPE_MAX)
606         {
607             Status = AE_AML_INVALID_RESOURCE_TYPE;
608             break;
609         }
610
611         /* Invoke the user function, abort on any error returned */
612
613         Status = UserFunction (Resource, Context);
614         if (ACPI_FAILURE (Status))
615         {
616             if (Status == AE_CTRL_TERMINATE)
617             {
618                 /* This is an OK termination by the user function */
619
620                 Status = AE_OK;
621             }
622             break;
623         }
624
625         /* EndTag indicates end-of-list */
626
627         if (Resource->Type == ACPI_RESOURCE_TYPE_END_TAG)
628         {
629             break;
630         }
631
632         /* Get the next resource descriptor */
633
634         Resource = ACPI_ADD_PTR (ACPI_RESOURCE, Resource, Resource->Length);
635     }
636
637     ACPI_FREE (Buffer.Pointer);
638     return_ACPI_STATUS (Status);
639 }
640
641 ACPI_EXPORT_SYMBOL (AcpiWalkResources)