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