diff options
Diffstat (limited to 'sys/contrib/dev/acpica/os_specific')
-rw-r--r-- | sys/contrib/dev/acpica/os_specific/service_layers/osunixxf.c | 140 |
1 files changed, 114 insertions, 26 deletions
diff --git a/sys/contrib/dev/acpica/os_specific/service_layers/osunixxf.c b/sys/contrib/dev/acpica/os_specific/service_layers/osunixxf.c index cf6382b..c18d65c 100644 --- a/sys/contrib/dev/acpica/os_specific/service_layers/osunixxf.c +++ b/sys/contrib/dev/acpica/os_specific/service_layers/osunixxf.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2012, Intel Corp. + * Copyright (C) 2000 - 2013, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -84,6 +84,10 @@ AeTableOverride ( typedef void* (*PTHREAD_CALLBACK) (void *); +/* Buffer used by AcpiOsVprintf */ + +#define ACPI_VPRINTF_BUFFER_SIZE 512 + /* Apple-specific */ #ifdef __APPLE__ @@ -268,7 +272,8 @@ AcpiOsRedirectOutput ( * * RETURN: None * - * DESCRIPTION: Formatted output + * DESCRIPTION: Formatted output. Note: very similar to AcpiOsVprintf + * (performance), changes should be tracked in both functions. * *****************************************************************************/ @@ -278,11 +283,36 @@ AcpiOsPrintf ( ...) { va_list Args; + UINT8 Flags; + + + Flags = AcpiGbl_DbOutputFlags; + if (Flags & ACPI_DB_REDIRECTABLE_OUTPUT) + { + /* Output is directable to either a file (if open) or the console */ + + if (AcpiGbl_DebugFile) + { + /* Output file is open, send the output there */ + + va_start (Args, Fmt); + vfprintf (AcpiGbl_DebugFile, Fmt, Args); + va_end (Args); + } + else + { + /* No redirection, send output to console (once only!) */ + Flags |= ACPI_DB_CONSOLE_OUTPUT; + } + } - va_start (Args, Fmt); - AcpiOsVprintf (Fmt, Args); - va_end (Args); + if (Flags & ACPI_DB_CONSOLE_OUTPUT) + { + va_start (Args, Fmt); + vfprintf (AcpiGbl_OutputFile, Fmt, Args); + va_end (Args); + } } @@ -295,7 +325,9 @@ AcpiOsPrintf ( * * RETURN: None * - * DESCRIPTION: Formatted output with argument list pointer + * DESCRIPTION: Formatted output with argument list pointer. Note: very + * similar to AcpiOsPrintf, changes should be tracked in both + * functions. * *****************************************************************************/ @@ -305,7 +337,20 @@ AcpiOsVprintf ( va_list Args) { UINT8 Flags; + char Buffer[ACPI_VPRINTF_BUFFER_SIZE]; + + /* + * We build the output string in a local buffer because we may be + * outputting the buffer twice. Using vfprintf is problematic because + * some implementations modify the args pointer/structure during + * execution. Thus, we use the local buffer for portability. + * + * Note: Since this module is intended for use by the various ACPICA + * utilities/applications, we can safely declare the buffer on the stack. + * Also, This function is used for relatively small error messages only. + */ + vsnprintf (Buffer, ACPI_VPRINTF_BUFFER_SIZE, Fmt, Args); Flags = AcpiGbl_DbOutputFlags; if (Flags & ACPI_DB_REDIRECTABLE_OUTPUT) @@ -316,7 +361,7 @@ AcpiOsVprintf ( { /* Output file is open, send the output there */ - vfprintf (AcpiGbl_DebugFile, Fmt, Args); + fputs (Buffer, AcpiGbl_DebugFile); } else { @@ -328,7 +373,7 @@ AcpiOsVprintf ( if (Flags & ACPI_DB_CONSOLE_OUTPUT) { - vfprintf (AcpiGbl_OutputFile, Fmt, Args); + fputs (Buffer, AcpiGbl_OutputFile); } } @@ -626,7 +671,7 @@ AcpiOsDeleteSemaphore ( * * PARAMETERS: Handle - Handle returned by AcpiOsCreateSemaphore * Units - How many units to wait for - * Timeout - How long to wait + * MsecTimeout - How long to wait (milliseconds) * * RETURN: Status * @@ -638,11 +683,14 @@ ACPI_STATUS AcpiOsWaitSemaphore ( ACPI_HANDLE Handle, UINT32 Units, - UINT16 Timeout) + UINT16 MsecTimeout) { ACPI_STATUS Status = AE_OK; sem_t *Sem = (sem_t *) Handle; - struct timespec T; +#ifndef ACPI_USE_ALTERNATE_TIMEOUT + struct timespec Time; + int RetVal; +#endif if (!Sem) @@ -650,7 +698,7 @@ AcpiOsWaitSemaphore ( return (AE_BAD_PARAMETER); } - switch (Timeout) + switch (MsecTimeout) { /* * No Wait: @@ -677,37 +725,71 @@ AcpiOsWaitSemaphore ( } break; - /* Wait with Timeout */ + /* Wait with MsecTimeout */ default: - T.tv_sec = Timeout / 1000; - T.tv_nsec = (Timeout - (T.tv_sec * 1000)) * 1000000; - #ifdef ACPI_USE_ALTERNATE_TIMEOUT /* * Alternate timeout mechanism for environments where * sem_timedwait is not available or does not work properly. */ - while (Timeout) + while (MsecTimeout) { if (sem_trywait (Sem) == 0) { /* Got the semaphore */ return (AE_OK); } - usleep (1000); /* one millisecond */ - Timeout--; + + if (MsecTimeout >= 10) + { + MsecTimeout -= 10; + usleep (10 * ACPI_USEC_PER_MSEC); /* ten milliseconds */ + } + else + { + MsecTimeout--; + usleep (ACPI_USEC_PER_MSEC); /* one millisecond */ + } } Status = (AE_TIME); #else + /* + * The interface to sem_timedwait is an absolute time, so we need to + * get the current time, then add in the millisecond Timeout value. + */ + if (clock_gettime (CLOCK_REALTIME, &Time) == -1) + { + perror ("clock_gettime"); + return (AE_TIME); + } + + Time.tv_sec += (MsecTimeout / ACPI_MSEC_PER_SEC); + Time.tv_nsec += ((MsecTimeout % ACPI_MSEC_PER_SEC) * ACPI_NSEC_PER_MSEC); + + /* Handle nanosecond overflow (field must be less than one second) */ + + if (Time.tv_nsec >= ACPI_NSEC_PER_SEC) + { + Time.tv_sec += (Time.tv_nsec / ACPI_NSEC_PER_SEC); + Time.tv_nsec = (Time.tv_nsec % ACPI_NSEC_PER_SEC); + } + + while (((RetVal = sem_timedwait (Sem, &Time)) == -1) && (errno == EINTR)) + { + continue; + } - if (sem_timedwait (Sem, &T)) + if (RetVal != 0) { + if (errno != ETIMEDOUT) + { + perror ("sem_timedwait"); + } Status = (AE_TIME); } #endif - break; } @@ -884,12 +966,15 @@ AcpiOsSleep ( UINT64 milliseconds) { - sleep (milliseconds / 1000); /* Sleep for whole seconds */ + /* Sleep for whole seconds */ + + sleep (milliseconds / ACPI_MSEC_PER_SEC); /* - * Arg to usleep() must be less than 1,000,000 (1 second) + * Sleep for remaining microseconds. + * Arg to usleep() is in usecs and must be less than 1,000,000 (1 second). */ - usleep ((milliseconds % 1000) * 1000); /* Sleep for remaining usecs */ + usleep ((milliseconds % ACPI_MSEC_PER_SEC) * ACPI_USEC_PER_MSEC); } @@ -912,11 +997,14 @@ AcpiOsGetTimer ( struct timeval time; + /* This timer has sufficient resolution for user-space application code */ + gettimeofday (&time, NULL); - /* Seconds * 10^7 = 100ns(10^-7), Microseconds(10^-6) * 10^1 = 100ns */ + /* (Seconds * 10^7 = 100ns(10^-7)) + (Microseconds(10^-6) * 10^1 = 100ns) */ - return (((UINT64) time.tv_sec * 10000000) + ((UINT64) time.tv_usec * 10)); + return (((UINT64) time.tv_sec * ACPI_100NSEC_PER_SEC) + + ((UINT64) time.tv_usec * ACPI_100NSEC_PER_USEC)); } |