aboutsummaryrefslogtreecommitdiff
path: root/include/linux/sdio/ctsystem_linux.h
diff options
context:
space:
mode:
authormokopatches <mokopatches@openmoko.org>2008-11-19 17:03:22 +0000
committerwarmcat <andy@warmcat.com>2008-11-19 17:03:22 +0000
commite7ab2e913536616b9f17e3323a7f2b83e808a198 (patch)
tree7e56b72e9d8e1ac85e1624fd33c6218da983714c /include/linux/sdio/ctsystem_linux.h
parent0a5a3e0ff3050d7baeeb40f50cf3ea7c174ef21e (diff)
atheros_2_0_sdio_stack.patch
Diffstat (limited to 'include/linux/sdio/ctsystem_linux.h')
-rw-r--r--include/linux/sdio/ctsystem_linux.h983
1 files changed, 983 insertions, 0 deletions
diff --git a/include/linux/sdio/ctsystem_linux.h b/include/linux/sdio/ctsystem_linux.h
new file mode 100644
index 00000000000..0de89a66d7b
--- /dev/null
+++ b/include/linux/sdio/ctsystem_linux.h
@@ -0,0 +1,983 @@
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+@file: ctsystem_linux.h
+
+@abstract: common system include file for Linux.
+
+@notice: Copyright (c), 2004-2006 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
+ *
+ *
+
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+#ifndef __CPSYSTEM_LINUX_H___
+#define __CPSYSTEM_LINUX_H___
+
+/* #define DBG_TIMESTAMP 1 */
+#define SD_TRACK_REQ 1
+
+/* LINUX support */
+#include <linux/version.h>
+
+#ifndef KERNEL_VERSION
+ #error KERNEL_VERSION macro not defined!
+#endif
+
+#ifndef LINUX_VERSION_CODE
+ #error LINUX_VERSION_CODE macro not defined!
+#endif
+
+#include <linux/autoconf.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/spinlock.h>
+#include <linux/module.h>
+
+#include <linux/interrupt.h>
+#include <linux/pnp.h>
+#include <asm/hardirq.h>
+#include <asm/semaphore.h>
+#include <asm/io.h>
+#include <asm/scatterlist.h>
+#ifdef DBG_TIMESTAMP
+#include <asm/timex.h>
+#endif /* DBG_TIMESTAMP */
+#ifndef in_atomic
+ /* released version of 2.6.9 */
+#include <linux/hardirq.h>
+#endif
+#include <linux/delay.h>
+#include <linux/device.h>
+
+/* generic types */
+typedef unsigned char UCHAR;
+typedef unsigned char * PUCHAR;
+typedef char TEXT;
+typedef char * PTEXT;
+typedef unsigned short USHORT;
+typedef unsigned short* PUSHORT;
+typedef unsigned int UINT;
+typedef unsigned int* PUINT;
+typedef int INT;
+typedef int* PINT;
+typedef unsigned long ULONG;
+typedef unsigned long* PULONG;
+typedef u8 UINT8;
+typedef u16 UINT16;
+typedef u32 UINT32;
+typedef u8* PUINT8;
+typedef u16* PUINT16;
+typedef u32* PUINT32;
+typedef unsigned char * ULONG_PTR;
+typedef void* PVOID;
+typedef unsigned char BOOL;
+typedef BOOL* PBOOL;
+typedef int SDIO_STATUS;
+typedef int SYSTEM_STATUS;
+typedef unsigned int EVENT_TYPE;
+typedef unsigned int EVENT_ARG;
+typedef unsigned int* PEVENT_TYPE;
+typedef struct semaphore OS_SEMAPHORE;
+typedef struct semaphore* POS_SEMAPHORE;
+typedef struct semaphore OS_SIGNAL; /* OS signals are just semaphores */
+typedef struct semaphore* POS_SIGNAL;
+typedef spinlock_t OS_CRITICALSECTION;
+typedef spinlock_t *POS_CRITICALSECTION;
+typedef int SDPOWER_STATE;
+typedef unsigned long ATOMIC_FLAGS;
+typedef INT THREAD_RETURN;
+typedef dma_addr_t DMA_ADDRESS;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,9)
+typedef struct task_struct* PKERNEL_TASK;
+typedef struct device_driver OS_DRIVER;
+typedef struct device_driver* POS_DRIVER;
+typedef struct device OS_DEVICE;
+typedef struct device* POS_DEVICE;
+typedef struct pnp_driver OS_PNPDRIVER;
+typedef struct pnp_driver* POS_PNPDRIVER;
+typedef struct pnp_dev OS_PNPDEVICE;
+typedef struct pnp_dev* POS_PNPDEVICE;
+typedef struct module* POS_MODULE;
+#else
+/* 2.4 */
+typedef int PKERNEL_TASK;
+typedef PVOID OS_DRIVER;
+typedef PVOID* POS_DRIVER;
+typedef PVOID OS_DEVICE;
+typedef PVOID* POS_DEVICE;
+typedef PVOID OS_PNPDRIVER;
+typedef PVOID* POS_PNPDRIVER;
+typedef PVOID OS_PNPDEVICE;
+typedef PVOID* POS_PNPDEVICE;
+typedef struct module* POS_MODULE;
+#define module_param(a,b,c) MODULE_PARM(a, "i")
+#endif
+
+typedef int CT_DEBUG_LEVEL;
+
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+#ifndef NULL
+#define NULL ((PVOID)0)
+#endif
+#define SDDMA_DESCRIPTION_FLAG_DMA 0x1 /* DMA enabled */
+#define SDDMA_DESCRIPTION_FLAG_SGDMA 0x2 /* Scatter-Gather DMA enabled */
+typedef struct _SDDMA_DESCRIPTION {
+ UINT16 Flags; /* SDDMA_DESCRIPTION_FLAG_xxx */
+ UINT16 MaxDescriptors; /* number of supported scatter gather entries */
+ UINT32 MaxBytesPerDescriptor; /* maximum bytes in a DMA descriptor entry */
+ u64 Mask; /* dma address mask */
+ UINT32 AddressAlignment; /* dma address alignment mask, least significant bits indicate illegal address bits */
+ UINT32 LengthAlignment; /* dma buffer length alignment mask, least significant bits indicate illegal length bits */
+}SDDMA_DESCRIPTION, *PSDDMA_DESCRIPTION;
+typedef struct scatterlist SDDMA_DESCRIPTOR, *PSDDMA_DESCRIPTOR;
+
+#define INLINE inline
+#define CT_PACK_STRUCT __attribute__ ((packed))
+
+#define CT_DECLARE_MODULE_PARAM_INTEGER(p) module_param(p, int, 0644);
+
+/* debug print macros */
+//#define SDDBG_KERNEL_PRINT_LEVEL KERN_DEBUG
+#define SDDBG_KERNEL_PRINT_LEVEL KERN_ALERT
+#define DBG_MASK_NONE 0x0
+#define DBG_MASK_HCD 0x100
+#define DBG_MASK_LIB 0x200
+#define DBG_MASK_BUS 0x400
+
+/* debug output levels, this must be order low number to higher */
+#define SDDBG_ERROR 3
+#define SDDBG_WARN 4
+#define SDDBG_DEBUG 6
+#define SDDBG_TRACE 7
+#define SDDBG_ALL 0xff
+
+#define DBG_LEVEL_NONE 0
+#define DBG_LEVEL_ERROR SDDBG_ERROR
+#define DBG_LEVEL_WARN SDDBG_WARN
+#define DBG_LEVEL_DEBUG SDDBG_DEBUG
+#define DBG_LEVEL_TRACE SDDBG_TRACE
+#define DBG_LEVEL_ALL SDDBG_ALL
+
+#define DBG_GET_LEVEL(lvl) ((lvl) & 0xff)
+#define DBG_GET_MASK(lvl) (((lvl) & 0xff00))
+
+#define DBG_SDIO_MASK (DBG_MASK_NONE | DBG_LEVEL_DEBUG)
+
+#define DEBUG 1
+
+#ifdef DEBUG
+
+#define DBG_ASSERT(test) \
+{ \
+ if (!(test)) { \
+ DBG_PRINT(SDDBG_ERROR, ("Debug Assert Caught, File %s, Line: %d, Test:%s \n",__FILE__, __LINE__,#test)); \
+ } \
+}
+#define DBG_ASSERT_WITH_MSG(test,s) \
+{ \
+ if (!(test)) { \
+ DBG_PRINT(SDDBG_ERROR, ("Assert:%s File %s, Line: %d \n",(s),__FILE__, __LINE__)); \
+ } \
+}
+
+#define DBG_PRINT(lvl, args)\
+ do {\
+ if (DBG_GET_LEVEL(lvl) <= (DBG_SDIO_MASK & 0xff)) \
+ printk(_DBG_PRINTX_ARG args); \
+ } while(0);
+
+#else /* DEBUG */
+
+#define DBG_PRINT(lvl, str)
+#define DBG_ASSERT(test)
+#define DBG_ASSERT_WITH_MSG(test,s)
+#endif /* DEBUG */
+
+#define _DBG_PRINTX_ARG(arg...) arg /* unroll the parens around the var args*/
+#define DBG_GET_DEBUG_LEVEL() DBG_GET_LEVEL(DBG_SDIO_MASK)
+#define DBG_SET_DEBUG_LEVEL(v)
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ @function: Print a string to the debugger or console
+
+ @function name: REL_PRINT
+ @prototype: void REL_PRINT(INT Level, string)
+ @category: Support_Reference
+ @input: Level - debug level for the print
+
+ @output: none
+
+ @return:
+
+ @notes: If Level is less than the current debug level, the print will be
+ issued. This print cannot be conditionally compiled.
+ @see also: DBG_PRINT
+
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+#define REL_PRINT(lvl, args)\
+ {if (lvl <= DBG_GET_DEBUG_LEVEL())\
+ printk(SDDBG_KERNEL_PRINT_LEVEL _DBG_PRINTX_ARG args);\
+ }
+/* debug output levels, this must be order low number to higher */
+#define SDDBG_ERROR 3
+#define SDDBG_WARN 4
+#define SDDBG_DEBUG 6
+#define SDDBG_TRACE 7
+
+#ifdef DBG_CRIT_SECTION_RECURSE
+ /* this macro thows an exception if the lock is recursively taken
+ * the kernel must be configured with: CONFIG_DEBUG_SPINLOCK=y */
+#define call_spin_lock(pCrit) \
+{ \
+ UINT32 unlocked = 1; \
+ if ((pCrit)->lock) {unlocked = 0;} \
+ spin_lock_bh(pCrit); \
+ if (!unlocked) { \
+ unlocked = 0x01; \
+ unlocked = *((volatile UINT32 *)unlocked); \
+ } \
+}
+
+#define call_spin_lock_irqsave(pCrit,isc) \
+{ \
+ UINT32 unlocked = 1; \
+ if ((pCrit)->lock) {unlocked = 0;} \
+ spin_lock_irqsave(pCrit,isc); \
+ if (!unlocked) { \
+ unlocked = 0x01; \
+ unlocked = *((volatile UINT32 *)unlocked); \
+ } \
+}
+
+#else
+#define call_spin_lock(s) spin_lock_bh(s)
+#define call_spin_lock_irqsave(s,isc) spin_lock_irqsave(s,isc)
+#endif
+
+#define call_spin_unlock(s) spin_unlock_bh((s))
+#define call_spin_unlock_irqrestore(s,isc) spin_unlock_irqrestore(s,isc)
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,9)
+#define NonSchedulable() (in_atomic() || irqs_disabled())
+#else
+#define NonSchedulable() (irqs_disabled())
+#endif
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ @function: Initialize a critical section object.
+
+ @function name: CriticalSectionInit
+ @prototype: SDIO_STATUS CriticalSectionInit(POS_CRITICALSECTION pCrit)
+ @category: Support_Reference
+ @output: pCrit - pointer to critical section to initialize
+
+ @return: SDIO_STATUS_SUCCESS on success.
+
+ @notes: CriticalSectionDelete() must be called to cleanup any resources
+ associated with the critical section.
+
+ @see also: CriticalSectionDelete, CriticalSectionAcquire, CriticalSectionRelease
+ @example: To initialize a critical section:
+ status = CriticalSectionInit(&pDevice->ListLock);
+ if (!SDIO_SUCCESS(status)) {
+ .. failed
+ return status;
+ }
+
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+static inline SDIO_STATUS CriticalSectionInit(POS_CRITICALSECTION pCrit) {
+ spin_lock_init(pCrit);
+ return SDIO_STATUS_SUCCESS;
+}
+
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ @function: Acquire a critical section lock.
+
+ @function name: CriticalSectionAcquire
+ @prototype: SDIO_STATUS CriticalSectionAcquire(POS_CRITICALSECTION pCrit)
+ @category: Support_Reference
+
+ @input: pCrit - pointer to critical section that was initialized
+
+ @return: SDIO_STATUS_SUCCESS on success.
+
+ @notes: The critical section lock is acquired when this function returns
+ SDIO_STATUS_SUCCESS. Use CriticalSectionRelease() to release
+ the critical section lock.
+
+ @see also: CriticalSectionRelease
+
+ @example: To acquire a critical section lock:
+ status = CriticalSectionAcquire(&pDevice->ListLock);
+ if (!SDIO_SUCCESS(status)) {
+ .. failed
+ return status;
+ }
+ ... access protected data
+ // unlock
+ status = CriticalSectionRelease(&pDevice->ListLock);
+ if (!SDIO_SUCCESS(status)) {
+ .. failed
+ return status;
+ }
+
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+static inline SDIO_STATUS CriticalSectionAcquire(POS_CRITICALSECTION pCrit) {
+ call_spin_lock(pCrit);
+ return SDIO_STATUS_SUCCESS;
+}
+
+// macro-tized versions
+#define CriticalSectionAcquire_M(pCrit) \
+ SDIO_STATUS_SUCCESS; call_spin_lock(pCrit)
+#define CriticalSectionRelease_M(pCrit) \
+ SDIO_STATUS_SUCCESS; call_spin_unlock(pCrit)
+
+#define CT_DECLARE_IRQ_SYNC_CONTEXT() unsigned long _ctSyncFlags
+
+#define CriticalSectionAcquireSyncIrq(pCrit) \
+ SDIO_STATUS_SUCCESS; call_spin_lock_irqsave(pCrit,_ctSyncFlags)
+
+#define CriticalSectionReleaseSyncIrq(pCrit) \
+ SDIO_STATUS_SUCCESS; call_spin_unlock_irqrestore(pCrit,_ctSyncFlags)
+
+
+
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ @function: Release a critical section lock.
+
+ @function name: CriticalSectionRelease
+ @prototype: SDIO_STATUS CriticalSectionRelease(POS_CRITICALSECTION pCrit)
+ @category: Support_Reference
+
+ @input: pCrit - pointer to critical section that was initialized
+
+ @return: SDIO_STATUS_SUCCESS on success.
+
+ @notes: The critical section lock is released when this function returns
+ SDIO_STATUS_SUCCESS.
+
+ @see also: CriticalSectionAcquire
+
+ @example: see CriticalSectionAcquire
+
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+static inline SDIO_STATUS CriticalSectionRelease(POS_CRITICALSECTION pCrit) {
+ call_spin_unlock(pCrit);
+ return SDIO_STATUS_SUCCESS;
+}
+
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ @function: Cleanup a critical section object
+
+ @function name: CriticalSectionDelete
+ @prototype: void CriticalSectionDelete(POS_CRITICALSECTION pCrit)
+ @category: Support_Reference
+
+ @input: pCrit - an initialized critical section object
+
+ @return: SDIO_STATUS_SUCCESS on success.
+
+ @notes:
+
+ @see also: CriticalSectionInit, CriticalSectionAcquire, CriticalSectionRelease
+
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+static inline void CriticalSectionDelete(POS_CRITICALSECTION pCrit) {
+ return;
+}
+
+/* internal use */
+static inline SDIO_STATUS SignalInitialize(POS_SIGNAL pSignal) {
+ sema_init(pSignal, 0);
+ return SDIO_STATUS_SUCCESS;
+}
+/* internal use */
+static inline void SignalDelete(POS_SIGNAL pSignal) {
+ return;
+}
+/* internal use */
+static inline SDIO_STATUS SignalWaitInterruptible(POS_SIGNAL pSignal) {
+ DBG_ASSERT_WITH_MSG(!NonSchedulable(),"SignalWaitInterruptible not allowed\n");
+ if (down_interruptible(pSignal) == 0) {
+ return SDIO_STATUS_SUCCESS;
+ } else {
+ return SDIO_STATUS_INTERRUPTED;
+ }
+}
+/* internal use */
+static inline SDIO_STATUS SignalWait(POS_SIGNAL pSignal) {
+ DBG_ASSERT_WITH_MSG(!NonSchedulable(),"SignalWait not allowed\n");
+ down(pSignal);
+ return SDIO_STATUS_SUCCESS;
+}
+
+/* internal use */
+static inline SDIO_STATUS SignalSet(POS_SIGNAL pSignal) {
+ up(pSignal);
+ return SDIO_STATUS_SUCCESS;
+}
+
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ @function: Initialize a semaphore object.
+
+ @function name: SemaphoreInitialize
+ @prototype: SDIO_STATUS SemaphoreInitialize(POS_SEMAPHORE pSem, UINT value)
+ @category: Support_Reference
+
+ @input: value - initial value of the semaphore
+
+ @output: pSem - pointer to a semaphore object to initialize
+
+ @return: SDIO_STATUS_SUCCESS on success.
+
+ @notes: SemaphoreDelete() must be called to cleanup any resources
+ associated with the semaphore
+
+ @see also: SemaphoreDelete, SemaphorePend, SemaphorePendInterruptable
+
+ @example: To initialize a semaphore:
+ status = SemaphoreInitialize(&pDevice->ResourceSem,1);
+ if (!SDIO_SUCCESS(status)) {
+ .. failed
+ return status;
+ }
+
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+static inline SDIO_STATUS SemaphoreInitialize(POS_SEMAPHORE pSem, UINT value) {
+ sema_init(pSem, value);
+ return SDIO_STATUS_SUCCESS;
+}
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ @function: Cleanup a semaphore object.
+
+ @function name: SemaphoreDelete
+ @prototype: void SemaphoreDelete(POS_SEMAPHORE pSem)
+ @category: Support_Reference
+
+ @input: pSem - pointer to a semaphore object to cleanup
+
+ @return:
+
+ @notes:
+
+ @see also: SemaphoreInitialize
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+static inline void SemaphoreDelete(POS_SEMAPHORE pSem) {
+ return;
+}
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ @function: Acquire the semaphore or pend if the resource is not available
+
+ @function name: SemaphorePend
+ @prototype: SDIO_STATUS SemaphorePend(POS_SEMAPHORE pSem)
+ @category: Support_Reference
+
+ @input: pSem - pointer to an initialized semaphore object
+
+ @return: SDIO_STATUS_SUCCESS on success.
+
+ @notes: If the semaphore count is zero this function blocks until the count
+ becomes non-zero, otherwise the count is decremented and execution
+ continues. While waiting, the task/thread cannot be interrupted.
+ If the task or thread should be interruptible, use SemaphorePendInterruptible.
+ On some OSes SemaphorePend and SemaphorePendInterruptible behave the same.
+
+ @see also: SemaphorePendInterruptable, SemaphorePost
+ @example: To wait for a resource using a semaphore:
+ status = SemaphorePend(&pDevice->ResourceSem);
+ if (!SDIO_SUCCESS(status)) {
+ .. failed
+ return status;
+ }
+ ... resource acquired
+ SemaphorePost(&pDevice->ResourceSem);
+
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+static inline SDIO_STATUS SemaphorePend(POS_SEMAPHORE pSem) {
+ DBG_ASSERT_WITH_MSG(!NonSchedulable(),"SemaphorePend not allowed\n");
+ down(pSem);
+ return SDIO_STATUS_SUCCESS;
+}
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ @function: Acquire the semaphore or pend if the resource is not available
+
+ @function name: SemaphorePendInterruptable
+ @prototype: SDIO_STATUS SemaphorePendInterruptable(POS_SEMAPHORE pSem)
+ @category: Support_Reference
+
+ @input: pSem - pointer to an initialized semaphore object
+
+ @return: SDIO_STATUS_SUCCESS on success.
+
+ @notes: If the semaphore count is zero this function blocks until the count
+ becomes non-zero, otherwise the count is decremented and execution
+ continues. While waiting, the task/thread can be interrupted.
+ If the task or thread should not be interruptible, use SemaphorePend.
+
+ @see also: SemaphorePend, SemaphorePost
+ @example: To wait for a resource using a semaphore:
+ status = SemaphorePendInterruptable(&pDevice->ResourceSem);
+ if (!SDIO_SUCCESS(status)) {
+ .. failed, could have been interrupted
+ return status;
+ }
+ ... resource acquired
+ SemaphorePost(&pDevice->ResourceSem);
+
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+static inline SDIO_STATUS SemaphorePendInterruptable(POS_SEMAPHORE pSem) {
+ DBG_ASSERT_WITH_MSG(!NonSchedulable(),"SemaphorePendInterruptable not allowed\n");
+ if (down_interruptible(pSem) == 0) {
+ return SDIO_STATUS_SUCCESS;
+ } else {
+ return SDIO_STATUS_INTERRUPTED;
+ }
+}
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ @function: Post a semaphore.
+
+ @function name: SemaphorePost
+ @prototype: SDIO_STATUS SemaphorePost(POS_SEMAPHORE pSem)
+ @category: Support_Reference
+
+ @input: pSem - pointer to an initialized semaphore object
+
+ @return: SDIO_STATUS_SUCCESS on success.
+
+ @notes: This function increments the semaphore count.
+
+ @see also: SemaphorePend, SemaphorePendInterruptable.
+ @example: Posting a semaphore:
+ status = SemaphorePendInterruptable(&pDevice->ResourceSem);
+ if (!SDIO_SUCCESS(status)) {
+ .. failed, could have been interrupted
+ return status;
+ }
+ ... resource acquired
+ // post the semaphore
+ SemaphorePost(&pDevice->ResourceSem);
+
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+static inline SDIO_STATUS SemaphorePost(POS_SEMAPHORE pSem) {
+ DBG_ASSERT_WITH_MSG(!NonSchedulable(),"SemaphorePost not allowed\n");
+ up(pSem);
+ return SDIO_STATUS_SUCCESS;
+}
+
+
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ @function: Allocate a block of kernel accessible memory
+
+ @function name: KernelAlloc
+ @prototype: PVOID KernelAlloc(UINT size)
+ @category: Support_Reference
+
+ @input: size - size of memory block to allocate
+
+ @return: pointer to the allocated memory, NULL if allocation failed
+
+ @notes: For operating systems that use paging, the allocated memory is always
+ non-paged memory. Caller should only use KernelFree() to release the
+ block of memory. This call can potentially block and should only be called
+ from a schedulable context. Use KernelAllocIrqSafe() if the allocation
+ must be made from a non-schedulable context.
+
+ @see also: KernelFree, KernelAllocIrqSafe
+ @example: allocating memory:
+ pBlock = KernelAlloc(1024);
+ if (pBlock == NULL) {
+ .. failed, no memory
+ return SDIO_STATUS_INSUFFICIENT_RESOURCES;
+ }
+
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+static inline PVOID KernelAlloc(UINT size) {
+ PVOID pMem = kmalloc(size, GFP_KERNEL);
+ if (pMem != NULL) { memset(pMem,0,size); }
+ return pMem;
+}
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ @function: Free a block of kernel accessible memory.
+
+ @function name: KernelFree
+ @prototype: void KernelFree(PVOID ptr)
+ @category: Support_Reference
+
+ @input: ptr - pointer to memory allocated with KernelAlloc()
+
+ @return:
+
+ @notes: Caller should only use KernelFree() to release memory that was allocated
+ with KernelAlloc().
+
+ @see also: KernelAlloc
+ @example: KernelFree(pBlock);
+
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+static inline void KernelFree(PVOID ptr) {
+ kfree(ptr);
+}
+
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ @function: Allocate a block of kernel accessible memory in an IRQ-safe manner
+
+ @function name: KernelAllocIrqSafe
+ @prototype: PVOID KernelAllocIrqSafe(UINT size)
+ @category: Support_Reference
+
+ @input: size - size of memory block to allocate
+
+ @return: pointer to the allocated memory, NULL if allocation failed
+
+ @notes: This variant of KernelAlloc allows the allocation of small blocks of
+ memory from an ISR or from a context where scheduling has been disabled.
+ The allocations should be small as the memory is typically allocated
+ from a critical heap. The caller should only use KernelFreeIrqSafe()
+ to release the block of memory.
+
+ @see also: KernelAlloc, KernelFreeIrqSafe
+ @example: allocating memory:
+ pBlock = KernelAllocIrqSafe(16);
+ if (pBlock == NULL) {
+ .. failed, no memory
+ return SDIO_STATUS_INSUFFICIENT_RESOURCES;
+ }
+
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+static inline PVOID KernelAllocIrqSafe(UINT size) {
+ return kmalloc(size, GFP_ATOMIC);
+}
+
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ @function: Free a block of kernel accessible memory.
+
+ @function name: KernelFreeIrqSafe
+ @prototype: void KernelFreeIrqSafe(PVOID ptr)
+ @category: Support_Reference
+
+ @input: ptr - pointer to memory allocated with KernelAllocIrqSafe()
+
+ @return:
+
+ @notes: Caller should only use KernelFreeIrqSafe() to release memory that was allocated
+ with KernelAllocIrqSafe().
+
+ @see also: KernelAllocIrqSafe
+ @example: KernelFreeIrqSafe(pBlock);
+
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+static inline void KernelFreeIrqSafe(PVOID ptr) {
+ kfree(ptr);
+}
+
+/* error status conversions */
+static inline SYSTEM_STATUS SDIOErrorToOSError(SDIO_STATUS status) {
+ switch (status) {
+ case SDIO_STATUS_SUCCESS:
+ return 0;
+ case SDIO_STATUS_INVALID_PARAMETER:
+ return -EINVAL;
+ case SDIO_STATUS_PENDING:
+ return -EAGAIN; /* try again */
+ case SDIO_STATUS_DEVICE_NOT_FOUND:
+ return -ENXIO;
+ case SDIO_STATUS_DEVICE_ERROR:
+ return -EIO;
+ case SDIO_STATUS_INTERRUPTED:
+ return -EINTR;
+ case SDIO_STATUS_NO_RESOURCES:
+ return -ENOMEM;
+ case SDIO_STATUS_ERROR:
+ default:
+ return -EFAULT;
+ }
+}
+static inline SDIO_STATUS OSErrorToSDIOError(SYSTEM_STATUS status) {
+ if (status >=0) {
+ return SDIO_STATUS_SUCCESS;
+ }
+ switch (status) {
+ case -EINVAL:
+ return SDIO_STATUS_INVALID_PARAMETER;
+ case -ENXIO:
+ return SDIO_STATUS_DEVICE_NOT_FOUND;
+ case -EIO:
+ return SDIO_STATUS_DEVICE_ERROR;
+ case -EINTR:
+ return SDIO_STATUS_INTERRUPTED;
+ case -ENOMEM:
+ return SDIO_STATUS_NO_RESOURCES;
+ case -EFAULT:
+ return SDIO_STATUS_ERROR;
+ default:
+ return SDIO_STATUS_ERROR;
+ }
+}
+
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ @function: Sleep or delay the execution context for a number of milliseconds.
+
+ @function name: OSSleep
+ @prototype: SDIO_STATUS OSSleep(INT SleepInterval)
+ @category: Support_Reference
+
+ @input: SleepInterval - time in milliseconds to put the execution context to sleep
+
+ @return: SDIO_STATUS_SUCCESS if sleep succeeded.
+
+ @notes: Caller should be in a context that allows it to sleep or block. The
+ minimum duration of sleep may be greater than 1 MS on some platforms and OSes.
+
+ @see also: OSSleep
+ @example: Using sleep to delay
+ EnableSlotPower(pSlot);
+ // wait for power to settle
+ status = OSSleep(100);
+ if (!SDIO_SUCCESS(status)){
+ // failed..
+ }
+
+
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+static inline SDIO_STATUS OSSleep(INT SleepInterval) {
+ UINT32 delta;
+
+ DBG_ASSERT_WITH_MSG(!NonSchedulable(),"OSSleep not allowed\n");
+ /* convert timeout to ticks */
+ delta = (SleepInterval * HZ)/1000;
+ if (delta == 0) {
+ delta = 1;
+ }
+ set_current_state(TASK_INTERRUPTIBLE);
+ if (schedule_timeout(delta) != 0) {
+ return SDIO_STATUS_INTERRUPTED;
+ }
+ return SDIO_STATUS_SUCCESS;
+}
+
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ @function: get the OSs device object
+
+ @function name: SD_GET_OS_DEVICE
+ @prototype: POS_DEVICE SD_GET_OS_DEVICE(PSDDEVICE pDevice)
+ @category: Support_Reference
+
+ @input: pDevice - the device on the HCD
+
+ @return: pointer to the OSs device
+
+ @see also:
+ @example: obtain low level device
+ pFunctionContext->GpsDevice.Port.dev = SD_GET_OS_DEVICE(pDevice);
+
+
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+#define SD_GET_OS_DEVICE(pDevice) &((pDevice)->Device.dev)
+
+
+#ifdef __iomem
+ /* new type checking in 2.6.9 */
+ /* I/O Access macros */
+#define _READ_DWORD_REG(reg) \
+ readl((const volatile void __iomem *)(reg))
+#define _READ_WORD_REG(reg) \
+ readw((const volatile void __iomem *)(reg))
+#define _READ_BYTE_REG(reg) \
+ readb((const volatile void __iomem *)(reg))
+#define _WRITE_DWORD_REG(reg,value) \
+ writel((value),(volatile void __iomem *)(reg))
+#define _WRITE_WORD_REG(reg,value) \
+ writew((value),(volatile void __iomem *)(reg))
+#define _WRITE_BYTE_REG(reg,value) \
+ writeb((value),(volatile void __iomem *)(reg))
+#else
+ /* I/O Access macros */
+#define _READ_DWORD_REG(reg) \
+ readl((reg))
+#define _READ_WORD_REG(reg) \
+ readw((reg))
+#define _READ_BYTE_REG(reg) \
+ readb((reg))
+#define _WRITE_DWORD_REG(reg,value) \
+ writel((value),(reg))
+#define _WRITE_WORD_REG(reg,value) \
+ writew((value),(reg))
+#define _WRITE_BYTE_REG(reg,value) \
+ writeb((value),(reg))
+#endif
+ /* atomic operators */
+static inline ATOMIC_FLAGS AtomicTest_Set(volatile ATOMIC_FLAGS *pValue, INT BitNo) {
+ return test_and_set_bit(BitNo,(ATOMIC_FLAGS *)pValue);
+}
+static inline ATOMIC_FLAGS AtomicTest_Clear(volatile ATOMIC_FLAGS *pValue, INT BitNo) {
+ return test_and_clear_bit(BitNo,(ATOMIC_FLAGS *)pValue);
+}
+
+struct _OSKERNEL_HELPER;
+
+typedef THREAD_RETURN (*PHELPER_FUNCTION)(struct _OSKERNEL_HELPER *);
+
+typedef struct _OSKERNEL_HELPER {
+ PKERNEL_TASK pTask;
+ BOOL ShutDown;
+ OS_SIGNAL WakeSignal;
+ struct completion Completion;
+ PVOID pContext;
+ PHELPER_FUNCTION pHelperFunc;
+}OSKERNEL_HELPER, *POSKERNEL_HELPER;
+
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ @function: Wake the helper thread
+
+ @function name: SD_WAKE_OS_HELPER
+ @prototype: SD_WAKE_OS_HELPER(POSKERNEL_HELPER pOSHelper)
+ @category: Support_Reference
+
+ @input: pOSHelper - the OS helper object
+
+ @return: SDIO_STATUS
+
+ @see also: SDLIB_OSCreateHelper
+
+ @example: Waking up a helper thread
+ status = SD_WAKE_OS_HELPER(&pInstance->OSHelper);
+
+
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+#define SD_WAKE_OS_HELPER(p) SignalSet(&(p)->WakeSignal)
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ @function: Obtains the context for the helper function
+
+ @function name: SD_GET_OS_HELPER_CONTEXT
+ @prototype: SD_GET_OS_HELPER_CONTEXT(POSKERNEL_HELPER pOSHelper)
+ @category: Support_Reference
+
+ @input: pOSHelper - the OS helper object
+
+ @return: helper specific context
+
+ @notes: This macro should only be called by the function associated with
+ the helper object.
+
+ @see also: SDLIB_OSCreateHelper
+
+ @example: Getting the helper specific context
+ PMYCONTEXT pContext = (PMYCONTEXT)SD_GET_OS_HELPER_CONTEXT(pHelper);
+
+
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+#define SD_GET_OS_HELPER_CONTEXT(p) (p)->pContext
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ @function: Check helper function shut down flag.
+
+ @function name: SD_IS_HELPER_SHUTTING_DOWN
+ @prototype: SD_IS_HELPER_SHUTTING_DOWN(POSKERNEL_HELPER pOSHelper)
+ @category: Support_Reference
+
+ @input: pOSHelper - the OS helper object
+
+ @return: TRUE if shutting down, else FALSE
+
+ @notes: This macro should only be called by the function associated with
+ the helper object. The function should call this macro when it
+ unblocks from the call to SD_WAIT_FOR_WAKEUP(). If this function
+ returns TRUE, the function should clean up and exit.
+
+ @see also: SDLIB_OSCreateHelper , SD_WAIT_FOR_WAKEUP
+
+ @example: Checking for shutdown
+ while(1) {
+ status = SD_WAIT_FOR_WAKEUP(pHelper);
+ if (!SDIO_SUCCESS(status)) {
+ break;
+ }
+ if (SD_IS_HELPER_SHUTTING_DOWN(pHelper)) {
+ ... shutting down
+ break;
+ }
+ }
+
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+#define SD_IS_HELPER_SHUTTING_DOWN(p) (p)->ShutDown
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ @function: Suspend and wait for wakeup signal
+
+ @function name: SD_WAIT_FOR_WAKEUP
+ @prototype: SD_WAIT_FOR_WAKEUP(POSKERNEL_HELPER pOSHelper)
+ @category: Support_Reference
+
+ @input: pOSHelper - the OS helper object
+
+ @return: SDIO_STATUS
+
+ @notes: This macro should only be called by the function associated with
+ the helper object. The function should call this function to suspend (block)
+ itself and wait for a wake up signal. The function should always check
+ whether the function should exit by calling SD_IS_HELPER_SHUTTING_DOWN.
+
+ @see also: SDLIB_OSCreateHelper , SD_IS_HELPER_SHUTTING_DOWN
+
+ @example: block on the wake signal
+ while(1) {
+ status = SD_WAIT_FOR_WAKEUP(pHelper);
+ if (!SDIO_SUCCESS(status)) {
+ break;
+ }
+ if (SD_IS_HELPER_SHUTTING_DOWN(pHelper)) {
+ ... shutting down
+ break;
+ }
+ }
+
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+#define SD_WAIT_FOR_WAKEUP(p) SignalWait(&(p)->WakeSignal);
+
+#define CT_LE16_TO_CPU_ENDIAN(x) __le16_to_cpu(x)
+#define CT_LE32_TO_CPU_ENDIAN(x) __le32_to_cpu(x)
+#define CT_CPU_ENDIAN_TO_LE16(x) __cpu_to_le16(x)
+#define CT_CPU_ENDIAN_TO_LE32(x) __cpu_to_le32(x)
+
+#define CT_CPU_ENDIAN_TO_BE16(x) __cpu_to_be16(x)
+#define CT_CPU_ENDIAN_TO_BE32(x) __cpu_to_be32(x)
+#define CT_BE16_TO_CPU_ENDIAN(x) __be16_to_cpu(x)
+#define CT_BE32_TO_CPU_ENDIAN(x) __be32_to_cpu(x)
+#endif /* __CPSYSTEM_LINUX_H___ */
+