utxface.c revision 281075
138738Sbrian/******************************************************************************
238738Sbrian *
33161Sache * Module Name: utxface - External interfaces, miscellaneous utility functions
43161Sache *
53161Sache *****************************************************************************/
63161Sache
735121Sdes/*
819911Sache * Copyright (C) 2000 - 2015, Intel Corp.
919033Sache * All rights reserved.
1035121Sdes *
1135121Sdes * Redistribution and use in source and binary forms, with or without
129249Sache * modification, are permitted provided that the following conditions
1319033Sache * are met:
1435121Sdes * 1. Redistributions of source code must retain the above copyright
154994Sache *    notice, this list of conditions, and the following disclaimer,
1635121Sdes *    without modification.
1735121Sdes * 2. Redistributions in binary form must reproduce at minimum a disclaimer
1812391Sache *    substantially similar to the "NO WARRANTY" disclaimer below
1912392Sache *    ("Disclaimer") and any redistribution must be conditioned upon
2019033Sache *    including a substantially similar Disclaimer requirement for further
2119033Sache *    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#define EXPORT_ACPI_INTERFACES
45
46#include <contrib/dev/acpica/include/acpi.h>
47#include <contrib/dev/acpica/include/accommon.h>
48#include <contrib/dev/acpica/include/acdebug.h>
49
50#define _COMPONENT          ACPI_UTILITIES
51        ACPI_MODULE_NAME    ("utxface")
52
53
54/*******************************************************************************
55 *
56 * FUNCTION:    AcpiTerminate
57 *
58 * PARAMETERS:  None
59 *
60 * RETURN:      Status
61 *
62 * DESCRIPTION: Shutdown the ACPICA subsystem and release all resources.
63 *
64 ******************************************************************************/
65
66ACPI_STATUS
67AcpiTerminate (
68    void)
69{
70    ACPI_STATUS         Status;
71
72
73    ACPI_FUNCTION_TRACE (AcpiTerminate);
74
75
76    /* Just exit if subsystem is already shutdown */
77
78    if (AcpiGbl_Shutdown)
79    {
80        ACPI_ERROR ((AE_INFO, "ACPI Subsystem is already terminated"));
81        return_ACPI_STATUS (AE_OK);
82    }
83
84    /* Subsystem appears active, go ahead and shut it down */
85
86    AcpiGbl_Shutdown = TRUE;
87    AcpiGbl_StartupFlags = 0;
88    ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Shutting down ACPI Subsystem\n"));
89
90    /* Terminate the AML Debugger if present */
91
92    ACPI_DEBUGGER_EXEC (AcpiGbl_DbTerminateThreads = TRUE);
93
94    /* Shutdown and free all resources */
95
96    AcpiUtSubsystemShutdown ();
97
98    /* Free the mutex objects */
99
100    AcpiUtMutexTerminate ();
101
102
103#ifdef ACPI_DEBUGGER
104
105    /* Shut down the debugger */
106
107    AcpiDbTerminate ();
108#endif
109
110    /* Now we can shutdown the OS-dependent layer */
111
112    Status = AcpiOsTerminate ();
113    return_ACPI_STATUS (Status);
114}
115
116ACPI_EXPORT_SYMBOL_INIT (AcpiTerminate)
117
118
119#ifndef ACPI_ASL_COMPILER
120/*******************************************************************************
121 *
122 * FUNCTION:    AcpiSubsystemStatus
123 *
124 * PARAMETERS:  None
125 *
126 * RETURN:      Status of the ACPI subsystem
127 *
128 * DESCRIPTION: Other drivers that use the ACPI subsystem should call this
129 *              before making any other calls, to ensure the subsystem
130 *              initialized successfully.
131 *
132 ******************************************************************************/
133
134ACPI_STATUS
135AcpiSubsystemStatus (
136    void)
137{
138
139    if (AcpiGbl_StartupFlags & ACPI_INITIALIZED_OK)
140    {
141        return (AE_OK);
142    }
143    else
144    {
145        return (AE_ERROR);
146    }
147}
148
149ACPI_EXPORT_SYMBOL (AcpiSubsystemStatus)
150
151
152/*******************************************************************************
153 *
154 * FUNCTION:    AcpiGetSystemInfo
155 *
156 * PARAMETERS:  OutBuffer       - A buffer to receive the resources for the
157 *                                device
158 *
159 * RETURN:      Status          - the status of the call
160 *
161 * DESCRIPTION: This function is called to get information about the current
162 *              state of the ACPI subsystem. It will return system information
163 *              in the OutBuffer.
164 *
165 *              If the function fails an appropriate status will be returned
166 *              and the value of OutBuffer is undefined.
167 *
168 ******************************************************************************/
169
170ACPI_STATUS
171AcpiGetSystemInfo (
172    ACPI_BUFFER             *OutBuffer)
173{
174    ACPI_SYSTEM_INFO        *InfoPtr;
175    ACPI_STATUS             Status;
176
177
178    ACPI_FUNCTION_TRACE (AcpiGetSystemInfo);
179
180
181    /* Parameter validation */
182
183    Status = AcpiUtValidateBuffer (OutBuffer);
184    if (ACPI_FAILURE (Status))
185    {
186        return_ACPI_STATUS (Status);
187    }
188
189    /* Validate/Allocate/Clear caller buffer */
190
191    Status = AcpiUtInitializeBuffer (OutBuffer, sizeof (ACPI_SYSTEM_INFO));
192    if (ACPI_FAILURE (Status))
193    {
194        return_ACPI_STATUS (Status);
195    }
196
197    /*
198     * Populate the return buffer
199     */
200    InfoPtr = (ACPI_SYSTEM_INFO *) OutBuffer->Pointer;
201
202    InfoPtr->AcpiCaVersion = ACPI_CA_VERSION;
203
204    /* System flags (ACPI capabilities) */
205
206    InfoPtr->Flags = ACPI_SYS_MODE_ACPI;
207
208    /* Timer resolution - 24 or 32 bits  */
209
210    if (AcpiGbl_FADT.Flags & ACPI_FADT_32BIT_TIMER)
211    {
212        InfoPtr->TimerResolution = 24;
213    }
214    else
215    {
216        InfoPtr->TimerResolution = 32;
217    }
218
219    /* Clear the reserved fields */
220
221    InfoPtr->Reserved1 = 0;
222    InfoPtr->Reserved2 = 0;
223
224    /* Current debug levels */
225
226    InfoPtr->DebugLayer = AcpiDbgLayer;
227    InfoPtr->DebugLevel = AcpiDbgLevel;
228
229    return_ACPI_STATUS (AE_OK);
230}
231
232ACPI_EXPORT_SYMBOL (AcpiGetSystemInfo)
233
234
235/*******************************************************************************
236 *
237 * FUNCTION:    AcpiGetStatistics
238 *
239 * PARAMETERS:  Stats           - Where the statistics are returned
240 *
241 * RETURN:      Status          - the status of the call
242 *
243 * DESCRIPTION: Get the contents of the various system counters
244 *
245 ******************************************************************************/
246
247ACPI_STATUS
248AcpiGetStatistics (
249    ACPI_STATISTICS         *Stats)
250{
251    ACPI_FUNCTION_TRACE (AcpiGetStatistics);
252
253
254    /* Parameter validation */
255
256    if (!Stats)
257    {
258        return_ACPI_STATUS (AE_BAD_PARAMETER);
259    }
260
261    /* Various interrupt-based event counters */
262
263    Stats->SciCount = AcpiSciCount;
264    Stats->GpeCount = AcpiGpeCount;
265
266    ACPI_MEMCPY (Stats->FixedEventCount, AcpiFixedEventCount,
267        sizeof (AcpiFixedEventCount));
268
269
270    /* Other counters */
271
272    Stats->MethodCount = AcpiMethodCount;
273
274    return_ACPI_STATUS (AE_OK);
275}
276
277ACPI_EXPORT_SYMBOL (AcpiGetStatistics)
278
279
280/*****************************************************************************
281 *
282 * FUNCTION:    AcpiInstallInitializationHandler
283 *
284 * PARAMETERS:  Handler             - Callback procedure
285 *              Function            - Not (currently) used, see below
286 *
287 * RETURN:      Status
288 *
289 * DESCRIPTION: Install an initialization handler
290 *
291 * TBD: When a second function is added, must save the Function also.
292 *
293 ****************************************************************************/
294
295ACPI_STATUS
296AcpiInstallInitializationHandler (
297    ACPI_INIT_HANDLER       Handler,
298    UINT32                  Function)
299{
300
301    if (!Handler)
302    {
303        return (AE_BAD_PARAMETER);
304    }
305
306    if (AcpiGbl_InitHandler)
307    {
308        return (AE_ALREADY_EXISTS);
309    }
310
311    AcpiGbl_InitHandler = Handler;
312    return (AE_OK);
313}
314
315ACPI_EXPORT_SYMBOL (AcpiInstallInitializationHandler)
316
317
318/*****************************************************************************
319 *
320 * FUNCTION:    AcpiPurgeCachedObjects
321 *
322 * PARAMETERS:  None
323 *
324 * RETURN:      Status
325 *
326 * DESCRIPTION: Empty all caches (delete the cached objects)
327 *
328 ****************************************************************************/
329
330ACPI_STATUS
331AcpiPurgeCachedObjects (
332    void)
333{
334    ACPI_FUNCTION_TRACE (AcpiPurgeCachedObjects);
335
336
337    (void) AcpiOsPurgeCache (AcpiGbl_StateCache);
338    (void) AcpiOsPurgeCache (AcpiGbl_OperandCache);
339    (void) AcpiOsPurgeCache (AcpiGbl_PsNodeCache);
340    (void) AcpiOsPurgeCache (AcpiGbl_PsNodeExtCache);
341
342    return_ACPI_STATUS (AE_OK);
343}
344
345ACPI_EXPORT_SYMBOL (AcpiPurgeCachedObjects)
346
347
348/*****************************************************************************
349 *
350 * FUNCTION:    AcpiInstallInterface
351 *
352 * PARAMETERS:  InterfaceName       - The interface to install
353 *
354 * RETURN:      Status
355 *
356 * DESCRIPTION: Install an _OSI interface to the global list
357 *
358 ****************************************************************************/
359
360ACPI_STATUS
361AcpiInstallInterface (
362    ACPI_STRING             InterfaceName)
363{
364    ACPI_STATUS             Status;
365    ACPI_INTERFACE_INFO     *InterfaceInfo;
366
367
368    /* Parameter validation */
369
370    if (!InterfaceName || (ACPI_STRLEN (InterfaceName) == 0))
371    {
372        return (AE_BAD_PARAMETER);
373    }
374
375    Status = AcpiOsAcquireMutex (AcpiGbl_OsiMutex, ACPI_WAIT_FOREVER);
376    if (ACPI_FAILURE (Status))
377    {
378        return (Status);
379    }
380
381    /* Check if the interface name is already in the global list */
382
383    InterfaceInfo = AcpiUtGetInterface (InterfaceName);
384    if (InterfaceInfo)
385    {
386        /*
387         * The interface already exists in the list. This is OK if the
388         * interface has been marked invalid -- just clear the bit.
389         */
390        if (InterfaceInfo->Flags & ACPI_OSI_INVALID)
391        {
392            InterfaceInfo->Flags &= ~ACPI_OSI_INVALID;
393            Status = AE_OK;
394        }
395        else
396        {
397            Status = AE_ALREADY_EXISTS;
398        }
399    }
400    else
401    {
402        /* New interface name, install into the global list */
403
404        Status = AcpiUtInstallInterface (InterfaceName);
405    }
406
407    AcpiOsReleaseMutex (AcpiGbl_OsiMutex);
408    return (Status);
409}
410
411ACPI_EXPORT_SYMBOL (AcpiInstallInterface)
412
413
414/*****************************************************************************
415 *
416 * FUNCTION:    AcpiRemoveInterface
417 *
418 * PARAMETERS:  InterfaceName       - The interface to remove
419 *
420 * RETURN:      Status
421 *
422 * DESCRIPTION: Remove an _OSI interface from the global list
423 *
424 ****************************************************************************/
425
426ACPI_STATUS
427AcpiRemoveInterface (
428    ACPI_STRING             InterfaceName)
429{
430    ACPI_STATUS             Status;
431
432
433    /* Parameter validation */
434
435    if (!InterfaceName || (ACPI_STRLEN (InterfaceName) == 0))
436    {
437        return (AE_BAD_PARAMETER);
438    }
439
440    Status = AcpiOsAcquireMutex (AcpiGbl_OsiMutex, ACPI_WAIT_FOREVER);
441    if (ACPI_FAILURE (Status))
442    {
443        return (Status);
444    }
445
446    Status = AcpiUtRemoveInterface (InterfaceName);
447
448    AcpiOsReleaseMutex (AcpiGbl_OsiMutex);
449    return (Status);
450}
451
452ACPI_EXPORT_SYMBOL (AcpiRemoveInterface)
453
454
455/*****************************************************************************
456 *
457 * FUNCTION:    AcpiInstallInterfaceHandler
458 *
459 * PARAMETERS:  Handler             - The _OSI interface handler to install
460 *                                    NULL means "remove existing handler"
461 *
462 * RETURN:      Status
463 *
464 * DESCRIPTION: Install a handler for the predefined _OSI ACPI method.
465 *              invoked during execution of the internal implementation of
466 *              _OSI. A NULL handler simply removes any existing handler.
467 *
468 ****************************************************************************/
469
470ACPI_STATUS
471AcpiInstallInterfaceHandler (
472    ACPI_INTERFACE_HANDLER  Handler)
473{
474    ACPI_STATUS             Status;
475
476
477    Status = AcpiOsAcquireMutex (AcpiGbl_OsiMutex, ACPI_WAIT_FOREVER);
478    if (ACPI_FAILURE (Status))
479    {
480        return (Status);
481    }
482
483    if (Handler && AcpiGbl_InterfaceHandler)
484    {
485        Status = AE_ALREADY_EXISTS;
486    }
487    else
488    {
489        AcpiGbl_InterfaceHandler = Handler;
490    }
491
492    AcpiOsReleaseMutex (AcpiGbl_OsiMutex);
493    return (Status);
494}
495
496ACPI_EXPORT_SYMBOL (AcpiInstallInterfaceHandler)
497
498
499/*****************************************************************************
500 *
501 * FUNCTION:    AcpiUpdateInterfaces
502 *
503 * PARAMETERS:  Action              - Actions to be performed during the
504 *                                    update
505 *
506 * RETURN:      Status
507 *
508 * DESCRIPTION: Update _OSI interface strings, disabling or enabling OS vendor
509 *              string or/and feature group strings.
510 *
511 ****************************************************************************/
512
513ACPI_STATUS
514AcpiUpdateInterfaces (
515    UINT8                   Action)
516{
517    ACPI_STATUS             Status;
518
519
520    Status = AcpiOsAcquireMutex (AcpiGbl_OsiMutex, ACPI_WAIT_FOREVER);
521    if (ACPI_FAILURE (Status))
522    {
523        return (Status);
524    }
525
526    Status = AcpiUtUpdateInterfaces (Action);
527
528    AcpiOsReleaseMutex (AcpiGbl_OsiMutex);
529    return (Status);
530}
531
532
533/*****************************************************************************
534 *
535 * FUNCTION:    AcpiCheckAddressRange
536 *
537 * PARAMETERS:  SpaceId             - Address space ID
538 *              Address             - Start address
539 *              Length              - Length
540 *              Warn                - TRUE if warning on overlap desired
541 *
542 * RETURN:      Count of the number of conflicts detected.
543 *
544 * DESCRIPTION: Check if the input address range overlaps any of the
545 *              ASL operation region address ranges.
546 *
547 ****************************************************************************/
548
549UINT32
550AcpiCheckAddressRange (
551    ACPI_ADR_SPACE_TYPE     SpaceId,
552    ACPI_PHYSICAL_ADDRESS   Address,
553    ACPI_SIZE               Length,
554    BOOLEAN                 Warn)
555{
556    UINT32                  Overlaps;
557    ACPI_STATUS             Status;
558
559
560    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
561    if (ACPI_FAILURE (Status))
562    {
563        return (0);
564    }
565
566    Overlaps = AcpiUtCheckAddressRange (SpaceId, Address,
567        (UINT32) Length, Warn);
568
569    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
570    return (Overlaps);
571}
572
573ACPI_EXPORT_SYMBOL (AcpiCheckAddressRange)
574
575#endif /* !ACPI_ASL_COMPILER */
576
577
578/*******************************************************************************
579 *
580 * FUNCTION:    AcpiDecodePldBuffer
581 *
582 * PARAMETERS:  InBuffer            - Buffer returned by _PLD method
583 *              Length              - Length of the InBuffer
584 *              ReturnBuffer        - Where the decode buffer is returned
585 *
586 * RETURN:      Status and the decoded _PLD buffer. User must deallocate
587 *              the buffer via ACPI_FREE.
588 *
589 * DESCRIPTION: Decode the bit-packed buffer returned by the _PLD method into
590 *              a local struct that is much more useful to an ACPI driver.
591 *
592 ******************************************************************************/
593
594ACPI_STATUS
595AcpiDecodePldBuffer (
596    UINT8                   *InBuffer,
597    ACPI_SIZE               Length,
598    ACPI_PLD_INFO           **ReturnBuffer)
599{
600    ACPI_PLD_INFO           *PldInfo;
601    UINT32                  *Buffer = ACPI_CAST_PTR (UINT32, InBuffer);
602    UINT32                  Dword;
603
604
605    /* Parameter validation */
606
607    if (!InBuffer || !ReturnBuffer || (Length < 16))
608    {
609        return (AE_BAD_PARAMETER);
610    }
611
612    PldInfo = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_PLD_INFO));
613    if (!PldInfo)
614    {
615        return (AE_NO_MEMORY);
616    }
617
618    /* First 32-bit DWord */
619
620    ACPI_MOVE_32_TO_32 (&Dword, &Buffer[0]);
621    PldInfo->Revision =             ACPI_PLD_GET_REVISION (&Dword);
622    PldInfo->IgnoreColor =          ACPI_PLD_GET_IGNORE_COLOR (&Dword);
623    PldInfo->Red =                  ACPI_PLD_GET_RED (&Dword);
624    PldInfo->Green =                ACPI_PLD_GET_GREEN (&Dword);
625    PldInfo->Blue =                 ACPI_PLD_GET_BLUE (&Dword);
626
627    /* Second 32-bit DWord */
628
629    ACPI_MOVE_32_TO_32 (&Dword, &Buffer[1]);
630    PldInfo->Width =                ACPI_PLD_GET_WIDTH (&Dword);
631    PldInfo->Height =               ACPI_PLD_GET_HEIGHT(&Dword);
632
633    /* Third 32-bit DWord */
634
635    ACPI_MOVE_32_TO_32 (&Dword, &Buffer[2]);
636    PldInfo->UserVisible =          ACPI_PLD_GET_USER_VISIBLE (&Dword);
637    PldInfo->Dock =                 ACPI_PLD_GET_DOCK (&Dword);
638    PldInfo->Lid =                  ACPI_PLD_GET_LID (&Dword);
639    PldInfo->Panel =                ACPI_PLD_GET_PANEL (&Dword);
640    PldInfo->VerticalPosition =     ACPI_PLD_GET_VERTICAL (&Dword);
641    PldInfo->HorizontalPosition =   ACPI_PLD_GET_HORIZONTAL (&Dword);
642    PldInfo->Shape =                ACPI_PLD_GET_SHAPE (&Dword);
643    PldInfo->GroupOrientation =     ACPI_PLD_GET_ORIENTATION (&Dword);
644    PldInfo->GroupToken =           ACPI_PLD_GET_TOKEN (&Dword);
645    PldInfo->GroupPosition =        ACPI_PLD_GET_POSITION (&Dword);
646    PldInfo->Bay =                  ACPI_PLD_GET_BAY (&Dword);
647
648    /* Fourth 32-bit DWord */
649
650    ACPI_MOVE_32_TO_32 (&Dword, &Buffer[3]);
651    PldInfo->Ejectable =            ACPI_PLD_GET_EJECTABLE (&Dword);
652    PldInfo->OspmEjectRequired =    ACPI_PLD_GET_OSPM_EJECT (&Dword);
653    PldInfo->CabinetNumber =        ACPI_PLD_GET_CABINET (&Dword);
654    PldInfo->CardCageNumber =       ACPI_PLD_GET_CARD_CAGE (&Dword);
655    PldInfo->Reference =            ACPI_PLD_GET_REFERENCE (&Dword);
656    PldInfo->Rotation =             ACPI_PLD_GET_ROTATION (&Dword);
657    PldInfo->Order =                ACPI_PLD_GET_ORDER (&Dword);
658
659    if (Length >= ACPI_PLD_BUFFER_SIZE)
660    {
661        /* Fifth 32-bit DWord (Revision 2 of _PLD) */
662
663        ACPI_MOVE_32_TO_32 (&Dword, &Buffer[4]);
664        PldInfo->VerticalOffset =       ACPI_PLD_GET_VERT_OFFSET (&Dword);
665        PldInfo->HorizontalOffset =     ACPI_PLD_GET_HORIZ_OFFSET (&Dword);
666    }
667
668    *ReturnBuffer = PldInfo;
669    return (AE_OK);
670}
671
672ACPI_EXPORT_SYMBOL (AcpiDecodePldBuffer)
673