blob: 91ed206740012a2cab8bd6eb8c635f6959cc6d19 [file] [log] [blame]
/*
* Copyright (c) 2012-2013 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/*
* This file was originally distributed by Qualcomm Atheros, Inc.
* under proprietary terms before Copyright ownership was assigned
* to the Linux Foundation.
*/
/**=========================================================================
\file vos_mq.c
\brief virtual Operating System Services (vOSS) message queue APIs
Message Queue Definitions and API
========================================================================*/
/* $Header$ */
/*--------------------------------------------------------------------------
Include Files
------------------------------------------------------------------------*/
#include <vos_mq.h>
#include "vos_sched.h"
#include <vos_api.h>
/*--------------------------------------------------------------------------
Preprocessor definitions and constants
------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------
Type declarations
------------------------------------------------------------------------*/
/*-------------------------------------------------------------------------
Function declarations and documenation
------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------
\brief vos_mq_init() - Initialize the vOSS Scheduler
The \a vos_mq_init() function initializes the Message queue.
\param pMq - pointer to the message queue
\return VOS_STATUS_SUCCESS - Message queue was successfully initialized and
is ready to be used.
VOS_STATUS_E_RESOURCES - Invalid parameter passed to the message
queue initialize function.
\sa vos_mq_init()
---------------------------------------------------------------------------*/
__inline VOS_STATUS vos_mq_init(pVosMqType pMq)
{
/* Some quick sanity check*/
if (pMq == NULL) {
VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
"%s: NULL pointer passed",__func__);
return VOS_STATUS_E_FAILURE;
}
/*
** Now initialize the lock
*/
spin_lock_init(&pMq->mqLock);
/*
** Now initialize the List data structure
*/
INIT_LIST_HEAD(&pMq->mqList);
return VOS_STATUS_SUCCESS;
} /* vos_mq_init()*/
/*---------------------------------------------------------------------------
\brief vos_mq_deinit() - DeInitialize the vOSS Scheduler
The \a vos_mq_init() function de-initializes the Message queue.
\param pMq - pointer to the message queue
\return None
\sa vos_mq_deinit()
---------------------------------------------------------------------------*/
__inline void vos_mq_deinit(pVosMqType pMq)
{
/*
** Some quick sanity check
*/
if (pMq == NULL) {
VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
"%s: NULL pointer passed",__func__);
return ;
}
/* we don't have to do anything with the embedded list or spinlock */
}/* vos_mq_deinit() */
/*---------------------------------------------------------------------------
\brief vos_mq_put() - Add a message to the message queue
The \a vos_mq_put() function add a message to the Message queue.
\param pMq - pointer to the message queue
\param pMsgWrapper - Msg Wrapper containing the message
\return None
\sa vos_mq_put()
---------------------------------------------------------------------------*/
__inline void vos_mq_put(pVosMqType pMq, pVosMsgWrapper pMsgWrapper)
{
unsigned long flags;
/*
** Some quick sanity check
*/
if ((pMq == NULL) || (pMsgWrapper == NULL)) {
VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
"%s: NULL pointer passed",__func__);
return ;
}
spin_lock_irqsave(&pMq->mqLock, flags);
list_add_tail(&pMsgWrapper->msgNode, &pMq->mqList);
spin_unlock_irqrestore(&pMq->mqLock, flags);
} /* vos_mq_put() */
/*---------------------------------------------------------------------------
\brief vos_mq_put_front() - Add a message to the head of message queue
The \a vos_mq_put_front() function add a message to the head of Message queue.
\param pMq - pointer to the message queue
\param pMsgWrapper - Msg Wrapper containing the message
\return None
\sa vos_mq_put()
---------------------------------------------------------------------------*/
void vos_mq_put_front(pVosMqType pMq, pVosMsgWrapper pMsgWrapper)
{
unsigned long flags;
/*
** Some quick sanity check
*/
if ((pMq == NULL) || (pMsgWrapper == NULL)) {
VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
"%s: NULL pointer passed",__func__);
return ;
}
spin_lock_irqsave(&pMq->mqLock, flags);
list_add(&pMsgWrapper->msgNode, &pMq->mqList);
spin_unlock_irqrestore(&pMq->mqLock, flags);
} /* vos_mq_put_front() */
/*---------------------------------------------------------------------------
\brief vos_mq_get() - Get a message with its wrapper from a message queue
The \a vos_mq_get() function retrieve a message with its wrapper from
the Message queue.
\param pMq - pointer to the message queue
\return pointer to the Message Wrapper
\sa vos_mq_get()
---------------------------------------------------------------------------*/
__inline pVosMsgWrapper vos_mq_get(pVosMqType pMq)
{
pVosMsgWrapper pMsgWrapper = NULL;
/*
** Some quick sanity check
*/
struct list_head * listptr;
unsigned long flags;
if (pMq == NULL) {
VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
"%s: NULL pointer passed",__func__);
return NULL;
}
spin_lock_irqsave(&pMq->mqLock, flags);
if( list_empty(&pMq->mqList) )
{
VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
"%s: VOS Message Queue is empty",__func__);
}
else
{
listptr = pMq->mqList.next;
pMsgWrapper = (pVosMsgWrapper)list_entry(listptr, VosMsgWrapper, msgNode);
list_del(pMq->mqList.next);
}
spin_unlock_irqrestore(&pMq->mqLock, flags);
return pMsgWrapper;
} /* vos_mq_get() */
/*---------------------------------------------------------------------------
\brief vos_is_mq_empty() - Return if the MQ is empty
The \a vos_is_mq_empty() returns true if the queue is empty
\param pMq - pointer to the message queue
\return pointer to the Message Wrapper
\sa vos_mq_get()
---------------------------------------------------------------------------*/
__inline v_BOOL_t vos_is_mq_empty(pVosMqType pMq)
{
v_BOOL_t state = VOS_FALSE;
unsigned long flags;
/*
** Some quick sanity check
*/
if (pMq == NULL)
{
VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
"%s: NULL pointer passed",__func__);
return VOS_STATUS_E_FAILURE;
}
spin_lock_irqsave(&pMq->mqLock, flags);
state = list_empty(&pMq->mqList)?VOS_TRUE:VOS_FALSE;
spin_unlock_irqrestore(&pMq->mqLock, flags);
return state;
} /* vos_mq_get() */