xref: /netbsd-src/sys/external/bsd/acpica/dist/os_specific/service_layers/osunixxf.c (revision 046a29855e04359424fd074e8313af6b6be8cfb6)
1 /******************************************************************************
2  *
3  * Module Name: osunixxf - UNIX OSL interfaces
4  *
5  *****************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2023, 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 MERCHANTABILITY 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  * These interfaces are required in order to compile the ASL compiler and the
46  * various ACPICA tools under Linux or other Unix-like system.
47  */
48 #include "acpi.h"
49 #include "accommon.h"
50 #include "amlcode.h"
51 #include "acparser.h"
52 #include "acdebug.h"
53 
54 #include <stdio.h>
55 #include <stdlib.h>
56 #include <stdarg.h>
57 #include <unistd.h>
58 #include <sys/time.h>
59 #include <semaphore.h>
60 #include <pthread.h>
61 #include <errno.h>
62 
63 #define _COMPONENT          ACPI_OS_SERVICES
64         ACPI_MODULE_NAME    ("osunixxf")
65 
66 
67 /* Upcalls to AcpiExec */
68 
69 void
70 AeTableOverride (
71     ACPI_TABLE_HEADER       *ExistingTable,
72     ACPI_TABLE_HEADER       **NewTable);
73 
74 typedef void* (*PTHREAD_CALLBACK) (void *);
75 
76 /* Buffer used by AcpiOsVprintf */
77 
78 #define ACPI_VPRINTF_BUFFER_SIZE    512
79 #define _ASCII_NEWLINE              '\n'
80 
81 /* Terminal support for AcpiExec only */
82 
83 #ifdef ACPI_EXEC_APP
84 #include <termios.h>
85 
86 struct termios              OriginalTermAttributes;
87 int                         TermAttributesWereSet = 0;
88 
89 ACPI_STATUS
90 AcpiUtReadLine (
91     char                    *Buffer,
92     UINT32                  BufferLength,
93     UINT32                  *BytesRead);
94 
95 static void
96 OsEnterLineEditMode (
97     void);
98 
99 static void
100 OsExitLineEditMode (
101     void);
102 
103 
104 /******************************************************************************
105  *
106  * FUNCTION:    OsEnterLineEditMode, OsExitLineEditMode
107  *
108  * PARAMETERS:  None
109  *
110  * RETURN:      None
111  *
112  * DESCRIPTION: Enter/Exit the raw character input mode for the terminal.
113  *
114  * Interactive line-editing support for the AML debugger. Used with the
115  * common/acgetline module.
116  *
117  * readline() is not used because of non-portability. It is not available
118  * on all systems, and if it is, often the package must be manually installed.
119  *
120  * Therefore, we use the POSIX tcgetattr/tcsetattr and do the minimal line
121  * editing that we need in AcpiOsGetLine.
122  *
123  * If the POSIX tcgetattr/tcsetattr interfaces are unavailable, these
124  * calls will also work:
125  *     For OsEnterLineEditMode: system ("stty cbreak -echo")
126  *     For OsExitLineEditMode:  system ("stty cooked echo")
127  *
128  *****************************************************************************/
129 
130 static void
OsEnterLineEditMode(void)131 OsEnterLineEditMode (
132     void)
133 {
134     struct termios          LocalTermAttributes;
135 
136 
137     TermAttributesWereSet = 0;
138 
139     /* STDIN must be a terminal */
140 
141     if (!isatty (STDIN_FILENO))
142     {
143         return;
144     }
145 
146     /* Get and keep the original attributes */
147 
148     if (tcgetattr (STDIN_FILENO, &OriginalTermAttributes))
149     {
150         fprintf (stderr, "Could not get terminal attributes!\n");
151         return;
152     }
153 
154     /* Set the new attributes to enable raw character input */
155 
156     memcpy (&LocalTermAttributes, &OriginalTermAttributes,
157         sizeof (struct termios));
158 
159     LocalTermAttributes.c_lflag &= ~(ICANON | ECHO);
160     LocalTermAttributes.c_cc[VMIN] = 1;
161     LocalTermAttributes.c_cc[VTIME] = 0;
162 
163     if (tcsetattr (STDIN_FILENO, TCSANOW, &LocalTermAttributes))
164     {
165         fprintf (stderr, "Could not set terminal attributes!\n");
166         return;
167     }
168 
169     TermAttributesWereSet = 1;
170 }
171 
172 
173 static void
OsExitLineEditMode(void)174 OsExitLineEditMode (
175     void)
176 {
177 
178     if (!TermAttributesWereSet)
179     {
180         return;
181     }
182 
183     /* Set terminal attributes back to the original values */
184 
185     if (tcsetattr (STDIN_FILENO, TCSANOW, &OriginalTermAttributes))
186     {
187         fprintf (stderr, "Could not restore terminal attributes!\n");
188     }
189 }
190 
191 
192 #else
193 
194 /* These functions are not needed for other ACPICA utilities */
195 
196 #define OsEnterLineEditMode()
197 #define OsExitLineEditMode()
198 #endif
199 
200 
201 /******************************************************************************
202  *
203  * FUNCTION:    AcpiOsInitialize, AcpiOsTerminate
204  *
205  * PARAMETERS:  None
206  *
207  * RETURN:      Status
208  *
209  * DESCRIPTION: Initialize and terminate this module.
210  *
211  *****************************************************************************/
212 
213 ACPI_STATUS
AcpiOsInitialize(void)214 AcpiOsInitialize (
215     void)
216 {
217     ACPI_STATUS            Status;
218 
219 
220     AcpiGbl_OutputFile = stdout;
221 
222     OsEnterLineEditMode ();
223 
224     Status = AcpiOsCreateLock (&AcpiGbl_PrintLock);
225     if (ACPI_FAILURE (Status))
226     {
227         return (Status);
228     }
229 
230     return (AE_OK);
231 }
232 
233 ACPI_STATUS
AcpiOsTerminate(void)234 AcpiOsTerminate (
235     void)
236 {
237 
238     OsExitLineEditMode ();
239     return (AE_OK);
240 }
241 
242 
243 #ifndef ACPI_USE_NATIVE_RSDP_POINTER
244 /******************************************************************************
245  *
246  * FUNCTION:    AcpiOsGetRootPointer
247  *
248  * PARAMETERS:  None
249  *
250  * RETURN:      RSDP physical address
251  *
252  * DESCRIPTION: Gets the ACPI root pointer (RSDP)
253  *
254  *****************************************************************************/
255 
256 ACPI_PHYSICAL_ADDRESS
AcpiOsGetRootPointer(void)257 AcpiOsGetRootPointer (
258     void)
259 {
260 
261     return (0);
262 }
263 #endif
264 
265 
266 /******************************************************************************
267  *
268  * FUNCTION:    AcpiOsPredefinedOverride
269  *
270  * PARAMETERS:  InitVal             - Initial value of the predefined object
271  *              NewVal              - The new value for the object
272  *
273  * RETURN:      Status, pointer to value. Null pointer returned if not
274  *              overriding.
275  *
276  * DESCRIPTION: Allow the OS to override predefined names
277  *
278  *****************************************************************************/
279 
280 ACPI_STATUS
AcpiOsPredefinedOverride(const ACPI_PREDEFINED_NAMES * InitVal,ACPI_STRING * NewVal)281 AcpiOsPredefinedOverride (
282     const ACPI_PREDEFINED_NAMES *InitVal,
283     ACPI_STRING                 *NewVal)
284 {
285 
286     if (!InitVal || !NewVal)
287     {
288         return (AE_BAD_PARAMETER);
289     }
290 
291     *NewVal = NULL;
292     return (AE_OK);
293 }
294 
295 
296 /******************************************************************************
297  *
298  * FUNCTION:    AcpiOsTableOverride
299  *
300  * PARAMETERS:  ExistingTable       - Header of current table (probably
301  *                                    firmware)
302  *              NewTable            - Where an entire new table is returned.
303  *
304  * RETURN:      Status, pointer to new table. Null pointer returned if no
305  *              table is available to override
306  *
307  * DESCRIPTION: Return a different version of a table if one is available
308  *
309  *****************************************************************************/
310 
311 ACPI_STATUS
AcpiOsTableOverride(ACPI_TABLE_HEADER * ExistingTable,ACPI_TABLE_HEADER ** NewTable)312 AcpiOsTableOverride (
313     ACPI_TABLE_HEADER       *ExistingTable,
314     ACPI_TABLE_HEADER       **NewTable)
315 {
316 
317     if (!ExistingTable || !NewTable)
318     {
319         return (AE_BAD_PARAMETER);
320     }
321 
322     *NewTable = NULL;
323 
324 #ifdef ACPI_EXEC_APP
325 
326     AeTableOverride (ExistingTable, NewTable);
327     return (AE_OK);
328 #else
329 
330     return (AE_NO_ACPI_TABLES);
331 #endif
332 }
333 
334 
335 /******************************************************************************
336  *
337  * FUNCTION:    AcpiOsPhysicalTableOverride
338  *
339  * PARAMETERS:  ExistingTable       - Header of current table (probably firmware)
340  *              NewAddress          - Where new table address is returned
341  *                                    (Physical address)
342  *              NewTableLength      - Where new table length is returned
343  *
344  * RETURN:      Status, address/length of new table. Null pointer returned
345  *              if no table is available to override.
346  *
347  * DESCRIPTION: Returns AE_SUPPORT, function not used in user space.
348  *
349  *****************************************************************************/
350 
351 ACPI_STATUS
AcpiOsPhysicalTableOverride(ACPI_TABLE_HEADER * ExistingTable,ACPI_PHYSICAL_ADDRESS * NewAddress,UINT32 * NewTableLength)352 AcpiOsPhysicalTableOverride (
353     ACPI_TABLE_HEADER       *ExistingTable,
354     ACPI_PHYSICAL_ADDRESS   *NewAddress,
355     UINT32                  *NewTableLength)
356 {
357 
358     return (AE_SUPPORT);
359 }
360 
361 
362 /******************************************************************************
363  *
364  * FUNCTION:    AcpiOsEnterSleep
365  *
366  * PARAMETERS:  SleepState          - Which sleep state to enter
367  *              RegaValue           - Register A value
368  *              RegbValue           - Register B value
369  *
370  * RETURN:      Status
371  *
372  * DESCRIPTION: A hook before writing sleep registers to enter the sleep
373  *              state. Return AE_CTRL_TERMINATE to skip further sleep register
374  *              writes.
375  *
376  *****************************************************************************/
377 
378 ACPI_STATUS
AcpiOsEnterSleep(UINT8 SleepState,UINT32 RegaValue,UINT32 RegbValue)379 AcpiOsEnterSleep (
380     UINT8                   SleepState,
381     UINT32                  RegaValue,
382     UINT32                  RegbValue)
383 {
384 
385     return (AE_OK);
386 }
387 
388 
389 /******************************************************************************
390  *
391  * FUNCTION:    AcpiOsRedirectOutput
392  *
393  * PARAMETERS:  Destination         - An open file handle/pointer
394  *
395  * RETURN:      None
396  *
397  * DESCRIPTION: Causes redirect of AcpiOsPrintf and AcpiOsVprintf
398  *
399  *****************************************************************************/
400 
401 void
AcpiOsRedirectOutput(void * Destination)402 AcpiOsRedirectOutput (
403     void                    *Destination)
404 {
405 
406     AcpiGbl_OutputFile = Destination;
407 }
408 
409 
410 /******************************************************************************
411  *
412  * FUNCTION:    AcpiOsPrintf
413  *
414  * PARAMETERS:  fmt, ...            - Standard printf format
415  *
416  * RETURN:      None
417  *
418  * DESCRIPTION: Formatted output. Note: very similar to AcpiOsVprintf
419  *              (performance), changes should be tracked in both functions.
420  *
421  *****************************************************************************/
422 
423 void ACPI_INTERNAL_VAR_XFACE
AcpiOsPrintf(const char * Fmt,...)424 AcpiOsPrintf (
425     const char              *Fmt,
426     ...)
427 {
428     va_list                 Args;
429     UINT8                   Flags;
430 
431 
432     Flags = AcpiGbl_DbOutputFlags;
433     if (Flags & ACPI_DB_REDIRECTABLE_OUTPUT)
434     {
435         /* Output is directable to either a file (if open) or the console */
436 
437         if (AcpiGbl_DebugFile)
438         {
439             /* Output file is open, send the output there */
440 
441             va_start (Args, Fmt);
442             vfprintf (AcpiGbl_DebugFile, Fmt, Args);
443             va_end (Args);
444         }
445         else
446         {
447             /* No redirection, send output to console (once only!) */
448 
449             Flags |= ACPI_DB_CONSOLE_OUTPUT;
450         }
451     }
452 
453     if (Flags & ACPI_DB_CONSOLE_OUTPUT)
454     {
455         va_start (Args, Fmt);
456         vfprintf (AcpiGbl_OutputFile, Fmt, Args);
457         va_end (Args);
458     }
459 }
460 
461 
462 /******************************************************************************
463  *
464  * FUNCTION:    AcpiOsVprintf
465  *
466  * PARAMETERS:  fmt                 - Standard printf format
467  *              args                - Argument list
468  *
469  * RETURN:      None
470  *
471  * DESCRIPTION: Formatted output with argument list pointer. Note: very
472  *              similar to AcpiOsPrintf, changes should be tracked in both
473  *              functions.
474  *
475  *****************************************************************************/
476 
477 void
AcpiOsVprintf(const char * Fmt,va_list Args)478 AcpiOsVprintf (
479     const char              *Fmt,
480     va_list                 Args)
481 {
482     UINT8                   Flags;
483     char                    Buffer[ACPI_VPRINTF_BUFFER_SIZE];
484 
485 
486     /*
487      * We build the output string in a local buffer because we may be
488      * outputting the buffer twice. Using vfprintf is problematic because
489      * some implementations modify the args pointer/structure during
490      * execution. Thus, we use the local buffer for portability.
491      *
492      * Note: Since this module is intended for use by the various ACPICA
493      * utilities/applications, we can safely declare the buffer on the stack.
494      * Also, This function is used for relatively small error messages only.
495      */
496     vsnprintf (Buffer, ACPI_VPRINTF_BUFFER_SIZE, Fmt, Args);
497 
498     Flags = AcpiGbl_DbOutputFlags;
499     if (Flags & ACPI_DB_REDIRECTABLE_OUTPUT)
500     {
501         /* Output is directable to either a file (if open) or the console */
502 
503         if (AcpiGbl_DebugFile)
504         {
505             /* Output file is open, send the output there */
506 
507             fputs (Buffer, AcpiGbl_DebugFile);
508         }
509         else
510         {
511             /* No redirection, send output to console (once only!) */
512 
513             Flags |= ACPI_DB_CONSOLE_OUTPUT;
514         }
515     }
516 
517     if (Flags & ACPI_DB_CONSOLE_OUTPUT)
518     {
519         fputs (Buffer, AcpiGbl_OutputFile);
520     }
521 }
522 
523 
524 #ifndef ACPI_EXEC_APP
525 /******************************************************************************
526  *
527  * FUNCTION:    AcpiOsGetLine
528  *
529  * PARAMETERS:  Buffer              - Where to return the command line
530  *              BufferLength        - Maximum length of Buffer
531  *              BytesRead           - Where the actual byte count is returned
532  *
533  * RETURN:      Status and actual bytes read
534  *
535  * DESCRIPTION: Get the next input line from the terminal. NOTE: For the
536  *              AcpiExec utility, we use the acgetline module instead to
537  *              provide line-editing and history support.
538  *
539  *****************************************************************************/
540 
541 ACPI_STATUS
AcpiOsGetLine(char * Buffer,UINT32 BufferLength,UINT32 * BytesRead)542 AcpiOsGetLine (
543     char                    *Buffer,
544     UINT32                  BufferLength,
545     UINT32                  *BytesRead)
546 {
547     int                     InputChar;
548     UINT32                  EndOfLine;
549 
550 
551     /* Standard AcpiOsGetLine for all utilities except AcpiExec */
552 
553     for (EndOfLine = 0; ; EndOfLine++)
554     {
555         if (EndOfLine >= BufferLength)
556         {
557             return (AE_BUFFER_OVERFLOW);
558         }
559 
560         if ((InputChar = getchar ()) == EOF)
561         {
562             return (AE_ERROR);
563         }
564 
565         if (!InputChar || InputChar == _ASCII_NEWLINE)
566         {
567             break;
568         }
569 
570         Buffer[EndOfLine] = (char) InputChar;
571     }
572 
573     /* Null terminate the buffer */
574 
575     Buffer[EndOfLine] = 0;
576 
577     /* Return the number of bytes in the string */
578 
579     if (BytesRead)
580     {
581         *BytesRead = EndOfLine;
582     }
583 
584     return (AE_OK);
585 }
586 #endif
587 
588 
589 #ifndef ACPI_USE_NATIVE_MEMORY_MAPPING
590 /******************************************************************************
591  *
592  * FUNCTION:    AcpiOsMapMemory
593  *
594  * PARAMETERS:  where               - Physical address of memory to be mapped
595  *              length              - How much memory to map
596  *
597  * RETURN:      Pointer to mapped memory. Null on error.
598  *
599  * DESCRIPTION: Map physical memory into caller's address space
600  *
601  *****************************************************************************/
602 
603 void *
AcpiOsMapMemory(ACPI_PHYSICAL_ADDRESS where,ACPI_SIZE length)604 AcpiOsMapMemory (
605     ACPI_PHYSICAL_ADDRESS   where,
606     ACPI_SIZE               length)
607 {
608 
609     return (ACPI_TO_POINTER ((ACPI_SIZE) where));
610 }
611 
612 
613 /******************************************************************************
614  *
615  * FUNCTION:    AcpiOsUnmapMemory
616  *
617  * PARAMETERS:  where               - Logical address of memory to be unmapped
618  *              length              - How much memory to unmap
619  *
620  * RETURN:      None.
621  *
622  * DESCRIPTION: Delete a previously created mapping. Where and Length must
623  *              correspond to a previous mapping exactly.
624  *
625  *****************************************************************************/
626 
627 void
AcpiOsUnmapMemory(void * where,ACPI_SIZE length)628 AcpiOsUnmapMemory (
629     void                    *where,
630     ACPI_SIZE               length)
631 {
632 
633     return;
634 }
635 #endif
636 
637 
638 /******************************************************************************
639  *
640  * FUNCTION:    AcpiOsAllocate
641  *
642  * PARAMETERS:  Size                - Amount to allocate, in bytes
643  *
644  * RETURN:      Pointer to the new allocation. Null on error.
645  *
646  * DESCRIPTION: Allocate memory. Algorithm is dependent on the OS.
647  *
648  *****************************************************************************/
649 
650 void *
AcpiOsAllocate(ACPI_SIZE size)651 AcpiOsAllocate (
652     ACPI_SIZE               size)
653 {
654     void                    *Mem;
655 
656 
657     Mem = (void *) malloc ((size_t) size);
658     return (Mem);
659 }
660 
661 
662 #ifdef USE_NATIVE_ALLOCATE_ZEROED
663 /******************************************************************************
664  *
665  * FUNCTION:    AcpiOsAllocateZeroed
666  *
667  * PARAMETERS:  Size                - Amount to allocate, in bytes
668  *
669  * RETURN:      Pointer to the new allocation. Null on error.
670  *
671  * DESCRIPTION: Allocate and zero memory. Algorithm is dependent on the OS.
672  *
673  *****************************************************************************/
674 
675 void *
AcpiOsAllocateZeroed(ACPI_SIZE size)676 AcpiOsAllocateZeroed (
677     ACPI_SIZE               size)
678 {
679     void                    *Mem;
680 
681 
682     Mem = (void *) calloc (1, (size_t) size);
683     return (Mem);
684 }
685 #endif
686 
687 
688 /******************************************************************************
689  *
690  * FUNCTION:    AcpiOsFree
691  *
692  * PARAMETERS:  mem                 - Pointer to previously allocated memory
693  *
694  * RETURN:      None.
695  *
696  * DESCRIPTION: Free memory allocated via AcpiOsAllocate
697  *
698  *****************************************************************************/
699 
700 void
AcpiOsFree(void * mem)701 AcpiOsFree (
702     void                    *mem)
703 {
704 
705     free (mem);
706 }
707 
708 
709 #ifdef ACPI_SINGLE_THREADED
710 /******************************************************************************
711  *
712  * FUNCTION:    Semaphore stub functions
713  *
714  * DESCRIPTION: Stub functions used for single-thread applications that do
715  *              not require semaphore synchronization. Full implementations
716  *              of these functions appear after the stubs.
717  *
718  *****************************************************************************/
719 
720 ACPI_STATUS
AcpiOsCreateSemaphore(UINT32 MaxUnits,UINT32 InitialUnits,ACPI_HANDLE * OutHandle)721 AcpiOsCreateSemaphore (
722     UINT32              MaxUnits,
723     UINT32              InitialUnits,
724     ACPI_HANDLE         *OutHandle)
725 {
726     *OutHandle = (ACPI_HANDLE) 1;
727     return (AE_OK);
728 }
729 
730 ACPI_STATUS
AcpiOsDeleteSemaphore(ACPI_HANDLE Handle)731 AcpiOsDeleteSemaphore (
732     ACPI_HANDLE         Handle)
733 {
734     return (AE_OK);
735 }
736 
737 ACPI_STATUS
AcpiOsWaitSemaphore(ACPI_HANDLE Handle,UINT32 Units,UINT16 Timeout)738 AcpiOsWaitSemaphore (
739     ACPI_HANDLE         Handle,
740     UINT32              Units,
741     UINT16              Timeout)
742 {
743     return (AE_OK);
744 }
745 
746 ACPI_STATUS
AcpiOsSignalSemaphore(ACPI_HANDLE Handle,UINT32 Units)747 AcpiOsSignalSemaphore (
748     ACPI_HANDLE         Handle,
749     UINT32              Units)
750 {
751     return (AE_OK);
752 }
753 
754 #else
755 /******************************************************************************
756  *
757  * FUNCTION:    AcpiOsCreateSemaphore
758  *
759  * PARAMETERS:  InitialUnits        - Units to be assigned to the new semaphore
760  *              OutHandle           - Where a handle will be returned
761  *
762  * RETURN:      Status
763  *
764  * DESCRIPTION: Create an OS semaphore
765  *
766  *****************************************************************************/
767 
768 ACPI_STATUS
AcpiOsCreateSemaphore(UINT32 MaxUnits,UINT32 InitialUnits,ACPI_HANDLE * OutHandle)769 AcpiOsCreateSemaphore (
770     UINT32              MaxUnits,
771     UINT32              InitialUnits,
772     ACPI_HANDLE         *OutHandle)
773 {
774     sem_t               *Sem;
775 
776 
777     if (!OutHandle)
778     {
779         return (AE_BAD_PARAMETER);
780     }
781 
782 #ifdef __APPLE__
783     {
784         static int      SemaphoreCount = 0;
785         char            SemaphoreName[32];
786 
787         snprintf (SemaphoreName, sizeof (SemaphoreName), "acpi_sem_%d",
788             SemaphoreCount++);
789         printf ("%s\n", SemaphoreName);
790         Sem = sem_open (SemaphoreName, O_EXCL|O_CREAT, 0755, InitialUnits);
791         if (!Sem)
792         {
793             return (AE_NO_MEMORY);
794         }
795         sem_unlink (SemaphoreName); /* This just deletes the name */
796     }
797 
798 #else
799     Sem = AcpiOsAllocate (sizeof (sem_t));
800     if (!Sem)
801     {
802         return (AE_NO_MEMORY);
803     }
804 
805     if (sem_init (Sem, 0, InitialUnits) == -1)
806     {
807         AcpiOsFree (Sem);
808         return (AE_BAD_PARAMETER);
809     }
810 #endif
811 
812     *OutHandle = (ACPI_HANDLE) Sem;
813     return (AE_OK);
814 }
815 
816 
817 /******************************************************************************
818  *
819  * FUNCTION:    AcpiOsDeleteSemaphore
820  *
821  * PARAMETERS:  Handle              - Handle returned by AcpiOsCreateSemaphore
822  *
823  * RETURN:      Status
824  *
825  * DESCRIPTION: Delete an OS semaphore
826  *
827  *****************************************************************************/
828 
829 ACPI_STATUS
AcpiOsDeleteSemaphore(ACPI_HANDLE Handle)830 AcpiOsDeleteSemaphore (
831     ACPI_HANDLE         Handle)
832 {
833     sem_t               *Sem = (sem_t *) Handle;
834 
835 
836     if (!Sem)
837     {
838         return (AE_BAD_PARAMETER);
839     }
840 
841 #ifdef __APPLE__
842     if (sem_close (Sem) == -1)
843     {
844         return (AE_BAD_PARAMETER);
845     }
846 #else
847     if (sem_destroy (Sem) == -1)
848     {
849         return (AE_BAD_PARAMETER);
850     }
851 #endif
852 
853     return (AE_OK);
854 }
855 
856 
857 /******************************************************************************
858  *
859  * FUNCTION:    AcpiOsWaitSemaphore
860  *
861  * PARAMETERS:  Handle              - Handle returned by AcpiOsCreateSemaphore
862  *              Units               - How many units to wait for
863  *              MsecTimeout         - How long to wait (milliseconds)
864  *
865  * RETURN:      Status
866  *
867  * DESCRIPTION: Wait for units
868  *
869  *****************************************************************************/
870 
871 ACPI_STATUS
AcpiOsWaitSemaphore(ACPI_HANDLE Handle,UINT32 Units,UINT16 MsecTimeout)872 AcpiOsWaitSemaphore (
873     ACPI_HANDLE         Handle,
874     UINT32              Units,
875     UINT16              MsecTimeout)
876 {
877     ACPI_STATUS         Status = AE_OK;
878     sem_t               *Sem = (sem_t *) Handle;
879     int                 RetVal;
880 #ifndef ACPI_USE_ALTERNATE_TIMEOUT
881     struct timespec     Time;
882 #endif
883 
884 
885     if (!Sem)
886     {
887         return (AE_BAD_PARAMETER);
888     }
889 
890     switch (MsecTimeout)
891     {
892     /*
893      * No Wait:
894      * --------
895      * A zero timeout value indicates that we shouldn't wait - just
896      * acquire the semaphore if available otherwise return AE_TIME
897      * (a.k.a. 'would block').
898      */
899     case 0:
900 
901         if (sem_trywait(Sem) == -1)
902         {
903             Status = (AE_TIME);
904         }
905         break;
906 
907     /* Wait Indefinitely */
908 
909     case ACPI_WAIT_FOREVER:
910 
911         while (((RetVal = sem_wait (Sem)) == -1) && (errno == EINTR))
912         {
913             continue;   /* Restart if interrupted */
914         }
915         if (RetVal != 0)
916         {
917             Status = (AE_TIME);
918         }
919         break;
920 
921 
922     /* Wait with MsecTimeout */
923 
924     default:
925 
926 #ifdef ACPI_USE_ALTERNATE_TIMEOUT
927         /*
928          * Alternate timeout mechanism for environments where
929          * sem_timedwait is not available or does not work properly.
930          */
931         while (MsecTimeout)
932         {
933             if (sem_trywait (Sem) == 0)
934             {
935                 /* Got the semaphore */
936                 return (AE_OK);
937             }
938 
939             if (MsecTimeout >= 10)
940             {
941                 MsecTimeout -= 10;
942                 usleep (10 * ACPI_USEC_PER_MSEC); /* ten milliseconds */
943             }
944             else
945             {
946                 MsecTimeout--;
947                 usleep (ACPI_USEC_PER_MSEC); /* one millisecond */
948             }
949         }
950         Status = (AE_TIME);
951 #else
952         /*
953          * The interface to sem_timedwait is an absolute time, so we need to
954          * get the current time, then add in the millisecond Timeout value.
955          */
956         if (clock_gettime (CLOCK_REALTIME, &Time) == -1)
957         {
958             perror ("clock_gettime");
959             return (AE_TIME);
960         }
961 
962         Time.tv_sec += (MsecTimeout / ACPI_MSEC_PER_SEC);
963         Time.tv_nsec += ((MsecTimeout % ACPI_MSEC_PER_SEC) * ACPI_NSEC_PER_MSEC);
964 
965         /* Handle nanosecond overflow (field must be less than one second) */
966 
967         if (Time.tv_nsec >= ACPI_NSEC_PER_SEC)
968         {
969             Time.tv_sec += (Time.tv_nsec / ACPI_NSEC_PER_SEC);
970             Time.tv_nsec = (Time.tv_nsec % ACPI_NSEC_PER_SEC);
971         }
972 
973         while (((RetVal = sem_timedwait (Sem, &Time)) == -1) && (errno == EINTR))
974         {
975             continue;   /* Restart if interrupted */
976 
977         }
978 
979         if (RetVal != 0)
980         {
981             if (errno != ETIMEDOUT)
982             {
983                 perror ("sem_timedwait");
984             }
985             Status = (AE_TIME);
986         }
987 #endif
988         break;
989     }
990 
991     return (Status);
992 }
993 
994 
995 /******************************************************************************
996  *
997  * FUNCTION:    AcpiOsSignalSemaphore
998  *
999  * PARAMETERS:  Handle              - Handle returned by AcpiOsCreateSemaphore
1000  *              Units               - Number of units to send
1001  *
1002  * RETURN:      Status
1003  *
1004  * DESCRIPTION: Send units
1005  *
1006  *****************************************************************************/
1007 
1008 ACPI_STATUS
AcpiOsSignalSemaphore(ACPI_HANDLE Handle,UINT32 Units)1009 AcpiOsSignalSemaphore (
1010     ACPI_HANDLE         Handle,
1011     UINT32              Units)
1012 {
1013     sem_t               *Sem = (sem_t *)Handle;
1014 
1015 
1016     if (!Sem)
1017     {
1018         return (AE_BAD_PARAMETER);
1019     }
1020 
1021     if (sem_post (Sem) == -1)
1022     {
1023         return (AE_LIMIT);
1024     }
1025 
1026     return (AE_OK);
1027 }
1028 
1029 #endif /* ACPI_SINGLE_THREADED */
1030 
1031 
1032 /******************************************************************************
1033  *
1034  * FUNCTION:    Spinlock interfaces
1035  *
1036  * DESCRIPTION: Map these interfaces to semaphore interfaces
1037  *
1038  *****************************************************************************/
1039 
1040 ACPI_STATUS
AcpiOsCreateLock(ACPI_SPINLOCK * OutHandle)1041 AcpiOsCreateLock (
1042     ACPI_SPINLOCK           *OutHandle)
1043 {
1044 
1045     return (AcpiOsCreateSemaphore (1, 1, OutHandle));
1046 }
1047 
1048 
1049 void
AcpiOsDeleteLock(ACPI_SPINLOCK Handle)1050 AcpiOsDeleteLock (
1051     ACPI_SPINLOCK           Handle)
1052 {
1053     AcpiOsDeleteSemaphore (Handle);
1054 }
1055 
1056 
1057 ACPI_CPU_FLAGS
AcpiOsAcquireLock(ACPI_HANDLE Handle)1058 AcpiOsAcquireLock (
1059     ACPI_HANDLE             Handle)
1060 {
1061     AcpiOsWaitSemaphore (Handle, 1, 0xFFFF);
1062     return (0);
1063 }
1064 
1065 
1066 void
AcpiOsReleaseLock(ACPI_SPINLOCK Handle,ACPI_CPU_FLAGS Flags)1067 AcpiOsReleaseLock (
1068     ACPI_SPINLOCK           Handle,
1069     ACPI_CPU_FLAGS          Flags)
1070 {
1071     AcpiOsSignalSemaphore (Handle, 1);
1072 }
1073 
1074 
1075 /******************************************************************************
1076  *
1077  * FUNCTION:    AcpiOsInstallInterruptHandler
1078  *
1079  * PARAMETERS:  InterruptNumber     - Level handler should respond to.
1080  *              Isr                 - Address of the ACPI interrupt handler
1081  *              ExceptPtr           - Where status is returned
1082  *
1083  * RETURN:      Handle to the newly installed handler.
1084  *
1085  * DESCRIPTION: Install an interrupt handler. Used to install the ACPI
1086  *              OS-independent handler.
1087  *
1088  *****************************************************************************/
1089 
1090 UINT32
AcpiOsInstallInterruptHandler(UINT32 InterruptNumber,ACPI_OSD_HANDLER ServiceRoutine,void * Context)1091 AcpiOsInstallInterruptHandler (
1092     UINT32                  InterruptNumber,
1093     ACPI_OSD_HANDLER        ServiceRoutine,
1094     void                    *Context)
1095 {
1096 
1097     return (AE_OK);
1098 }
1099 
1100 
1101 /******************************************************************************
1102  *
1103  * FUNCTION:    AcpiOsRemoveInterruptHandler
1104  *
1105  * PARAMETERS:  Handle              - Returned when handler was installed
1106  *
1107  * RETURN:      Status
1108  *
1109  * DESCRIPTION: Uninstalls an interrupt handler.
1110  *
1111  *****************************************************************************/
1112 
1113 ACPI_STATUS
AcpiOsRemoveInterruptHandler(UINT32 InterruptNumber,ACPI_OSD_HANDLER ServiceRoutine)1114 AcpiOsRemoveInterruptHandler (
1115     UINT32                  InterruptNumber,
1116     ACPI_OSD_HANDLER        ServiceRoutine)
1117 {
1118 
1119     return (AE_OK);
1120 }
1121 
1122 
1123 /******************************************************************************
1124  *
1125  * FUNCTION:    AcpiOsStall
1126  *
1127  * PARAMETERS:  microseconds        - Time to sleep
1128  *
1129  * RETURN:      Blocks until sleep is completed.
1130  *
1131  * DESCRIPTION: Sleep at microsecond granularity
1132  *
1133  *****************************************************************************/
1134 
1135 void
AcpiOsStall(UINT32 microseconds)1136 AcpiOsStall (
1137     UINT32                  microseconds)
1138 {
1139 
1140     if (microseconds)
1141     {
1142         usleep (microseconds);
1143     }
1144 }
1145 
1146 
1147 /******************************************************************************
1148  *
1149  * FUNCTION:    AcpiOsSleep
1150  *
1151  * PARAMETERS:  milliseconds        - Time to sleep
1152  *
1153  * RETURN:      Blocks until sleep is completed.
1154  *
1155  * DESCRIPTION: Sleep at millisecond granularity
1156  *
1157  *****************************************************************************/
1158 
1159 void
AcpiOsSleep(UINT64 milliseconds)1160 AcpiOsSleep (
1161     UINT64                  milliseconds)
1162 {
1163 
1164     /* Sleep for whole seconds */
1165 
1166     sleep (milliseconds / ACPI_MSEC_PER_SEC);
1167 
1168     /*
1169      * Sleep for remaining microseconds.
1170      * Arg to usleep() is in usecs and must be less than 1,000,000 (1 second).
1171      */
1172     usleep ((milliseconds % ACPI_MSEC_PER_SEC) * ACPI_USEC_PER_MSEC);
1173 }
1174 
1175 
1176 /******************************************************************************
1177  *
1178  * FUNCTION:    AcpiOsGetTimer
1179  *
1180  * PARAMETERS:  None
1181  *
1182  * RETURN:      Current time in 100 nanosecond units
1183  *
1184  * DESCRIPTION: Get the current system time
1185  *
1186  *****************************************************************************/
1187 
1188 UINT64
AcpiOsGetTimer(void)1189 AcpiOsGetTimer (
1190     void)
1191 {
1192     struct timeval          time;
1193 
1194 
1195     /* This timer has sufficient resolution for user-space application code */
1196 
1197     gettimeofday (&time, NULL);
1198 
1199     /* (Seconds * 10^7 = 100ns(10^-7)) + (Microseconds(10^-6) * 10^1 = 100ns) */
1200 
1201     return (((UINT64) time.tv_sec * ACPI_100NSEC_PER_SEC) +
1202             ((UINT64) time.tv_usec * ACPI_100NSEC_PER_USEC));
1203 }
1204 
1205 
1206 /******************************************************************************
1207  *
1208  * FUNCTION:    AcpiOsReadPciConfiguration
1209  *
1210  * PARAMETERS:  PciId               - Seg/Bus/Dev
1211  *              PciRegister         - Device Register
1212  *              Value               - Buffer where value is placed
1213  *              Width               - Number of bits
1214  *
1215  * RETURN:      Status
1216  *
1217  * DESCRIPTION: Read data from PCI configuration space
1218  *
1219  *****************************************************************************/
1220 
1221 ACPI_STATUS
AcpiOsReadPciConfiguration(ACPI_PCI_ID * PciId,UINT32 PciRegister,UINT64 * Value,UINT32 Width)1222 AcpiOsReadPciConfiguration (
1223     ACPI_PCI_ID             *PciId,
1224     UINT32                  PciRegister,
1225     UINT64                  *Value,
1226     UINT32                  Width)
1227 {
1228 
1229     *Value = 0;
1230     return (AE_OK);
1231 }
1232 
1233 
1234 /******************************************************************************
1235  *
1236  * FUNCTION:    AcpiOsWritePciConfiguration
1237  *
1238  * PARAMETERS:  PciId               - Seg/Bus/Dev
1239  *              PciRegister         - Device Register
1240  *              Value               - Value to be written
1241  *              Width               - Number of bits
1242  *
1243  * RETURN:      Status.
1244  *
1245  * DESCRIPTION: Write data to PCI configuration space
1246  *
1247  *****************************************************************************/
1248 
1249 ACPI_STATUS
AcpiOsWritePciConfiguration(ACPI_PCI_ID * PciId,UINT32 PciRegister,UINT64 Value,UINT32 Width)1250 AcpiOsWritePciConfiguration (
1251     ACPI_PCI_ID             *PciId,
1252     UINT32                  PciRegister,
1253     UINT64                  Value,
1254     UINT32                  Width)
1255 {
1256 
1257     return (AE_OK);
1258 }
1259 
1260 
1261 /******************************************************************************
1262  *
1263  * FUNCTION:    AcpiOsReadPort
1264  *
1265  * PARAMETERS:  Address             - Address of I/O port/register to read
1266  *              Value               - Where value is placed
1267  *              Width               - Number of bits
1268  *
1269  * RETURN:      Value read from port
1270  *
1271  * DESCRIPTION: Read data from an I/O port or register
1272  *
1273  *****************************************************************************/
1274 
1275 ACPI_STATUS
AcpiOsReadPort(ACPI_IO_ADDRESS Address,UINT32 * Value,UINT32 Width)1276 AcpiOsReadPort (
1277     ACPI_IO_ADDRESS         Address,
1278     UINT32                  *Value,
1279     UINT32                  Width)
1280 {
1281 
1282     switch (Width)
1283     {
1284     case 8:
1285 
1286         *Value = 0xFF;
1287         break;
1288 
1289     case 16:
1290 
1291         *Value = 0xFFFF;
1292         break;
1293 
1294     case 32:
1295 
1296         *Value = 0xFFFFFFFF;
1297         break;
1298 
1299     default:
1300 
1301         return (AE_BAD_PARAMETER);
1302     }
1303 
1304     return (AE_OK);
1305 }
1306 
1307 
1308 /******************************************************************************
1309  *
1310  * FUNCTION:    AcpiOsWritePort
1311  *
1312  * PARAMETERS:  Address             - Address of I/O port/register to write
1313  *              Value               - Value to write
1314  *              Width               - Number of bits
1315  *
1316  * RETURN:      None
1317  *
1318  * DESCRIPTION: Write data to an I/O port or register
1319  *
1320  *****************************************************************************/
1321 
1322 ACPI_STATUS
AcpiOsWritePort(ACPI_IO_ADDRESS Address,UINT32 Value,UINT32 Width)1323 AcpiOsWritePort (
1324     ACPI_IO_ADDRESS         Address,
1325     UINT32                  Value,
1326     UINT32                  Width)
1327 {
1328 
1329     return (AE_OK);
1330 }
1331 
1332 
1333 /******************************************************************************
1334  *
1335  * FUNCTION:    AcpiOsReadMemory
1336  *
1337  * PARAMETERS:  Address             - Physical Memory Address to read
1338  *              Value               - Where value is placed
1339  *              Width               - Number of bits (8,16,32, or 64)
1340  *
1341  * RETURN:      Value read from physical memory address. Always returned
1342  *              as a 64-bit integer, regardless of the read width.
1343  *
1344  * DESCRIPTION: Read data from a physical memory address
1345  *
1346  *****************************************************************************/
1347 
1348 ACPI_STATUS
AcpiOsReadMemory(ACPI_PHYSICAL_ADDRESS Address,UINT64 * Value,UINT32 Width)1349 AcpiOsReadMemory (
1350     ACPI_PHYSICAL_ADDRESS   Address,
1351     UINT64                  *Value,
1352     UINT32                  Width)
1353 {
1354 
1355     switch (Width)
1356     {
1357     case 8:
1358     case 16:
1359     case 32:
1360     case 64:
1361 
1362         *Value = 0;
1363         break;
1364 
1365     default:
1366 
1367         return (AE_BAD_PARAMETER);
1368     }
1369     return (AE_OK);
1370 }
1371 
1372 
1373 /******************************************************************************
1374  *
1375  * FUNCTION:    AcpiOsWriteMemory
1376  *
1377  * PARAMETERS:  Address             - Physical Memory Address to write
1378  *              Value               - Value to write
1379  *              Width               - Number of bits (8,16,32, or 64)
1380  *
1381  * RETURN:      None
1382  *
1383  * DESCRIPTION: Write data to a physical memory address
1384  *
1385  *****************************************************************************/
1386 
1387 ACPI_STATUS
AcpiOsWriteMemory(ACPI_PHYSICAL_ADDRESS Address,UINT64 Value,UINT32 Width)1388 AcpiOsWriteMemory (
1389     ACPI_PHYSICAL_ADDRESS   Address,
1390     UINT64                  Value,
1391     UINT32                  Width)
1392 {
1393 
1394     return (AE_OK);
1395 }
1396 
1397 
1398 /******************************************************************************
1399  *
1400  * FUNCTION:    AcpiOsReadable
1401  *
1402  * PARAMETERS:  Pointer             - Area to be verified
1403  *              Length              - Size of area
1404  *
1405  * RETURN:      TRUE if readable for entire length
1406  *
1407  * DESCRIPTION: Verify that a pointer is valid for reading
1408  *
1409  *****************************************************************************/
1410 
1411 BOOLEAN
AcpiOsReadable(void * Pointer,ACPI_SIZE Length)1412 AcpiOsReadable (
1413     void                    *Pointer,
1414     ACPI_SIZE               Length)
1415 {
1416 
1417     return (TRUE);
1418 }
1419 
1420 
1421 /******************************************************************************
1422  *
1423  * FUNCTION:    AcpiOsWritable
1424  *
1425  * PARAMETERS:  Pointer             - Area to be verified
1426  *              Length              - Size of area
1427  *
1428  * RETURN:      TRUE if writable for entire length
1429  *
1430  * DESCRIPTION: Verify that a pointer is valid for writing
1431  *
1432  *****************************************************************************/
1433 
1434 BOOLEAN
AcpiOsWritable(void * Pointer,ACPI_SIZE Length)1435 AcpiOsWritable (
1436     void                    *Pointer,
1437     ACPI_SIZE               Length)
1438 {
1439 
1440     return (TRUE);
1441 }
1442 
1443 
1444 /******************************************************************************
1445  *
1446  * FUNCTION:    AcpiOsSignal
1447  *
1448  * PARAMETERS:  Function            - ACPI A signal function code
1449  *              Info                - Pointer to function-dependent structure
1450  *
1451  * RETURN:      Status
1452  *
1453  * DESCRIPTION: Miscellaneous functions. Example implementation only.
1454  *
1455  *****************************************************************************/
1456 
1457 ACPI_STATUS
AcpiOsSignal(UINT32 Function,void * Info)1458 AcpiOsSignal (
1459     UINT32                  Function,
1460     void                    *Info)
1461 {
1462 
1463     switch (Function)
1464     {
1465     case ACPI_SIGNAL_FATAL:
1466 
1467         break;
1468 
1469     case ACPI_SIGNAL_BREAKPOINT:
1470 
1471         break;
1472 
1473     default:
1474 
1475         break;
1476     }
1477 
1478     return (AE_OK);
1479 }
1480 
1481 /* Optional multi-thread support */
1482 
1483 #ifndef ACPI_SINGLE_THREADED
1484 /******************************************************************************
1485  *
1486  * FUNCTION:    AcpiOsGetThreadId
1487  *
1488  * PARAMETERS:  None
1489  *
1490  * RETURN:      Id of the running thread
1491  *
1492  * DESCRIPTION: Get the ID of the current (running) thread
1493  *
1494  *****************************************************************************/
1495 
1496 ACPI_THREAD_ID
AcpiOsGetThreadId(void)1497 AcpiOsGetThreadId (
1498     void)
1499 {
1500     pthread_t               thread;
1501 
1502 
1503     thread = pthread_self();
1504     return (ACPI_CAST_PTHREAD_T (thread));
1505 }
1506 
1507 
1508 /******************************************************************************
1509  *
1510  * FUNCTION:    AcpiOsExecute
1511  *
1512  * PARAMETERS:  Type                - Type of execution
1513  *              Function            - Address of the function to execute
1514  *              Context             - Passed as a parameter to the function
1515  *
1516  * RETURN:      Status.
1517  *
1518  * DESCRIPTION: Execute a new thread
1519  *
1520  *****************************************************************************/
1521 
1522 ACPI_STATUS
AcpiOsExecute(ACPI_EXECUTE_TYPE Type,ACPI_OSD_EXEC_CALLBACK Function,void * Context)1523 AcpiOsExecute (
1524     ACPI_EXECUTE_TYPE       Type,
1525     ACPI_OSD_EXEC_CALLBACK  Function,
1526     void                    *Context)
1527 {
1528     pthread_t               thread;
1529     int                     ret;
1530 
1531 
1532     ret = pthread_create (&thread, NULL, (PTHREAD_CALLBACK) Function, Context);
1533     if (ret)
1534     {
1535         AcpiOsPrintf("Create thread failed");
1536     }
1537     return (0);
1538 }
1539 
1540 #else /* ACPI_SINGLE_THREADED */
1541 ACPI_THREAD_ID
AcpiOsGetThreadId(void)1542 AcpiOsGetThreadId (
1543     void)
1544 {
1545     return (1);
1546 }
1547 
1548 ACPI_STATUS
AcpiOsExecute(ACPI_EXECUTE_TYPE Type,ACPI_OSD_EXEC_CALLBACK Function,void * Context)1549 AcpiOsExecute (
1550     ACPI_EXECUTE_TYPE       Type,
1551     ACPI_OSD_EXEC_CALLBACK  Function,
1552     void                    *Context)
1553 {
1554 
1555     Function (Context);
1556 
1557     return (AE_OK);
1558 }
1559 
1560 #endif /* ACPI_SINGLE_THREADED */
1561 
1562 
1563 /******************************************************************************
1564  *
1565  * FUNCTION:    AcpiOsWaitEventsComplete
1566  *
1567  * PARAMETERS:  None
1568  *
1569  * RETURN:      None
1570  *
1571  * DESCRIPTION: Wait for all asynchronous events to complete. This
1572  *              implementation does nothing.
1573  *
1574  *****************************************************************************/
1575 
1576 void
AcpiOsWaitEventsComplete(void)1577 AcpiOsWaitEventsComplete (
1578     void)
1579 {
1580     return;
1581 }
1582