Implement the internal locks of an ACPI semaphore with splhigh() on

4-stable.  -current uses a mutex for this purpose.

Sponsored by:	The Weather Channel
This commit is contained in:
John Baldwin 2002-10-16 17:23:34 +00:00
parent 90fa95e81d
commit b60bd0c129

View File

@ -35,22 +35,37 @@
#include "opt_acpi.h"
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mutex.h>
#include <sys/sysctl.h>
#if __FreeBSD_version >= 500000
#include <sys/lock.h>
#include <sys/mutex.h>
#endif
#define _COMPONENT ACPI_OS_SERVICES
ACPI_MODULE_NAME("SYNCH")
static MALLOC_DEFINE(M_ACPISEM, "acpisem", "ACPI semaphore");
#if __FreeBSD_version < 500000
# define AS_LOCK(as) s = splhigh()
# define AS_UNLOCK(as) splx(s)
# define AS_LOCK_DECL int s
# define msleep(a, b, c, d, e) tsleep(a, c, d, e)
#else
# define AS_LOCK(as) mtx_lock(&(as)->as_mtx)
# define AS_UNLOCK(as) mtx_unlock(&(as)->as_mtx)
# define AS_LOCK_DECL
#endif
/*
* Simple counting semaphore implemented using a mutex. (Subsequently used
* in the OSI code to implement a mutex. Go figure.)
*/
struct acpi_semaphore {
#if __FreeBSD_version >= 500000
struct mtx as_mtx;
#endif
UINT32 as_units;
UINT32 as_maxunits;
UINT32 as_pendings;
@ -85,7 +100,9 @@ AcpiOsCreateSemaphore(UINT32 MaxUnits, UINT32 InitialUnits, ACPI_HANDLE *OutHand
return_ACPI_STATUS(AE_NO_MEMORY);
bzero(as, sizeof(*as));
#if __FreeBSD_version >= 500000
mtx_init(&as->as_mtx, "ACPI semaphore", NULL, MTX_DEF);
#endif
as->as_units = InitialUnits;
as->as_maxunits = MaxUnits;
as->as_pendings = as->as_resetting = as->as_timeouts = 0;
@ -111,7 +128,9 @@ AcpiOsDeleteSemaphore (ACPI_HANDLE Handle)
ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "destroyed semaphore %p\n", as));
#if __FreeBSD_version >= 500000
mtx_destroy(&as->as_mtx);
#endif
free(Handle, M_ACPISEM);
return_ACPI_STATUS(AE_OK);
#else
@ -132,6 +151,7 @@ AcpiOsWaitSemaphore(ACPI_HANDLE Handle, UINT32 Units, UINT32 Timeout)
ACPI_STATUS result;
int rv, tmo;
struct timeval timeouttv, currenttv, timelefttv;
AS_LOCK_DECL;
ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
@ -144,13 +164,13 @@ AcpiOsWaitSemaphore(ACPI_HANDLE Handle, UINT32 Units, UINT32 Timeout)
#if 0
if (as->as_units < Units && as->as_timeouts > 10) {
printf("%s: semaphore %p too many timeouts, resetting\n", __func__, as);
mtx_lock(&as->as_mtx);
AS_LOCK(as);
as->as_units = as->as_maxunits;
if (as->as_pendings)
as->as_resetting = 1;
as->as_timeouts = 0;
wakeup(as);
mtx_unlock(&as->as_mtx);
AS_UNLOCK(as);
return_ACPI_STATUS(AE_TIME);
}
@ -177,7 +197,7 @@ AcpiOsWaitSemaphore(ACPI_HANDLE Handle, UINT32 Units, UINT32 Timeout)
getmicrotime(&currenttv);
timevaladd(&timeouttv, &currenttv);
mtx_lock(&as->as_mtx);
AS_LOCK(as);
ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
"get %d units from semaphore %p (has %d), timeout %d\n",
Units, as, as->as_units, Timeout));
@ -204,9 +224,11 @@ AcpiOsWaitSemaphore(ACPI_HANDLE Handle, UINT32 Units, UINT32 Timeout)
break;
}
#if __FreeBSD_version >= 500000
ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
"semaphore blocked, calling msleep(%p, %p, %d, \"acsem\", %d)\n",
as, &as->as_mtx, PCATCH, tmo));
#endif
as->as_pendings++;
@ -274,7 +296,7 @@ AcpiOsWaitSemaphore(ACPI_HANDLE Handle, UINT32 Units, UINT32 Timeout)
as->as_timeouts = 0;
}
mtx_unlock(&as->as_mtx);
AS_UNLOCK(as);
return_ACPI_STATUS(result);
#else
@ -287,13 +309,14 @@ AcpiOsSignalSemaphore(ACPI_HANDLE Handle, UINT32 Units)
{
#ifndef ACPI_NO_SEMAPHORES
struct acpi_semaphore *as = (struct acpi_semaphore *)Handle;
AS_LOCK_DECL;
ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
if (as == NULL)
return_ACPI_STATUS(AE_BAD_PARAMETER);
mtx_lock(&as->as_mtx);
AS_LOCK(as);
ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
"return %d units to semaphore %p (has %d)\n",
Units, as, as->as_units));
@ -309,7 +332,7 @@ AcpiOsSignalSemaphore(ACPI_HANDLE Handle, UINT32 Units)
}
wakeup(as);
mtx_unlock(&as->as_mtx);
AS_UNLOCK(as);
return_ACPI_STATUS(AE_OK);
#else
return(AE_OK);