diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-06-26 15:46:08 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-06-26 15:46:08 -0700 |
commit | 23908db413eccd77084b09c9b0a4451dfb0524c0 (patch) | |
tree | 646f21a92496bdc04175e95642b0ecb2dc3dd09e /drivers/staging/wilc1000/wilc_msgqueue.c | |
parent | 8d7804a2f03dbd34940fcb426450c730adf29dae (diff) | |
parent | 53a20e9e378ecd52f0afa4b60f8f8c81b6f97c27 (diff) | |
download | linux-23908db413eccd77084b09c9b0a4451dfb0524c0.tar.bz2 |
Merge tag 'staging-4.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging
Pull staging driver updates from Greg KH:
"Here's the big, really big, staging tree patches for 4.2-rc1.
Loads of stuff in here, almost all just coding style fixes / churn,
and a few new drivers as well, one of which I just disabled from the
build a few minutes ago due to way too many build warnings.
Other than the one "disable this driver" patch, all of these have been
in linux-next for quite a while with no reported issues"
* tag 'staging-4.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging: (1163 commits)
staging: wilc1000: disable driver due to build warnings
Staging: rts5208: fix CHANGE_LINK_STATE value
Staging: sm750fb: ddk750_swi2c.c: Insert spaces before parenthesis
Staging: sm750fb: ddk750_swi2c.c: Place braces on correct lines
Staging: sm750fb: ddk750_swi2c.c: Insert spaces around operators
Staging: sm750fb: ddk750_swi2c.c: Replace spaces with tabs
Staging: sm750fb: ddk750_swi2c.h: Shorten lines to under 80 characters
Staging: sm750fb: ddk750_swi2c.h: Replace spaces with tabs
Staging: sm750fb: modedb.h: Shorten lines to under 80 characters
Staging: sm750fb: modedb.h: Replace spaces with tabs
staging: comedi: addi_apci_3120: rename 'this_board' variables
staging: comedi: addi_apci_1516: rename 'this_board' variables
staging: comedi: ni_atmio: cleanup ni_getboardtype()
staging: comedi: vmk80xx: sanity check context used to get the boardinfo
staging: comedi: vmk80xx: rename 'boardinfo' variables
staging: comedi: dt3000: rename 'this_board' variables
staging: comedi: adv_pci_dio: rename 'this_board' variables
staging: comedi: cb_pcidas64: rename 'thisboard' variables
staging: comedi: cb_pcidas: rename 'thisboard' variables
staging: comedi: me4000: rename 'thisboard' variables
...
Diffstat (limited to 'drivers/staging/wilc1000/wilc_msgqueue.c')
-rw-r--r-- | drivers/staging/wilc1000/wilc_msgqueue.c | 190 |
1 files changed, 190 insertions, 0 deletions
diff --git a/drivers/staging/wilc1000/wilc_msgqueue.c b/drivers/staging/wilc1000/wilc_msgqueue.c new file mode 100644 index 000000000000..16bcef4b5c00 --- /dev/null +++ b/drivers/staging/wilc1000/wilc_msgqueue.c @@ -0,0 +1,190 @@ + +#include "wilc_msgqueue.h" +#include <linux/spinlock.h> + +/*! + * @author syounan + * @date 1 Sep 2010 + * @note copied from FLO glue implementatuion + * @version 1.0 + */ +WILC_ErrNo WILC_MsgQueueCreate(WILC_MsgQueueHandle *pHandle, + tstrWILC_MsgQueueAttrs *pstrAttrs) +{ + spin_lock_init(&pHandle->strCriticalSection); + sema_init(&pHandle->hSem, 0); + pHandle->pstrMessageList = NULL; + pHandle->u32ReceiversCount = 0; + pHandle->bExiting = false; + return WILC_SUCCESS; +} + +/*! + * @author syounan + * @date 1 Sep 2010 + * @note copied from FLO glue implementatuion + * @version 1.0 + */ +WILC_ErrNo WILC_MsgQueueDestroy(WILC_MsgQueueHandle *pHandle, + tstrWILC_MsgQueueAttrs *pstrAttrs) +{ + + pHandle->bExiting = true; + + /* Release any waiting receiver thread. */ + while (pHandle->u32ReceiversCount > 0) { + up(&(pHandle->hSem)); + pHandle->u32ReceiversCount--; + } + + while (pHandle->pstrMessageList != NULL) { + Message *pstrMessge = pHandle->pstrMessageList->pstrNext; + WILC_FREE(pHandle->pstrMessageList); + pHandle->pstrMessageList = pstrMessge; + } + + return WILC_SUCCESS; +} + +/*! + * @author syounan + * @date 1 Sep 2010 + * @note copied from FLO glue implementatuion + * @version 1.0 + */ +WILC_ErrNo WILC_MsgQueueSend(WILC_MsgQueueHandle *pHandle, + const void *pvSendBuffer, u32 u32SendBufferSize, + tstrWILC_MsgQueueAttrs *pstrAttrs) +{ + WILC_ErrNo s32RetStatus = WILC_SUCCESS; + unsigned long flags; + Message *pstrMessage = NULL; + + if ((pHandle == NULL) || (u32SendBufferSize == 0) || (pvSendBuffer == NULL)) { + WILC_ERRORREPORT(s32RetStatus, WILC_INVALID_ARGUMENT); + } + + if (pHandle->bExiting == true) { + WILC_ERRORREPORT(s32RetStatus, WILC_FAIL); + } + + spin_lock_irqsave(&pHandle->strCriticalSection, flags); + + /* construct a new message */ + pstrMessage = WILC_NEW(Message, 1); + WILC_NULLCHECK(s32RetStatus, pstrMessage); + pstrMessage->u32Length = u32SendBufferSize; + pstrMessage->pstrNext = NULL; + pstrMessage->pvBuffer = WILC_MALLOC(u32SendBufferSize); + WILC_NULLCHECK(s32RetStatus, pstrMessage->pvBuffer); + WILC_memcpy(pstrMessage->pvBuffer, pvSendBuffer, u32SendBufferSize); + + + /* add it to the message queue */ + if (pHandle->pstrMessageList == NULL) { + pHandle->pstrMessageList = pstrMessage; + } else { + Message *pstrTailMsg = pHandle->pstrMessageList; + while (pstrTailMsg->pstrNext != NULL) { + pstrTailMsg = pstrTailMsg->pstrNext; + } + pstrTailMsg->pstrNext = pstrMessage; + } + + spin_unlock_irqrestore(&pHandle->strCriticalSection, flags); + + up(&pHandle->hSem); + + WILC_CATCH(s32RetStatus) + { + /* error occured, free any allocations */ + if (pstrMessage != NULL) { + if (pstrMessage->pvBuffer != NULL) { + WILC_FREE(pstrMessage->pvBuffer); + } + WILC_FREE(pstrMessage); + } + } + + return s32RetStatus; +} + + + +/*! + * @author syounan + * @date 1 Sep 2010 + * @note copied from FLO glue implementatuion + * @version 1.0 + */ +WILC_ErrNo WILC_MsgQueueRecv(WILC_MsgQueueHandle *pHandle, + void *pvRecvBuffer, u32 u32RecvBufferSize, + u32 *pu32ReceivedLength, + tstrWILC_MsgQueueAttrs *pstrAttrs) +{ + + Message *pstrMessage; + WILC_ErrNo s32RetStatus = WILC_SUCCESS; + unsigned long flags; + if ((pHandle == NULL) || (u32RecvBufferSize == 0) + || (pvRecvBuffer == NULL) || (pu32ReceivedLength == NULL)) { + WILC_ERRORREPORT(s32RetStatus, WILC_INVALID_ARGUMENT); + } + + if (pHandle->bExiting == true) { + WILC_ERRORREPORT(s32RetStatus, WILC_FAIL); + } + + spin_lock_irqsave(&pHandle->strCriticalSection, flags); + pHandle->u32ReceiversCount++; + spin_unlock_irqrestore(&pHandle->strCriticalSection, flags); + + down(&(pHandle->hSem)); + + if (s32RetStatus == WILC_TIMEOUT) { + /* timed out, just exit without consumeing the message */ + spin_lock_irqsave(&pHandle->strCriticalSection, flags); + pHandle->u32ReceiversCount--; + spin_unlock_irqrestore(&pHandle->strCriticalSection, flags); + } else { + /* other non-timeout scenarios */ + WILC_ERRORCHECK(s32RetStatus); + + if (pHandle->bExiting) { + WILC_ERRORREPORT(s32RetStatus, WILC_FAIL); + } + + spin_lock_irqsave(&pHandle->strCriticalSection, flags); + + pstrMessage = pHandle->pstrMessageList; + if (pstrMessage == NULL) { + spin_unlock_irqrestore(&pHandle->strCriticalSection, flags); + WILC_ERRORREPORT(s32RetStatus, WILC_FAIL); + } + /* check buffer size */ + if (u32RecvBufferSize < pstrMessage->u32Length) { + spin_unlock_irqrestore(&pHandle->strCriticalSection, flags); + up(&pHandle->hSem); + WILC_ERRORREPORT(s32RetStatus, WILC_BUFFER_OVERFLOW); + } + + /* consume the message */ + pHandle->u32ReceiversCount--; + WILC_memcpy(pvRecvBuffer, pstrMessage->pvBuffer, pstrMessage->u32Length); + *pu32ReceivedLength = pstrMessage->u32Length; + + pHandle->pstrMessageList = pstrMessage->pstrNext; + + WILC_FREE(pstrMessage->pvBuffer); + WILC_FREE(pstrMessage); + + spin_unlock_irqrestore(&pHandle->strCriticalSection, flags); + + } + + WILC_CATCH(s32RetStatus) + { + } + + return s32RetStatus; +} |