| /* |
| * Copyright (c) 2014, 2016 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() */ |
| |
| /** |
| * vos_mq_put_front() - adds a message to the head of message queue |
| * @mq: message queue |
| * @msg_wrapper: message wrapper |
| * |
| * This function is used to add a message to the head of message queue |
| * |
| * Return: None |
| */ |
| void vos_mq_put_front(pVosMqType mq, pVosMsgWrapper msg_wrapper) |
| { |
| unsigned long flags; |
| |
| if ((mq == NULL) || (msg_wrapper == NULL)) { |
| VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, |
| "%s: NULL pointer passed", __func__); |
| return; |
| } |
| |
| spin_lock_irqsave(&mq->mqLock, flags); |
| list_add(&msg_wrapper->msgNode, &mq->mqList); |
| spin_unlock_irqrestore(&mq->mqLock, flags); |
| } |
| |
| /*--------------------------------------------------------------------------- |
| |
| \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() */ |