[hsflinux] hsfconfig fails to compile on RedHat 9
Wig
vv1gg1 at yahoo.co.uk
Fri Apr 11 12:34:23 EDT 2003
I had the same problems, replace your ostime.c file with the one ive
attached. This makes it compile fine but its a complete hack so might
not be too reliable. That said ive not had any problems yet... but still
when an official version/patch for RH9.0 comes out use that instead of
my bodge job.
VViGGi
R. A. Rivas Diaz wrote:
> MY pc is configured to dualboot Windows XP and Redhat Linux 9, both
> recently instaled on a recently acquired PC.
> I have a Conexant HSF Modem and it's correctly installed and working
> perfectly under Windows XP.
> I downloaded the last available drivers for the mothem as an src.rpm...
> it get compiled and installed without problems, but when I run
> hsfconfig, I get compilation errors.
> I have attached the log generated by hsfconfig.
> Any idea of what it's happening?
> Thanks,
> Rivas.
>
-------------- next part --------------
/*osTime.c
This file includes os specific code for timing related functionalities.
*/
/*
* Copyright (c) 2001 Conexant Systems, Inc.
*
* 1. Permitted use. Redistribution and use in source and binary forms,
* with or without modification, are permitted under the terms set forth
* herein.
*
* 2. Disclaimer of Warranties. CONEXANT AND OTHER CONTRIBUTORS MAKE NO
* REPRESENTATION ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE.
* IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTIES OF ANY KIND.
* CONEXANT AND OTHER CONTRIBUTORS DISCLAIMS ALL WARRANTIES WITH REGARD TO
* THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE, GOOD TITLE AND AGAINST INFRINGEMENT.
*
* This software has not been formally tested, and there is no guarantee that
* it is free of errors including, but not limited to, bugs, defects,
* interrupted operation, or unexpected results. Any use of this software is
* at user's own risk.
*
* 3. No Liability.
*
* (a) Conexant or contributors shall not be responsible for any loss or
* damage to Company, its customers, or any third parties for any reason
* whatsoever, and CONEXANT OR CONTRIBUTORS SHALL NOT BE LIABLE FOR ANY
* ACTUAL, DIRECT, INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL, OR CONSEQUENTIAL
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED, WHETHER IN CONTRACT, STRICT OR OTHER LEGAL THEORY OF
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* (b) User agrees to hold Conexant and contributors harmless from any
* liability, loss, cost, damage or expense, including attorney's fees,
* as a result of any claims which may be made by any person, including
* but not limited to User, its agents and employees, its customers, or
* any third parties that arise out of or result from the manufacture,
* delivery, actual or alleged ownership, performance, use, operation
* or possession of the software furnished hereunder, whether such claims
* are based on negligence, breach of contract, absolute liability or any
* other legal theory.
*
* 4. Notices. User hereby agrees not to remove, alter or destroy any
* copyright, trademark, credits, other proprietary notices or confidential
* legends placed upon, contained within or associated with the Software,
* and shall include all such unaltered copyright, trademark, credits,
* other proprietary notices or confidential legends on or in every copy of
* the Software.
*
*/
#include "oscompat.h"
#include <linux/timer.h>
#include <linux/time.h>
#include <linux/ptrace.h>
#include <linux/interrupt.h>
#include <asm/semaphore.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <asm/system.h>
#include <linux/smp_lock.h>
#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,7) )
#include <linux/completion.h>
#endif
#include "oscompat.h"
#include "ossysenv.h"
#include "ostime_ex.h"
#include "osmemory_ex.h"
#include "osstring_ex.h"
#include "linuxres.h"
#define TICKS_TO_MSECS(ticks) (ticks*(1000/HZ))
static inline long MSECS_TO_TICKS(UINT32 msecs)
{
long ticks = (msecs)/(1000/HZ);
// round up to next tick
if ((!ticks && msecs) || (msecs % (1000/HZ)) >= ((1000/HZ) / 2))
ticks++;
return ticks;
}
typedef struct TIME_OUT_INSTANCE_TYPE
{
struct tq_struct TaskQueue;
struct wait_queue *WaitQueue;
struct timer_list Timer;
BOOL active;
int SchedCount;
UINT32 mSec;
BOOL bLocked;
PFREE_FUNC pFuncFree;
PVOID pRefData;
PCBFUNC pTimeOutCallBack;
}TIME_OUT_INSTANCE_T, *PTIME_OUT_INSTANCE_T;
typedef struct TIMER_TAG
{
UINT32 msec;
struct timer_list timer;
} TIMER_T, *PTIMER_T;
/********************************************************************/
STATIC VOID TimerThreadFunction(PVOID pData)
{
PTIME_OUT_INSTANCE_T pTimeOutInstance = (PTIME_OUT_INSTANCE_T)pData;
if (pTimeOutInstance->active == TRUE )
{
/* beware: some callback functions use FPU instructions */
pTimeOutInstance->pTimeOutCallBack(pTimeOutInstance->pRefData);
// callback might have set active to FALSE
if (pTimeOutInstance->active == TRUE ) {
mod_timer(&pTimeOutInstance -> Timer, jiffies + MSECS_TO_TICKS(pTimeOutInstance -> mSec));
}
}
pTimeOutInstance->SchedCount--;
}
STATIC VOID TimeOutHandler( unsigned long Data )
{
PTIME_OUT_INSTANCE_T pTimeOutInstance = (PTIME_OUT_INSTANCE_T)Data;
if (pTimeOutInstance->active == FALSE )
{
return;
}
pTimeOutInstance->SchedCount++;
if (OsModemThreadSchedule(&(pTimeOutInstance -> TaskQueue)) == 0)
{
//printk(KERN_ERR "%s: TimeOutHandler(%d) - schedule_task FAILED (jiffies=%ld)\n", __FUNCTION__, pTimeOutInstance->SchedCount, jiffies);
pTimeOutInstance->SchedCount--;
}
}
static DECLARE_TASK_QUEUE(tq_mdmthrd);
static DECLARE_WAIT_QUEUE_HEAD(mdmthrd_wait);
#ifdef DECLARE_COMPLETION
static DECLARE_COMPLETION(mdmthrd_exited);
#endif
static int mdmthrd_pid;
int OsModemThreadSchedule(PVOID task)
{
int ret;
if(mdmthrd_pid <= 0) {
printk(KERN_ERR"%s: WARNING: modem thread not present\n", __FUNCTION__);
}
#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,19) )
ret = queue_task((struct tq_struct *)task, &tq_mdmthrd);
#else
{
struct tq_struct *bh_pointer = (struct tq_struct *)task;
task_queue *bh_list = &tq_mdmthrd;
ret = 0;
if (!test_and_set_bit(0,&bh_pointer->sync)) {
unsigned long flags;
spin_lock_irqsave(&tqueue_lock, flags);
bh_pointer->next = *bh_list;
*bh_list = bh_pointer;
spin_unlock_irqrestore(&tqueue_lock, flags);
ret = 1;
}
}
#endif
wake_up(&mdmthrd_wait);
return ret;
}
/* lock_kernel() must be called before this function */
static void thrd_daemonize(void)
{
#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) )
exit_files(current); /* daemonize doesn't do exit_files */
current->files = init_task.files;
atomic_inc(¤t->files->count);
#endif
#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,2,18) ) && !defined(daemonize)
{
struct fs_struct *fs;
exit_mm(current);
current->session = 1;
current->pgrp = 1;
exit_fs(current); /* current->fs->count--; */
fs = init_task.fs;
current->fs = fs;
atomic_inc(&fs->count);
}
#else
daemonize();
#endif
#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,10) ) && \
( LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) )
reparent_to_init();
#endif
}
#ifndef DECLARE_COMPLETION
static int mdmthrd_running;
#endif
static int mdmthrd(void *startup)
{
register struct task_struct *curtask = current;
lock_kernel();
/* this thread doesn't need any user-level access,
* so get rid of all our resources.
*/
thrd_daemonize();
strncpy(curtask->comm, __FUNCTION__, sizeof(curtask->comm));
unlock_kernel();
//spin_lock_irq(&curtask->sigmask_lock);
sigemptyset(&curtask->blocked);
flush_signals(curtask);
{ // flush_signal_handlers
int i;
//struct k_sigaction *ka = &curtask->sig->action[0];
for (i = _NSIG ; i != 0 ; i--) {
//if (ka->sa.sa_handler != SIG_IGN)
// ka->sa.sa_handler = SIG_DFL;
//ka->sa.sa_flags = 0;
//sigemptyset(&ka->sa.sa_mask);
//ka++;
}
}
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
recalc_sigpending();
#endif
spin_unlock_irq(&curtask->sigmask_lock);
#ifdef DECLARE_COMPLETION
complete((struct completion *)startup);
#else
mdmthrd_running = 1;
#endif
/* beware: this thread executes floating-point instructions! */
while(1) {
set_current_state(TASK_RUNNING);
run_task_queue(&tq_mdmthrd);
if(signal_pending(curtask))
break;
interruptible_sleep_on(&mdmthrd_wait);
}
//spin_lock_irq(&curtask->sigmask_lock);
flush_signals(curtask);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
recalc_sigpending();
#endif
spin_unlock_irq(&curtask->sigmask_lock);
#ifdef DECLARE_COMPLETION
#if defined(complete_and_exit) || ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,9) )
complete_and_exit(&mdmthrd_exited, 0);
#else
complete(&mdmthrd_exited);
up_and_exit(NULL, 0);
#endif
#else
mdmthrd_running = 0;
return 0;
#endif
}
static INT32 ntimers;
/********************************************************************/
/* Construct a periodic time out instance.RunTime manager does not */
/* simply use global timers , since these are called with the */
/* same thread handle as the ring3 application. This prevent */
/* synchronization between passive and async calls with semaphores */
/* or mutexes. */
/* Parameters : */
/* Irql - run time IQRL in which the timeout call back */
/* should be called. In Wi95 this parameter in ignored, */
/* and all timeout are called at dispatch level. */
/* InitialTimeout - Initial timeout interval in ms pRefData */
/* should be passed as a parameter to this function*/
/* PTimeOutCallBack - CallBack to be call every timeout duration. */
/* pFuncAlloc - alloc function,pRefData should be passed as */
/* parameter for thids function. function should */
/* allocate memory in non-paged pool */
/* pFuncFree - free function,pRefData should be passed as */
/* parameter for thids function */
/* pRefData - reference data to be passed to pTimeOutCallBack */
/* pFuncAllc and pFuncFree */
/********************************************************************/
// @@@@ Irql unreferenced
GLOBAL HANDLE OSCreatePeriodicTimeOut ( IN TIMER_IRQL_TYPE Irql,
IN UINT32 InitialTimeOut,
IN PCBFUNC pTimeOutCallBack,
IN PALLOC_FUNC pFuncAlloc,
IN PFREE_FUNC pFuncFree,
IN PVOID pRefData)
{
PTIME_OUT_INSTANCE_T pTimeOutInstance;
if(pFuncAlloc) {
pTimeOutInstance= pFuncAlloc(sizeof(TIME_OUT_INSTANCE_T), pRefData);
} else {
ASSERT(OSContextAllowsSleeping());
pTimeOutInstance= kmalloc(sizeof(TIME_OUT_INSTANCE_T), GFP_KERNEL);
}
if (NULL == pTimeOutInstance )
return(NULL);
pTimeOutInstance->pFuncFree = pFuncFree;
pTimeOutInstance->pRefData = pRefData;
pTimeOutInstance->pTimeOutCallBack = pTimeOutCallBack;
pTimeOutInstance->bLocked = FALSE;
pTimeOutInstance->mSec = InitialTimeOut;
INIT_TQUEUE(&pTimeOutInstance -> TaskQueue, TimerThreadFunction, pTimeOutInstance);
init_timer(&pTimeOutInstance -> Timer);
pTimeOutInstance -> Timer.function = TimeOutHandler;
pTimeOutInstance -> Timer.data = (unsigned long)pTimeOutInstance;
pTimeOutInstance -> Timer.expires = jiffies + MSECS_TO_TICKS(100);
pTimeOutInstance -> SchedCount = 0;
if(OsAtomicIncrement(&ntimers) == 1) {
#ifdef COMPLETION_INITIALIZER
static struct completion startup = COMPLETION_INITIALIZER(startup);
#endif
MOD_INC_USE_COUNT;
#ifdef COMPLETION_INITIALIZER
mdmthrd_pid = kernel_thread(mdmthrd, &startup, 0);
wait_for_completion(&startup);
#else
mdmthrd_running = 0;
mdmthrd_pid = kernel_thread(mdmthrd, NULL, 0);
{
int i;
/* wait 5 seconds maximum for modem thread to start */
for (i=5000; !mdmthrd_running && (i > 0); i -= 50) {
OsSleep(50);
}
if(i <= 0) {
printk(KERN_ERR"%s: giving up on modem thread\n", __FUNCTION__);
}
}
#endif
if(mdmthrd_pid <= 0) {
MOD_DEC_USE_COUNT;
OsAtomicDecrement(&ntimers);
if(pTimeOutInstance->pFuncFree) {
pTimeOutInstance->pFuncFree(pTimeOutInstance,pTimeOutInstance->pRefData);
} else {
kfree(pTimeOutInstance);
}
return NULL;
}
}
if(InitialTimeOut != 0) {
pTimeOutInstance -> active = TRUE;
add_timer(&(pTimeOutInstance -> Timer));
} else
pTimeOutInstance -> active = FALSE;
return( (HANDLE)pTimeOutInstance);
}
/********************************************************************/
GLOBAL VOID OSDestroyPeriodicTimeOut (IN HANDLE hTimeOut)
{
PTIME_OUT_INSTANCE_T pTimeOutInstance = (PTIME_OUT_INSTANCE_T)hTimeOut;
ASSERT(OSContextAllowsSleeping());
pTimeOutInstance -> bLocked = TRUE;
pTimeOutInstance -> active = FALSE;
#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) )
del_timer_sync(&pTimeOutInstance -> Timer);
#else
del_timer(&pTimeOutInstance -> Timer);
#endif
while(pTimeOutInstance->SchedCount > 0) {
schedule();
}
if(OsAtomicDecrement(&ntimers) == 0) {
if(mdmthrd_pid > 0) {
int r = kill_proc(mdmthrd_pid, SIGKILL, 1);
if(r) {
printk(KERN_ERR"%s: kill_proc mdmthrd_pid=%d r=%d\n", __FUNCTION__, mdmthrd_pid, r);
}
#ifdef DECLARE_COMPLETION
wait_for_completion(&mdmthrd_exited);
#else
{
int i;
/* wait 5 seconds maximum for modem thread to terminate */
for (i=5000; mdmthrd_running && (i > 0); i -= 50) {
OsSleep(50);
}
if(i <= 0) {
printk(KERN_ERR"%s: giving up on modem thread\n", __FUNCTION__);
}
}
#endif
MOD_DEC_USE_COUNT;
}
}
if(pTimeOutInstance->pFuncFree) {
pTimeOutInstance->pFuncFree(pTimeOutInstance,pTimeOutInstance->pRefData);
} else {
kfree(pTimeOutInstance);
}
}
/********************************************************************/
GLOBAL BOOL OSSetPeriodicTimeOut ( IN HANDLE hTimeOut,
IN UINT32 NewTimeOut)
{
PTIME_OUT_INSTANCE_T pTimeOutInstance = (PTIME_OUT_INSTANCE_T)hTimeOut;
pTimeOutInstance->mSec = NewTimeOut;
if(NewTimeOut != 0) {
pTimeOutInstance -> active = TRUE;
mod_timer(&pTimeOutInstance -> Timer, jiffies + MSECS_TO_TICKS(pTimeOutInstance -> mSec));
} else {
pTimeOutInstance -> active = FALSE;
del_timer(&pTimeOutInstance -> Timer);
}
return TRUE;
}
static time_t epoch = 0;
/********************************************************************/
GLOBAL UINT32 OSGetSystemTime( VOID )
{
struct timeval timestamp;
do_gettimeofday(×tamp);
// result returned in milliseconds
return ((UINT32)(((timestamp.tv_sec-epoch)*1000) + (timestamp.tv_usec/1000)));
}
/********************************************************************/
HANDLE OSCreateTimer(UINT32 msec, PVOID pCBFunc, PVOID pRefData)
{
PTIMER_T pTimer;
if ( pCBFunc == NULL )
{
ASSERT(pCBFunc);
return (NULL);
}
ASSERT(OSContextAllowsSleeping());
pTimer = kmalloc(sizeof(TIMER_T),GFP_KERNEL);
if ( NULL == pTimer )
{
ASSERT(pTimer);
return (NULL);
}
memset(pTimer,0,sizeof(TIMER_T));
init_timer(&(pTimer->timer));
pTimer->timer.function = pCBFunc ;
pTimer->timer.data = (unsigned long)pRefData;
pTimer->timer.expires = jiffies + MSECS_TO_TICKS(msec);
pTimer->msec = msec;
return ((HANDLE)pTimer);
}
void OSSetTimer(PVOID pTimer)
{
struct timer_list* pTimerH;
PTIMER_T pTimerS = (PTIMER_T)pTimer;
if ( pTimer == NULL )
{
ASSERT(pTimer);
return;
}
pTimerH = &(pTimerS->timer);
mod_timer(pTimerH, jiffies + MSECS_TO_TICKS(pTimerS->msec));
}
void OSCancelTimer(PVOID pTimer)
{
struct timer_list* pTimerH;
if ( pTimer == NULL )
{
ASSERT(pTimer);
return;
}
pTimerH = &((PTIMER_T)pTimer)->timer;
del_timer(pTimerH);
}
void OSChangeTimerTimeOut(PVOID pTimer, UINT32 msec)
{
PTIMER_T pTimerS = (PTIMER_T)pTimer;
if ( pTimer == NULL )
{
ASSERT(pTimer);
return;
}
pTimerS->msec = msec;
}
void OSDestroyTimer(PVOID pTimer)
{
if ( pTimer == NULL )
{
ASSERT(pTimer);
return;
}
#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) )
del_timer_sync(&((PTIMER_T)pTimer)->timer);
#else
del_timer(&((PTIMER_T)pTimer)->timer);
#endif
kfree(pTimer);
}
/********************************************************************/
/* Utilities */
/********************************************************************/
static spinlock_t atomic_lock __attribute__((unused)) = SPIN_LOCK_UNLOCKED;
/****************************************************************************************
The OsAtomicCompareAndSwap function compares the value at the specified address with
oldVal. The value of newValue is written to the address only if oldValue and the
value at the address are equal. OSCompareAndSwap returns true if newValue is written
to the address; otherwise, it returns false.
Params:
oldValue The value to compare at address.
newValue The value to write to address if oldValue compares true.
address The 4-byte aligned address of the data to update atomically.
Result: true if newValue was written to the address.
****************************************************************************************/
BOOL OsAtomicCompareAndSwap (PVOID oldValue, PVOID newValue, PVOID* address)
{
#ifdef __HAVE_ARCH_CMPXCHG
return (cmpxchg(address, oldValue, newValue) == oldValue);
#else
unsigned long flags;
spin_lock_irqsave(&atomic_lock, flags);
if (*(PUINT32)address == (UINT32)oldValue)
{
*(PUINT32)address = (UINT32)newValue;
spin_unlock_irqrestore(&atomic_lock, flags);
return TRUE;
}
spin_unlock_irqrestore(&atomic_lock, flags);
return FALSE;
#endif
}
/****************************************************************************************
OsAtomicAdd
OsAtomicAdd function adds the specified amount to the value at the specified
address and returns the result.
Params:
amount The amount to add.
address The 4-byte aligned address of the value to update atomically.
Result: The result of the addition.
****************************************************************************************/
INT32 OsAtomicAdd (INT32 amount, PINT32 address)
{
unsigned long flags;
atomic_t *v = (atomic_t *)address;
spin_lock_irqsave(&atomic_lock, flags);
atomic_add(amount, v);
amount = atomic_read(v);
spin_unlock_irqrestore(&atomic_lock, flags);
return amount;
}
INT32 OsAtomicIncrement (PINT32 address)
{
unsigned long flags;
atomic_t *v = (atomic_t *)address;
INT32 amount;
spin_lock_irqsave(&atomic_lock, flags);
atomic_inc(v);
amount = atomic_read(v);
spin_unlock_irqrestore(&atomic_lock, flags);
return amount;
}
INT32 OsAtomicDecrement (PINT32 address)
{
unsigned long flags;
atomic_t *v = (atomic_t *)address;
INT32 amount;
spin_lock_irqsave(&atomic_lock, flags);
atomic_dec(v);
amount = atomic_read(v);
spin_unlock_irqrestore(&atomic_lock, flags);
return amount;
}
void OsSleep(UINT32 ms)
{
if(!OSContextAllowsSleeping()) {
printk(KERN_ERR"%s(%lu): cannot sleep in this context!\n", __FUNCTION__, ms);
ASSERT(OSContextAllowsSleeping());
return;
}
if(ms > TICKS_TO_MSECS(1)) {
UINT32 start, end;
long timeout = MSECS_TO_TICKS(ms);
//long ort = timeout;
start = OSGetSystemTime();
do {
set_current_state(TASK_UNINTERRUPTIBLE);
} while ((timeout = schedule_timeout(timeout)));
end = OSGetSystemTime() - start;
if(end < ms) {
//printk(KERN_ERR"OsSleep: short timeout; wanted %ld got %ldms ort=%ld\n", ms, end, ort);
OsSleep(end);
}
//else if(end > ms) {
// printk(KERN_ERR"OsSleep: timeout %ldms (%ldms too much) ort=%ld\n", ms, end - ms, ort);
//}
} else {
// short delay
mdelay(ms);
}
}
DWORD OsGlobalProcessorFreq;
tMuSecTimeStamp OsGetMuSecStartStamp(void)
{
tMuSecTimeStamp StartCnt;
rdtscl(StartCnt);
if(0==StartCnt)
StartCnt=1;
return StartCnt;
}
tMuSecTimeStamp OsDeltaTimeMuSec(tMuSecTimeStamp PrevStamp, tMuSecTimeStamp NextStamp)
{
tMuSecTimeStamp Delta=0;
if(PrevStamp)
{
if(0==NextStamp)
{
NextStamp=OsGetMuSecStartStamp();
}
Delta=NextStamp - PrevStamp;
Delta/=OsGlobalProcessorFreq;
}
return Delta;
}
void OsBusyLoopMuSec(DWORD DelayInMicroSecs)
{
tMuSecTimeStamp StartCnt=OsGetMuSecStartStamp();
while( OsDeltaTimeMuSec(StartCnt, 0) < (tMuSecTimeStamp)DelayInMicroSecs );
}
void OsBusyLoopMilliSec(DWORD DelayInMilliSecs)
{
int Cnt;
for(Cnt=0;Cnt<1000;Cnt++)
OsBusyLoopMuSec(DelayInMilliSecs);
}
static atomic_t locksHeld;
void OsObtainedLock(void)
{
atomic_inc(&locksHeld);
}
void OsReleasedLock(void)
{
atomic_dec(&locksHeld);
}
int OsLocksHeld(void)
{
return atomic_read(&locksHeld);
}
/* Semaphores */
/********************************************************************/
GLOBAL HANDLE OSSemaphoreCreate( IN int InitCount)
{
struct semaphore *pSemaphore;
ASSERT(OSContextAllowsSleeping());
pSemaphore = kmalloc(sizeof(struct semaphore), GFP_KERNEL);
if (NULL == pSemaphore)
{
ASSERT(pSemaphore);
return (NULL);
}
sema_init(pSemaphore, InitCount);
return ((HANDLE)pSemaphore);
}
/********************************************************************/
GLOBAL VOID OSSemaphoreDestroy( IN HANDLE hSemaphore)
{
if (NULL != hSemaphore)
kfree((void *)hSemaphore);
}
/********************************************************************/
GLOBAL VOID OSSemaphoreWait( IN HANDLE hSemaphore)
{
struct semaphore *pSemaphore = (struct semaphore *)hSemaphore;
if (NULL == hSemaphore) {
ASSERT(hSemaphore);
return;
}
ASSERT(OSContextAllowsSleeping());
down(pSemaphore);
}
/********************************************************************/
GLOBAL VOID OSSemaphoreSignal( IN HANDLE hSemaphore)
{
struct semaphore *pSemaphore = (struct semaphore *)hSemaphore;
if (NULL == hSemaphore) {
ASSERT(hSemaphore);
return;
}
up(pSemaphore);
}
/* Critical Section (Mutex) */
/********************************************************************/
typedef struct {
spinlock_t spinlock;
unsigned long flags;
#ifdef DEBUG
void *pmutex, *pfrom;
#endif
void *owner;
unsigned long nestcnt;
} CRIT_T;
GLOBAL HANDLE __OSCriticalSectionCreate( char *file, int line )
{
CRIT_T *mutex;
ASSERT(OSContextAllowsSleeping());
mutex = kmalloc(sizeof(CRIT_T), GFP_KERNEL);
if(!mutex) {
ASSERT(mutex);
return NULL;
}
spin_lock_init(&mutex->spinlock);
#ifdef DEBUG
mutex->pmutex = NULL;
mutex->pfrom = NULL;
#endif
mutex->owner = NULL;
mutex->nestcnt = 0;
return ((HANDLE)mutex);
}
/********************************************************************/
GLOBAL VOID OSCriticalSectionDestroy( IN HANDLE hMutex)
{
if ( NULL == hMutex )
{
ASSERT(hMutex);
return;
}
kfree((CRIT_T *)hMutex);
}
#ifdef DEBUG
static CRIT_T *pmutex;
static void *pfrom;
#endif
/********************************************************************/
GLOBAL VOID OSCriticalSectionAcquire( IN HANDLE hMutex)
{
CRIT_T *mutex = (CRIT_T *) hMutex;
unsigned long flags;
#ifdef local_irq_save
local_irq_save(flags);
#else
save_flags(flags);
cli();
#endif
if(!spin_trylock(&mutex->spinlock)) {
if(!in_interrupt() && mutex->owner == current) {
mutex->nestcnt++;
#ifdef local_irq_restore
local_irq_restore(flags);
#else
restore_flags(flags);
#endif
return;
}
spin_lock(&mutex->spinlock);
}
mutex->flags = flags;
#ifdef DEBUG
mutex->pmutex = pmutex;
mutex->pfrom = pfrom;
pmutex = mutex;
pfrom = __builtin_return_address(0);
#endif
if(!in_interrupt())
mutex->owner = current;
else
mutex->owner = 0;
OsObtainedLock();
}
/********************************************************************/
GLOBAL VOID OSCriticalSectionRelease( IN HANDLE hMutex)
{
CRIT_T *mutex = (CRIT_T *) hMutex;
#ifdef DEBUG
ASSERT(pmutex == mutex);
pmutex = mutex->pmutex;
pfrom = mutex->pfrom;
#endif
if(mutex->nestcnt) {
mutex->nestcnt--;
return;
}
spin_unlock_irqrestore(&mutex->spinlock, mutex->flags);
OsReleasedLock();
}
/********************************************************************/
GLOBAL VOID OSSetTimeSensitivity( IN UINT32 Interval)
{
}
/********************************************************************/
GLOBAL VOID OSRestoreTimeSensitivity( IN UINT32 Interval)
{
}
/********************************************************************/
GLOBAL VOID OSInitTime( VOID )
{
struct timeval timestamp;
do_gettimeofday(×tamp);
epoch = timestamp.tv_sec;
OsGlobalProcessorFreq = LinuxCalcCpuRate()/1000000;
}
More information about the hsflinux
mailing list