aboutsummaryrefslogtreecommitdiff
path: root/drivers/sdio/stack/lib/sdio_lib_c.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/sdio/stack/lib/sdio_lib_c.c')
-rw-r--r--drivers/sdio/stack/lib/sdio_lib_c.c908
1 files changed, 0 insertions, 908 deletions
diff --git a/drivers/sdio/stack/lib/sdio_lib_c.c b/drivers/sdio/stack/lib/sdio_lib_c.c
deleted file mode 100644
index 4bc5a83ecf6..00000000000
--- a/drivers/sdio/stack/lib/sdio_lib_c.c
+++ /dev/null
@@ -1,908 +0,0 @@
-/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-@file: sdio_lib_c.c
-
-@abstract: OS independent SDIO library functions
-@category abstract: Support_Reference Support Functions.
-
-@notes: Support functions for device I/O
-
-@notice: Copyright (c), 2004-2005 Atheros Communications, Inc.
-
-
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * Portions of this code were developed with information supplied from the
- * SD Card Association Simplified Specifications. The following conditions and disclaimers may apply:
- *
- * The following conditions apply to the release of the SD simplified specification (�Simplified
- * Specification�) by the SD Card Association. The Simplified Specification is a subset of the complete
- * SD Specification which is owned by the SD Card Association. This Simplified Specification is provided
- * on a non-confidential basis subject to the disclaimers below. Any implementation of the Simplified
- * Specification may require a license from the SD Card Association or other third parties.
- * Disclaimers:
- * The information contained in the Simplified Specification is presented only as a standard
- * specification for SD Cards and SD Host/Ancillary products and is provided "AS-IS" without any
- * representations or warranties of any kind. No responsibility is assumed by the SD Card Association for
- * any damages, any infringements of patents or other right of the SD Card Association or any third
- * parties, which may result from its use. No license is granted by implication, estoppel or otherwise
- * under any patent or other rights of the SD Card Association or any third party. Nothing herein shall
- * be construed as an obligation by the SD Card Association to disclose or distribute any technical
- * information, know-how or other confidential information to any third party.
- *
- *
- * The initial developers of the original code are Seung Yi and Paul Lever
- *
- * sdio@atheros.com
- *
- *
-
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-#define MODULE_NAME SDLIB_
-
-#include <linux/sdio/ctsystem.h>
-#include <linux/sdio/sdio_busdriver.h>
-#include <linux/sdio/_sdio_defs.h>
-#include <linux/sdio/sdio_lib.h>
-#include "_sdio_lib.h"
-
-#define _Cmd52WriteByteCommon(pDev, Address, pValue) \
- _SDLIB_IssueCMD52((pDev),0,(Address),(pValue),1,TRUE)
-#define _Cmd52ReadByteCommon(pDev, Address, pValue) \
- _SDLIB_IssueCMD52((pDev),0,(Address),pValue,1,FALSE)
-#define _Cmd52ReadMultipleCommon(pDev, Address, pBuf,length) \
- _SDLIB_IssueCMD52((pDev),0,(Address),(pBuf),(length),FALSE)
-
-/* inline version */
-static INLINE void _iSDLIB_SetupCMD52Request(UINT8 FuncNo,
- UINT32 Address,
- BOOL Write,
- UINT8 WriteData,
- PSDREQUEST pRequest) {
- if (Write) {
- SDIO_SET_CMD52_ARG(pRequest->Argument,CMD52_WRITE,
- FuncNo,
- CMD52_NORMAL_WRITE,Address,WriteData);
- } else {
- SDIO_SET_CMD52_ARG(pRequest->Argument,CMD52_READ,FuncNo,0,Address,0x00);
- }
-
- pRequest->Flags = SDREQ_FLAGS_RESP_SDIO_R5;
- pRequest->Command = CMD52;
-}
-
-/**++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- @function: Setup cmd52 requests
-
- @function name: SDLIB_SetupCMD52Request
- @prototype: void SDLIB_SetupCMD52Request(UINT8 FuncNo,
- UINT32 Address,
- BOOL Write,
- UINT8 WriteData,
- PSDREQUEST pRequest)
- @category: PD_Reference
-
- @input: FunctionNo - function number.
- @input: Address - I/O address, 17-bit register address.
- @input: Write - TRUE if a write operation, FALSE for reads.
- @input: WriteData - write data, byte to write if write operation.
-
- @output: pRequest - request is updated with cmd52 parameters
-
- @return: none
-
- @notes: This function does not perform any I/O. For register reads, the completion
- routine can use the SD_R5_GET_READ_DATA() macro to extract the register value.
- The routine should also extract the response flags using the SD_R5_GET_RESP_FLAGS()
- macro and check the flags with the SD_R5_ERRORS mask.
-
- @example: Getting the register value from the completion routine:
- flags = SD_R5_GET_RESP_FLAGS(pRequest->Response);
- if (flags & SD_R5_ERRORS) {
- ... errors
- } else {
- registerValue = SD_R5_GET_READ_DATA(pRequest->Response);
- }
-
- @see also: SDLIB_IssueCMD52
- @see also: SDDEVICE_CALL_REQUEST_FUNC
-
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-void _SDLIB_SetupCMD52Request(UINT8 FuncNo,
- UINT32 Address,
- BOOL Write,
- UINT8 WriteData,
- PSDREQUEST pRequest)
-{
- _iSDLIB_SetupCMD52Request(FuncNo,Address,Write,WriteData,pRequest);
-}
-
-/**++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- @function: Issue a CMD52 to read or write a register
-
- @function name: SDLIB_IssueCMD52
- @prototype: SDIO_STATUS SDLIB_IssueCMD52(PSDDEVICE pDevice,
- UINT8 FuncNo,
- UINT32 Address,
- PUINT8 pData,
- INT ByteCount,
- BOOL Write)
- @category: PD_Reference
- @input: pDevice - the device that is the target of the command.
- @input: FunctionNo - function number of the target.
- @input: Address - 17-bit register address.
- @input: ByteCount - number of bytes to read or write,
- @input: Write - TRUE if a write operation, FALSE for reads.
- @input: pData - data buffer for writes.
-
- @output: pData - data buffer for writes.
-
- @return: SDIO Status
-
- @notes: This function will allocate a request and issue multiple byte reads or writes
- to satisfy the ByteCount requested. This function is fully synchronous and will block
- the caller.
-
- @see also: SDLIB_SetupCMD52Request
-
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-SDIO_STATUS _SDLIB_IssueCMD52(PSDDEVICE pDevice,
- UINT8 FuncNo,
- UINT32 Address,
- PUINT8 pData,
- INT ByteCount,
- BOOL Write)
-{
- SDIO_STATUS status = SDIO_STATUS_SUCCESS;
-
- PSDREQUEST pReq = NULL;
-
- pReq = SDDeviceAllocRequest(pDevice);
-
- if (NULL == pReq) {
- return SDIO_STATUS_NO_RESOURCES;
- }
-
- while (ByteCount) {
- _iSDLIB_SetupCMD52Request(FuncNo,Address,Write,*pData,pReq);
- status = SDDEVICE_CALL_REQUEST_FUNC(pDevice,pReq);
- if (!SDIO_SUCCESS(status)) {
- break;
- }
-
- status = ConvertCMD52ResponseToSDIOStatus(SD_R5_GET_RESP_FLAGS(pReq->Response));
- if (!SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_TRACE, ("SDIO Library: CMD52 resp error: 0x%X \n",
- SD_R5_GET_RESP_FLAGS(pReq->Response)));
- break;
- }
- if (!Write) {
- /* store the byte */
- *pData = SD_R5_GET_READ_DATA(pReq->Response);
- }
- pData++;
- Address++;
- ByteCount--;
- }
-
- SDDeviceFreeRequest(pDevice,pReq);
- return status;
-}
-
-
-
-/**++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- @function: Find a device's tuple.
-
- @function name: SDLIB_FindTuple
- @prototype: SDIO_STATUS SDLIB_FindTuple(PSDDEVICE pDevice,
- UINT8 Tuple,
- UINT32 *pTupleScanAddress,
- PUINT8 pBuffer,
- UINT8 *pLength)
-
- @category: PD_Reference
- @input: pDevice - the device that is the target of the command.
- @input: Tuple - 8-bit ID of tuple to find
- @input: pTupleScanAddress - On entry pTupleScanAddress is the adddress to start scanning
- @input: pLength - length of pBuffer
-
- @output: pBuffer - storage for tuple
- @output: pTupleScanAddress - address of the next tuple
- @output: pLength - length of tuple read
-
- @return: status
-
- @notes: It is possible to have the same tuple ID multiple times with different lengths. This function
- blocks and is fully synchronous.
-
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-SDIO_STATUS _SDLIB_FindTuple(PSDDEVICE pDevice,
- UINT8 Tuple,
- UINT32 *pTupleScanAddress,
- PUINT8 pBuffer,
- UINT8 *pLength)
-{
- SDIO_STATUS status = SDIO_STATUS_SUCCESS;
- UINT32 scanStart = *pTupleScanAddress;
- UINT8 tupleCode;
- UINT8 tupleLink;
-
- /* sanity check */
- if (scanStart < SDIO_CIS_AREA_BEGIN) {
- return SDIO_STATUS_CIS_OUT_OF_RANGE;
- }
-
- while (TRUE) {
- /* check for end */
- if (scanStart > SDIO_CIS_AREA_END) {
- status = SDIO_STATUS_TUPLE_NOT_FOUND;
- break;
- }
- /* get the code */
- status = _Cmd52ReadByteCommon(pDevice, scanStart, &tupleCode);
- if (!SDIO_SUCCESS(status)) {
- break;
- }
- if (CISTPL_END == tupleCode) {
- /* found the end */
- status = SDIO_STATUS_TUPLE_NOT_FOUND;
- break;
- }
- /* bump past tuple code */
- scanStart++;
- /* get the tuple link value */
- status = _Cmd52ReadByteCommon(pDevice, scanStart, &tupleLink);
- if (!SDIO_SUCCESS(status)) {
- break;
- }
- /* bump past tuple link*/
- scanStart++;
- /* check tuple we just found */
- if (tupleCode == Tuple) {
- DBG_PRINT(SDDBG_TRACE, ("SDIO Library: Tuple:0x%2.2X Found at Address:0x%X, TupleLink:0x%X \n",
- Tuple, (scanStart - 2), tupleLink));
- if (tupleLink != CISTPL_LINK_END) {
- /* return the next scan address to the caller */
- *pTupleScanAddress = scanStart + tupleLink;
- } else {
- /* the tuple link is an end marker */
- *pTupleScanAddress = 0xFFFFFFFF;
- }
- /* go get the tuple */
- status = _Cmd52ReadMultipleCommon(pDevice, scanStart,pBuffer,min(*pLength,tupleLink));
- if (SDIO_SUCCESS(status)) {
- /* set the actual return length */
- *pLength = min(*pLength,tupleLink);
- }
- /* break out of loop */
- break;
- }
- /*increment past this entire tuple */
- scanStart += tupleLink;
- }
-
- return status;
-}
-
-/**++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- @function: Issue an SDIO configuration command.
-
- @function name: SDLIB_IssueConfig
- @prototype: SDIO_STATUS _SDLIB_IssueConfig(PSDDEVICE pDevice,
- SDCONFIG_COMMAND Command,
- PVOID pData,
- INT Length)
-
- @category: PD_Reference
- @input: pDevice - the device that is the target of the command.
- @input: Command - command to send, see example.
- @input: pData - command's data
- @input: Length length of pData
-
- @output: pData - updated on commands that return data.
-
- @return: SDIO Status
-
- @example: Command and data pairs:
- Type Data
- SDCONFIG_GET_WP SDCONFIG_WP_VALUE
- SDCONFIG_SEND_INIT_CLOCKS none
- SDCONFIG_SDIO_INT_CTRL SDCONFIG_SDIO_INT_CTRL_DATA
- SDCONFIG_SDIO_REARM_INT none
- SDCONFIG_BUS_MODE_CTRL SDCONFIG_BUS_MODE_DATA
- SDCONFIG_POWER_CTRL SDCONFIG_POWER_CTRL_DATA
-
- @notes:
-
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-SDIO_STATUS _SDLIB_IssueConfig(PSDDEVICE pDevice,
- SDCONFIG_COMMAND Command,
- PVOID pData,
- INT Length)
-{
- SDCONFIG configHdr;
- SET_SDCONFIG_CMD_INFO(&configHdr,Command,pData,Length);
- return SDDEVICE_CALL_CONFIG_FUNC(pDevice,&configHdr);
-}
-
-/**++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- @function: Set function block size
-
- @function name: SDLIB_SetFunctionBlockSize
- @prototype: SDIO_STATUS SDLIB_SetFunctionBlockSize(PSDDEVICE pDevice,
- UINT16 BlockSize)
-
- @category: PD_Reference
- @input: pDevice - the device that is the target of the command.
- @input: BlockSize - block size to set in function
-
- @output: none
-
- @return: SDIO Status
-
- @notes: Issues CMD52 to set the block size. This function is fully synchronous and may
- block.
-
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-SDIO_STATUS _SDLIB_SetFunctionBlockSize(PSDDEVICE pDevice,
- UINT16 BlockSize)
-{
- UINT8 data[2];
-
- /* endian safe */
- data[0] = (UINT8)BlockSize;
- data[1] = (UINT8)(BlockSize >> 8);
- /* write the function blk size control register */
- return _SDLIB_IssueCMD52(pDevice,
- 0, /* function 0 register space */
- FBR_FUNC_BLK_SIZE_LOW_OFFSET(CalculateFBROffset(
- SDDEVICE_GET_SDIO_FUNCNO(pDevice))),
- data,
- 2,
- TRUE);
-}
-
-/**++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- @function: Print a buffer to the debug output
-
- @function name: SDLIB_PrintBuffer
- @prototype: void SDLIB_PrintBuffer(PUCHAR pBuffer, INT Length, PTEXT pDescription)
- @category: Support_Reference
-
- @input: pBuffer - Hex buffer to be printed.
- @input: Length - length of pBuffer.
- @input: pDescription - String title to be printed above the dump.
-
- @output: none
-
- @return: none
-
- @notes: Prints the buffer by converting to ASCII and using REL_PRINT() with 16
- bytes per line.
-
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-void _SDLIB_PrintBuffer(PUCHAR pBuffer, INT Length, PTEXT pDescription)
-{
- TEXT line[49];
- TEXT address[5];
- TEXT ascii[17];
- TEXT temp[5];
- INT i;
- UCHAR num;
- USHORT offset = 0;
-
- REL_PRINT(0,
- ("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"));
- if (pDescription != NULL) {
- REL_PRINT(0, ("Description: %s \n\n",pDescription));
- } else {
- REL_PRINT(0, ("Description: NONE \n\n"));
- }
- REL_PRINT(0,
- ("Offset Data ASCII \n"));
- REL_PRINT(0,
- ("--------------------------------------------------------------------------\n"));
-
- while (Length) {
- line[0] = (TEXT)0;
- ascii[0] = (TEXT)0;
- address[0] = (TEXT)0;
- sprintf(address,"%4.4X",offset);
- for (i = 0; i < 16; i++) {
- if (Length != 0) {
- num = *pBuffer;
- sprintf(temp,"%2.2X ",num);
- strcat(line,temp);
- if ((num >= 0x20) && (num <= 0x7E)) {
- sprintf(temp,"%c",*pBuffer);
- } else {
- sprintf(temp,"%c",0x2e);
- }
- strcat(ascii,temp);
- pBuffer++;
- Length--;
- } else {
- /* pad partial line with spaces */
- strcat(line," ");
- strcat(ascii," ");
- }
- }
- REL_PRINT(0,("%s %s %s\n", address, line, ascii));
- offset += 16;
- }
- REL_PRINT(0,
- ("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"));
-
-}
-
-/**++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- @function: Get default operational current
-
- @function name: SDLIB_GetDefaultOpCurrent
- @prototype: SDIO_STATUS SDLIB_GetDefaultOpCurrent(PSDDEVICE pDevice, SD_SLOT_CURRENT *pOpCurrent)
- @category: PD_Reference
-
- @input: pDevice - the device that is the target of the command.
-
- @output: pOpCurrent - operational current in mA.
-
- @return: SDIO_STATUS
-
- @notes: This routine reads the function's CISTPL_FUNCE tuple for the default operational
- current. For SDIO 1.0 devices this value is read from the 8-bit TPLFE_OP_MAX_PWR
- field. For SDIO 1.1 devices, the HP MAX power field is used only if the device is
- operating in HIPWR mode. Otherwise the 8-bit TPLFE_OP_MAX_PWR field is used.
- Some systems may restrict high power/current mode and force cards to operate in a
- legacy (< 200mA) mode. This function is fully synchronous and will block the caller.
-
- @example: Getting the default operational current for this function:
- // get default operational current
- status = SDLIB_GetDefaultOpCurrent(pDevice, &slotCurrent);
- if (!SDIO_SUCCESS(status)) {
- .. failed
- }
-
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-SDIO_STATUS _SDLIB_GetDefaultOpCurrent(PSDDEVICE pDevice, SD_SLOT_CURRENT *pOpCurrent)
-{
- UINT32 nextTpl;
- UINT8 tplLength;
- struct SDIO_FUNC_EXT_FUNCTION_TPL_1_1 funcTuple;
- SDIO_STATUS status;
-
- /* get the FUNCE tuple */
- nextTpl = SDDEVICE_GET_SDIO_FUNC_CISPTR(pDevice);
- tplLength = sizeof(funcTuple);
- /* go get the function Extension tuple */
- status = _SDLIB_FindTuple(pDevice,
- CISTPL_FUNCE,
- &nextTpl,
- (PUINT8)&funcTuple,
- &tplLength);
-
- if (!SDIO_SUCCESS(status)) {
- DBG_PRINT(SDDBG_ERROR, ("SDLIB_GetDefaultOpCurrent: Failed to get FuncE Tuple: %d \n", status));
- return status;
- }
- /* use the operational power (8-bit) value of current in mA as default*/
- *pOpCurrent = funcTuple.CommonInfo.OpMaxPwr;
- if ((tplLength >= sizeof(funcTuple)) && (SDDEVICE_IS_SDIO_REV_GTEQ_1_10(pDevice))) {
- /* we have a 1.1 tuple */
- /* check for HIPWR mode */
- if (SDDEVICE_GET_CARD_FLAGS(pDevice) & CARD_HIPWR) {
- /* use the maximum operational power (16 bit ) from the tuple */
- *pOpCurrent = CT_LE16_TO_CPU_ENDIAN(funcTuple.HiPwrMaxPwr);
- }
- }
- return SDIO_STATUS_SUCCESS;
-}
-
-
-static INLINE void FreeMessageBlock(PSDMESSAGE_QUEUE pQueue, PSDMESSAGE_BLOCK pMsg) {
- SDListInsertHead(&pQueue->FreeMessageList, &pMsg->SDList);
-}
-static INLINE void QueueMessageBlock(PSDMESSAGE_QUEUE pQueue, PSDMESSAGE_BLOCK pMsg) {
- SDListInsertTail(&pQueue->MessageList, &pMsg->SDList);
-}
-static INLINE void QueueMessageToHead(PSDMESSAGE_QUEUE pQueue, PSDMESSAGE_BLOCK pMsg) {
- SDListInsertHead(&pQueue->MessageList, &pMsg->SDList);
-}
-
-static INLINE PSDMESSAGE_BLOCK GetFreeMessageBlock(PSDMESSAGE_QUEUE pQueue) {
- PSDLIST pItem = SDListRemoveItemFromHead(&pQueue->FreeMessageList);
- if (pItem != NULL) {
- return CONTAINING_STRUCT(pItem, SDMESSAGE_BLOCK , SDList);
- }
- return NULL;
-}
-static INLINE PSDMESSAGE_BLOCK GetQueuedMessage(PSDMESSAGE_QUEUE pQueue) {
- PSDLIST pItem = SDListRemoveItemFromHead(&pQueue->MessageList);
- if (pItem != NULL) {
- return CONTAINING_STRUCT(pItem, SDMESSAGE_BLOCK , SDList);
- }
- return NULL;
-}
-
-/**++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- @function: Create a message queue
-
- @function name: SDLIB_CreateMessageQueue
- @prototype: PSDMESSAGE_QUEUE SDLIB_CreateMessageQueue(INT MaxMessages, INT MaxMessageLength)
- @category: Support_Reference
-
- @input: MaxMessages - Maximum number of messages this queue supports
- @input: MaxMessageLength - Maximum size of each message
-
- @return: Message queue object, NULL on failure
-
- @notes: This function creates a simple first-in-first-out message queue. The caller must determine
- the maximum number of messages the queue supports and the size of each message. This
- function will pre-allocate memory for each message. A producer of data posts a message
- using SDLIB_PostMessage with a user defined data structure. A consumer of this data
- can retrieve the message (in FIFO order) using SDLIB_GetMessage. A message queue does not
- provide a signaling mechanism for notifying a consumer of data. Notifying a consumer is
- user defined.
-
- @see also: SDLIB_DeleteMessageQueue, SDLIB_GetMessage, SDLIB_PostMessage.
-
- @example: Creating a message queue:
- typedef struct _MyMessage {
- UINT8 Code;
- PVOID pDataBuffer;
- } MyMessage;
- // create message queue, 16 messages max.
- pMsgQueue = SDLIB_CreateMessageQueue(16,sizeof(MyMessage));
- if (NULL == pMsgQueue) {
- .. failed
- }
-
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-PSDMESSAGE_QUEUE _CreateMessageQueue(INT MaxMessages, INT MaxMessageLength)
-{
- PSDMESSAGE_QUEUE pQueue = NULL;
- SDIO_STATUS status = SDIO_STATUS_SUCCESS;
- INT ii;
- PSDMESSAGE_BLOCK pMsg;
-
- do {
- pQueue = (PSDMESSAGE_QUEUE)KernelAlloc(sizeof(SDMESSAGE_QUEUE));
-
- if (NULL == pQueue) {
- status = SDIO_STATUS_NO_RESOURCES;
- break;
- }
- SDLIST_INIT(&pQueue->MessageList);
- SDLIST_INIT(&pQueue->FreeMessageList);
- pQueue->MaxMessageLength = MaxMessageLength;
- status = CriticalSectionInit(&pQueue->MessageCritSection);
- if (!SDIO_SUCCESS(status)) {
- break;
- }
- /* allocate message blocks */
- for (ii = 0; ii < MaxMessages; ii++) {
- pMsg = (PSDMESSAGE_BLOCK)KernelAlloc(sizeof(SDMESSAGE_BLOCK) + MaxMessageLength -1);
- if (NULL == pMsg) {
- break;
- }
- FreeMessageBlock(pQueue, pMsg);
- }
-
- if (0 == ii) {
- status = SDIO_STATUS_NO_RESOURCES;
- break;
- }
-
- } while (FALSE);
-
- if (!SDIO_SUCCESS(status)) {
- if (pQueue != NULL) {
- _DeleteMessageQueue(pQueue);
- pQueue = NULL;
- }
- }
- return pQueue;
-}
-
-/**++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- @function: Delete a message queue
-
- @function name: SDLIB_DeleteMessageQueue
- @prototype: void SDLIB_DeleteMessageQueue(PSDMESSAGE_QUEUE pQueue)
- @category: Support_Reference
-
- @input: pQueue - message queue to delete
-
- @notes: This function flushes the message queue and frees all memory allocated for
- messages.
-
- @see also: SDLIB_CreateMessageQueue
-
- @example: Deleting a message queue:
- if (pMsgQueue != NULL) {
- SDLIB_DeleteMessageQueue(pMsgQueue);
- }
-
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-void _DeleteMessageQueue(PSDMESSAGE_QUEUE pQueue)
-{
- PSDMESSAGE_BLOCK pMsg;
- SDIO_STATUS status;
- CT_DECLARE_IRQ_SYNC_CONTEXT();
-
- status = CriticalSectionAcquireSyncIrq(&pQueue->MessageCritSection);
-
- /* cleanup free list */
- while (1) {
- pMsg = GetFreeMessageBlock(pQueue);
- if (pMsg != NULL) {
- KernelFree(pMsg);
- } else {
- break;
- }
- }
- /* cleanup any in the queue */
- while (1) {
- pMsg = GetQueuedMessage(pQueue);
- if (pMsg != NULL) {
- KernelFree(pMsg);
- } else {
- break;
- }
- }
-
- status = CriticalSectionReleaseSyncIrq(&pQueue->MessageCritSection);
- CriticalSectionDelete(&pQueue->MessageCritSection);
- KernelFree(pQueue);
-
-}
-
-/**++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- @function: Post a message queue
-
- @function name: SDLIB_PostMessage
- @prototype: SDIO_STATUS SDLIB_PostMessage(PSDMESSAGE_QUEUE pQueue, PVOID pMessage, INT MessageLength)
- @category: Support_Reference
-
- @input: pQueue - message queue to post to
- @input: pMessage - message to post
- @input: MessageLength - length of message (for validation)
-
- @return: SDIO_STATUS
-
- @notes: The message queue uses an internal list of user defined message structures. When
- posting a message the message is copied into an allocated structure and queued. The memory
- pointed to by pMessage does not need to be allocated and can reside on the stack.
- The length of the message to post can be smaller that the maximum message size. This allows
- for variable length messages up to the maximum message size. This
- function returns SDIO_STATUS_NO_RESOURCES, if the message queue is full. This
- function returns SDIO_STATUS_BUFFER_TOO_SMALL, if the message size exceeds the maximum
- size of a message. Posting and getting messsages from a message queue is safe in any
- driver context.
-
- @see also: SDLIB_CreateMessageQueue , SDLIB_GetMessage
-
- @example: Posting a message
- MyMessage message;
- // set up message
- message.code = MESSAGE_DATA_READY;
- message.pData = pInstance->pDataBuffers[currentIndex];
- // post message
- status = SDLIB_PostMessage(pInstance->pReadQueue,&message,sizeof(message));
- if (!SDIO_SUCCESS(status)) {
- // failed
- }
-
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-SDIO_STATUS _PostMessage(PSDMESSAGE_QUEUE pQueue, PVOID pMessage, INT MessageLength)
-{
- SDIO_STATUS status2;
- SDIO_STATUS status = SDIO_STATUS_SUCCESS;
- PSDMESSAGE_BLOCK pMsg;
- CT_DECLARE_IRQ_SYNC_CONTEXT();
-
- if (MessageLength > pQueue->MaxMessageLength) {
- return SDIO_STATUS_BUFFER_TOO_SMALL;
- }
-
- status = CriticalSectionAcquireSyncIrq(&pQueue->MessageCritSection);
- if (!SDIO_SUCCESS(status)) {
- return status;
- }
-
- do {
- /* get a message block */
- pMsg = GetFreeMessageBlock(pQueue);
- if (NULL == pMsg) {
- status = SDIO_STATUS_NO_RESOURCES;
- break;
- }
- /* copy the message */
- memcpy(pMsg->MessageStart,pMessage,MessageLength);
- /* set the length of the message */
- pMsg->MessageLength = MessageLength;
- /* queue the message to the list */
- QueueMessageBlock(pQueue,pMsg);
- } while (FALSE);
-
- status2 = CriticalSectionReleaseSyncIrq(&pQueue->MessageCritSection);
- return status;
-}
-
-/**++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- @function: Get a message from a message queue
-
- @function name: SDLIB_GetMessage
- @prototype: SDIO_STATUS SDLIB_GetMessage(PSDMESSAGE_QUEUE pQueue, PVOID pData, INT *pBufferLength)
- @category: Support_Reference
-
- @input: pQueue - message queue to retreive a message from
- @input: pBufferLength - on entry, the length of the data buffer
- @output: pData - buffer to hold the message
- @output: pBufferLength - on return, contains the number of bytes copied
-
- @return: SDIO_STATUS
-
- @notes: The message queue uses an internal list of user defined message structures. The message is
- dequeued (FIFO order) and copied to the callers buffer. The internal allocation for the message
- is returned back to the message queue. This function returns SDIO_STATUS_NO_MORE_MESSAGES
- if the message queue is empty. If the length of the buffer is smaller than the length of
- the message at the head of the queue,this function returns SDIO_STATUS_BUFFER_TOO_SMALL and
- returns the required length in pBufferLength.
-
- @see also: SDLIB_CreateMessageQueue , SDLIB_PostMessage
-
- @example: Getting a message
- MyMessage message;
- INT length;
- // set length
- length = sizeof(message);
- // post message
- status = SDLIB_GetMessage(pInstance->pReadQueue,&message,&length);
- if (!SDIO_SUCCESS(status)) {
- // failed
- }
-
- @example: Checking queue for a message and getting the size of the message
- INT length;
- // use zero length to get the size of the message
- length = 0;
- status = SDLIB_GetMessage(pInstance->pReadQueue,NULL,&length);
- if (status == SDIO_STATUS_NO_MORE_MESSAGES) {
- // no messages in queue
- } else if (status == SDIO_STATUS_BUFFER_TOO_SMALL) {
- // message exists in queue and length of message is returned
- messageSizeInQueue = length;
- } else {
- // some other failure
- }
-
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-SDIO_STATUS _GetMessage(PSDMESSAGE_QUEUE pQueue, PVOID pData, INT *pBufferLength)
-{
- SDIO_STATUS status2;
- SDIO_STATUS status = SDIO_STATUS_SUCCESS;
- PSDMESSAGE_BLOCK pMsg;
- CT_DECLARE_IRQ_SYNC_CONTEXT();
-
- status = CriticalSectionAcquireSyncIrq(&pQueue->MessageCritSection);
- if (!SDIO_SUCCESS(status)) {
- return status;
- }
-
- do {
- pMsg = GetQueuedMessage(pQueue);
- if (NULL == pMsg) {
- status = SDIO_STATUS_NO_MORE_MESSAGES;
- break;
- }
- if (*pBufferLength < pMsg->MessageLength) {
- /* caller buffer is too small */
- *pBufferLength = pMsg->MessageLength;
- /* stick it back to the front */
- QueueMessageToHead(pQueue, pMsg);
- status = SDIO_STATUS_BUFFER_TOO_SMALL;
- break;
- }
- /* copy the message to the callers buffer */
- memcpy(pData,pMsg->MessageStart,pMsg->MessageLength);
- /* return actual length */
- *pBufferLength = pMsg->MessageLength;
- /* return this message block back to the free list */
- FreeMessageBlock(pQueue, pMsg);
-
- } while (FALSE);
-
- status2 = CriticalSectionReleaseSyncIrq(&pQueue->MessageCritSection);
-
- return status;
-}
-
-/* the following documents the OS helper APIs */
-
-/**++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- @function: Create an OS-specific helper task/thread
-
- @function name: SDLIB_OSCreateHelper
- @prototype: SDIO_STATUS SDLIB_OSCreateHelper(POSKERNEL_HELPER pHelper,
- PHELPER_FUNCTION pFunction,
- PVOID pContext)
- @category: Support_Reference
-
- @input: pHelper - caller allocated helper object
- @input: pFunction - helper function
- @input: pContext - helper context
-
- @return: SDIO_STATUS
-
- @notes: This function creates a helper task/thread that runs in a new execution context. The newly
- created task/thread invokes the helper function. The thread/task exits when the helper
- function returns. The helper function has the prototype of:
- THREAD_RETURN HelperFunction(POSKERNEL_HELPER pHelper)
- The helper function usually implements a while loop and suspends execution using
- SD_WAIT_FOR_WAKEUP(). On exit the helper function can return an OS-specific THREAD_RETURN
- code (usually zero). The helper function executes in a fully schedule-able context and
- can block on semaphores and sleep.
-
- @see also: SDLIB_OSDeleteHelper , SD_WAIT_FOR_WAKEUP
-
- @example: A thread helper function:
- THREAD_RETURN HelperFunction(POSKERNEL_HELPER pHelper)
- {
- SDIO_STATUS status;
- PMYCONTEXT pContext = (PMYCONTEXT)SD_GET_OS_HELPER_CONTEXT(pHelper);
- // wait for wake up
- while(1) {
- status = SD_WAIT_FOR_WAKEUP(pHelper);
- if (!SDIO_SUCCESS(status)) {
- break;
- }
- if (SD_IS_HELPER_SHUTTING_DOWN(pHelper)) {
- //... shutting down
- break;
- }
- // handle wakeup...
- }
- return 0;
- }
-
- @example: Creating a helper:
- status = SDLIB_OSCreateHelper(&pInstance->OSHelper,HelperFunction,pInstance);
- if (!SDIO_SUCCESS(status)) {
- // failed
- }
-
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-
-/**++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- @function: Delete an OS helper task/thread
-
- @function name: SDLIB_OSDeleteHelper
- @prototype: void SDLIB_OSDeleteHelper(POSKERNEL_HELPER pHelper)
- @category: Support_Reference
-
- @input: pHelper - caller allocated helper object
-
- @notes: This function wakes the helper and waits(blocks) until the helper exits. The caller can
- only pass an OS helper structure that was initialized sucessfully by
- SDLIB_OSCreateHelper. The caller must be in a schedulable context.
-
- @see also: SDLIB_OSCreateHelper
-
- @example: Deleting a helper:
- if (pInstance->HelperCreated) {
- // clean up the helper if we successfully created it
- SDLIB_OSDeleteHelper(&pInstance->OSHelper);
- }
-
-
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-
-