aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/s3c24xx/patches-2.6.26/1055-atheros_2_0_sdio_stack.patch.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/s3c24xx/patches-2.6.26/1055-atheros_2_0_sdio_stack.patch.patch')
-rwxr-xr-xtarget/linux/s3c24xx/patches-2.6.26/1055-atheros_2_0_sdio_stack.patch.patch13982
1 files changed, 0 insertions, 13982 deletions
diff --git a/target/linux/s3c24xx/patches-2.6.26/1055-atheros_2_0_sdio_stack.patch.patch b/target/linux/s3c24xx/patches-2.6.26/1055-atheros_2_0_sdio_stack.patch.patch
deleted file mode 100755
index e29f050afe..0000000000
--- a/target/linux/s3c24xx/patches-2.6.26/1055-atheros_2_0_sdio_stack.patch.patch
+++ /dev/null
@@ -1,13982 +0,0 @@
-From 79b0634b39757c62f4e61256c12ddf8e7b3783c4 Mon Sep 17 00:00:00 2001
-From: mokopatches <mokopatches@openmoko.org>
-Date: Fri, 25 Jul 2008 22:21:24 +0100
-Subject: [PATCH] atheros_2_0_sdio_stack.patch
-
----
- arch/arm/Kconfig | 2 +
- drivers/Kconfig | 2 +
- drivers/Makefile | 1 +
- drivers/sdio/Kconfig | 17 +
- drivers/sdio/Makefile | 4 +
- drivers/sdio/stack/Makefile | 1 +
- drivers/sdio/stack/busdriver/Makefile | 2 +
- drivers/sdio/stack/busdriver/_busdriver.h | 466 ++++
- drivers/sdio/stack/busdriver/sdio_bus.c | 2120 +++++++++++++++
- drivers/sdio/stack/busdriver/sdio_bus_events.c | 1040 +++++++
- drivers/sdio/stack/busdriver/sdio_bus_misc.c | 3122 ++++++++++++++++++++++
- drivers/sdio/stack/busdriver/sdio_bus_os.c | 832 ++++++
- drivers/sdio/stack/busdriver/sdio_function.c | 715 +++++
- drivers/sdio/stack/lib/Makefile | 2 +
- drivers/sdio/stack/lib/_sdio_lib.h | 50 +
- drivers/sdio/stack/lib/sdio_lib_c.c | 908 +++++++
- drivers/sdio/stack/lib/sdio_lib_os.c | 251 ++
- drivers/sdio/stack/platform/Makefile | 2 +
- drivers/sdio/stack/platform/sdioplatformdriver.c | 300 +++
- include/linux/sdio/_sdio_defs.h | 638 +++++
- include/linux/sdio/ctsystem.h | 115 +
- include/linux/sdio/ctsystem_linux.h | 983 +++++++
- include/linux/sdio/mmc_defs.h | 103 +
- include/linux/sdio/sdio_busdriver.h | 1435 ++++++++++
- include/linux/sdio/sdio_hcd_defs.h | 219 ++
- include/linux/sdio/sdio_lib.h | 270 ++
- include/linux/sdio/sdlist.h | 141 +
- 27 files changed, 13741 insertions(+), 0 deletions(-)
- create mode 100644 drivers/sdio/Kconfig
- create mode 100644 drivers/sdio/Makefile
- create mode 100644 drivers/sdio/stack/Makefile
- create mode 100644 drivers/sdio/stack/busdriver/Makefile
- create mode 100644 drivers/sdio/stack/busdriver/_busdriver.h
- create mode 100644 drivers/sdio/stack/busdriver/sdio_bus.c
- create mode 100644 drivers/sdio/stack/busdriver/sdio_bus_events.c
- create mode 100644 drivers/sdio/stack/busdriver/sdio_bus_misc.c
- create mode 100644 drivers/sdio/stack/busdriver/sdio_bus_os.c
- create mode 100644 drivers/sdio/stack/busdriver/sdio_function.c
- create mode 100644 drivers/sdio/stack/lib/Makefile
- create mode 100644 drivers/sdio/stack/lib/_sdio_lib.h
- create mode 100644 drivers/sdio/stack/lib/sdio_lib_c.c
- create mode 100644 drivers/sdio/stack/lib/sdio_lib_os.c
- create mode 100644 drivers/sdio/stack/platform/Makefile
- create mode 100644 drivers/sdio/stack/platform/sdioplatformdriver.c
- create mode 100644 include/linux/sdio/_sdio_defs.h
- create mode 100644 include/linux/sdio/ctsystem.h
- create mode 100644 include/linux/sdio/ctsystem_linux.h
- create mode 100644 include/linux/sdio/mmc_defs.h
- create mode 100644 include/linux/sdio/sdio_busdriver.h
- create mode 100644 include/linux/sdio/sdio_hcd_defs.h
- create mode 100644 include/linux/sdio/sdio_lib.h
- create mode 100644 include/linux/sdio/sdlist.h
-
-diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
-index b786e68..e394067 100644
---- a/arch/arm/Kconfig
-+++ b/arch/arm/Kconfig
-@@ -1169,6 +1169,8 @@ source "drivers/hid/Kconfig"
-
- source "drivers/usb/Kconfig"
-
-+source "drivers/sdio/Kconfig"
-+
- source "drivers/mmc/Kconfig"
-
- source "drivers/leds/Kconfig"
-diff --git a/drivers/Kconfig b/drivers/Kconfig
-index 59f33fa..f5900b7 100644
---- a/drivers/Kconfig
-+++ b/drivers/Kconfig
-@@ -78,6 +78,8 @@ source "drivers/hid/Kconfig"
-
- source "drivers/usb/Kconfig"
-
-+source "drivers/sdio/Kconfig"
-+
- source "drivers/mmc/Kconfig"
-
- source "drivers/memstick/Kconfig"
-diff --git a/drivers/Makefile b/drivers/Makefile
-index f65deda..ce63a01 100644
---- a/drivers/Makefile
-+++ b/drivers/Makefile
-@@ -80,6 +80,7 @@ obj-$(CONFIG_CPU_FREQ) += cpufreq/
- obj-$(CONFIG_CPU_IDLE) += cpuidle/
- obj-$(CONFIG_MMC) += mmc/
- obj-$(CONFIG_MEMSTICK) += memstick/
-+obj-$(CONFIG_SDIO) += sdio/
- obj-$(CONFIG_NEW_LEDS) += leds/
- obj-$(CONFIG_INFINIBAND) += infiniband/
- obj-$(CONFIG_SGI_SN) += sn/
-diff --git a/drivers/sdio/Kconfig b/drivers/sdio/Kconfig
-new file mode 100644
-index 0000000..14bf5e3
---- /dev/null
-+++ b/drivers/sdio/Kconfig
-@@ -0,0 +1,17 @@
-+#
-+# SDIO driver and host controller support
-+#
-+
-+menu "SDIO support"
-+
-+config SDIO
-+ tristate "SDIO support"
-+ default m
-+ ---help---
-+ good luck.
-+
-+source "drivers/sdio/hcd/Kconfig"
-+
-+source "drivers/sdio/function/Kconfig"
-+
-+endmenu
-diff --git a/drivers/sdio/Makefile b/drivers/sdio/Makefile
-new file mode 100644
-index 0000000..f56aa0f
---- /dev/null
-+++ b/drivers/sdio/Makefile
-@@ -0,0 +1,4 @@
-+#Makefile for SDIO stack
-+obj-$(CONFIG_SDIO) += stack/
-+obj-$(CONFIG_SDIO) += hcd/
-+obj-$(CONFIG_SDIO) += function/
-diff --git a/drivers/sdio/stack/Makefile b/drivers/sdio/stack/Makefile
-new file mode 100644
-index 0000000..ff0e24d
---- /dev/null
-+++ b/drivers/sdio/stack/Makefile
-@@ -0,0 +1 @@
-+obj-$(CONFIG_SDIO) += busdriver/ lib/
-\ No newline at end of file
-diff --git a/drivers/sdio/stack/busdriver/Makefile b/drivers/sdio/stack/busdriver/Makefile
-new file mode 100644
-index 0000000..1130e2d
---- /dev/null
-+++ b/drivers/sdio/stack/busdriver/Makefile
-@@ -0,0 +1,2 @@
-+obj-$(CONFIG_SDIO) += sdio_busdriver.o
-+sdio_busdriver-objs := sdio_bus.o sdio_function.o sdio_bus_misc.o sdio_bus_events.o sdio_bus_os.o
-diff --git a/drivers/sdio/stack/busdriver/_busdriver.h b/drivers/sdio/stack/busdriver/_busdriver.h
-new file mode 100644
-index 0000000..a85aed1
---- /dev/null
-+++ b/drivers/sdio/stack/busdriver/_busdriver.h
-@@ -0,0 +1,466 @@
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+@file: _busdriver.h
-+
-+@abstract: internal include file for busdriver
-+
-+@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 ___BUSDRIVER_H___
-+#define ___BUSDRIVER_H___
-+#include <linux/sdio/sdio_lib.h>
-+
-+#define SDIODBG_FUNC_IRQ (SDDBG_TRACE + 1)
-+#define SDIODBG_REQUESTS (SDDBG_TRACE + 2)
-+#define SDIODBG_CD_TIMER (SDDBG_TRACE + 3)
-+#define SDIODBG_HCD_EVENTS (SDDBG_TRACE + 4)
-+
-+#define SDIOBUS_CD_TIMER_ID 0
-+
-+#define SDBUS_MAX_RETRY 3
-+
-+/* Notes on list linkages:
-+ * list heads are held in BDCONTEXT
-+ * HcdList - SDHCD
-+ * one per registered host controller
-+ * Next - links of all HCDs
-+ * DeviceList SDDEVICE
-+ * one per inserted device
-+ * Next - links of all devices
-+ * DeviceListNext - links of all devices on a function
-+ * pFunction - ptr to Function supportting this device
-+ * pHcd - ptr to HCD with supporting this device
-+ * FunctionList SDFUNCTION
-+ * one per register function driver
-+ * Next - links of all functions
-+ * DeviceList - list of devices being support by this function
-+ * uses DeviceListNext in SDDEVICE to link
-+ *
-+ *
-+*/
-+
-+#define SDMMC_DEFAULT_CMD_RETRIES 1
-+#define SDMMC_DEFAULT_CARD_READY_RETRIES 200
-+#define OCR_READY_CHECK_DELAY_MS 10
-+#define SDMMC_POWER_SETTLE_DELAY 400 /* in milliseconds */
-+#define SDBUS_DEFAULT_REQ_LIST_SIZE 16
-+#define SDBUS_DEFAULT_REQ_SIG_SIZE 8
-+#define CARD_DETECT_PAUSE 100
-+#define SDBUS_DEFAULT_CD_POLLING_INTERVAL 1000 /* in milliseconds */
-+#define MAX_CARD_DETECT_MSGS 16
-+#define SDMMC_DEFAULT_BYTES_PER_BLOCK 2048
-+#define SDMMC_DEFAULT_BLOCKS_PER_TRANS 512
-+#define SDMMC_CMD13_POLLING_MULTIPLIER 1000 /* per block multiplier */
-+#define MAX_HCD_REQ_RECURSION 5
-+#define MAX_HCD_RECURSION_RUNAWAY 100
-+
-+ /* internal signalling item */
-+typedef struct _SIGNAL_ITEM{
-+ SDLIST SDList; /* list link*/
-+ OS_SIGNAL Signal; /* signal */
-+}SIGNAL_ITEM, *PSIGNAL_ITEM;
-+
-+typedef struct _HCD_EVENT_MESSAGE {
-+ HCD_EVENT Event; /* the event */
-+ PSDHCD pHcd; /* hcd that generated the event */
-+}HCD_EVENT_MESSAGE, *PHCD_EVENT_MESSAGE;
-+
-+/* internal data for bus driver */
-+typedef struct _BDCONTEXT {
-+
-+ /* list of SD requests and signalling semaphores and a semaphore to protect it */
-+ SDLIST RequestList;
-+ SDLIST SignalList;
-+ OS_CRITICALSECTION RequestListCritSection;
-+ /* list of host controller bus drivers, sempahore to protect it */
-+ SDLIST HcdList;
-+ OS_SEMAPHORE HcdListSem;
-+ /* list of inserted devices, semaphore to protect it */
-+ SDLIST DeviceList;
-+ OS_SEMAPHORE DeviceListSem;
-+ /* list of function drivers, semaphore to protect it */
-+ SDLIST FunctionList;
-+ OS_SEMAPHORE FunctionListSem;
-+ INT RequestListSize; /* default request list */
-+ INT SignalSemListSize; /* default signalling semaphore size */
-+ INT CurrentRequestAllocations; /*current count of allocated requests */
-+ INT CurrentSignalAllocations; /* current count of signal allocations */
-+ INT MaxRequestAllocations; /* max number of allocated requests to keep around*/
-+ INT MaxSignalAllocations; /* max number of signal allocations to keep around*/
-+ INT RequestRetries; /* cmd retries */
-+ INT CardReadyPollingRetry; /* card ready polling retry count */
-+ INT PowerSettleDelay; /* power settle delay */
-+ INT CMD13PollingMultiplier; /* CMD13 (GET STATUS) multiplier */
-+ SD_BUSCLOCK_RATE DefaultOperClock; /* default operation clock */
-+ SD_BUSMODE_FLAGS DefaultBusMode; /* default bus mode */
-+ UINT16 DefaultOperBlockLen; /* default operational block length per block */
-+ UINT16 DefaultOperBlockCount; /* default operational block count per transaction */
-+ UINT32 CDPollingInterval; /* card insert/removal polling interval */
-+ UINT8 InitMask; /* bus driver init mask */
-+#define BD_TIMER_INIT 0x01
-+#define HELPER_INIT 0x02
-+#define RESOURCE_INIT 0x04
-+ BOOL CDTimerQueued; /* card detect timer queued */
-+ OSKERNEL_HELPER CardDetectHelper; /* card detect helper */
-+ PSDMESSAGE_QUEUE pCardDetectMsgQueue; /* card detect message queue */
-+ ULONG HcdInUseField; /* bit field of in use HCD numbers*/
-+ UINT32 ConfigFlags; /* bus driver configuration flags */
-+#define BD_CONFIG_SDREQ_FORCE_ALL_ASYNC 0x00000001
-+ INT MaxHcdRecursion; /* max HCD recurion level */
-+}BDCONTEXT, *PBDCONTEXT;
-+
-+#define BD_DEFAULT_CONFIG_FLAGS 0x00000000
-+#define IsQueueBusy(pRequestQueue) (pRequestQueue)->Busy
-+#define MarkQueueBusy(pRequestQueue) (pRequestQueue)->Busy = TRUE
-+#define MarkQueueNotBusy(pRequestQueue) (pRequestQueue)->Busy = FALSE
-+
-+#define CLEAR_INTERNAL_REQ_FLAGS(pReq) (pReq)->Flags &= ~(UINT)((SDREQ_FLAGS_RESP_SPI_CONVERTED | \
-+ SDREQ_FLAGS_FORCE_DEFERRED_COMPLETE))
-+
-+/* macros to insert request into the queue */
-+#define QueueRequest(pReqQ,pReq) SDListInsertTail(&(pReqQ)->Queue,&(pReq)->SDList)
-+#define QueueRequestToFront(pReqQ,pReq) SDListInsertHead(&(pReqQ)->Queue,&(pReq)->SDList)
-+
-+/* macros to remove an item from the head of the queue */
-+static INLINE PSDREQUEST DequeueRequest(PSDREQUESTQUEUE pRequestQueue) {
-+ PSDLIST pItem;
-+ pItem = SDListRemoveItemFromHead(&pRequestQueue->Queue);
-+ if (pItem != NULL) {
-+ return CONTAINING_STRUCT(pItem, SDREQUEST, SDList);
-+ }
-+ return NULL;
-+};
-+
-+static INLINE SDIO_STATUS InitializeRequestQueue(PSDREQUESTQUEUE pRequestQueue) {
-+ SDLIST_INIT(&pRequestQueue->Queue);
-+ MarkQueueNotBusy(pRequestQueue);
-+ return SDIO_STATUS_SUCCESS;
-+}
-+
-+static INLINE void CleanupRequestQueue(PSDREQUESTQUEUE pRequestQueue) {
-+
-+}
-+
-+/* for bus driver internal use only */
-+SDIO_STATUS _SDIO_BusDriverInitialize(void);
-+SDIO_STATUS _SDIO_BusGetDefaultSettings(PBDCONTEXT pBdc);
-+void _SDIO_BusDriverCleanup(void);
-+SDIO_STATUS RemoveAllFunctions(void);
-+SDIO_STATUS RemoveHcdFunctions(PSDHCD pHcd);
-+PSDDEVICE AllocateDevice(PSDHCD pHcd);
-+BOOL AddDeviceToList(PSDDEVICE pDevice);
-+SDIO_STATUS DeleteDevices(PSDHCD pHcd);
-+SDIO_STATUS NotifyDeviceRemove(PSDDEVICE pDevice);
-+extern PBDCONTEXT pBusContext;
-+extern const CT_VERSION_CODE g_Version;
-+SDIO_STATUS _SDIO_RegisterHostController(PSDHCD pHcd);
-+SDIO_STATUS _SDIO_UnregisterHostController(PSDHCD pHcd);
-+SDIO_STATUS _SDIO_HandleHcdEvent(PSDHCD pHcd, HCD_EVENT Event);
-+SDIO_STATUS _SDIO_RegisterFunction(PSDFUNCTION pFunction);
-+SDIO_STATUS _SDIO_UnregisterFunction(PSDFUNCTION pFunction);
-+SDIO_STATUS _SDIO_CheckResponse(PSDHCD pHcd, PSDREQUEST pReq, SDHCD_RESPONSE_CHECK_MODE CheckMode);
-+SDIO_STATUS ProbeForFunction(PSDDEVICE pDevice, PSDHCD pHcd);
-+SDIO_STATUS SDInitializeCard(PSDHCD pHcd);
-+SDIO_STATUS SDQuerySDMMCInfo(PSDDEVICE pDevice);
-+SDIO_STATUS SDQuerySDIOInfo(PSDDEVICE pDevice);
-+SDIO_STATUS SDEnableFunction(PSDDEVICE pDevice, PSDCONFIG_FUNC_ENABLE_DISABLE_DATA pEnData);
-+SDIO_STATUS SDAllocFreeSlotCurrent(PSDDEVICE pDevice, BOOL Allocate, PSDCONFIG_FUNC_SLOT_CURRENT_DATA pData);
-+SDIO_STATUS SDMaskUnmaskFunctionIRQ(PSDDEVICE pDevice, BOOL Mask);
-+SDIO_STATUS SDFunctionAckInterrupt(PSDDEVICE pDevice);
-+SDIO_STATUS SDSPIModeEnableDisableCRC(PSDDEVICE pDevice,BOOL Enable);
-+SDIO_STATUS IssueBusConfig(PSDDEVICE pDev, PSDCONFIG pConfig);
-+SDIO_STATUS IssueBusRequest(PSDDEVICE pDev, PSDREQUEST pReq);
-+PSDREQUEST IssueAllocRequest(PSDDEVICE pDev);
-+void IssueFreeRequest(PSDDEVICE pDev, PSDREQUEST pReq);
-+PSDREQUEST AllocateRequest(void);
-+void FreeRequest(PSDREQUEST pReq);
-+PSIGNAL_ITEM AllocateSignal(void);
-+void FreeSignal(PSIGNAL_ITEM pSignal);
-+SDIO_STATUS InitializeTimers(void);
-+SDIO_STATUS CleanupTimers(void);
-+SDIO_STATUS QueueTimer(INT TimerID, UINT32 TimeOut);
-+SDIO_STATUS DeviceAttach(PSDHCD pHcd);
-+SDIO_STATUS DeviceDetach(PSDHCD pHcd);
-+SDIO_STATUS DeviceInterrupt(PSDHCD pHcd);
-+SDIO_STATUS CardInitSetup(PSDHCD pHcd);
-+void RunCardDetect(void);
-+void SDIO_NotifyTimerTriggered(INT TimerID);
-+SDIO_STATUS TestPresence(PSDHCD pHcd,
-+ CARD_INFO_FLAGS TestType,
-+ PSDREQUEST pReq);
-+#define _IssueSimpleBusRequest(pHcd,Cmd,Arg,Flags,pReqToUse) \
-+ _IssueBusRequestBd((pHcd),(Cmd),(Arg),(Flags),(pReqToUse),NULL,0)
-+
-+SDIO_STATUS Do_OS_IncHcdReference(PSDHCD pHcd);
-+SDIO_STATUS Do_OS_DecHcdReference(PSDHCD pHcd);
-+SDIO_STATUS TryNoIrqPendingCheck(PSDDEVICE pDev);
-+
-+ /* check API version compatibility of an HCD or function driver to a stack major/minor version
-+ if the driver version is greater than the major number, we are compatible
-+ if the driver version is equal, then we check if the minor is greater than or equal
-+ we don't have to check for the less than major, because the bus driver never loads
-+ drivers with different major numbers ...
-+ if the busdriver compiled version major is greater than the major version being checked this
-+ macro will resolved to ALWAYS true thus optimizing the code to not check the HCD since
-+ as a rule we never load an HCD with a lower major number */
-+#define CHECK_API_VERSION_COMPAT(p,major,minor) \
-+ ((CT_SDIO_STACK_VERSION_MAJOR(CT_SDIO_STACK_VERSION_CODE) > (major)) || \
-+ (GET_SDIO_STACK_VERSION_MINOR((p)) >= (minor)))
-+
-+static INLINE SDIO_STATUS OS_IncHcdReference(PSDHCD pHcd) {
-+ /* this API was added in version 2.3 which requires access to a field in the HCD structure */
-+ if (CHECK_API_VERSION_COMPAT(pHcd,2,3)) {
-+ /* we can safely call the OS-dependent function */
-+ return Do_OS_IncHcdReference(pHcd);
-+ }
-+ return SDIO_STATUS_SUCCESS;
-+}
-+
-+static INLINE SDIO_STATUS OS_DecHcdReference(PSDHCD pHcd) {
-+ /* this API was added in version 2.3 which requires access to a field in the HCD structure */
-+ if (CHECK_API_VERSION_COMPAT(pHcd,2,3)) {
-+ /* we can safely call the OS-dependent function */
-+ return Do_OS_DecHcdReference(pHcd);
-+ }
-+ return SDIO_STATUS_SUCCESS;
-+}
-+
-+SDIO_STATUS _IssueBusRequestBd(PSDHCD pHcd,
-+ UINT8 Cmd,
-+ UINT32 Argument,
-+ SDREQUEST_FLAGS Flags,
-+ PSDREQUEST pReqToUse,
-+ PVOID pData,
-+ INT Length);
-+
-+SDIO_STATUS IssueRequestToHCD(PSDHCD pHcd,PSDREQUEST pReq);
-+
-+#define CALL_HCD_CONFIG(pHcd,pCfg) (pHcd)->pConfigure((pHcd),(pCfg))
-+ /* macro to force all requests to be asynchronous in the HCD */
-+static INLINE BOOL ForceAllRequestsAsync(void) {
-+ return (pBusContext->ConfigFlags & BD_CONFIG_SDREQ_FORCE_ALL_ASYNC);
-+}
-+
-+static INLINE SDIO_STATUS CallHcdRequest(PSDHCD pHcd) {
-+
-+ if (pHcd->pCurrentRequest->Flags & SDREQ_FLAGS_PSEUDO) {
-+ DBG_PRINT(SDIODBG_REQUESTS, ("SDIO Bus Driver: PSEUDO Request 0x%X \n",
-+ (INT)pHcd->pCurrentRequest));
-+ /* return successful completion so that processing can finish */
-+ return SDIO_STATUS_SUCCESS;
-+ }
-+
-+ if (ForceAllRequestsAsync()) {
-+ /* all requests must be completed(indicated) in a separate context */
-+ pHcd->pCurrentRequest->Flags |= SDREQ_FLAGS_FORCE_DEFERRED_COMPLETE;
-+ } else {
-+ /* otherwise perform a test on flags in the HCD */
-+ if (!CHECK_API_VERSION_COMPAT(pHcd,2,6) &&
-+ AtomicTest_Set(&pHcd->HcdFlags, HCD_REQUEST_CALL_BIT)) {
-+
-+ /* bit was already set, this is a recursive call,
-+ * we need to tell the HCD to complete the
-+ * request in a separate context */
-+ DBG_PRINT(SDIODBG_REQUESTS, ("SDIO Bus Driver: Recursive CallHcdRequest \n"));
-+ pHcd->pCurrentRequest->Flags |= SDREQ_FLAGS_FORCE_DEFERRED_COMPLETE;
-+ }
-+ }
-+ #if DEBUG
-+ {
-+ SDIO_STATUS status;
-+ BOOL forceDeferred;
-+ forceDeferred = pHcd->pCurrentRequest->Flags & SDREQ_FLAGS_FORCE_DEFERRED_COMPLETE;
-+ status = pHcd->pRequest(pHcd);
-+ if (forceDeferred) {
-+ /* status better be pending... */
-+ DBG_ASSERT(status == SDIO_STATUS_PENDING);
-+ }
-+ return status;
-+ }
-+ #else
-+ return pHcd->pRequest(pHcd);
-+ #endif
-+
-+}
-+
-+/* note the caller of this macro must take the HCD lock to protect the count */
-+#define CHECK_HCD_RECURSE(pHcd,pReq) \
-+{ \
-+ (pHcd)->Recursion++; \
-+ DBG_ASSERT((pHcd)->Recursion < MAX_HCD_RECURSION_RUNAWAY); \
-+ if ((pHcd)->Recursion > pBusContext->MaxHcdRecursion) { \
-+ DBG_PRINT(SDIODBG_REQUESTS, ("SDIO Bus Driver: Recursive Request Count Exceeded (%d) \n",(pHcd)->Recursion)); \
-+ (pReq)->Flags |= SDREQ_FLAGS_FORCE_DEFERRED_COMPLETE; \
-+ } \
-+}
-+
-+/* InternalFlags bit number settings */
-+#define SDBD_INIT 1
-+#define SDBD_PENDING 15
-+#define SDBD_ALLOC_IRQ_SAFE 2
-+
-+#define SDBD_ALLOC_IRQ_SAFE_MASK (1 << SDBD_ALLOC_IRQ_SAFE)
-+
-+static void INLINE DoRequestCompletion(PSDREQUEST pReq, PSDHCD pHcd) {
-+ CLEAR_INTERNAL_REQ_FLAGS(pReq);
-+ if (pReq->pCompletion != NULL) {
-+ DBG_PRINT(SDIODBG_REQUESTS, ("SDIO Bus Driver: Calling completion on request:0x%X, CMD:%d \n",
-+ (INT)pReq, pReq->Command));
-+ /* call completion routine, mark request reusable */
-+ AtomicTest_Clear(&pReq->InternalFlags, SDBD_PENDING);
-+ pReq->pCompletion(pReq);
-+ } else {
-+ /* mark request reusable */
-+ AtomicTest_Clear(&pReq->InternalFlags, SDBD_PENDING);
-+ }
-+}
-+
-+THREAD_RETURN CardDetectHelperFunction(POSKERNEL_HELPER pHelper);
-+THREAD_RETURN SDIOIrqHelperFunction(POSKERNEL_HELPER pHelper);
-+
-+void ConvertSPI_Response(PSDREQUEST pReq, UINT8 *pRespBuffer);
-+
-+static INLINE SDIO_STATUS PostCardDetectEvent(PBDCONTEXT pSDB, HCD_EVENT Event, PSDHCD pHcd) {
-+ HCD_EVENT_MESSAGE message;
-+ SDIO_STATUS status;
-+ message.Event = Event;
-+ message.pHcd = pHcd;
-+
-+ if (pHcd != NULL) {
-+ /* increment HCD reference count to process this HCD message */
-+ status = OS_IncHcdReference(pHcd);
-+ if (!SDIO_SUCCESS(status)) {
-+ return status;
-+ }
-+ }
-+ /* post card detect message */
-+ status = SDLIB_PostMessage(pSDB->pCardDetectMsgQueue, &message, sizeof(message));
-+ if (!SDIO_SUCCESS(status)) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: PostCardDetectEvent error status %d\n",status));
-+ if (pHcd != NULL) {
-+ /* decrement count */
-+ OS_DecHcdReference(pHcd);
-+ }
-+ return status;
-+ }
-+ /* wake card detect helper */
-+ DBG_PRINT(SDIODBG_HCD_EVENTS, ("SDIO Bus Driver: PostCardDetectEvent waking\n"));
-+ return SD_WAKE_OS_HELPER(&pSDB->CardDetectHelper);
-+};
-+
-+/* initialize device fields */
-+static INLINE void InitDeviceData(PSDHCD pHcd, PSDDEVICE pDevice) {
-+ ZERO_POBJECT(pDevice);
-+ SDLIST_INIT(&pDevice->SDList);
-+ SDLIST_INIT(&pDevice->FuncListLink);
-+ pDevice->pRequest = IssueBusRequest;
-+ pDevice->pConfigure = IssueBusConfig;
-+ pDevice->AllocRequest = IssueAllocRequest;
-+ pDevice->FreeRequest = IssueFreeRequest;
-+ /* set card flags in the ID */
-+ pDevice->pId[0].CardFlags = pHcd->CardProperties.Flags;
-+ pDevice->pFunction = NULL;
-+ pDevice->pHcd = pHcd;
-+ SET_SDIO_STACK_VERSION(pDevice);
-+}
-+
-+/* de-initialize device fields */
-+static INLINE void DeinitDeviceData(PSDDEVICE pDevice) {
-+}
-+
-+/* reset hcd state */
-+static INLINE void ResetHcdState(PSDHCD pHcd) {
-+ ZERO_POBJECT(&pHcd->CardProperties);
-+ pHcd->PendingHelperIrqs = 0;
-+ pHcd->PendingIrqAcks = 0;
-+ pHcd->IrqsEnabled = 0;
-+ pHcd->pCurrentRequest = NULL;
-+ pHcd->IrqProcState = SDHCD_IDLE;
-+ /* mark this device as special */
-+ pHcd->pPseudoDev->pId[0].CardFlags = CARD_PSEUDO;
-+ pHcd->SlotCurrentAllocated = 0;
-+}
-+
-+static INLINE SDIO_STATUS _IssueConfig(PSDHCD pHcd,
-+ SDCONFIG_COMMAND Command,
-+ PVOID pData,
-+ INT Length){
-+ SDCONFIG configHdr;
-+ SET_SDCONFIG_CMD_INFO(&configHdr,Command,pData,Length);
-+ return CALL_HCD_CONFIG(pHcd,&configHdr);
-+}
-+
-+/* prototypes */
-+#define _AcquireHcdLock(pHcd)CriticalSectionAcquireSyncIrq(&(pHcd)->HcdCritSection)
-+#define _ReleaseHcdLock(pHcd)CriticalSectionReleaseSyncIrq(&(pHcd)->HcdCritSection)
-+
-+#define AcquireHcdLock(pDev) CriticalSectionAcquireSyncIrq(&(pDev)->pHcd->HcdCritSection)
-+#define ReleaseHcdLock(pDev) CriticalSectionReleaseSyncIrq(&(pDev)->pHcd->HcdCritSection)
-+
-+SDIO_STATUS OS_AddDevice(PSDDEVICE pDevice, PSDFUNCTION pFunction);
-+void OS_RemoveDevice(PSDDEVICE pDevice);
-+SDIO_STATUS OS_InitializeDevice(PSDDEVICE pDevice, PSDFUNCTION pFunction);
-+SDIO_STATUS SetOperationalBusMode(PSDDEVICE pDevice,
-+ PSDCONFIG_BUS_MODE_DATA pBusMode);
-+void FreeDevice(PSDDEVICE pDevice);
-+BOOL IsPotentialIdMatch(PSD_PNP_INFO pIdsDev, PSD_PNP_INFO pIdsFuncList);
-+
-+
-+#define CHECK_FUNCTION_DRIVER_VERSION(pF) \
-+ (GET_SDIO_STACK_VERSION_MAJOR((pF)) == CT_SDIO_STACK_VERSION_MAJOR(g_Version))
-+#define CHECK_HCD_DRIVER_VERSION(pH) \
-+ (GET_SDIO_STACK_VERSION_MAJOR((pH)) == CT_SDIO_STACK_VERSION_MAJOR(g_Version))
-+
-+/* CLARIFICATION on SDREQ_FLAGS_PSEUDO and SDREQ_FLAGS_BARRIER flags :
-+ *
-+ * A request marked as PSEUDO is synchronized with bus requests and is not a true request
-+ * that is issued to an HCD.
-+ *
-+ * A request marked with a BARRIER flag requires that the completion routine be called
-+ * before the next bus request starts. This is required for HCD requests that can change
-+ * bus or clock modes. Changing the clock or bus mode while a bus request is pending
-+ * can cause problems.
-+ *
-+ *
-+ *
-+ * */
-+#define SD_PSEUDO_REQ_FLAGS \
-+ (SDREQ_FLAGS_PSEUDO | SDREQ_FLAGS_BARRIER | SDREQ_FLAGS_TRANS_ASYNC)
-+
-+#endif /*___BUSDRIVER_H___*/
-diff --git a/drivers/sdio/stack/busdriver/sdio_bus.c b/drivers/sdio/stack/busdriver/sdio_bus.c
-new file mode 100644
-index 0000000..ffc1e9f
---- /dev/null
-+++ b/drivers/sdio/stack/busdriver/sdio_bus.c
-@@ -0,0 +1,2120 @@
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+@file: sdio_bus.c
-+
-+@abstract: OS independent bus driver support
-+@category abstract: HD_Reference Host Controller Driver Interfaces.
-+@category abstract: PD_Reference
-+ Peripheral Driver Interfaces.
-+
-+#notes: this file supports the HCD's and generic functions
-+
-+@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
-+ *
-+ *
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+#define MODULE_NAME SDBUSDRIVER
-+#include <linux/sdio/ctsystem.h>
-+#include <linux/sdio/sdio_busdriver.h>
-+#include <linux/sdio/_sdio_defs.h>
-+#include <linux/sdio/sdio_lib.h>
-+#include <linux/sdio/mmc_defs.h>
-+#include "_busdriver.h"
-+
-+/* list of host controller bus drivers */
-+PBDCONTEXT pBusContext = NULL;
-+static void CleanUpBusResources(void);
-+static SDIO_STATUS AllocateBusResources(void);
-+static PSIGNAL_ITEM BuildSignal(void);
-+static void DestroySignal(PSIGNAL_ITEM pSignal);
-+
-+const CT_VERSION_CODE g_Version = CT_SDIO_STACK_VERSION_CODE;
-+/*
-+ * _SDIO_BusDriverInitialize - call once on driver loading
-+ *
-+*/
-+SDIO_STATUS _SDIO_BusDriverInitialize(void)
-+{
-+ SDIO_STATUS status = SDIO_STATUS_SUCCESS;
-+
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: Version: %d.%d\n",
-+ CT_SDIO_STACK_VERSION_MAJOR(g_Version),CT_SDIO_STACK_VERSION_MINOR(g_Version)));
-+
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: enter _SDIO_BusDriverInitialize\n"));
-+
-+ do {
-+ /* allocate our internal data initialize it */
-+ pBusContext = KernelAlloc(sizeof(BDCONTEXT));
-+ if (pBusContext == NULL) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: _SDIO_BusDriverInitialize can't allocate memory.\n"));
-+ status = SDIO_STATUS_NO_RESOURCES;
-+ break;
-+ }
-+ memset(pBusContext,0,sizeof(BDCONTEXT));
-+ SDLIST_INIT(&pBusContext->RequestList);
-+ SDLIST_INIT(&pBusContext->HcdList);
-+ SDLIST_INIT(&pBusContext->DeviceList);
-+ SDLIST_INIT(&pBusContext->FunctionList);
-+ SDLIST_INIT(&pBusContext->SignalList);
-+
-+ /* setup defaults */
-+ pBusContext->RequestRetries = SDMMC_DEFAULT_CMD_RETRIES;
-+ pBusContext->CardReadyPollingRetry = SDMMC_DEFAULT_CARD_READY_RETRIES;
-+ pBusContext->PowerSettleDelay = SDMMC_POWER_SETTLE_DELAY;
-+ pBusContext->DefaultOperClock = MMC_HS_MAX_BUS_CLOCK;
-+ pBusContext->DefaultBusMode = SDCONFIG_BUS_WIDTH_4_BIT;
-+ pBusContext->RequestListSize = SDBUS_DEFAULT_REQ_LIST_SIZE;
-+ pBusContext->SignalSemListSize = SDBUS_DEFAULT_REQ_SIG_SIZE;
-+ pBusContext->CDPollingInterval = SDBUS_DEFAULT_CD_POLLING_INTERVAL;
-+ pBusContext->DefaultOperBlockLen = SDMMC_DEFAULT_BYTES_PER_BLOCK;
-+ pBusContext->DefaultOperBlockCount = SDMMC_DEFAULT_BLOCKS_PER_TRANS;
-+ pBusContext->ConfigFlags = BD_DEFAULT_CONFIG_FLAGS;
-+ pBusContext->CMD13PollingMultiplier = SDMMC_CMD13_POLLING_MULTIPLIER;
-+ pBusContext->MaxHcdRecursion = MAX_HCD_REQ_RECURSION;
-+
-+ /* get overrides for the defaults */
-+ status = _SDIO_BusGetDefaultSettings(pBusContext);
-+ if (!SDIO_SUCCESS(status)) {
-+ break;
-+ }
-+
-+ pBusContext->MaxRequestAllocations = pBusContext->RequestListSize << 1;
-+ pBusContext->MaxSignalAllocations = pBusContext->SignalSemListSize << 1;
-+
-+ status = CriticalSectionInit(&pBusContext->RequestListCritSection);
-+ if (!SDIO_SUCCESS(status)) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: _SDIO_BusDriverInitialize can't CriticalSectionInit.\n"));
-+ break;
-+ }
-+ status = SemaphoreInitialize(&pBusContext->HcdListSem, 1);
-+ if (!SDIO_SUCCESS(status)) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: _SDIO_BusDriverInitialize can't SemaphoreInitialize HcdListSem.\n"));
-+ break;
-+ }
-+ status = SemaphoreInitialize(&pBusContext->DeviceListSem, 1);
-+ if (!SDIO_SUCCESS(status)) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: _SDIO_BusDriverInitialize can't SemaphoreInitialize DeviceListSem.\n"));
-+ break;
-+ }
-+ status = SemaphoreInitialize(&pBusContext->FunctionListSem, 1);
-+ if (!SDIO_SUCCESS(status)) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: _SDIO_BusDriverInitialize can't SemaphoreInitialize FunctionListSem.\n"));
-+ break;
-+ }
-+ status = AllocateBusResources();
-+ if (!SDIO_SUCCESS(status)) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: _SDIO_BusDriverInitialize can't AllocateBusResources.\n"));
-+ break;
-+ }
-+
-+ pBusContext->InitMask |= RESOURCE_INIT;
-+
-+ pBusContext->pCardDetectMsgQueue = SDLIB_CreateMessageQueue(MAX_CARD_DETECT_MSGS,
-+ sizeof(HCD_EVENT_MESSAGE));
-+
-+ if (NULL == pBusContext->pCardDetectMsgQueue) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: _SDIO_BusDriverInitialize can't CreateMessageQueue.\n"));
-+ status = SDIO_STATUS_NO_RESOURCES;
-+ break;
-+ }
-+
-+ status = SDLIB_OSCreateHelper(&pBusContext->CardDetectHelper,
-+ CardDetectHelperFunction,
-+ NULL);
-+
-+ if (!SDIO_SUCCESS(status)) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: _SDIO_BusDriverInitialize can't OSCreateHelper.\n"));
-+ break;
-+ }
-+
-+ pBusContext->InitMask |= HELPER_INIT;
-+
-+ status = InitializeTimers();
-+ if (!SDIO_SUCCESS(status)) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: _SDIO_BusDriverInitialize can't InitializeTimers.\n"));
-+ break;
-+ }
-+ pBusContext->InitMask |= BD_TIMER_INIT;
-+ } while(FALSE);
-+
-+ if (!SDIO_SUCCESS(status)) {
-+ _SDIO_BusDriverCleanup();
-+ }
-+
-+ return status;
-+}
-+
-+
-+/*
-+ * _SDIO_BusDriverBusDriverCleanup - call once on driver unloading
-+ *
-+*/
-+void _SDIO_BusDriverCleanup(void) {
-+ DBG_PRINT(SDDBG_TRACE, ("+SDIO Bus Driver: _SDIO_BusDriverCleanup\n"));
-+
-+ if (pBusContext->InitMask & BD_TIMER_INIT) {
-+ CleanupTimers();
-+ }
-+
-+ if (pBusContext->InitMask & HELPER_INIT) {
-+ SDLIB_OSDeleteHelper(&pBusContext->CardDetectHelper);
-+ }
-+
-+ if (pBusContext->pCardDetectMsgQueue != NULL) {
-+ SDLIB_DeleteMessageQueue(pBusContext->pCardDetectMsgQueue);
-+ pBusContext->pCardDetectMsgQueue = NULL;
-+ }
-+ /* remove functions */
-+ RemoveAllFunctions();
-+ /* cleanup all devices */
-+ DeleteDevices(NULL);
-+ CleanUpBusResources();
-+ CriticalSectionDelete(&pBusContext->RequestListCritSection);
-+ SemaphoreDelete(&pBusContext->HcdListSem);
-+ SemaphoreDelete(&pBusContext->DeviceListSem);
-+ SemaphoreDelete(&pBusContext->FunctionListSem);
-+ KernelFree(pBusContext);
-+ pBusContext = NULL;
-+ DBG_PRINT(SDDBG_TRACE, ("-SDIO Bus Driver: _SDIO_BusDriverCleanup\n"));
-+}
-+
-+
-+/* cleanup hcd */
-+static void CleanupHcd(PSDHCD pHcd)
-+{
-+ SDLIB_OSDeleteHelper(&pHcd->SDIOIrqHelper);
-+ CleanupRequestQueue(&pHcd->CompletedRequestQueue);
-+ CleanupRequestQueue(&pHcd->RequestQueue);
-+ CriticalSectionDelete(&pHcd->HcdCritSection);
-+ SemaphoreDelete(&pHcd->ConfigureOpsSem);
-+ pHcd->pCurrentRequest = NULL;
-+ if (pHcd->pPseudoDev != NULL) {
-+ FreeDevice(pHcd->pPseudoDev);
-+ pHcd->pPseudoDev = NULL;
-+ }
-+}
-+
-+/* set up the hcd */
-+static SDIO_STATUS SetupHcd(PSDHCD pHcd)
-+{
-+ SDIO_STATUS status;
-+
-+ ZERO_POBJECT(&pHcd->SDIOIrqHelper);
-+ ZERO_POBJECT(&pHcd->ConfigureOpsSem);
-+ ZERO_POBJECT(&pHcd->HcdCritSection);
-+ ZERO_POBJECT(&pHcd->RequestQueue);
-+ ZERO_POBJECT(&pHcd->CompletedRequestQueue);
-+ pHcd->pPseudoDev = NULL;
-+ pHcd->Recursion = 0;
-+
-+ do {
-+
-+ pHcd->pPseudoDev = AllocateDevice(pHcd);
-+
-+ if (NULL == pHcd->pPseudoDev) {
-+ status = SDIO_STATUS_NO_RESOURCES;
-+ break;
-+ }
-+
-+ ResetHcdState(pHcd);
-+
-+ status = SemaphoreInitialize(&pHcd->ConfigureOpsSem,1);
-+ if (!SDIO_SUCCESS(status)) {
-+ break;
-+ }
-+ status = CriticalSectionInit(&pHcd->HcdCritSection);
-+ if (!SDIO_SUCCESS(status)) {
-+ break;
-+ }
-+ status = InitializeRequestQueue(&pHcd->RequestQueue);
-+ if (!SDIO_SUCCESS(status)) {
-+ break;
-+ }
-+ status = InitializeRequestQueue(&pHcd->CompletedRequestQueue);
-+ if (!SDIO_SUCCESS(status)) {
-+ break;
-+ }
-+ /* create SDIO Irq helper */
-+ status = SDLIB_OSCreateHelper(&pHcd->SDIOIrqHelper,
-+ SDIOIrqHelperFunction,
-+ (PVOID)pHcd);
-+ } while(FALSE);
-+
-+ if (!SDIO_SUCCESS(status)) {
-+ /* undo what we did */
-+ CleanupHcd(pHcd);
-+ }
-+ return status;
-+}
-+
-+
-+/*
-+ * _SDIO_RegisterHostController - register a host controller bus driver
-+ *
-+*/
-+
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Register a host controller driver with the bus driver.
-+
-+ @function name: SDIO_RegisterHostController
-+ @prototype: SDIO_STATUS SDIO_RegisterHostController (PSDHCD pHcd)
-+ @category: HD_Reference
-+
-+ @input: pHcd - the host controller definition structure.
-+
-+ @output: none
-+
-+ @return: SDIO_STATUS - SDIO_STATUS_SUCCESS when successful.
-+
-+ @notes: Each host controller driver must register with the bus driver when loaded.
-+ The driver registers an SDHCD structure initialized with hardware properties
-+ and callback functions for bus requests and configuration. On multi-slot
-+ hardware ,each slot should be registered with a separate SDHCD structure.
-+ The bus driver views each slot as a seperate host controller object.
-+ The driver should be prepared to receive configuration requests before
-+ this call returns. The host controller driver must unregister itself when
-+ shutting down.
-+
-+ @example: Registering a host controller driver:
-+ static SDHCD Hcd = {
-+ .pName = "sdio_custom_hcd",
-+ .Version = CT_SDIO_STACK_VERSION_CODE, // set stack version code
-+ .SlotNumber = 0, // bus driver internal use
-+ .Attributes = SDHCD_ATTRIB_BUS_1BIT | SDHCD_ATTRIB_BUS_4BIT | SDHCD_ATTRIB_MULTI_BLK_IRQ
-+ SDHCD_ATTRIB_AUTO_CMD12 ,
-+ .MaxBytesPerBlock = 2048 // each data block can be up to 2048 bytes
-+ .MaxBlocksPerTrans = 1024, // each data transaction can consist of 1024 blocks
-+ .MaxSlotCurrent = 500, // max FET switch current rating
-+ .SlotVoltageCaps = SLOT_POWER_3_3V, // only 3.3V operation
-+ .SlotVoltagePreferred = SLOT_POWER_3_3V,
-+ .MaxClockRate = 24000000, // 24 Mhz max operation
-+ .pContext = &HcdContext, // set our driver context
-+ .pRequest = HcdRequest, // set SDIO bus request callback
-+ .pConfigure = HcdConfig, // set SDIO bus configuration callback
-+ };
-+ if (!SDIO_SUCCESS((status = SDIO_RegisterHostController(&Hcd)))) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO HCD - failed to register with host, status =%d\n",
-+ status));
-+ }
-+
-+ @see also: SDIO_UnregisterHostController
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+SDIO_STATUS _SDIO_RegisterHostController(PSDHCD pHcd) {
-+ SDIO_STATUS status = SDIO_STATUS_SUCCESS;
-+
-+ DBG_PRINT(SDDBG_TRACE, ("+SDIO Bus Driver: _SDIO_RegisterHostController - %s\n",pHcd->pName));
-+ DBG_PRINT(SDDBG_TRACE, ("+SDIO Bus Driver: Host Controller Stack Version: %d.%d \n",
-+ GET_SDIO_STACK_VERSION_MAJOR(pHcd),GET_SDIO_STACK_VERSION_MINOR(pHcd)));
-+
-+ if (!CHECK_HCD_DRIVER_VERSION(pHcd)) {
-+ DBG_PRINT(SDDBG_ERROR,
-+ ("SDIO Bus Driver: HCD Major Version Mismatch (hcd = %d, bus driver = %d)\n",
-+ GET_SDIO_STACK_VERSION_MAJOR(pHcd), CT_SDIO_STACK_VERSION_MAJOR(g_Version)));
-+ return SDIO_STATUS_INVALID_PARAMETER;
-+ }
-+ /* setup hcd */
-+ status = SetupHcd(pHcd);
-+ if (!SDIO_SUCCESS(status)) {
-+ return status;
-+ }
-+
-+ do {
-+ INT slotNumber;
-+
-+ /* protect the HCD list */
-+ if (!SDIO_SUCCESS((status = SemaphorePendInterruptable(&pBusContext->HcdListSem)))) {
-+ break; /* wait interrupted */
-+ }
-+ /* find a unique number for this HCD, must be done under semaphore protection */
-+ slotNumber = FirstClearBit(&pBusContext->HcdInUseField);
-+ if (slotNumber < 0) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: _SDIO_RegisterHostController, error, slotNumber exceeded\n"));
-+ /* fake something */
-+ slotNumber = 31;
-+ }
-+ SetBit(&pBusContext->HcdInUseField, slotNumber);
-+ pHcd->SlotNumber = slotNumber;
-+ /* add HCD to the end of the internal list */
-+ SDListAdd(&pBusContext->HcdList , &pHcd->SDList);
-+ if (!SDIO_SUCCESS((status = SemaphorePost(&pBusContext->HcdListSem)))) {
-+ break; /* wait interrupted */
-+ }
-+ if (pHcd->Attributes & SDHCD_ATTRIB_SLOT_POLLING) {
-+ /* post message to card detect helper to do polling */
-+ PostCardDetectEvent(pBusContext, EVENT_HCD_CD_POLLING, NULL);
-+ }
-+ } while (FALSE);
-+
-+ if (!SDIO_SUCCESS(status)) {
-+ CleanupHcd(pHcd);
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: _SDIO_RegisterHostController, error 0x%X.\n", status));
-+ }
-+ DBG_PRINT(SDDBG_TRACE, ("-SDIO Bus Driver: _SDIO_RegisterHostController\n"));
-+ return status;
-+}
-+
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Unregister a host controller driver with the bus driver.
-+
-+ @function name: SDIO_UnregisterHostController
-+ @prototype: SDIO_STATUS SDIO_UnregisterHostController (PSDHCD pHcd)
-+ @category: HD_Reference
-+
-+ @input: pHcd - the host controller definition structure that was registered.
-+
-+ @output: none
-+
-+ @return: SDIO_STATUS - SDIO_STATUS_SUCCESS when successful.
-+
-+ @notes: Each host controller driver must unregister with the bus driver when
-+ unloading. The driver is responsible for halting any outstanding I/O
-+ operations. The bus driver will automatically unload function drivers
-+ that may be attached assigned to cards inserted into slots.
-+
-+ @example: Unregistering a host controller driver:
-+ if (!SDIO_SUCCESS((status = SDIO_UnregisterHostController(&Hcd)))) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO HCD - failed to unregister with host, status =%d\n",
-+ status));
-+ }
-+
-+ @see also: SDIO_RegisterHostController
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+SDIO_STATUS _SDIO_UnregisterHostController(PSDHCD pHcd) {
-+ SDIO_STATUS status = SDIO_STATUS_SUCCESS;
-+
-+ DBG_PRINT(SDDBG_TRACE, ("+SDIO Bus Driver: _SDIO_UnregisterHostController\n"));
-+
-+ /* remove functions associated with the HCD */
-+ RemoveHcdFunctions(pHcd);
-+ /* remove any devices associated with the HCD */
-+ DeleteDevices(pHcd);
-+ /* wait for the message queue to be empty, so we don't have any delayed requests going
-+ to this device */
-+ while(!SDLIB_IsQueueEmpty(pBusContext->pCardDetectMsgQueue)) {
-+ /* wait for the messages to be handled */
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: _SDIO_UnregisterHostController, waiting on messages\n"));
-+ OSSleep(250);
-+ }
-+
-+ /* protect the HCD list */
-+ if (!SDIO_SUCCESS((status = SemaphorePendInterruptable(&pBusContext->HcdListSem)))) {
-+ goto cleanup; /* wait interrupted */
-+ }
-+ ClearBit(&pBusContext->HcdInUseField, pHcd->SlotNumber);
-+ /* delete HCD from list */
-+ SDListRemove(&pHcd->SDList);
-+ if (!SDIO_SUCCESS((status = SemaphorePost(&pBusContext->HcdListSem)))) {
-+ goto cleanup; /* wait interrupted */
-+ }
-+ /* cleanup anything we allocated */
-+ CleanupHcd(pHcd);
-+ DBG_PRINT(SDDBG_TRACE, ("-SDIO Bus Driver: _SDIO_UnregisterHostController\n"));
-+ return status;
-+cleanup:
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: _SDIO_UnregisterHostController, error 0x%X.\n", status));
-+ return status;
-+}
-+
-+/* documentation headers only for Request and Configure */
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: The bus driver calls the request callback to start an SDIO bus transaction.
-+ @function name: Request
-+ @prototype: SDIO_STATUS (*pRequest) (struct _SDHCD *pHcd)
-+ @category: HD_Reference
-+
-+ @input: pHcd - the host controller structure that was registered
-+
-+ @output: none
-+
-+ @return: SDIO_STATUS
-+
-+ @notes:
-+ The bus driver maintains an internal queue of SDREQUEST structures submited by function
-+ drivers. The driver should use request macros to obtain a pointer to the current SDREQUEST
-+ at the head of the queue. The driver can access the fields of the current request in order
-+ to program hardware appropriately. Once the request completes, the driver should update
-+ the current request information (final status, response bytes and/or data) and call
-+ SDIO_HandleHcdEvent() with the event type of EVENT_HCD_TRANSFER_DONE.
-+ The bus driver will remove the current request from the head of the queue and start the next
-+ request.
-+
-+ @example: Example of a typical Request callback:
-+ SDIO_STATUS HcdRequest(PSDHCD pHcd)
-+ {
-+ SDIO_STATUS status = SDIO_STATUS_SUCCESS;
-+ PSDHCD_DRIVER_CONTEXT pHct = (PSDHCD_DRIVER_CONTEXT)pHcd->pContext;
-+ UINT32 temp = 0;
-+ PSDREQUEST pReq;
-+ // get the current request
-+ pReq = GET_CURRENT_REQUEST(pHcd);
-+ DBG_ASSERT(pReq != NULL);
-+ // get controller settings based on response type
-+ switch (GET_SDREQ_RESP_TYPE(pReq->Flags)) {
-+ case SDREQ_FLAGS_NO_RESP:
-+ break;
-+ case SDREQ_FLAGS_RESP_R1:
-+ case SDREQ_FLAGS_RESP_MMC_R4:
-+ case SDREQ_FLAGS_RESP_MMC_R5:
-+ case SDREQ_FLAGS_RESP_R6:
-+ case SDREQ_FLAGS_RESP_SDIO_R5:
-+ temp |= CMDDAT_RES_R1_R4_R5;
-+ break;
-+ case SDREQ_FLAGS_RESP_R1B:
-+ temp |= (CMDDAT_RES_R1_R4_R5 | CMDAT_RES_BUSY);
-+ break;
-+ case SDREQ_FLAGS_RESP_R2:
-+ temp |= CMDDAT_RES_R2;
-+ break;
-+ case SDREQ_FLAGS_RESP_R3:
-+ case SDREQ_FLAGS_RESP_SDIO_R4:
-+ temp |= CMDDAT_RES_R3;
-+ break;
-+ }
-+ // check for data
-+ if (pReq->Flags & SDREQ_FLAGS_DATA_TRANS){
-+ temp |= CMDDAT_DATA_EN;
-+ // set data remaining count
-+ pReq->DataRemaining = pReq->BlockLen * pReq->BlockCount;
-+ DBG_PRINT(TRACE_DATA, ("SDIO %s Data Transfer, Blocks:%d, BlockLen:%d, Total:%d \n",
-+ IS_SDREQ_WRITE_DATA(pReq->Flags) ? "TX":"RX",
-+ pReq->BlockCount, pReq->BlockLen, pReq->DataRemaining));
-+ if (IS_SDREQ_WRITE_DATA(pReq->Flags)) {
-+ // write operation
-+ }
-+ }
-+ // .... program hardware, interrupt handler will complete request
-+ return SDIO_STATUS_PENDING;
-+ }
-+
-+ @see also: SDIO_HandleHcdEvent
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: The bus driver calls the configure callback to set various options
-+ and modes in the host controller hardware.
-+
-+ @function name: Configure
-+ @prototype: SDIO_STATUS (*pConfigure) (struct _SDHCD *pHcd, PSDCONFIG pConfig)
-+ @category: HD_Reference
-+
-+ @input: pHcd - the host controller structure that was registered
-+ @input: pConfig - configuration request structure
-+
-+ @output: none
-+
-+ @return: SDIO_STATUS
-+
-+ @notes:
-+ The host controller driver recieves configuration requests for options
-+ such as slot voltage, bus width, clock rates and interrupt detection.
-+ The bus driver guarantees that only one configuration option request
-+ can be issued at a time.
-+
-+ @example: Example of a typical configure callback:
-+ SDIO_STATUS HcdConfig(PSDHCD pHcd, PSDCONFIG pConfig)
-+ {
-+ SDIO_STATUS status = SDIO_STATUS_SUCCESS;
-+ PSDHCD_DRIVER_CONTEXT pHct = (PSDHCD_DRIVER_CONTEXT)pHcd->pContext;
-+ UINT16 command;
-+ // get command
-+ command = GET_SDCONFIG_CMD(pConfig);
-+ // decode command
-+ switch (command){
-+ case SDCONFIG_GET_WP:
-+ if (GetGpioPinLevel(pHct,SDIO_CARD_WP_GPIO) == WP_POLARITY) {
-+ *((SDCONFIG_WP_VALUE *)pConfig->pData) = 1;
-+ } else {
-+ *((SDCONFIG_WP_VALUE *)pConfig->pData) = 0;
-+ }
-+ break;
-+ case SDCONFIG_SEND_INIT_CLOCKS:
-+ ClockStartStop(pHct,CLOCK_ON);
-+ // sleep a little, should be at least 80 clocks at our lowest clock setting
-+ status = OSSleep(100);
-+ ClockStartStop(pHct,CLOCK_OFF);
-+ break;
-+ case SDCONFIG_SDIO_INT_CTRL:
-+ if (GET_SDCONFIG_CMD_DATA(PSDCONFIG_SDIO_INT_CTRL_DATA,pConfig)->SlotIRQEnable) {
-+ // request to enable IRQ detection
-+ } else {
-+ // request to disable IRQ detectioon
-+ }
-+ break;
-+ case SDCONFIG_SDIO_REARM_INT:
-+ // request to re-arm the card IRQ detection logic
-+ break;
-+ case SDCONFIG_BUS_MODE_CTRL:
-+ // request to set bus mode
-+ {
-+ // get bus mode data structure
-+ PSDCONFIG_BUS_MODE_DATA pBusMode =
-+ GET_SDCONFIG_CMD_DATA(PSDCONFIG_SDIO_INT_CTRL_DATA,pConfig);
-+ // set bus mode based on settings in bus mode structure
-+ // bus mode : pBusMode->BusModeFlags
-+ // clock rate : pBusMode->ClockRate
-+ }
-+ break;
-+ case SDCONFIG_POWER_CTRL:
-+ // request to set power/voltage
-+ {
-+ PSDCONFIG_POWER_CTRL_DATA pPowerSetting =
-+ GET_SDCONFIG_CMD_DATA(PSDCONFIG_POWER_CTRL_DATA,pConfig);
-+ if (pPowerSetting->SlotPowerEnable) {
-+ // turn on slot power
-+ //
-+ } else {
-+ // turn off slot power
-+ }
-+ DBG_PRINT(PXA_TRACE_CONFIG, ("SDIO PXA255 PwrControl: En:%d, VCC:0x%X \n",
-+ pPowerSetting->SlotPowerEnable,
-+ pPowerSetting->SlotPowerVoltageMask));
-+ }
-+ break;
-+ default:
-+ // unsupported
-+ status = SDIO_STATUS_INVALID_PARAMETER;
-+ }
-+ return status;
-+ }
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+
-+
-+/*
-+ * Allocate a Device instance
-+ */
-+PSDDEVICE AllocateDevice(PSDHCD pHcd)
-+{
-+ PSDDEVICE pDevice;
-+
-+ pDevice = KernelAlloc(sizeof(SDDEVICE));
-+ if (pDevice != NULL) {
-+ InitDeviceData(pHcd,pDevice);
-+ }
-+ return pDevice;
-+}
-+
-+
-+/*
-+ * Free a Device instance
-+ */
-+void FreeDevice(PSDDEVICE pDevice)
-+{
-+ DeinitDeviceData(pDevice);
-+ KernelFree(pDevice);
-+}
-+/*
-+ * add this device to the list
-+ */
-+BOOL AddDeviceToList(PSDDEVICE pDevice)
-+{
-+ BOOL success = FALSE;
-+
-+ do {
-+ /* protect the driver list */
-+ if (!SDIO_SUCCESS(SemaphorePendInterruptable(&pBusContext->DeviceListSem))) {
-+ break; /* wait interrupted */
-+ }
-+
-+ /* add new device to the internal list */
-+ SDListAdd(&pBusContext->DeviceList , &pDevice->SDList);
-+
-+ if (!SDIO_SUCCESS(SemaphorePost(&pBusContext->DeviceListSem))) {
-+ break;
-+ }
-+
-+ success = TRUE;
-+ } while (FALSE);
-+
-+ return success;
-+}
-+
-+/*
-+ * Delete device associated with the HCD
-+ * if pHCD is NULL this function cleans up all devices, the caller
-+ * better have cleaned up functions first!
-+ */
-+SDIO_STATUS DeleteDevices(PSDHCD pHcd)
-+{
-+ SDIO_STATUS status;
-+ PSDDEVICE pDevice;
-+ DBG_PRINT(SDDBG_TRACE, ("+SDIO Bus Driver: DeleteDevices hcd:0x%X \n", (INT)pHcd));
-+ /* protect the device list */
-+ if (!SDIO_SUCCESS((status = SemaphorePendInterruptable(&pBusContext->DeviceListSem)))) {
-+ goto cleanup; /* wait interrupted */
-+ }
-+ SDITERATE_OVER_LIST_ALLOW_REMOVE(&pBusContext->DeviceList,pDevice,SDDEVICE,SDList) {
-+ /* only remove devices for the hcd or if we are cleaning up all */
-+ if ((NULL == pHcd) || (pDevice->pHcd == pHcd)) {
-+ SDListRemove(&pDevice->SDList);
-+ DeinitDeviceData(pDevice);
-+ FreeDevice(pDevice);
-+ }
-+ }SDITERATE_END;
-+ if (!SDIO_SUCCESS((status = SemaphorePost(&pBusContext->DeviceListSem)))) {
-+ goto cleanup; /* wait interrupted */
-+ }
-+ DBG_PRINT(SDDBG_TRACE, ("-SDIO Bus Driver: DeleteDevices \n"));
-+ return status;
-+cleanup:
-+ DBG_PRINT(SDDBG_ERROR, ("-SDIO Bus Driver: DeleteDevice, error exit 0x%X\n", status));
-+ return status;
-+}
-+
-+
-+static SDIO_STATUS AllocateBusResources(void)
-+{
-+ INT ii;
-+ PSDREQUEST pReq;
-+ PSIGNAL_ITEM pSignal;
-+
-+ DBG_PRINT(SDDBG_TRACE,
-+ ("+SDIO Bus Driver: AllocateBusResources (R:%d,S:%d) (CR:%d,MR:%d)(CS:%d,MS:%d) \n",
-+ pBusContext->RequestListSize,
-+ pBusContext->SignalSemListSize,
-+ pBusContext->CurrentRequestAllocations,pBusContext->MaxRequestAllocations,
-+ pBusContext->CurrentSignalAllocations,pBusContext->MaxSignalAllocations));
-+
-+ /* allocate some initial requests */
-+ for (ii = 0; ii < pBusContext->RequestListSize; ii++) {
-+ pReq = AllocateRequest();
-+ if (pReq == NULL) {
-+ break;
-+ }
-+ /* free requests adds the request to the list */
-+ FreeRequest(pReq);
-+ }
-+
-+ for (ii = 0; ii < pBusContext->SignalSemListSize; ii++) {
-+ pSignal = AllocateSignal();
-+ if (pSignal == NULL) {
-+ break;
-+ }
-+ /* freeing it adds it to the list */
-+ FreeSignal(pSignal);
-+ }
-+
-+ DBG_PRINT(SDDBG_TRACE, ("-SDIO Bus Driver: AllocateBusResources\n"));
-+ return SDIO_STATUS_SUCCESS;
-+}
-+
-+
-+/* cleanup bus resources */
-+static void CleanUpBusResources(void)
-+{
-+ PSDLIST pItem;
-+ PSDREQUEST pReq;
-+ PSIGNAL_ITEM pSignal;
-+
-+ DBG_PRINT(SDDBG_TRACE, ("+SDIO Bus Driver: CleanUpBusResources (CR:%d,MR:%d)(CS:%d,MS:%d) \n",
-+ pBusContext->CurrentRequestAllocations,pBusContext->MaxRequestAllocations,
-+ pBusContext->CurrentSignalAllocations,pBusContext->MaxSignalAllocations));
-+
-+ while(1) {
-+ pItem = SDListRemoveItemFromHead(&pBusContext->RequestList);
-+ if (NULL == pItem) {
-+ break;
-+ }
-+ /* free the request */
-+ pReq = CONTAINING_STRUCT(pItem, SDREQUEST, SDList);
-+ if (pReq->InternalFlags & SDBD_ALLOC_IRQ_SAFE_MASK) {
-+ KernelFreeIrqSafe(pReq);
-+ } else {
-+ KernelFree(pReq);
-+ }
-+ pBusContext->CurrentRequestAllocations--;
-+ }
-+
-+ if (pBusContext->CurrentRequestAllocations != 0) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Request allocations are not ZERO! (CR:%d)\n",
-+ pBusContext->CurrentRequestAllocations));
-+ }
-+
-+ while(1) {
-+ pItem = SDListRemoveItemFromHead(&pBusContext->SignalList);
-+ if (NULL == pItem) {
-+ break;
-+ }
-+ pSignal = CONTAINING_STRUCT(pItem, SIGNAL_ITEM, SDList);
-+ DestroySignal(pSignal);
-+ pBusContext->CurrentSignalAllocations--;
-+ }
-+
-+ if (pBusContext->CurrentSignalAllocations != 0) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Signal allocations are not ZERO! (CR:%d)\n",
-+ pBusContext->CurrentRequestAllocations));
-+ }
-+
-+ DBG_PRINT(SDDBG_TRACE, ("-SDIO Bus Driver: CleanUpBusResources\n"));
-+}
-+
-+
-+/* free a request to the lookaside list */
-+void FreeRequest(PSDREQUEST pReq)
-+{
-+ SDIO_STATUS status;
-+ CT_DECLARE_IRQ_SYNC_CONTEXT();
-+
-+ status = CriticalSectionAcquireSyncIrq(&pBusContext->RequestListCritSection);
-+ /* protect request list */
-+ if (!SDIO_SUCCESS(status)) {
-+ return;
-+ }
-+
-+ if ((pBusContext->CurrentRequestAllocations <= pBusContext->MaxRequestAllocations) ||
-+ !(pReq->InternalFlags & SDBD_ALLOC_IRQ_SAFE_MASK)) {
-+ /* add it to the list */
-+ SDListAdd(&pBusContext->RequestList, &pReq->SDList);
-+ /* we will hold onto this one */
-+ pReq = NULL;
-+ } else {
-+ /* decrement count */
-+ pBusContext->CurrentRequestAllocations--;
-+ }
-+
-+ status = CriticalSectionReleaseSyncIrq(&pBusContext->RequestListCritSection);
-+
-+ if (pReq != NULL) {
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: Free Request allocation (CR:%d,MR:%d)\n",
-+ pBusContext->CurrentRequestAllocations,pBusContext->MaxRequestAllocations));
-+ if (pReq->InternalFlags & SDBD_ALLOC_IRQ_SAFE_MASK) {
-+ KernelFreeIrqSafe(pReq);
-+ } else {
-+ /* we should never free the ones that were normally allocated */
-+ DBG_ASSERT(FALSE);
-+ }
-+ }
-+}
-+
-+/* allocate a request from the lookaside list */
-+PSDREQUEST AllocateRequest(void)
-+{
-+ PSDLIST pItem;
-+ SDIO_STATUS status;
-+ PSDREQUEST pReq = NULL;
-+ ATOMIC_FLAGS internalflags;
-+ CT_DECLARE_IRQ_SYNC_CONTEXT();
-+
-+
-+ status = CriticalSectionAcquireSyncIrq(&pBusContext->RequestListCritSection);
-+
-+ if (!SDIO_SUCCESS(status)) {
-+ return NULL;
-+ }
-+
-+ if (pBusContext->InitMask & RESOURCE_INIT) {
-+ /* check the list, we are now running... */
-+ pItem = SDListRemoveItemFromHead(&pBusContext->RequestList);
-+ } else {
-+ /* we are loading the list with requests at initialization */
-+ pItem = NULL;
-+ }
-+ status = CriticalSectionReleaseSyncIrq(&pBusContext->RequestListCritSection);
-+
-+ if (pItem != NULL) {
-+ pReq = CONTAINING_STRUCT(pItem, SDREQUEST, SDList);
-+ } else {
-+ if (pBusContext->InitMask & RESOURCE_INIT) {
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: Request List empty..allocating new one (irq-safe) (CR:%d,MR:%d)\n",
-+ pBusContext->CurrentRequestAllocations,pBusContext->MaxRequestAllocations));
-+ /* the resource list was already allocated, we must be running now.
-+ * at run-time, we allocate using the safe IRQ */
-+ pReq = (PSDREQUEST)KernelAllocIrqSafe(sizeof(SDREQUEST));
-+ /* mark that this one was created using IRQ safe allocation */
-+ internalflags = SDBD_ALLOC_IRQ_SAFE_MASK;
-+ } else {
-+ /* use the normal allocation since we are called at initialization */
-+ pReq = (PSDREQUEST)KernelAlloc(sizeof(SDREQUEST));
-+ internalflags = 0;
-+ }
-+
-+ if (pReq != NULL) {
-+ pReq->InternalFlags = internalflags;
-+ /* keep track of allocations */
-+ status = CriticalSectionAcquireSyncIrq(&pBusContext->RequestListCritSection);
-+ pBusContext->CurrentRequestAllocations++;
-+ status = CriticalSectionReleaseSyncIrq(&pBusContext->RequestListCritSection);
-+ }
-+ }
-+
-+
-+ if (pReq != NULL) {
-+ /* preserve internal flags */
-+ internalflags = pReq->InternalFlags;
-+ ZERO_POBJECT(pReq);
-+ pReq->InternalFlags = internalflags;
-+ }
-+
-+ return pReq;
-+}
-+
-+void DestroySignal(PSIGNAL_ITEM pSignal)
-+{
-+ SignalDelete(&pSignal->Signal);
-+ KernelFree(pSignal);
-+}
-+
-+PSIGNAL_ITEM BuildSignal(void)
-+{
-+ PSIGNAL_ITEM pSignal;
-+
-+ pSignal = (PSIGNAL_ITEM)KernelAlloc(sizeof(SIGNAL_ITEM));
-+ if (pSignal != NULL) {
-+ /* initialize signal */
-+ if (!SDIO_SUCCESS(SignalInitialize(&pSignal->Signal))) {
-+ KernelFree(pSignal);
-+ pSignal = NULL;
-+ }
-+ }
-+ return pSignal;
-+}
-+/* free a signal*/
-+void FreeSignal(PSIGNAL_ITEM pSignal)
-+{
-+ SDIO_STATUS status;
-+ CT_DECLARE_IRQ_SYNC_CONTEXT();
-+
-+ status = CriticalSectionAcquireSyncIrq(&pBusContext->RequestListCritSection);
-+
-+ if (!SDIO_SUCCESS(status)) {
-+ return;
-+ }
-+
-+ if (pBusContext->CurrentSignalAllocations <= pBusContext->MaxSignalAllocations) {
-+ /* add it to the list */
-+ SDListAdd(&pBusContext->SignalList, &pSignal->SDList);
-+ /* flag that we are holding onto it */
-+ pSignal = NULL;
-+ } else {
-+ /* decrement count */
-+ pBusContext->CurrentSignalAllocations--;
-+ }
-+
-+ status = CriticalSectionReleaseSyncIrq(&pBusContext->RequestListCritSection);
-+
-+ if (pSignal != NULL) {
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: Free signal allocation (CS:%d,MS:%d)\n",
-+ pBusContext->CurrentSignalAllocations,pBusContext->MaxSignalAllocations));
-+ DestroySignal(pSignal);
-+ }
-+}
-+
-+/* allocate a signal from the list */
-+PSIGNAL_ITEM AllocateSignal(void)
-+{
-+ PSDLIST pItem;
-+ PSIGNAL_ITEM pSignal;
-+ SDIO_STATUS status;
-+ CT_DECLARE_IRQ_SYNC_CONTEXT();
-+
-+ status = CriticalSectionAcquireSyncIrq(&pBusContext->RequestListCritSection);
-+
-+ if (!SDIO_SUCCESS(status)) {
-+ return NULL;
-+ }
-+
-+ if (pBusContext->InitMask & RESOURCE_INIT) {
-+ /* check the list */
-+ pItem = SDListRemoveItemFromHead(&pBusContext->SignalList);
-+ } else {
-+ /* we are loading the list */
-+ pItem = NULL;
-+ }
-+
-+ status = CriticalSectionReleaseSyncIrq(&pBusContext->RequestListCritSection);
-+ if (pItem != NULL) {
-+ /* return the one from the list */
-+ pSignal = CONTAINING_STRUCT(pItem, SIGNAL_ITEM, SDList);
-+ } else {
-+ if (pBusContext->InitMask & RESOURCE_INIT) {
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: Signal List empty..allocating new one (CS:%d,MS:%d)\n",
-+ pBusContext->CurrentSignalAllocations,pBusContext->MaxSignalAllocations));
-+ }
-+ /* just allocate one */
-+ pSignal = BuildSignal();
-+ status = CriticalSectionAcquireSyncIrq(&pBusContext->RequestListCritSection);
-+ if (pSignal != NULL) {
-+ pBusContext->CurrentSignalAllocations++;
-+ }
-+ status = CriticalSectionReleaseSyncIrq(&pBusContext->RequestListCritSection);
-+ }
-+
-+
-+ return pSignal;
-+}
-+
-+/*
-+ * Issus Bus Request (exposed to function drivers)
-+*/
-+PSDREQUEST IssueAllocRequest(PSDDEVICE pDev)
-+{
-+ return AllocateRequest();
-+}
-+
-+/*
-+ * Free Request (exposed to function drivers)
-+*/
-+void IssueFreeRequest(PSDDEVICE pDev, PSDREQUEST pReq)
-+{
-+ FreeRequest(pReq);
-+}
-+
-+/*
-+ * Issus Bus Request (exposed to function drivers)
-+*/
-+SDIO_STATUS IssueBusRequest(PSDDEVICE pDev, PSDREQUEST pReq)
-+{
-+ pReq->pFunction = pDev->pFunction;
-+ return IssueRequestToHCD(pDev->pHcd,pReq);
-+}
-+
-+
-+ /* completion routine for HCD configs, this is synchronized with normal bus requests */
-+static void HcdConfigComplete(PSDREQUEST pReq)
-+{
-+
-+ pReq->Status = CALL_HCD_CONFIG((PSDHCD)pReq->pDataBuffer, (PSDCONFIG)pReq->pCompleteContext);
-+
-+ SignalSet(&((PSIGNAL_ITEM)pReq->pHcdContext)->Signal);
-+}
-+
-+SDIO_STATUS SendSyncedHcdBusConfig(PSDDEVICE pDevice, PSDCONFIG pConfig)
-+{
-+ SDIO_STATUS status = SDIO_STATUS_SUCCESS;
-+ PSDREQUEST pReq = NULL;
-+ PSIGNAL_ITEM pSignal = NULL;
-+
-+ do {
-+
-+ pSignal = AllocateSignal();
-+ if (NULL == pSignal) {
-+ status = SDIO_STATUS_NO_RESOURCES;
-+ break;
-+ }
-+
-+ pReq = AllocateRequest();
-+ if (NULL == pReq) {
-+ status = SDIO_STATUS_NO_RESOURCES;
-+ break;
-+ }
-+
-+ /* issue pseudo request to sync this with bus requests */
-+ pReq->pCompletion = HcdConfigComplete;
-+ pReq->pCompleteContext = pConfig;
-+ /* re-use hcd context to store the signal since this request
-+ * never actually goes to an HCD */
-+ pReq->pHcdContext = pSignal;
-+ pReq->pDataBuffer = pDevice->pHcd;
-+ /* flag this as barrier in case it may change the bus mode of the HCD */
-+ pReq->Flags = SDREQ_FLAGS_PSEUDO | SDREQ_FLAGS_BARRIER | SDREQ_FLAGS_TRANS_ASYNC;
-+ pReq->Status = SDIO_STATUS_SUCCESS;
-+
-+ /* issue request */
-+ status = IssueRequestToHCD(pDevice->pHcd,pReq);
-+
-+ } while (FALSE);
-+
-+ if (SDIO_SUCCESS(status)) {
-+ DBG_PRINT(SDIODBG_REQUESTS, ("SDIO Bus Driver: Config Request Sync-Op waiting....\n"));
-+ status = SignalWait(&pSignal->Signal);
-+
-+ if (SDIO_SUCCESS(status)) {
-+ /* return the result of the configuration request */
-+ status = pReq->Status;
-+ }
-+ }
-+
-+ /* cleanup */
-+ if (pReq != NULL) {
-+ FreeRequest(pReq);
-+ }
-+
-+ if (pSignal != NULL) {
-+ FreeSignal(pSignal);
-+ }
-+
-+ return status;
-+}
-+
-+/*
-+ * Issus bus Configuration (exposed to function drivers)
-+*/
-+SDIO_STATUS IssueBusConfig(PSDDEVICE pDev, PSDCONFIG pConfig)
-+{
-+ SDIO_STATUS status;
-+ INT cmdLength;
-+ UINT8 debugLevel = SDDBG_ERROR;
-+
-+ cmdLength = GET_SDCONFIG_CMD_LEN(pConfig);
-+ status = SDIO_STATUS_INVALID_PARAMETER;
-+
-+ do {
-+ /* check buffers and length */
-+ if (IS_SDCONFIG_CMD_GET(pConfig) || IS_SDCONFIG_CMD_PUT(pConfig)) {
-+ if ((GET_SDCONFIG_CMD_DATA(PVOID,pConfig) == NULL) || (0 == cmdLength)) {
-+ break;
-+ }
-+ }
-+
-+ switch (GET_SDCONFIG_CMD(pConfig)) {
-+ case SDCONFIG_FUNC_ACK_IRQ:
-+ status = SDFunctionAckInterrupt(pDev);
-+ break;
-+ case SDCONFIG_FUNC_ENABLE_DISABLE:
-+ if (cmdLength < sizeof(SDCONFIG_FUNC_ENABLE_DISABLE_DATA)) {
-+ break;
-+ }
-+ status = SDEnableFunction(pDev,
-+ GET_SDCONFIG_CMD_DATA(PSDCONFIG_FUNC_ENABLE_DISABLE_DATA,pConfig));
-+ break;
-+ case SDCONFIG_FUNC_UNMASK_IRQ:
-+ status = SDMaskUnmaskFunctionIRQ(pDev,FALSE);
-+ break;
-+ case SDCONFIG_FUNC_MASK_IRQ:
-+ status = SDMaskUnmaskFunctionIRQ(pDev,TRUE);
-+ break;
-+ case SDCONFIG_FUNC_SPI_MODE_DISABLE_CRC:
-+ status = SDSPIModeEnableDisableCRC(pDev,FALSE);
-+ break;
-+ case SDCONFIG_FUNC_SPI_MODE_ENABLE_CRC:
-+ status = SDSPIModeEnableDisableCRC(pDev,TRUE);
-+ break;
-+ case SDCONFIG_FUNC_ALLOC_SLOT_CURRENT:
-+ status = SDAllocFreeSlotCurrent(pDev,
-+ TRUE,
-+ GET_SDCONFIG_CMD_DATA(PSDCONFIG_FUNC_SLOT_CURRENT_DATA,pConfig));
-+ break;
-+ case SDCONFIG_FUNC_FREE_SLOT_CURRENT:
-+ status = SDAllocFreeSlotCurrent(pDev, FALSE, NULL);
-+ break;
-+ case SDCONFIG_FUNC_CHANGE_BUS_MODE:
-+
-+ status = SetOperationalBusMode(pDev,
-+ GET_SDCONFIG_CMD_DATA(PSDCONFIG_BUS_MODE_DATA,
-+ pConfig));
-+ break;
-+ case SDCONFIG_FUNC_NO_IRQ_PEND_CHECK:
-+ status = TryNoIrqPendingCheck(pDev);
-+ break;
-+ default:
-+
-+ if (GET_SDCONFIG_CMD(pConfig) & SDCONFIG_FLAGS_HC_CONFIG) {
-+ /* synchronize config requests with busrequests */
-+ status = SendSyncedHcdBusConfig(pDev,pConfig);
-+ } else {
-+ DBG_PRINT(SDDBG_ERROR,
-+ ("SDIO Bus Driver: IssueBusConfig - unknown command:0x%X \n",
-+ GET_SDCONFIG_CMD(pConfig)));
-+ status = SDIO_STATUS_INVALID_PARAMETER;
-+ }
-+ break;
-+ }
-+ } while(FALSE);
-+
-+ if (!SDIO_SUCCESS(status)) {
-+
-+ if(status == SDIO_STATUS_FUNC_ENABLE_TIMEOUT ){ /* reduce debug level to avoid timeout error messages */
-+ debugLevel = SDDBG_TRACE;
-+ }
-+
-+
-+ DBG_PRINT(debugLevel,
-+ ("SDIO Bus Driver: IssueBusConfig - Error in command:0x%X, Buffer:0x%X, Length:%d Err:%d\n",
-+ GET_SDCONFIG_CMD(pConfig),
-+ GET_SDCONFIG_CMD_DATA(INT,pConfig),
-+ cmdLength, status));
-+ }
-+ return status;
-+}
-+
-+/* start a request */
-+static INLINE SDIO_STATUS StartHcdRequest(PSDHCD pHcd, PSDREQUEST pReq)
-+{
-+ SDIO_STATUS status = SDIO_STATUS_SUCCESS;
-+ CT_DECLARE_IRQ_SYNC_CONTEXT();
-+
-+ if ((pReq->pFunction != NULL) && (pReq->pFunction->Flags & SDFUNCTION_FLAG_REMOVING)) {
-+ /* this device or function is going away, fail any new requests */
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: StartHcdRequest, fail request 0x%X, device is removing\n", (UINT)pReq));
-+ pReq->Status = SDIO_STATUS_CANCELED;
-+ return SDIO_STATUS_SDREQ_QUEUE_FAILED;
-+ }
-+
-+ status = _AcquireHcdLock(pHcd);
-+
-+ if (!SDIO_SUCCESS(status)) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to acquire HCD request lock: Err:%d\n", status));
-+ pReq->Status = SDIO_STATUS_SDREQ_QUEUE_FAILED;
-+ return SDIO_STATUS_SDREQ_QUEUE_FAILED;
-+ }
-+
-+ if (pReq->Flags & SDREQ_FLAGS_QUEUE_HEAD) {
-+ /* caller wants this request queued to the head */
-+
-+ /* a completion routine for a barrier request is called
-+ * while the queue is busy. A barrier request can
-+ * insert a new request at the head of the queue */
-+ DBG_ASSERT(IsQueueBusy(&pHcd->RequestQueue));
-+ QueueRequestToFront(&pHcd->RequestQueue,pReq);
-+ } else {
-+ /* insert in queue at tail */
-+ QueueRequest(&pHcd->RequestQueue,pReq);
-+
-+ /* is queue busy ? */
-+ if (IsQueueBusy(&pHcd->RequestQueue)) {
-+ /* release lock */
-+ status = _ReleaseHcdLock(pHcd);
-+ /* controller is busy already, no need to call the hcd */
-+ return SDIO_STATUS_PENDING;
-+ }
-+ /* mark it as busy */
-+ MarkQueueBusy(&pHcd->RequestQueue);
-+ }
-+
-+ /* remove item from head and set current request */
-+ SET_CURRENT_REQUEST(pHcd, DequeueRequest(&pHcd->RequestQueue));
-+ if (CHECK_API_VERSION_COMPAT(pHcd,2,6)) {
-+ CHECK_HCD_RECURSE(pHcd, pHcd->pCurrentRequest);
-+ }
-+ /* release lock */
-+ status = _ReleaseHcdLock(pHcd);
-+ /* controller was not busy, call into HCD to process current request */
-+ status = CallHcdRequest(pHcd);
-+ return status;
-+}
-+
-+
-+/* used by CMD12,CMD13 to save the original completion routine */
-+#define GET_BD_RSV_REQUEST_COMPLETION(pR) (PSDEQUEST_COMPLETION)(pR)->pBdRsv1
-+#define SET_BD_RSV_REQUEST_COMPLETION(pR,c) (pR)->pBdRsv1 = (PVOID)(c)
-+
-+/* used by CMD12 processing to save/restore the original data transfer status */
-+#define GET_BD_RSV_ORIG_STATUS(pR) (SDIO_STATUS)(pR)->pBdRsv2
-+#define SET_BD_RSV_ORIG_STATUS(pR,s) (pR)->pBdRsv2 = (PVOID)(s)
-+
-+/* used by CMD13 processing to get/set polling count */
-+#define GET_BD_RSV_STATUS_POLL_COUNT(pR) (INT)(pR)->pBdRsv2
-+#define SET_BD_RSV_STATUS_POLL_COUNT(pR,s) (pR)->pBdRsv2 = (PVOID)(s)
-+
-+/* used by CMD55 processing to save the second part of the request */
-+#define GET_BD_RSV_ORIG_REQ(pR) (PSDREQUEST)(pR)->pBdRsv1
-+#define SET_BD_RSV_ORIG_REQ(pR,r) (pR)->pBdRsv1 = (PVOID)(r)
-+
-+/* used by all to save HCD */
-+#define GET_BD_RSV_HCD(pR) (PSDHCD)(pR)->pBdRsv3
-+#define SET_BD_RSV_HCD(pR,h) (pR)->pBdRsv3 = (PVOID)(h)
-+
-+static void CMD13CompletionBarrier(PSDREQUEST pReq);
-+
-+static INLINE void SetupCMD13(PSDHCD pHcd, PSDREQUEST pReq)
-+{
-+ pReq->Command = CMD13;
-+ /* sequence must be atomic, queue it to the head and flag as a barrier */
-+ pReq->Flags = SDREQ_FLAGS_QUEUE_HEAD | SDREQ_FLAGS_BARRIER | SDREQ_FLAGS_TRANS_ASYNC;
-+ if (IS_HCD_BUS_MODE_SPI(pHcd)) {
-+ pReq->Argument = 0;
-+ pReq->Flags |= SDREQ_FLAGS_RESP_R2;
-+ } else {
-+ pReq->Flags |= SDREQ_FLAGS_RESP_R1;
-+ pReq->Argument |= pHcd->CardProperties.RCA << 16;
-+ }
-+ /* insert completion */
-+ pReq->pCompletion = CMD13CompletionBarrier;
-+}
-+
-+/* CMD13 (GET STATUS) completion */
-+static void CMD13CompletionBarrier(PSDREQUEST pReq)
-+{
-+ PSDEQUEST_COMPLETION pOrigCompletion = GET_BD_RSV_REQUEST_COMPLETION(pReq);
-+ PSDHCD pHcd = GET_BD_RSV_HCD(pReq);
-+ INT pollingCount = GET_BD_RSV_STATUS_POLL_COUNT(pReq);
-+ BOOL doCompletion = TRUE;
-+ UINT32 cardStatus;
-+
-+ DBG_ASSERT(pOrigCompletion != NULL);
-+ DBG_ASSERT(pHcd != NULL);
-+ DBG_PRINT(SDIODBG_REQUESTS, ("+SDIO Bus Driver: CMD13CompletionBarrier (cnt:%d) \n",pollingCount));
-+
-+ do {
-+ if (!SDIO_SUCCESS(pReq->Status)) {
-+ break;
-+ }
-+
-+ cardStatus = SD_R1_GET_CARD_STATUS(pReq->Response);
-+
-+ if (cardStatus & SD_CS_TRANSFER_ERRORS) {
-+ DBG_PRINT(SDIODBG_REQUESTS,("SDIO Bus Driver: Card transfer errors : 0x%X \n",cardStatus));
-+ pReq->Status = SDIO_STATUS_PROGRAM_STATUS_ERROR;
-+ break;
-+ }
-+
-+ if (SD_CS_GET_STATE(cardStatus) != SD_CS_STATE_PRG) {
-+ DBG_PRINT(SDIODBG_REQUESTS,("SDIO Bus Driver: Card programming done \n"));
-+ break;
-+ }
-+
-+ DBG_PRINT(SDIODBG_REQUESTS, ("SDIO Bus Driver: Card still programming.. \n"));
-+ pollingCount--;
-+
-+ if (pollingCount < 0) {
-+ pReq->Status = SDIO_STATUS_PROGRAM_TIMEOUT;
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: card programming timeout!\n"));
-+ break;
-+ }
-+
-+ doCompletion = FALSE;
-+ /* keep trying */
-+ SET_BD_RSV_STATUS_POLL_COUNT(pReq, pollingCount);
-+ SetupCMD13(pHcd,pReq);
-+ DBG_PRINT(SDIODBG_REQUESTS, ("SDIO Bus Driver: re-issuing CMD13 \n"));
-+ /* re-issue */
-+ IssueRequestToHCD(pHcd, pReq);
-+
-+ } while (FALSE);
-+
-+
-+ if (doCompletion) {
-+ /* restore original completion routine */
-+ pReq->pCompletion = pOrigCompletion;
-+ /* call original completion routine */
-+ pOrigCompletion(pReq);
-+ }
-+
-+ DBG_PRINT(SDIODBG_REQUESTS, ("-SDIO Bus Driver: CMD13CompletionBarrier \n"));
-+}
-+
-+/* command 13 (GET STATUS) preparation */
-+static void PrepCMD13Barrier(PSDREQUEST pReq)
-+{
-+ SDIO_STATUS status = pReq->Status;
-+ PSDHCD pHcd = GET_BD_RSV_HCD(pReq);
-+ INT pollingCount;
-+ PSDEQUEST_COMPLETION pOrigCompletion = GET_BD_RSV_REQUEST_COMPLETION(pReq);
-+
-+ DBG_ASSERT(pHcd != NULL);
-+ DBG_ASSERT(pOrigCompletion != NULL);
-+
-+ DBG_PRINT(SDIODBG_REQUESTS, ("+SDIO Bus Driver: PrepCMD13Barrier \n"));
-+
-+ if (SDIO_SUCCESS(status)) {
-+ /* re-use the request for CMD13 */
-+ SetupCMD13(pHcd,pReq);
-+ /* set polling count to a multiple of the Block count, if the BlockCount was
-+ * zeroed by the HCD, then set it to 1X multiplier */
-+ pollingCount = max(pBusContext->CMD13PollingMultiplier,
-+ pBusContext->CMD13PollingMultiplier * (INT)pReq->BlockCount);
-+ /* initialize count */
-+ SET_BD_RSV_STATUS_POLL_COUNT(pReq, pollingCount);
-+ /* re-issue it, we can call IssueRequest here since we are re-using the request */
-+ IssueRequestToHCD(pHcd, pReq);
-+ } else {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Request Failure (%d) , CMD13 bypassed.\n",status));
-+ /* call the original completion routine */
-+ pOrigCompletion(pReq);
-+ }
-+
-+ DBG_PRINT(SDIODBG_REQUESTS, ("-SDIO Bus Driver: PrepCMD13Barrier (%d) \n",status));
-+}
-+
-+/* CMD12 completion */
-+static void CMD12Completion(PSDREQUEST pReq)
-+{
-+ PSDEQUEST_COMPLETION pOrigCompletion = GET_BD_RSV_REQUEST_COMPLETION(pReq);
-+
-+ DBG_ASSERT(pOrigCompletion != NULL);
-+
-+ DBG_PRINT(SDIODBG_REQUESTS, ("+SDIO Bus Driver: CMD12Completion \n"));
-+
-+ /* restore original completion routine */
-+ pReq->pCompletion = pOrigCompletion;
-+
-+ if (SDIO_SUCCESS(pReq->Status)) {
-+ /* if CMD12 succeeds, we want to return the result of the original
-+ * request */
-+ pReq->Status = GET_BD_RSV_ORIG_STATUS(pReq);
-+ DBG_PRINT(SDIODBG_REQUESTS,
-+ ("SDIO Bus Driver: PrepCMD12Completion original status %d \n",pReq->Status));
-+ }
-+ /* call original completion routine */
-+ pOrigCompletion(pReq);
-+
-+ DBG_PRINT(SDIODBG_REQUESTS, ("-SDIO Bus Driver: CMD12Completion \n"));
-+}
-+
-+/* CMD12 preparation */
-+static void PrepCMD12Barrier(PSDREQUEST pReq)
-+{
-+
-+ SDIO_STATUS status = pReq->Status;
-+ PSDHCD pHcd = GET_BD_RSV_HCD(pReq);
-+ PSDEQUEST_COMPLETION pOrigCompletion = GET_BD_RSV_REQUEST_COMPLETION(pReq);
-+
-+ DBG_ASSERT(pHcd != NULL);
-+ DBG_ASSERT(pOrigCompletion != NULL);
-+
-+ DBG_PRINT(SDIODBG_REQUESTS, ("+SDIO Bus Driver: PrepCMD12Barrier \n"));
-+
-+ if (SDIO_SUCCESS(status) || /* only issue CMD12 on success or specific bus errors */
-+ (SDIO_STATUS_BUS_READ_TIMEOUT == status) ||
-+ (SDIO_STATUS_BUS_READ_CRC_ERR == status) ||
-+ (SDIO_STATUS_BUS_WRITE_ERROR == status)) {
-+ if (!CHECK_API_VERSION_COMPAT(pHcd,2,6)) {
-+ if (!ForceAllRequestsAsync()) {
-+ /* clear the call bit as an optimization, note clearing it wholesale here will
-+ * allow request processing to recurse one more level */
-+ AtomicTest_Clear(&pHcd->HcdFlags, HCD_REQUEST_CALL_BIT);
-+ }
-+ }
-+ /* re-use the request for CMD12 */
-+ pReq->Command = CMD12;
-+ pReq->Argument = 0;
-+
-+ /* if the data transfer was successful, check for transfer check */
-+ if (SDIO_SUCCESS(status) &&
-+ (pReq->Flags & SDREQ_FLAGS_AUTO_TRANSFER_STATUS)) {
-+ /* original data request requires a transfer status check, which is another
-+ * barrier request */
-+ pReq->Flags = SDREQ_FLAGS_RESP_R1B | SDREQ_FLAGS_QUEUE_HEAD | SDREQ_FLAGS_BARRIER |
-+ SDREQ_FLAGS_TRANS_ASYNC;
-+ DBG_PRINT(SDIODBG_REQUESTS, ("-SDIO Bus Driver: PrepCMD12Barrier , chaining CMD13 \n"));
-+ /* switch out completion to send the CMD13 next */
-+ pReq->pCompletion = PrepCMD13Barrier;
-+ } else {
-+ pReq->Flags = SDREQ_FLAGS_RESP_R1B | SDREQ_FLAGS_QUEUE_HEAD | SDREQ_FLAGS_TRANS_ASYNC;
-+ pReq->pCompletion = CMD12Completion;
-+ }
-+
-+ /* save the original data transfer request status */
-+ SET_BD_RSV_ORIG_STATUS(pReq,status);
-+ /* re-issue it, we can call IssueRequest here since we are re-using the request */
-+ IssueRequestToHCD(pHcd, pReq);
-+ } else {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Request Failure (%d) , CMD12 bypassed.\n",status));
-+ /* call the original completion routine */
-+ pOrigCompletion(pReq);
-+ }
-+
-+ DBG_PRINT(SDIODBG_REQUESTS, ("-SDIO Bus Driver: PrepCMD12Barrier (%d) \n",status));
-+}
-+
-+
-+/* CMD55 barrier - this is a special barrier completion routine, we have to submit the second
-+ * part of the command command sequence atomically */
-+static void CMD55CompletionBarrier(PSDREQUEST pReq)
-+{
-+ SDIO_STATUS status = pReq->Status;
-+ PSDREQUEST pOrigReq = GET_BD_RSV_ORIG_REQ(pReq);
-+ PSDHCD pHcd = GET_BD_RSV_HCD(pReq);
-+ BOOL doCompletion = FALSE;
-+
-+ DBG_ASSERT(pOrigReq != NULL);
-+ DBG_ASSERT(pHcd != NULL);
-+
-+ DBG_PRINT(SDIODBG_REQUESTS, ("+SDIO Bus Driver: CMD55Completion \n"));
-+
-+ do {
-+
-+ if (!SDIO_SUCCESS(status)) {
-+ /* command 55 failed */
-+ pOrigReq->Status = status;
-+ doCompletion = TRUE;
-+ break;
-+ }
-+
-+ if (!(SD_R1_GET_CARD_STATUS(pReq->Response) & SD_CS_APP_CMD)) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Card is not accepting CMD55, status:0x%X \n",
-+ SD_R1_GET_CARD_STATUS(pReq->Response)));
-+ pOrigReq->Status = SDIO_STATUS_INVALID_COMMAND;
-+ doCompletion = TRUE;
-+ break;
-+ }
-+
-+ if (!CHECK_API_VERSION_COMPAT(pHcd,2,6)) {
-+ if (!ForceAllRequestsAsync()) {
-+ AtomicTest_Clear(&pHcd->HcdFlags, HCD_REQUEST_CALL_BIT);
-+ }
-+ }
-+
-+ /* flag the original request to queue to the head */
-+ pOrigReq->Flags |= SDREQ_FLAGS_QUEUE_HEAD;
-+ /* submit original request, we cannot call IssueRequestHCD() here because the
-+ * original request has already gone through IssueRequestHCD() already */
-+ status = StartHcdRequest(pHcd, pOrigReq);
-+
-+ if (SDIO_STATUS_PENDING == status) {
-+ break;
-+ }
-+
-+ pOrigReq->Status = status;
-+
-+ if (SDIO_STATUS_SDREQ_QUEUE_FAILED == status) {
-+ /* never made it to the queue */
-+ doCompletion = TRUE;
-+ break;
-+ }
-+
-+ /* request completed in-line */
-+ _SDIO_HandleHcdEvent(pHcd, EVENT_HCD_TRANSFER_DONE);
-+
-+ } while (FALSE);
-+
-+ if (doCompletion) {
-+ DoRequestCompletion(pOrigReq, pHcd);
-+ }
-+
-+ /* free the CMD55 request */
-+ FreeRequest(pReq);
-+
-+ DBG_PRINT(SDIODBG_REQUESTS, ("-SDIO Bus Driver: CMD55Completion \n"));
-+}
-+
-+
-+/* synch completion routine */
-+static void SynchCompletion(PSDREQUEST pRequest)
-+{
-+ PSIGNAL_ITEM pSignal;
-+
-+ pSignal = (PSIGNAL_ITEM)pRequest->pCompleteContext;
-+ DBG_ASSERT(pSignal != NULL);
-+ if (!SDIO_SUCCESS(SignalSet(&pSignal->Signal))) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: SynchCompletion - signal failed \n"));
-+ }
-+
-+}
-+
-+/*
-+ * Issue a request to the host controller
-+ *
-+ *
-+ * The following flags are handled internally by the bus driver to guarantee atomicity.
-+ *
-+ * SDREQ_FLAGS_APP_CMD - SD Extended commands requiring CMD55 to precede the actual command
-+ * SDREQ_FLAGS_AUTO_CMD12 - Memory Card Data transfer needs CMD12 to stop transfer
-+ * (multi-block reads/writes)
-+ * SDREQ_FLAGS_AUTO_TRANSFER_STATUS - Memory card data transfer needs transfer status polling
-+ * using CMD13
-+ *
-+ * These request flags require additional commands prepended or appended to the original command
-+ *
-+ * The order of command execution :
-+ *
-+ * Order Condition Command Issued
-+ * -------------------------------------------------------------
-+ * 1. If APP_CMD CMD55 issued.
-+ * 2. Always Caller command issued.
-+ * 3. If AUTO_CMD12 CMD12 issued.
-+ * 4. If AUTO_TRANSFER_STATUS CMD13 issued until card programming is complete
-+*/
-+SDIO_STATUS IssueRequestToHCD(PSDHCD pHcd, PSDREQUEST pReq)
-+{
-+ SDIO_STATUS status = SDIO_STATUS_SUCCESS;
-+ PSIGNAL_ITEM pSignal = NULL;
-+ BOOL handleFailedReqSubmit = FALSE;
-+
-+ CLEAR_INTERNAL_REQ_FLAGS(pReq);
-+
-+ do {
-+ /* mark request in-use */
-+ ATOMIC_FLAGS internal = AtomicTest_Set(&pReq->InternalFlags, SDBD_PENDING);
-+ if (internal & (1<<SDBD_PENDING)) {
-+ DBG_ASSERT_WITH_MSG(FALSE,
-+ "SDIO Bus Driver: IssueRequestToHCD - request already in use \n");
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Request already in use: 0x%X",(INT)pReq));
-+ }
-+
-+ if (!(pReq->Flags & SDREQ_FLAGS_TRANS_ASYNC)) {
-+ /* caller wants synchronous operation, insert our completion routine */
-+ pReq->pCompletion = SynchCompletion;
-+ pSignal = AllocateSignal();
-+ if (NULL == pSignal) {
-+ status = SDIO_STATUS_NO_RESOURCES;
-+ pReq->Status = SDIO_STATUS_NO_RESOURCES;
-+ handleFailedReqSubmit = TRUE;
-+ /* no need to continue */
-+ break;
-+ }
-+ pReq->pCompleteContext = (PVOID)pSignal;
-+ }
-+
-+ if ((pReq->Flags & SDREQ_FLAGS_AUTO_CMD12) &&
-+ !(pHcd->Attributes & SDHCD_ATTRIB_AUTO_CMD12) &&
-+ !(IS_HCD_BUS_MODE_SPI(pHcd) && IS_SDREQ_WRITE_DATA(pReq->Flags))) {
-+ DBG_PRINT(SDIODBG_REQUESTS, ("SDIO Bus Driver: Auto CMD12 on Request:0x%08X \n",(INT)pReq));
-+ /* caller wants CMD12 auto-issued and the HCD does not support it */
-+ /* setup caller's request as a barrier and replace their completion routine */
-+ pReq->Flags |= SDREQ_FLAGS_BARRIER;
-+ /* take off the flag, since the BD will be issuing it */
-+ pReq->Flags &= ~SDREQ_FLAGS_AUTO_CMD12;
-+ /* save original completion */
-+ SET_BD_RSV_REQUEST_COMPLETION(pReq,pReq->pCompletion);
-+ /* save the HCD we are on */
-+ SET_BD_RSV_HCD(pReq,pHcd);
-+ /* use completion for preping CMD12 */
-+ pReq->pCompletion = PrepCMD12Barrier;
-+ }
-+
-+ if (pReq->Flags & SDREQ_FLAGS_AUTO_TRANSFER_STATUS) {
-+ /* caller wants transfer status checked. If a CMD12
-+ * barrier request has been setup we let the CMD12 completion take care
-+ * of setting up the transfer check */
-+ if (pReq->pCompletion != PrepCMD12Barrier) {
-+ /* make CMD13 prep a barrier */
-+ pReq->Flags |= SDREQ_FLAGS_BARRIER;
-+ /* save original completion */
-+ SET_BD_RSV_REQUEST_COMPLETION(pReq,pReq->pCompletion);
-+ /* save the HCD we are on */
-+ SET_BD_RSV_HCD(pReq,pHcd);
-+ /* use completion for preping CMD13 */
-+ pReq->pCompletion = PrepCMD13Barrier;
-+ }
-+ }
-+
-+ /* check app command, the two command sequence must be handled atomically */
-+ if (pReq->Flags & SDREQ_FLAGS_APP_CMD) {
-+ PSDREQUEST pCmd55;
-+ /* allocate request to handle initial CMD55 command */
-+ pCmd55 = AllocateRequest();
-+ if (NULL == pCmd55) {
-+ status = SDIO_STATUS_NO_RESOURCES;
-+ pReq->Status = SDIO_STATUS_NO_RESOURCES;
-+ /* complete the caller's request with error */
-+ handleFailedReqSubmit = TRUE;
-+ /* no need to continue */
-+ break;
-+ }
-+ /* first submit CMD55 */
-+ /* set RCA */
-+ pCmd55->Argument = pHcd->CardProperties.RCA << 16;
-+ /* mark as a barrier request */
-+ pCmd55->Flags = SDREQ_FLAGS_RESP_R1 | SDREQ_FLAGS_BARRIER | SDREQ_FLAGS_TRANS_ASYNC;
-+ pCmd55->Command = CMD55;
-+ /* call our barrier completion routine when done */
-+ pCmd55->pCompletion = CMD55CompletionBarrier;
-+ /* save request and target HCD */
-+ SET_BD_RSV_ORIG_REQ(pCmd55,pReq);
-+ SET_BD_RSV_HCD(pCmd55,pHcd);
-+ /* recursively start the CMD55 request, since the CMD55 is a barrier
-+ * request, it's completion routine will submit the actual request
-+ * atomically */
-+ status = IssueRequestToHCD(pHcd, pCmd55);
-+
-+ } else {
-+ /* start the normal request */
-+ status = StartHcdRequest(pHcd,pReq);
-+ }
-+
-+
-+ if (SDIO_STATUS_SDREQ_QUEUE_FAILED == status) {
-+ handleFailedReqSubmit = TRUE;
-+ /* no need to continue, clean up at the end */
-+ break;
-+ }
-+
-+ /* at this point, the request was either queued or was processed by the
-+ * HCD */
-+
-+ DBG_PRINT(SDIODBG_REQUESTS, ("SDIO Bus Driver: HCD returned status:%d on request: 0x%X, (CMD:%d) \n",
-+ status, (INT)pReq, pReq->Command));
-+
-+ if (status != SDIO_STATUS_PENDING) {
-+ /* the HCD completed the request within the HCD request callback,
-+ * check and see if this is a synchronous request */
-+ if (pSignal != NULL) {
-+ /* it was synchronous */
-+ DBG_PRINT(SDIODBG_REQUESTS, ("SDIO Bus Driver: Sync-Op signal wait bypassed \n"));
-+ /* NULL out completion info, there's no need to
-+ * signal the semaphore */
-+ pReq->pCompletion = NULL;
-+
-+ } else {
-+ DBG_PRINT(SDIODBG_REQUESTS, ("SDIO Bus Driver: Async operation completed in-line \n"));
-+ /* this was an async call, always return pending */
-+ status = SDIO_STATUS_PENDING;
-+ }
-+ /* process this completed transfer on behalf of the HCD */
-+ _SDIO_HandleHcdEvent(pHcd, EVENT_HCD_TRANSFER_DONE);
-+
-+ /* done processing */
-+ break;
-+ }
-+ /* I/O is now pending, could be sync or async */
-+ /* check for synch op */
-+ if (pSignal != NULL) {
-+ /* wait for completion */
-+ DBG_PRINT(SDIODBG_REQUESTS, ("SDIO Bus Driver: Sync-Op signal waiting....\n"));
-+ /* this is not interruptable, as the HCD must complete it. */
-+ status = SignalWait(&pSignal->Signal);
-+ /* don't need the signal anymore */
-+ FreeSignal(pSignal);
-+ pSignal = NULL;
-+
-+ /* note: it is safe to touch pReq since we own
-+ * the completion routine for synch transfers */
-+
-+ /* check signal wait status */
-+ if (!SDIO_SUCCESS(status)) {
-+ DBG_PRINT(SDDBG_TRACE,
-+ ("SDIO Bus Driver - IssueRequestToHCD: Synch transfer - signal wait failed, cancelling req 0X%X\n",
-+ (UINT)pReq));
-+ pReq->Status = SDIO_STATUS_CANCELED;
-+ status = SDIO_STATUS_CANCELED;
-+ break;
-+ }
-+ DBG_PRINT(SDIODBG_REQUESTS, ("SDIO Bus Driver: Sync-Op woke up\n"));
-+ /* return the completion status of the request */
-+ status = pReq->Status;
-+ } else {
-+ DBG_PRINT(SDIODBG_REQUESTS, ("SDIO Bus Driver: Async operation Pending \n"));
-+ }
-+
-+ } while (FALSE);
-+
-+ /* see if we need to clean up failed submissions */
-+ if (handleFailedReqSubmit) {
-+ /* make sure this is cleared */
-+ AtomicTest_Clear(&pReq->InternalFlags, SDBD_PENDING);
-+ /* the request processing failed before it was submitted to the HCD */
-+ /* note: since it never made it to the queue we can touch pReq */
-+ if (pReq->Flags & SDREQ_FLAGS_TRANS_ASYNC) {
-+ /* for ASYNC requests, we need to call the completion routine */
-+ DoRequestCompletion(pReq, pHcd);
-+ /* return pending for all ASYNC requests */
-+ status = SDIO_STATUS_PENDING;
-+ }
-+ }
-+
-+ /* check if we need to clean up the signal */
-+ if (pSignal != NULL) {
-+ /* make sure this is freed */
-+ FreeSignal(pSignal);
-+ }
-+ /* return status */
-+ return status;
-+}
-+
-+/* documentation for configuration requests */
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Enable or Disable the SDIO Function
-+
-+ @function name: SDCONFIG_FUNC_ENABLE_DISABLE
-+ @prototype: SDCONFIG_FUNC_ENABLE_DISABLE
-+ @category: PD_Reference
-+
-+ @input: SDCONFIG_FUNC_ENABLE_DISABLE_DATA - Enable Data structure
-+
-+ @output: none
-+
-+ @return: SDIO Status
-+
-+ @notes: This command code is used in the SDLIB_IssueConfig() API. The command
-+ uses the SDCONFIG_FUNC_ENABLE_DISABLE_DATA structure. The caller must set the
-+ EnableFlags and specify the TimeOut value in milliseconds. The TimeOut
-+ value is used for polling the I/O ready bit. This command returns a status
-+ of SDIO_STATUS_FUNC_ENABLE_TIMEOUT if the ready bit was not set/cleared
-+ by the card within the timeout period.
-+
-+ @example: Example of enabling an I/O function:
-+ fData.EnableFlags = SDCONFIG_ENABLE_FUNC;
-+ fData.TimeOut = 500;
-+ status = SDLIB_IssueConfig(pInstance->pDevice,
-+ SDCONFIG_FUNC_ENABLE_DISABLE,
-+ &fData,
-+ sizeof(fData));
-+
-+ @see also: SDLIB_IssueConfig
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+
-+
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Unmask the function's IRQ
-+
-+ @function name: SDCONFIG_FUNC_UNMASK_IRQ
-+ @prototype: SDCONFIG_FUNC_UNMASK_IRQ
-+ @category: PD_Reference
-+
-+ @input: none
-+
-+ @output: none
-+
-+ @return: SDIO Status
-+
-+ @notes: This command code is used in the SDLIB_IssueConfig() API. The command
-+ unmasks the IRQ for the I/O function. This request sets the function's
-+ interrupt enable bit in the INTENABLE register in the
-+ common register space.
-+
-+ @example: Example of unmasking interrupt :
-+ status = SDLIB_IssueConfig(pInstance->pDevice,
-+ SDCONFIG_FUNC_UNMASK_IRQ,
-+ NULL,
-+ 0);
-+
-+ @see also: SDCONFIG_FUNC_MASK_IRQ
-+ @see also: SDLIB_IssueConfig
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Mask the function's IRQ
-+
-+ @function name: SDCONFIG_FUNC_MASK_IRQ
-+ @prototype: SDCONFIG_FUNC_MASK_IRQ
-+ @category: PD_Reference
-+
-+ @input: none
-+
-+ @output: none
-+
-+ @return: SDIO Status
-+
-+ @notes: This command code is used in the SDLIB_IssueConfig() API. The command
-+ masks the IRQ for the I/O function.
-+
-+ @example: Example of unmasking interrupt :
-+ status = SDLIB_IssueConfig(pInstance->pDevice,
-+ SDCONFIG_FUNC_MASK_IRQ,
-+ NULL,
-+ 0);
-+
-+ @see also: SDCONFIG_FUNC_UNMASK_IRQ
-+ @see also: SDLIB_IssueConfig
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Acknowledge that the function's IRQ has been handled
-+
-+ @function name: SDCONFIG_FUNC_ACK_IRQ
-+ @prototype: SDCONFIG_FUNC_ACK_IRQ
-+ @category: PD_Reference
-+
-+ @input: none
-+
-+ @output: none
-+
-+ @return: SDIO Status
-+
-+ @notes: This command code is used in the SDLIB_IssueConfig() API. The command
-+ indicates to the bus driver that the function driver has handled the
-+ interrupt. The bus driver will notify the host controller to unmask the
-+ interrupt source. SDIO interrupts are level triggered and are masked at the
-+ host controller level until all function drivers have indicated that they
-+ have handled their respective interrupt. This command can be issued in either
-+ the IRQ handler or asynchronous IRQ handler.
-+
-+ @example: Example of acknowledging an interrupt :
-+ status = SDLIB_IssueConfig(pInstance->pDevice,
-+ SDCONFIG_FUNC_ACK_IRQ,
-+ NULL,
-+ 0);
-+
-+ @see also: SDLIB_IssueConfig
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Disable SD/MMC/SDIO card CRC checking.
-+
-+ @function name: SDCONFIG_FUNC_SPI_MODE_DISABLE_CRC
-+ @prototype: SDCONFIG_FUNC_SPI_MODE_DISABLE_CRC
-+ @category: PD_Reference
-+
-+ @input: none
-+
-+ @output: none
-+
-+ @return: SDIO Status
-+
-+ @notes: This command code is used in the SDLIB_IssueConfig() API. The command
-+ issues CMD59 to disable SPI-CRC checking and requests the host controller
-+ driver to stop checking the CRC. This is typically used in systems where
-+ CRC checking is not required and performance is improved if the CRC checking
-+ is ommitted (i.e. SPI implementations without hardware CRC support).
-+
-+ @example: Example of disabling SPI CRC checking:
-+ status = SDLIB_IssueConfig(pInstance->pDevice,
-+ SDCONFIG_FUNC_SPI_MODE_DISABLE_CRC,
-+ NULL,
-+ 0);
-+
-+ @see also: SDCONFIG_FUNC_SPI_MODE_ENABLE_CRC
-+ @see also: SDLIB_IssueConfig
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Enable SD/MMC/SDIO card CRC checking.
-+
-+ @function name: SDCONFIG_FUNC_SPI_MODE_ENABLE_CRC
-+ @prototype: SDCONFIG_FUNC_SPI_MODE_ENABLE_CRC
-+ @category: PD_Reference
-+
-+ @input: none
-+
-+ @output: none
-+
-+ @return: SDIO Status
-+
-+ @notes: This command code is used in the SDLIB_IssueConfig() API. The command
-+ issues CMD59 to enable SPI-CRC checking and requests the host controller
-+ driver to generate valid CRCs for commands and data as well as
-+ check the CRC in responses and incomming data blocks.
-+
-+ @example: Example of enabling SPI CRC checking:
-+ status = SDLIB_IssueConfig(pInstance->pDevice,
-+ SDCONFIG_FUNC_SPI_MODE_ENABLE_CRC,
-+ NULL,
-+ 0);
-+
-+ @see also: SDCONFIG_FUNC_SPI_MODE_DISABLE_CRC
-+ @see also: SDLIB_IssueConfig
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Allocate slot current for a card function.
-+
-+ @function name: SDCONFIG_FUNC_ALLOC_SLOT_CURRENT
-+ @prototype: SDCONFIG_FUNC_ALLOC_SLOT_CURRENT
-+ @category: PD_Reference
-+
-+ @input: SDCONFIG_FUNC_SLOT_CURRENT_DATA
-+
-+ @output: SDCONFIG_FUNC_SLOT_CURRENT_DATA
-+
-+ @return: SDIO Status
-+
-+ @notes: This command code is used in the SDLIB_IssueConfig() API. The command
-+ requests an allocation of slot current to satisfy the power requirements
-+ of the function. The command uses the SDCONFIG_FUNC_SLOT_CURRENT_DATA
-+ data structure to pass the required current in mA. Slot current allocation
-+ is not cummulative and this command should only be issued once by each function
-+ driver with the worse case slot current usage.
-+ The command returns SDIO_STATUS_NO_RESOURCES if the
-+ requirement cannot be met by the host hardware. The SlotCurrent field will
-+ contain the remaining current available to the slot. The slot current should
-+ be allocated before the function is enabled using SDCONFIG_FUNC_ENABLE_DISABLE.
-+ When a function driver is unloaded it should free the slot current allocation
-+ by using the SDCONFIG_FUNC_FREE_SLOT_CURRENT command.
-+
-+ @example: Example of allocating slot current:
-+ slotCurrent.SlotCurrent = 150; // 150 mA
-+ status = SDLIB_IssueConfig(pInstance->pDevice,
-+ SDCONFIG_FUNC_ALLOC_SLOT_CURRENT,
-+ &slotCurrent,
-+ sizeof(slotCurrent));
-+
-+
-+ @see also: SDCONFIG_FUNC_FREE_SLOT_CURRENT
-+ @see also: SDLIB_IssueConfig
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Free slot current for a card function.
-+
-+ @function name: SDCONFIG_FUNC_FREE_SLOT_CURRENT
-+ @prototype: SDCONFIG_FUNC_FREE_SLOT_CURRENT
-+ @category: PD_Reference
-+
-+ @input: none
-+
-+ @output: none
-+
-+ @return: SDIO Status
-+
-+ @notes: This command code is used in the SDLIB_IssueConfig() API. The command
-+ frees the allocated current for a card function. This command should be
-+ issued only once (per function) and only after an allocation was successfully made.
-+
-+ @example: Example of freeing slot current:
-+ status = SDLIB_IssueConfig(pInstance->pDevice,
-+ SDCONFIG_FUNC_FREE_SLOT_CURRENT,
-+ NULL,
-+ 0);
-+
-+ @see also: SDCONFIG_FUNC_ALLOC_SLOT_CURRENT
-+ @see also: SDLIB_IssueConfig
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Set the bus mode for the SD/SDIO card.
-+
-+ @function name: SDCONFIG_FUNC_CHANGE_BUS_MODE
-+ @prototype: SDCONFIG_FUNC_CHANGE_BUS_MODE
-+ @category: PD_Reference
-+
-+ @input: none
-+
-+ @output: none
-+
-+ @return: SDIO Status
-+
-+ @notes: This command code is used in the SDLIB_IssueConfig() API. The command
-+ alters the card's bus mode (width and clock rate) to a driver specified
-+ value. The driver must read the current bus mode flags, modify if necessary
-+ and pass the value in the SDCONFIG_BUS_MODE_DATA structure.
-+ If the bus width is changed (1 or 4 bit) the caller must adjust the mode flags
-+ for the new width. Cards cannot be switched between 1/4 bit and SPI mode.
-+ Switching to or from SPI mode requires a power cycle. Adjustments to the clock
-+ rate is immediate on the next bus transaction. The actual clock rate value is
-+ limited by the host controller and is reported in the ClockRate field when the
-+ command completes successfully.
-+ The bus mode change is card wide and may affect other SDIO functions on
-+ multi-function cards. Use this feature with caution. This feature should NOT be
-+ used to dynamically control clock rates during runtime and should only be used
-+ at card initialization. Changing the bus mode must be done with SDIO function
-+ interrupts masked.
-+ This request can block and must only be called from a schedulable context.
-+
-+ @example: Example of changing the clock rate:
-+ SDCONFIG_BUS_MODE_DATA busSettings;
-+ ZERO_OBJECT(busSettings);
-+ // get current bus flags and keep the same bus width
-+ busSettings.BusModeFlags = SDDEVICE_GET_BUSMODE_FLAGS(pInstance->pDevice);
-+ busSettings.ClockRate = 8000000; // adjust clock to 8 Mhz
-+ // issue config request to override clock rate
-+ status = SDLIB_IssueConfig(pInstance->pDevice,
-+ SDCONFIG_FUNC_CHANGE_BUS_MODE,
-+ &busSettings,
-+ sizeof(SDCONFIG_BUS_MODE_DATA));
-+
-+ @see also: SDDEVICE_GET_BUSMODE_FLAGS
-+ @see also: SDLIB_IssueConfig
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Get the debug level of the underlying host controller driver.
-+
-+ @function name: SDCONFIG_GET_HCD_DEBUG
-+ @prototype: SDCONFIG_GET_HCD_DEBUG
-+ @category: PD_Reference
-+
-+ @input: none
-+
-+ @output: CT_DEBUG_LEVEL
-+
-+ @return: SDIO Status
-+
-+ @notes: This command code is used in the SDLIB_IssueConfig() API. The command
-+ requests the current debug level of the HCD driver. This API is useful for
-+ saving the current debug level of the HCD prior to issuing SDCONFIG_SET_HCD_DEBUG
-+ in order to increase the verbosity of the HCD. This API should be used only for
-+ debugging purposes. If multiple functions attempt to save and set the HCD debug
-+ level simultanously, the final debug level will be unknown. Not all HCDs support
-+ this command.
-+
-+ @example: Example of saving the debug level:
-+ CT_DEBUG_LEVEL savedDebug;
-+ status = SDLIB_IssueConfig(pInstance->pDevice,
-+ SDCONFIG_GET_HCD_DEBUG,
-+ &savedDebug,
-+ sizeof(savedDebug));
-+
-+ @see also: SDCONFIG_SET_HCD_DEBUG
-+ @see also: SDLIB_IssueConfig
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Set the debug level of the underlying host controller driver.
-+
-+ @function name: SDCONFIG_SET_HCD_DEBUG
-+ @prototype: SDCONFIG_SET_HCD_DEBUG
-+ @category: PD_Reference
-+
-+ @input: CT_DEBUG_LEVEL
-+
-+ @output: none
-+
-+ @return: SDIO Status
-+
-+ @notes: This command code is used in the SDLIB_IssueConfig() API. The command
-+ sets the current debug level of the HCD driver. This API is useful for
-+ setting the debug level of the HCD programatically for debugging purposes.
-+ If multiple functions attempt to save and set the HCD debug
-+ level simultanously, the final debug level will be unknown. Not all HCDs support
-+ this request.
-+
-+ @example: Example of setting the debug level:
-+ CT_DEBUG_LEVEL setDebug = 15;
-+ status = SDLIB_IssueConfig(pInstance->pDevice,
-+ SDCONFIG_GET_HCD_DEBUG,
-+ &setDebug,
-+ sizeof(setDebug));
-+
-+ @see also: SDCONFIG_GET_HCD_DEBUG
-+ @see also: SDLIB_IssueConfig
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Instruct the bus driver to not check the SDIO card interrupt pending
-+ register on card interrupts, if possible.
-+
-+ @function name: SDCONFIG_FUNC_NO_IRQ_PEND_CHECK
-+ @prototype: SDCONFIG_FUNC_NO_IRQ_PEND_CHECK
-+ @category: PD_Reference
-+
-+ @input: none
-+
-+ @output: none
-+
-+ @return: SDIO Status
-+
-+ @notes: This command code is used in the SDLIB_IssueConfig() API. The command instructs the
-+ bus driver to skip checking the card interrupt pending register on each card
-+ interrupt. The bus driver will assume the function is interrupting and immediately start
-+ the interrupt processing stage. This option is only valid for single function cards.
-+ The bus driver will reject the command for a card with more than 1 function.
-+ For single function cards, this can improve interrupt response time.
-+
-+ @example: Example of skipping IRQ pending checks:
-+
-+ status = SDLIB_IssueConfig(pInstance->pDevice,
-+ SDCONFIG_FUNC_NO_IRQ_PEND_CHECK,
-+ NULL,
-+ 0);
-+
-+ @see also: SDLIB_IssueConfig
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-diff --git a/drivers/sdio/stack/busdriver/sdio_bus_events.c b/drivers/sdio/stack/busdriver/sdio_bus_events.c
-new file mode 100644
-index 0000000..5b3148d
---- /dev/null
-+++ b/drivers/sdio/stack/busdriver/sdio_bus_events.c
-@@ -0,0 +1,1040 @@
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+@file: sdio_bus_events.c
-+
-+@abstract: OS independent bus driver support
-+
-+#notes: this file contains various event handlers and helpers
-+
-+@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
-+ *
-+ *
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+#define MODULE_NAME SDBUSDRIVER
-+#include <linux/sdio/ctsystem.h>
-+#include <linux/sdio/sdio_busdriver.h>
-+#include <linux/sdio/sdio_lib.h>
-+#include "_busdriver.h"
-+#include <linux/sdio/_sdio_defs.h>
-+#include <linux/sdio/mmc_defs.h>
-+
-+static SDIO_STATUS ScanSlotForCard(PSDHCD pHcd,
-+ PBOOL pCardPresent);
-+static void GetPendingIrqComplete(PSDREQUEST pReq);
-+static void ProcessPendingIrqs(PSDHCD pHcd, UINT8 IntPendingMsk);
-+
-+/*
-+ * DeviceDetach - tell core a device was removed from a slot
-+*/
-+SDIO_STATUS DeviceDetach(PSDHCD pHcd)
-+{
-+ SDCONFIG_SDIO_INT_CTRL_DATA irqData;
-+
-+ ZERO_OBJECT(irqData);
-+
-+ DBG_PRINT(SDDBG_TRACE, ("+SDIO Bus Driver: DeviceDetach\n"));
-+ /* tell any function drivers we are gone */
-+ RemoveHcdFunctions(pHcd);
-+ /* delete the devices associated with this HCD */
-+ DeleteDevices(pHcd);
-+ /* check and see if there are any IRQs that were left enabled */
-+ if (pHcd->IrqsEnabled) {
-+ irqData.SlotIRQEnable = FALSE;
-+ /* turn off IRQ detection in HCD */
-+ _IssueConfig(pHcd,SDCONFIG_SDIO_INT_CTRL,(PVOID)&irqData, sizeof(irqData));
-+ }
-+
-+ /* reset hcd state */
-+ ResetHcdState(pHcd);
-+
-+ DBG_PRINT(SDDBG_TRACE, ("-SDIO Bus Driver: DeviceDetach\n"));
-+ return SDIO_STATUS_SUCCESS;
-+}
-+
-+/*
-+ * DeviceAttach - tell core a device was inserted into a slot
-+*/
-+SDIO_STATUS DeviceAttach(PSDHCD pHcd)
-+{
-+ SDIO_STATUS status = SDIO_STATUS_SUCCESS;
-+ PSDDEVICE pDevice = NULL;
-+ UINT ii;
-+
-+
-+ if (IS_CARD_PRESENT(pHcd)) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: DeviceAttach called on occupied slot!\n"));
-+ return SDIO_STATUS_ERROR;
-+ }
-+
-+ DBG_PRINT(SDDBG_TRACE, ("+SDIO Bus Driver: DeviceAttach bdctxt:0x%X \n", (UINT32)pBusContext));
-+
-+ if (IS_HCD_RAW(pHcd)) {
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: RAW HCD (%s) device attach \n",pHcd->pName));
-+ /* this is a raw HCD */
-+ memset(&pHcd->CardProperties,0,sizeof(pHcd->CardProperties));
-+ pHcd->CardProperties.Flags = CARD_RAW;
-+ pHcd->CardProperties.IOFnCount = 0;
-+ /* for raw HCD, set up minimum parameters
-+ * since we cannot determine these values using any standard, use values
-+ * reported by the HCD */
-+ /* the operational rate is just the max clock rate reported */
-+ pHcd->CardProperties.OperBusClock = pHcd->MaxClockRate;
-+ /* the max bytes per data transfer is just the max bytes per block */
-+ pHcd->CardProperties.OperBlockLenLimit = pHcd->MaxBytesPerBlock;
-+ /* if the raw HCD uses blocks to transfer, report the operational size
-+ * from the HCD max value */
-+ pHcd->CardProperties.OperBlockCountLimit = pHcd->MaxBlocksPerTrans;
-+ /* set the slot preferred voltage */
-+ pHcd->CardProperties.CardVoltage = pHcd->SlotVoltagePreferred;
-+ } else {
-+ /* initialize this card and get card properties */
-+ if (!SDIO_SUCCESS((status = SDInitializeCard(pHcd)))) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: DeviceAttach, failed to initialize card, %d\n",
-+ status));
-+ return status;
-+ }
-+ }
-+
-+ /* check for SD or MMC, this must be done first as the query may involve
-+ * de-selecting the card */
-+ do {
-+ if (!(pHcd->CardProperties.Flags & (CARD_MMC | CARD_SD | CARD_RAW))) {
-+ /* none of these were discovered */
-+ break;
-+ }
-+ pDevice = AllocateDevice(pHcd);
-+ if (NULL == pDevice) {
-+ break;
-+ }
-+ if (pHcd->CardProperties.Flags & CARD_RAW) {
-+ /* set function number to 1 for IRQ processing */
-+ SDDEVICE_SET_SDIO_FUNCNO(pDevice,1);
-+ } else {
-+ /* get the ID info for the SD/MMC Card */
-+ if (!SDIO_SUCCESS((status = SDQuerySDMMCInfo(pDevice)))) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: DeviceAttach, query SDMMC Info failed \n"));
-+ FreeDevice(pDevice);
-+ break;
-+ }
-+ }
-+ AddDeviceToList(pDevice);
-+ /* look for a function driver to handle this card */
-+ ProbeForFunction(pDevice, pHcd);
-+ } while (FALSE);
-+
-+ /* create a device for each I/O function */
-+ for(ii= 1; ii <= pHcd->CardProperties.IOFnCount; ii++) {
-+ pDevice = AllocateDevice(pHcd);
-+ if (NULL == pDevice) {
-+ break;
-+ }
-+ /* set the function number */
-+ SDDEVICE_SET_SDIO_FUNCNO(pDevice,ii);
-+ /* get the ID info for each I/O function */
-+ if (!SDIO_SUCCESS((status = SDQuerySDIOInfo(pDevice)))) {
-+ DBG_PRINT(SDDBG_ERROR,
-+ ("SDIO Bus Driver: DeviceAttach, could not query SDIO Info, funcNo:%d status:%d \n",
-+ ii, status));
-+ FreeDevice(pDevice);
-+ /* keep loading other functions */
-+ continue;
-+ }
-+ AddDeviceToList(pDevice);
-+ /* look for a function driver to handle this card */
-+ ProbeForFunction(pDevice, pHcd);
-+ }
-+
-+
-+ DBG_PRINT(SDDBG_TRACE, ("-SDIO Bus Driver: DeviceAttach \n"));
-+ return status;
-+}
-+
-+static INLINE void CompleteRequestCheckCancel(PSDHCD pHcd, PSDREQUEST pReqToComplete)
-+{
-+ BOOL cancel = FALSE;
-+ PSDFUNCTION pFunc = NULL;
-+
-+ /* handle cancel of current request */
-+ if (pReqToComplete->Flags & SDREQ_FLAGS_CANCELED) {
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver - _SDIO_HandleHcdEvent: cancelling req 0X%X\n", (UINT)pReqToComplete));
-+ cancel = TRUE;
-+ pReqToComplete->Status = SDIO_STATUS_CANCELED;
-+ pFunc = pReqToComplete->pFunction;
-+ DBG_ASSERT(pFunc != NULL);
-+ }
-+
-+ DoRequestCompletion(pReqToComplete, pHcd);
-+
-+ if (cancel) {
-+ SignalSet(&pFunc->CleanupReqSig);
-+ }
-+}
-+
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Indicate to the SDIO bus driver (core) of an event in the host controller
-+ driver.
-+
-+ @function name: SDIO_HandleHcdEvent
-+ @prototype: SDIO_STATUS SDIO_HandleHcdEvent(PSDHCD pHcd, HCD_EVENT Event)
-+ @category: HD_Reference
-+
-+ @input: pHcd - the host controller structure that was registered
-+ HCD_EVENT - event code
-+
-+ @output: none
-+
-+ @return: SDIO_STATUS
-+
-+ @notes:
-+ The host controller driver can indicate asynchronous events by calling this
-+ function with an appropriate event code. Refer to the HDK help manual for
-+ more information on the event types
-+
-+ @example: Example of indicating a card insertion event:
-+ SDIO_HandleHcdEvent(&Hcd, EVENT_HCD_ATTACH);
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+SDIO_STATUS _SDIO_HandleHcdEvent(PSDHCD pHcd, HCD_EVENT Event)
-+{
-+ PSDREQUEST pReq;
-+ PSDREQUEST pReqToComplete = NULL;
-+ PSDREQUEST pNextReq = NULL;
-+ SDIO_STATUS status;
-+ CT_DECLARE_IRQ_SYNC_CONTEXT();
-+
-+ DBG_PRINT(SDIODBG_HCD_EVENTS, ("SDIO Bus Driver: _SDIO_HandleHcdEvent, event type 0x%X, HCD:0x%X\n",
-+ Event, (UINT)pHcd));
-+
-+ if (Event == EVENT_HCD_TRANSFER_DONE) {
-+ pReq = GET_CURRENT_REQUEST(pHcd);
-+ if (NULL == pReq) {
-+ DBG_ASSERT(FALSE);
-+ return SDIO_STATUS_ERROR;
-+ }
-+
-+ status = _AcquireHcdLock(pHcd);
-+ if (SDIO_SUCCESS(status)) {
-+ /* null out the current request */
-+ SET_CURRENT_REQUEST(pHcd, NULL);
-+ status = _ReleaseHcdLock(pHcd);
-+ } else {
-+ DBG_PRINT(SDDBG_ERROR,
-+ ("SDIO Bus Driver: SDIO_HandleHcdEvent Failed to acquire HCD lock \n"));
-+ return SDIO_STATUS_ERROR;
-+ }
-+
-+ /* note: the queue is still marked busy to prevent other threads/tasks from starting
-+ * new requests while we are handling completion , some completed requests are
-+ * marked as barrier requests which must be handled atomically */
-+
-+ status = pReq->Status;
-+ DBG_PRINT(SDIODBG_REQUESTS,
-+ ("+SDIO Bus Driver: Handling Transfer Done (CMD:%d, Status:%d) from HCD:0x%08X \n",
-+ pReq->Command, status, (INT)pHcd));
-+ /* check SPI mode conversion */
-+ if (IS_HCD_BUS_MODE_SPI(pHcd) && SDIO_SUCCESS(status)) {
-+ if (!(pReq->Flags & SDREQ_FLAGS_RESP_SKIP_SPI_FILT) && !(pReq->Flags & SDREQ_FLAGS_PSEUDO) &&
-+ (GET_SDREQ_RESP_TYPE(pReq->Flags) != SDREQ_FLAGS_NO_RESP)) {
-+ ConvertSPI_Response(pReq, NULL);
-+ }
-+ }
-+
-+ DBG_PRINT(SDIODBG_REQUESTS, ("SDIO Bus Driver: Completing Request:0x%08X \n",(INT)pReq));
-+
-+ if (!SDIO_SUCCESS(status) &&
-+ (status != SDIO_STATUS_CANCELED) &&
-+ !(pReq->Flags & SDREQ_FLAGS_CANCELED) &&
-+ (pReq->RetryCount > 0)) {
-+ /* retry the request if it failed, was NOT cancelled and the retry count
-+ * is greater than zero */
-+ pReq->RetryCount--;
-+ pReqToComplete = NULL;
-+ /* clear SPI converted flag */
-+ pReq->Flags &= ~SDREQ_FLAGS_RESP_SPI_CONVERTED;
-+ pNextReq = pReq;
-+ } else {
-+ /* complete the request */
-+ if (pReq->Flags & SDREQ_FLAGS_BARRIER) {
-+ /* a barrier request must be completed before the next bus request is
-+ * started */
-+ CompleteRequestCheckCancel(pHcd, pReq);
-+ if (!ForceAllRequestsAsync()) {
-+ if (CHECK_API_VERSION_COMPAT(pHcd,2,6)) {
-+ /* the request was completed, decrement recursion count */
-+ status = _AcquireHcdLock(pHcd);
-+ if (!SDIO_SUCCESS(status)) {
-+ return status;
-+ }
-+ pHcd->Recursion--;
-+ DBG_ASSERT(pHcd->Recursion >= 0);
-+ status = _ReleaseHcdLock(pHcd);
-+ } else {
-+ /* reset bit */
-+ AtomicTest_Clear(&pHcd->HcdFlags, HCD_REQUEST_CALL_BIT);
-+ }
-+ }
-+ pReqToComplete = NULL;
-+ } else {
-+ /* complete this after the next request has
-+ * been started */
-+ pReqToComplete = pReq;
-+ }
-+ }
-+
-+ /* acquire the hcd lock to look at the queues */
-+ status = _AcquireHcdLock(pHcd);
-+ if (SDIO_SUCCESS(status)) {
-+ if (pReqToComplete != NULL) {
-+ /* queue the request that was completed */
-+ QueueRequest(&pHcd->CompletedRequestQueue, pReqToComplete);
-+ }
-+ if (NULL == pNextReq) {
-+ /* check the queue for the next request */
-+ DBG_PRINT(SDIODBG_REQUESTS, ("SDIO Bus Driver: Checking queue.. \n"));
-+ /* check to see if the HCD was already working on one. This occurs if
-+ * the current request being completed was a barrier request and the
-+ * barrier completion routine submitted a new request to the head of the
-+ * queue */
-+ if (GET_CURRENT_REQUEST(pHcd) == NULL) {
-+ pNextReq = DequeueRequest(&pHcd->RequestQueue);
-+ if (NULL == pNextReq) {
-+ /* nothing in the queue, mark it not busy */
-+ MarkQueueNotBusy(&pHcd->RequestQueue);
-+ DBG_PRINT(SDIODBG_REQUESTS, ("SDIO Bus Driver: Queue idle \n"));
-+ } else {
-+ DBG_PRINT(SDIODBG_REQUESTS, ("SDIO Bus Driver: Next request in queue: 0x%X \n",
-+ (INT)pNextReq));
-+ }
-+ } else {
-+ DBG_PRINT(SDIODBG_REQUESTS,
-+ ("SDIO Bus Driver: Busy Queue from barrier request \n"));
-+ }
-+ }
-+
-+ if (pNextReq != NULL) {
-+ /* a new request will be submitted to the HCD below,
-+ * check recursion while we have the lock */
-+ if (CHECK_API_VERSION_COMPAT(pHcd,2,6)) {
-+ CHECK_HCD_RECURSE(pHcd,pNextReq);
-+ }
-+ }
-+ status = _ReleaseHcdLock(pHcd);
-+ } else {
-+ DBG_PRINT(SDDBG_ERROR,
-+ ("SDIO Bus Driver: SDIO_HandleHcdEvent Failed to acquire HCD lock \n"));
-+ return SDIO_STATUS_ERROR;
-+ }
-+ /* check for the next request to issue */
-+ if (pNextReq != NULL) {
-+ DBG_PRINT(SDIODBG_REQUESTS, ("SDIO Bus Driver: Starting Next Request: 0x%X \n",
-+ (INT)pNextReq));
-+ SET_CURRENT_REQUEST(pHcd,pNextReq);
-+ status = CallHcdRequest(pHcd);
-+ /* check and see if the HCD completed the request in the callback */
-+ if (status != SDIO_STATUS_PENDING) {
-+ /* recurse and process the request */
-+ _SDIO_HandleHcdEvent(pHcd, EVENT_HCD_TRANSFER_DONE);
-+ }
-+ }
-+
-+ /* now empty the completed request queue
-+ * - this guarantees in-order completion even during recursion */
-+ status = _AcquireHcdLock(pHcd);
-+ if (SDIO_SUCCESS(status)) {
-+ while (1) {
-+ pReqToComplete = DequeueRequest(&pHcd->CompletedRequestQueue);
-+ status = _ReleaseHcdLock(pHcd);
-+ if (pReqToComplete != NULL) {
-+ CompleteRequestCheckCancel(pHcd, pReqToComplete);
-+ if (!CHECK_API_VERSION_COMPAT(pHcd,2,6)) {
-+ if (!ForceAllRequestsAsync()) {
-+ /* reset bit */
-+ AtomicTest_Clear(&pHcd->HcdFlags, HCD_REQUEST_CALL_BIT);
-+ }
-+ }
-+ /* re-acquire lock */
-+ status = _AcquireHcdLock(pHcd);
-+ if (!SDIO_SUCCESS(status)) {
-+ return SDIO_STATUS_ERROR;
-+ }
-+ if (CHECK_API_VERSION_COMPAT(pHcd,2,6)) {
-+ if (!ForceAllRequestsAsync()) {
-+ /* while we have the lock, decrement recursion count each time
-+ * we complete a request */
-+ pHcd->Recursion--;
-+ DBG_ASSERT(pHcd->Recursion >= 0);
-+ }
-+ }
-+ } else {
-+ /* we're done */
-+ break;
-+ }
-+ }
-+ } else {
-+ DBG_PRINT(SDDBG_ERROR,
-+ ("SDIO Bus Driver: SDIO_HandleHcdEvent Failed to acquire HCD lock \n"));
-+ return SDIO_STATUS_ERROR;
-+ }
-+ DBG_PRINT(SDIODBG_REQUESTS, ("-SDIO Bus Driver: Transfer Done Handled \n"));
-+ return SDIO_STATUS_SUCCESS;
-+ }
-+
-+ switch(Event) {
-+ case EVENT_HCD_ATTACH:
-+ case EVENT_HCD_DETACH:
-+ /* card detect helper does the actual attach detach */
-+ return PostCardDetectEvent(pBusContext,Event,pHcd);
-+ case EVENT_HCD_SDIO_IRQ_PENDING:
-+ return DeviceInterrupt(pHcd);
-+ default:
-+ DBG_PRINT(SDDBG_ERROR, ("-SDIO Bus Driver: SDIO_HandleHcdEvent, invalid event type 0x%X, HCD:0x%X\n",
-+ Event, (UINT)pHcd));
-+ return SDIO_STATUS_INVALID_PARAMETER;
-+ }
-+
-+}
-+
-+/* card detect helper function */
-+THREAD_RETURN CardDetectHelperFunction(POSKERNEL_HELPER pHelper)
-+{
-+ SDIO_STATUS status;
-+ HCD_EVENT_MESSAGE message;
-+ INT length;
-+
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver - CardDetectHelperFunction starting up: 0x%X \n", (INT)pHelper));
-+
-+ while (1) {
-+
-+ /* wait for wake up event */
-+ status = SD_WAIT_FOR_WAKEUP(pHelper);
-+ if (!SDIO_SUCCESS(status)) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver - Card Detect Helper Semaphore Pend Error:%d \n",
-+ status));
-+ break;
-+ }
-+
-+ if (SD_IS_HELPER_SHUTTING_DOWN(pHelper)) {
-+ /* cleanup message queue on shutdown */
-+ while (1) {
-+ length = sizeof(message);
-+ /* get a message */
-+ status = SDLIB_GetMessage(pBusContext->pCardDetectMsgQueue,
-+ &message, &length);
-+ if (!SDIO_SUCCESS(status)) {
-+ break;
-+ }
-+ if (message.pHcd != NULL) {
-+ /* decrement HCD reference count */
-+ OS_DecHcdReference(message.pHcd);
-+ }
-+ }
-+
-+ break;
-+ }
-+
-+ while (1) {
-+ length = sizeof(message);
-+ /* get a message */
-+ status = SDLIB_GetMessage(pBusContext->pCardDetectMsgQueue,
-+ &message, &length);
-+ if (!SDIO_SUCCESS(status)) {
-+ break;
-+ }
-+
-+ switch (message.Event) {
-+ case EVENT_HCD_ATTACH:
-+ DeviceAttach(message.pHcd);
-+ break;
-+ case EVENT_HCD_DETACH:
-+ DeviceDetach(message.pHcd);
-+ break;
-+ case EVENT_HCD_CD_POLLING:
-+ /* run detector */
-+ RunCardDetect();
-+ break;
-+ default:
-+ DBG_ASSERT(FALSE);
-+ break;
-+ }
-+
-+ if (message.pHcd != NULL) {
-+ /* message was processed, decrement reference count */
-+ OS_DecHcdReference(message.pHcd);
-+ }
-+ }
-+ }
-+
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver - Card Detect Helper Exiting.. \n"));
-+ return 0;
-+}
-+
-+
-+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ RunCardDetect - run card detect on host controller slots that require polling
-+ Input:
-+ Output:
-+ Return:
-+ Notes: This function is called from the card detect timer thread
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+void RunCardDetect(void)
-+{
-+ BOOL CDPollingRequired = FALSE;
-+ PSDLIST pListItem;
-+ PSDHCD pHcd;
-+ BOOL cardPresent;
-+
-+ DBG_PRINT(SDIODBG_CD_TIMER, ("+SDIO Bus Driver: RunCardDetect\n"));
-+
-+ /* protect the HCD list */
-+ if (!SDIO_SUCCESS(SemaphorePendInterruptable(&pBusContext->HcdListSem))) {
-+ DBG_ASSERT(FALSE);
-+ return; /* wait interrupted */
-+ }
-+ /* while we are running the detector we are blocking HCD removal*/
-+ SDITERATE_OVER_LIST(&pBusContext->HcdList, pListItem) {
-+ pHcd = CONTAINING_STRUCT(pListItem, SDHCD, SDList);
-+ /* does the HCD require polling ? */
-+ if (pHcd->Attributes & SDHCD_ATTRIB_SLOT_POLLING) {
-+ DBG_PRINT(SDIODBG_CD_TIMER, ("SDIO Bus Driver: Found HCD requiring polling \n"));
-+ /* set flag to queue the timer */
-+ CDPollingRequired = TRUE;
-+ if (IS_CARD_PRESENT(pHcd)) {
-+ /* there is a device in the slot */
-+ cardPresent = TRUE;
-+ if (SDIO_SUCCESS(ScanSlotForCard(pHcd,&cardPresent))) {
-+ if (!cardPresent) {
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver CD Polling.. Card Removal Detected\n"));
-+ DeviceDetach(pHcd);
-+ }
-+ }
-+ } else {
-+ cardPresent = FALSE;
-+ if (SDIO_SUCCESS(ScanSlotForCard(pHcd,&cardPresent))) {
-+ if (cardPresent) {
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver CD Polling.. Card Detected\n"));
-+ DeviceAttach(pHcd);
-+ }
-+ }
-+ }
-+ }
-+
-+ DBG_PRINT(SDIODBG_CD_TIMER, ("SDIO Bus Driver: moving to next hcd:0x%X \n",
-+ (INT)pListItem->pNext));
-+ }
-+
-+ /* check if we need to queue the timer */
-+ if (CDPollingRequired && !pBusContext->CDTimerQueued) {
-+ pBusContext->CDTimerQueued = TRUE;
-+ DBG_PRINT(SDIODBG_CD_TIMER, ("SDIO Bus Driver: Queuing Card detect timer \n"));
-+ if (!SDIO_SUCCESS(
-+ QueueTimer(SDIOBUS_CD_TIMER_ID, pBusContext->CDPollingInterval))) {
-+ DBG_PRINT(SDDBG_WARN, ("SDIO Bus Driver: failed to queue CD timer \n"));
-+ pBusContext->CDTimerQueued = FALSE;
-+ }
-+ }
-+ /* release HCD list lock */
-+ SemaphorePost(&pBusContext->HcdListSem);
-+ DBG_PRINT(SDIODBG_CD_TIMER, ("-SDIO Bus Driver: RunCardDetect\n"));
-+}
-+
-+
-+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ ScanSlotForCard - scan slot for a card
-+ Input: pHcd - the hcd
-+ Output: pCardPresent - card present flag (set/cleared on return)
-+ Return:
-+ Notes:
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+static SDIO_STATUS ScanSlotForCard(PSDHCD pHcd,PBOOL pCardPresent)
-+{
-+ SDIO_STATUS status = SDIO_STATUS_SUCCESS;
-+ UINT8 temp;
-+
-+ DBG_PRINT(SDIODBG_CD_TIMER, ("+SDIO Bus Driver: ScanSlotForCard\n"));
-+
-+ do {
-+ if (!IS_CARD_PRESENT(pHcd)) {
-+ INT dbgLvl;
-+ dbgLvl = DBG_GET_DEBUG_LEVEL();
-+ DBG_SET_DEBUG_LEVEL(SDDBG_WARN);
-+ status = CardInitSetup(pHcd);
-+ DBG_SET_DEBUG_LEVEL(dbgLvl);
-+ if (!SDIO_SUCCESS(status)) {
-+ break;
-+ }
-+ /* issue go-idle */
-+ if (IS_HCD_BUS_MODE_SPI(pHcd)) {
-+ _IssueSimpleBusRequest(pHcd,CMD0,0,SDREQ_FLAGS_RESP_R1,NULL);
-+ } else {
-+ _IssueSimpleBusRequest(pHcd,CMD0,0,SDREQ_FLAGS_NO_RESP,NULL);
-+ }
-+ /* try SDIO */
-+ status = TestPresence(pHcd,CARD_SDIO,NULL);
-+ if (SDIO_SUCCESS(status)) {
-+ *pCardPresent = TRUE;
-+ break;
-+ }
-+ /* issue go-idle */
-+ if (IS_HCD_BUS_MODE_SPI(pHcd)) {
-+ _IssueSimpleBusRequest(pHcd,CMD0,0,SDREQ_FLAGS_RESP_R1,NULL);
-+ } else {
-+ _IssueSimpleBusRequest(pHcd,CMD0,0,SDREQ_FLAGS_NO_RESP,NULL);
-+ }
-+ /* try SD */
-+ status = TestPresence(pHcd,CARD_SD,NULL);
-+ if (SDIO_SUCCESS(status)) {
-+ *pCardPresent = TRUE;
-+ break;
-+ }
-+ /* issue go-idle */
-+ if (IS_HCD_BUS_MODE_SPI(pHcd)) {
-+ _IssueSimpleBusRequest(pHcd,CMD0,0,SDREQ_FLAGS_RESP_R1,NULL);
-+ } else {
-+ _IssueSimpleBusRequest(pHcd,CMD0,0,SDREQ_FLAGS_NO_RESP,NULL);
-+ }
-+ /* try MMC */
-+ status = TestPresence(pHcd,CARD_MMC,NULL);
-+ if (SDIO_SUCCESS(status)) {
-+ *pCardPresent = TRUE;
-+ break;
-+ }
-+ } else {
-+ if (pHcd->CardProperties.Flags & CARD_SDIO) {
-+#ifdef DUMP_INT_PENDING
-+ temp = 0;
-+ /* handy debug prints to check interrupt status and print pending register */
-+ status = Cmd52ReadByteCommon(pHcd->pPseudoDev, SDIO_INT_ENABLE_REG, &temp);
-+ if (SDIO_SUCCESS(status) && (temp != 0)) {
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: INT Enable Reg: 0x%2.2X\n", temp));
-+ status = Cmd52ReadByteCommon(pHcd->pPseudoDev, SDIO_INT_PENDING_REG, &temp);
-+ if (SDIO_SUCCESS(status)) {
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: INT Pend Reg: 0x%2.2X\n", temp));
-+ }
-+ }
-+#endif
-+ /* for SDIO cards, read the revision register */
-+ status = Cmd52ReadByteCommon(pHcd->pPseudoDev, CCCR_SDIO_REVISION_REG, &temp);
-+ } else if (pHcd->CardProperties.Flags & (CARD_SD | CARD_MMC)) {
-+ /* for SD/MMC cards, issue SEND_STATUS */
-+ if (IS_HCD_BUS_MODE_SPI(pHcd)) {
-+ /* SPI uses the SPI R2 response */
-+ status = _IssueSimpleBusRequest(pHcd,
-+ CMD13,
-+ 0,
-+ SDREQ_FLAGS_RESP_R2,
-+ NULL);
-+ } else {
-+ status = _IssueSimpleBusRequest(pHcd,
-+ CMD13,
-+ (pHcd->CardProperties.RCA << 16),
-+ SDREQ_FLAGS_RESP_R1,NULL);
-+ }
-+ } else {
-+ DBG_ASSERT(FALSE);
-+ }
-+ if (!SDIO_SUCCESS(status)) {
-+ /* card is gone */
-+ *pCardPresent = FALSE;
-+ }
-+ }
-+ } while (FALSE);
-+
-+ if (status == SDIO_STATUS_BUS_RESP_TIMEOUT) {
-+ status = SDIO_STATUS_SUCCESS;
-+ }
-+
-+ DBG_PRINT(SDIODBG_CD_TIMER, ("-SDIO Bus Driver: ScanSlotForCard status:%d\n",
-+ status));
-+
-+ return status;
-+}
-+
-+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ DeviceInterrupt - handle device interrupt
-+ Input: pHcd - host controller
-+ Output:
-+ Return:
-+ Notes:
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+SDIO_STATUS DeviceInterrupt(PSDHCD pHcd)
-+{
-+ SDIO_STATUS status = SDIO_STATUS_SUCCESS;
-+ SDIO_STATUS status2;
-+ PSDREQUEST pReq = NULL;
-+ CT_DECLARE_IRQ_SYNC_CONTEXT();
-+
-+ DBG_PRINT(SDIODBG_FUNC_IRQ, ("+SDIO Bus Driver: DeviceInterrupt\n"));
-+
-+ if (!IS_CARD_PRESENT(pHcd)) {
-+ DBG_PRINT(SDDBG_ERROR, ("-SDIO Bus Driver: Device interrupt asserted on empty slot!\n"));
-+ return SDIO_STATUS_ERROR;
-+ }
-+
-+ do {
-+ /* for RAW HCDs or HCDs flagged for single-function IRQ optimization */
-+ if (IS_HCD_RAW(pHcd) || (pHcd->HcdFlags & (1 << HCD_IRQ_NO_PEND_CHECK))) {
-+ status = _AcquireHcdLock(pHcd);
-+ if (!SDIO_SUCCESS(status)) {
-+ return status;
-+ }
-+ if (pHcd->IrqProcState != SDHCD_IDLE) {
-+ status = SDIO_STATUS_ERROR;
-+ status2 = _ReleaseHcdLock(pHcd);
-+ } else {
-+ DBG_PRINT(SDIODBG_FUNC_IRQ, ("SDIO Bus Driver : Device Interrupt \n"));
-+ /* mark that we are processing */
-+ pHcd->IrqProcState = SDHCD_IRQ_PENDING;
-+ status2 = _ReleaseHcdLock(pHcd);
-+ /* process Irqs for raw hcds or HCDs with the single function optimization */
-+ /* force processing of function 1 interrupt */
-+ ProcessPendingIrqs(pHcd, (1 << 1));
-+ }
-+ DBG_PRINT(SDIODBG_FUNC_IRQ, ("-SDIO Bus Driver: DeviceInterrupt: %d\n", status));
-+ /* done with RAW irqs */
-+ return status;
-+ }
-+
-+ /* pre-allocate a request to get the pending bits, we have to do this outside the
-+ * hcd lock acquisition */
-+ pReq = AllocateRequest();
-+
-+ if (NULL == pReq) {
-+ status = SDIO_STATUS_NO_RESOURCES;
-+ break;
-+ }
-+
-+ status = _AcquireHcdLock(pHcd);
-+
-+ if (!SDIO_SUCCESS(status)) {
-+ break;
-+ }
-+
-+ if (pHcd->IrqProcState != SDHCD_IDLE) {
-+ status = SDIO_STATUS_ERROR;
-+ } else {
-+ /* mark that we are processing */
-+ pHcd->IrqProcState = SDHCD_IRQ_PENDING;
-+ /* build argument to read IRQ pending register */
-+ SDIO_SET_CMD52_READ_ARG(pReq->Argument,0,SDIO_INT_PENDING_REG);
-+ pReq->Command = CMD52;
-+ pReq->Flags = SDREQ_FLAGS_TRANS_ASYNC | SDREQ_FLAGS_RESP_SDIO_R5;
-+ pReq->pCompleteContext = (PVOID)pHcd;
-+ pReq->pCompletion = GetPendingIrqComplete;
-+ pReq->RetryCount = SDBUS_MAX_RETRY;
-+ }
-+
-+ status2 = _ReleaseHcdLock(pHcd);
-+
-+ if (!SDIO_SUCCESS(status2)) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: lock release error: %d\n", status2));
-+ }
-+
-+ } while (FALSE);
-+
-+ if (SDIO_SUCCESS(status)) {
-+ DBG_ASSERT(pReq != NULL);
-+ IssueRequestToHCD(pHcd,pReq);
-+ status = SDIO_STATUS_PENDING;
-+ } else {
-+ if (pReq != NULL) {
-+ FreeRequest(pReq);
-+ }
-+ }
-+
-+ DBG_PRINT(SDIODBG_FUNC_IRQ, ("-SDIO Bus Driver: DeviceInterrupt: %d\n", status));
-+ return status;
-+}
-+
-+
-+/* SDIO IRQ helper */
-+THREAD_RETURN SDIOIrqHelperFunction(POSKERNEL_HELPER pHelper)
-+{
-+ PSDHCD pHcd;
-+ SDIO_STATUS status;
-+ PSDLIST pListItem;
-+ PSDDEVICE pDevice;
-+ UINT8 funcMask;
-+ PSDDEVICE pDeviceIRQ[7];
-+ UINT deviceIrqCount = 0;
-+ UINT ii;
-+
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver - SDIOIrqHelperFunction starting up \n"));
-+
-+ pHcd = (PSDHCD)pHelper->pContext;
-+ DBG_ASSERT(pHcd != NULL);
-+
-+ while (1) {
-+
-+ /* wait for wake up event */
-+ status = SD_WAIT_FOR_WAKEUP(pHelper);
-+
-+ if (!SDIO_SUCCESS(status)) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver - SDIOIrqHelperFunction Pend Error:%d \n",
-+ status));
-+ break;
-+ }
-+
-+ if (SD_IS_HELPER_SHUTTING_DOWN(pHelper)) {
-+ break;
-+ }
-+
-+ DBG_PRINT(SDIODBG_FUNC_IRQ, ("SDIO Bus Driver - Pending IRQs:0x%X \n",
-+ pHcd->PendingHelperIrqs));
-+
-+ /* take the device list lock as we iterate through the list, this blocks
-+ * device removals */
-+ status = SemaphorePendInterruptable(&pBusContext->DeviceListSem);
-+ if (!SDIO_SUCCESS(status)) {
-+ break;
-+ }
-+ /* walk through the device list matching HCD and interrupting function */
-+ SDITERATE_OVER_LIST(&pBusContext->DeviceList, pListItem) {
-+ pDevice = CONTAINING_STRUCT(pListItem, SDDEVICE, SDList);
-+ /* check if device belongs to the HCD */
-+ if (pDevice->pHcd != pHcd){
-+ /* not on this hcd */
-+ continue;
-+ }
-+ funcMask = 1 << SDDEVICE_GET_SDIO_FUNCNO(pDevice);
-+ /* check device function against the pending mask */
-+ if (!(funcMask & pHcd->PendingHelperIrqs)) {
-+ /* this one is not scheduled for the helper */
-+ continue;
-+ }
-+ /* clear bit */
-+ pHcd->PendingHelperIrqs &= ~funcMask;
-+ /* check for sync IRQ and call handler */
-+ if (pDevice->pIrqFunction != NULL) {
-+ DBG_PRINT(SDIODBG_FUNC_IRQ, ("SDIO Bus Driver: Calling IRQ Handler. Fn:%d\n",
-+ SDDEVICE_GET_SDIO_FUNCNO(pDevice)));
-+ /* save the device so we can process it without holding any locks */
-+ pDeviceIRQ[deviceIrqCount++] = pDevice;
-+ } else {
-+ /* this is actually okay if the device is removing, the callback
-+ * is NULLed out */
-+ DBG_PRINT(SDIODBG_FUNC_IRQ, ("SDIO Bus Driver: No IRQ handler Fn:%d\n",
-+ SDDEVICE_GET_SDIO_FUNCNO(pDevice)));
-+ }
-+ }
-+ /* should have handled all these */
-+ DBG_ASSERT(pHcd->PendingHelperIrqs == 0);
-+ pHcd->PendingHelperIrqs = 0;
-+ SemaphorePost(&pBusContext->DeviceListSem);
-+ for (ii = 0; ii < deviceIrqCount; ii++) {
-+ /* now call the function */
-+ SDDEVICE_CALL_IRQ_HANDLER(pDeviceIRQ[ii]);
-+ }
-+ deviceIrqCount = 0;
-+ }
-+
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver - SDIOIrqHelperFunction Exiting.. \n"));
-+ return 0;
-+}
-+
-+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ GetPendingIrqComplete - completion routine for getting pending IRQs
-+ Input: pRequest - completed request
-+ Output:
-+ Return:
-+ Notes:
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+static void GetPendingIrqComplete(PSDREQUEST pReq)
-+{
-+ UINT8 intPendingMsk;
-+ PSDHCD pHcd;
-+
-+ do {
-+ pHcd = (PSDHCD)pReq->pCompleteContext;
-+ DBG_ASSERT(pHcd != NULL);
-+
-+ if (!SDIO_SUCCESS(pReq->Status)) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to get Interrupt pending register Err:%d\n",
-+ pReq->Status));
-+ break;
-+ }
-+
-+ if (SD_R5_GET_RESP_FLAGS(pReq->Response) & SD_R5_ERRORS) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: CMD52 resp error: 0x%X \n",
-+ SD_R5_GET_RESP_FLAGS(pReq->Response)));
-+ break;
-+ }
-+ /* extract the pending mask */
-+ intPendingMsk = SD_R5_GET_READ_DATA(pReq->Response) & SDIO_INT_PEND_MASK;
-+ /* process them */
-+ ProcessPendingIrqs(pHcd, intPendingMsk);
-+
-+ } while (FALSE);
-+
-+ FreeRequest(pReq);
-+
-+ DBG_PRINT(SDIODBG_FUNC_IRQ, ("-SDIO Bus Driver: GetPendingIrqComplete \n"));
-+}
-+
-+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ ProcessPendingIrqs - processing pending Irqs
-+ Input: pHcd - host controller
-+ Input: IntPendingMsk - pending irq bit mask
-+ Output:
-+ Return:
-+ Notes:
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+static void ProcessPendingIrqs(PSDHCD pHcd, UINT8 IntPendingMsk)
-+{
-+ PSDLIST pListItem;
-+ PSDDEVICE pDevice;
-+ UINT8 funcMask;
-+ SDIO_STATUS status = SDIO_STATUS_SUCCESS;
-+ CT_DECLARE_IRQ_SYNC_CONTEXT();
-+
-+ DBG_PRINT(SDIODBG_FUNC_IRQ, ("+SDIO Bus Driver: ProcessPendingIrqs \n"));
-+ do {
-+ /* acquire lock to protect configuration and irq enables */
-+ status = _AcquireHcdLock(pHcd);
-+ if (!SDIO_SUCCESS(status)) {
-+ break;
-+ }
-+
-+ /* sanity check */
-+ if ((IntPendingMsk & pHcd->IrqsEnabled) != IntPendingMsk) {
-+ DBG_PRINT(SDDBG_ERROR,
-+ ("SDIO Bus Driver: IRQs asserting when not enabled : curr:0x%X , card reports: 0x%X\n",
-+ pHcd->IrqsEnabled, IntPendingMsk));
-+ /* remove the pending IRQs that are not enabled */
-+ IntPendingMsk &= pHcd->IrqsEnabled;
-+ /* fall through */
-+ }
-+
-+ if (!IntPendingMsk) {
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: No interrupts on HCD:0x%X \n", (INT)pHcd));
-+ pHcd->IrqProcState = SDHCD_IDLE;
-+ if (pHcd->IrqsEnabled) {
-+ /* only re-arm if there are IRQs enabled */
-+ _IssueConfig(pHcd,SDCONFIG_SDIO_REARM_INT,NULL,0);
-+ }
-+ status = _ReleaseHcdLock(pHcd);
-+ break;
-+ }
-+ /* reset helper IRQ bits */
-+ pHcd->PendingHelperIrqs = 0;
-+ /* save pending IRQ acks */
-+ pHcd->PendingIrqAcks = IntPendingMsk;
-+ status = _ReleaseHcdLock(pHcd);
-+ DBG_PRINT(SDIODBG_FUNC_IRQ, ("SDIO Bus Driver: INTs Pending - 0x%2.2X \n", IntPendingMsk));
-+ /* take the device list lock as we iterate through the list, this blocks
-+ * device removals */
-+ status = SemaphorePendInterruptable(&pBusContext->DeviceListSem);
-+ if (!SDIO_SUCCESS(status)) {
-+ break;
-+ }
-+ /* walk through the device list matching HCD and interrupting function */
-+ SDITERATE_OVER_LIST(&pBusContext->DeviceList, pListItem) {
-+ pDevice = CONTAINING_STRUCT(pListItem, SDDEVICE, SDList);
-+ /* check if device belongs to the HCD */
-+ if (pDevice->pHcd != pHcd){
-+ /* not on this hcd */
-+ continue;
-+ }
-+ funcMask = 1 << SDDEVICE_GET_SDIO_FUNCNO(pDevice);
-+ /* check device function against the pending mask */
-+ if (!(funcMask & IntPendingMsk)) {
-+ /* this one is not interrupting */
-+ continue;
-+ }
-+ /* check for async IRQ and call handler */
-+ if (pDevice->pIrqAsyncFunction != NULL) {
-+ DBG_PRINT(SDIODBG_FUNC_IRQ, ("SDIO Bus Driver: Calling Async IRQ Handler. Fn:%d\n",
-+ SDDEVICE_GET_SDIO_FUNCNO(pDevice)));
-+ SDDEVICE_CALL_IRQ_ASYNC_HANDLER(pDevice);
-+ } else {
-+ /* this one needs the helper */
-+ pHcd->PendingHelperIrqs |= funcMask;
-+ DBG_PRINT(SDIODBG_FUNC_IRQ, ("SDIO Bus Driver: No Async IRQ, Pending Helper Fn:%d\n",
-+ SDDEVICE_GET_SDIO_FUNCNO(pDevice)));
-+ }
-+ }
-+ /* release HCD list lock */
-+ SemaphorePost(&pBusContext->DeviceListSem);
-+ /* check for helper IRQs */
-+ if (pHcd->PendingHelperIrqs) {
-+ pHcd->IrqProcState = SDHCD_IRQ_HELPER;
-+ DBG_PRINT(SDIODBG_FUNC_IRQ, ("SDIO Bus Driver: Waking IRQ Helper \n"));
-+ if (!SDIO_SUCCESS(SD_WAKE_OS_HELPER(&pHcd->SDIOIrqHelper))) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: failed to wake helper! \n"));
-+ }
-+ }
-+ } while (FALSE);
-+
-+ DBG_PRINT(SDIODBG_FUNC_IRQ, ("-SDIO Bus Driver: ProcessPendingIrqs \n"));
-+}
-+
-+SDIO_STATUS TryNoIrqPendingCheck(PSDDEVICE pDevice)
-+{
-+ if (pDevice->pHcd->CardProperties.IOFnCount > 1) {
-+ /* not supported on multi-function cards */
-+ DBG_PRINT(SDDBG_WARN, ("SDIO Bus Driver: IRQ Pending Check cannot be bypassed, (Funcs:%d)\n",
-+ pDevice->pHcd->CardProperties.IOFnCount));
-+ return SDIO_STATUS_UNSUPPORTED;
-+ }
-+
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: pending IRQ check bypassed \n"));
-+ /* set flag to optimize this */
-+ AtomicTest_Set(&pDevice->pHcd->HcdFlags, HCD_IRQ_NO_PEND_CHECK);
-+ return SDIO_STATUS_SUCCESS;
-+}
-+
-+
-+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ SDIO_NotifyTimerTriggered - notification handler that a timer expired
-+ Input: TimerID - ID of timer that expired
-+ Output:
-+ Return:
-+ Notes:
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+void SDIO_NotifyTimerTriggered(INT TimerID)
-+{
-+
-+ switch (TimerID) {
-+ case SDIOBUS_CD_TIMER_ID:
-+ pBusContext->CDTimerQueued = FALSE;
-+ /* post an HCD polling event to the helper thread */
-+ PostCardDetectEvent(pBusContext, EVENT_HCD_CD_POLLING, NULL);
-+ break;
-+ default:
-+ DBG_ASSERT(FALSE);
-+ }
-+
-+}
-diff --git a/drivers/sdio/stack/busdriver/sdio_bus_misc.c b/drivers/sdio/stack/busdriver/sdio_bus_misc.c
-new file mode 100644
-index 0000000..c5c7381
---- /dev/null
-+++ b/drivers/sdio/stack/busdriver/sdio_bus_misc.c
-@@ -0,0 +1,3122 @@
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+@file: sdio_bus_misc.c
-+
-+@abstract: OS independent bus driver support
-+
-+#notes: this file contains miscellaneous control functions
-+
-+@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
-+ *
-+ *
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+#define MODULE_NAME SDBUSDRIVER
-+#include <linux/sdio/ctsystem.h>
-+#include <linux/sdio/sdio_busdriver.h>
-+#include <linux/sdio/sdio_lib.h>
-+#include "_busdriver.h"
-+#include <linux/sdio/_sdio_defs.h>
-+#include <linux/sdio/mmc_defs.h>
-+
-+
-+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ IssueBusRequestBd - issue a bus request
-+ Input: pHcd - HCD object
-+ Cmd - command to issue
-+ Argument - command argument
-+ Flags - request flags
-+
-+ Output: pReqToUse - request to use (if caller wants response data)
-+ Return: SDIO Status
-+ Notes: This function only issues 1 block data transfers
-+ This function issues the request synchronously
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+SDIO_STATUS _IssueBusRequestBd(PSDHCD pHcd,
-+ UINT8 Cmd,
-+ UINT32 Argument,
-+ SDREQUEST_FLAGS Flags,
-+ PSDREQUEST pReqToUse,
-+ PVOID pData,
-+ INT Length)
-+{
-+ SDIO_STATUS status = SDIO_STATUS_SUCCESS;
-+ PSDREQUEST pReq;
-+
-+ if (NULL == pReqToUse) {
-+ /* caller doesn't care about the response data, allocate locally */
-+ pReq = AllocateRequest();
-+ if (NULL == pReq) {
-+ return SDIO_STATUS_NO_RESOURCES;
-+ }
-+ } else {
-+ /* use the caller's request buffer */
-+ pReq = pReqToUse;
-+ }
-+
-+ pReq->Argument = Argument;
-+ pReq->Flags = Flags;
-+ pReq->Command = Cmd;
-+ if (pReq->Flags & SDREQ_FLAGS_DATA_TRANS) {
-+ pReq->pDataBuffer = pData;
-+ pReq->BlockCount = 1;
-+ pReq->BlockLen = Length;
-+ }
-+
-+ status = IssueRequestToHCD(pHcd,pReq);
-+
-+ if (NULL == pReqToUse) {
-+ DBG_ASSERT(pReq != NULL);
-+ FreeRequest(pReq);
-+ }
-+ return status;
-+}
-+
-+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ ConvertVoltageCapsToOCRMask - initialize card
-+ Input: VoltageCaps - voltage cap to look up
-+ Return: 32 bit OCR mask
-+ Notes: this function sets voltage for +- 10%
-+
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+static UINT32 ConvertVoltageCapsToOCRMask(SLOT_VOLTAGE_MASK VoltageCaps)
-+{
-+ UINT32 ocrMask;
-+
-+ ocrMask = 0;
-+
-+ if (VoltageCaps & SLOT_POWER_3_3V) {
-+ ocrMask |= SD_OCR_3_2_TO_3_3_VDD | SD_OCR_3_3_TO_3_4_VDD;
-+ }
-+ if (VoltageCaps & SLOT_POWER_3_0V) {
-+ ocrMask |= SD_OCR_2_9_TO_3_0_VDD | SD_OCR_3_0_TO_3_1_VDD;
-+ }
-+ if (VoltageCaps & SLOT_POWER_2_8V) {
-+ ocrMask |= SD_OCR_2_7_TO_2_8_VDD | SD_OCR_2_8_TO_2_9_VDD;
-+ }
-+ if (VoltageCaps & SLOT_POWER_2_0V) {
-+ ocrMask |= SD_OCR_1_9_TO_2_0_VDD | SD_OCR_2_0_TO_2_1_VDD;
-+ }
-+ if (VoltageCaps & SLOT_POWER_1_8V) {
-+ ocrMask |= SD_OCR_1_7_TO_1_8_VDD | SD_OCR_1_8_TO_1_9_VDD;
-+ }
-+ if (VoltageCaps & SLOT_POWER_1_6V) {
-+ ocrMask |= SD_OCR_1_6_TO_1_7_VDD;
-+ }
-+
-+ return ocrMask;
-+}
-+
-+static UINT32 GetUsableOCRValue(UINT32 CardOCR, UINT32 SlotOCRMask)
-+{
-+ INT i;
-+ UINT32 mask = 0;
-+
-+ for (i = 0; i < 32; i++) {
-+ mask = 1 << i;
-+ if ((SlotOCRMask & mask) && (CardOCR & mask)) {
-+ return mask;
-+ }
-+ }
-+
-+ return mask;
-+}
-+
-+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ GetPowerSetting - power up the SDIO card
-+ Input: pHcd - HCD object
-+ pOCRvalue - OCR value of the card
-+ Output: pOCRvalue - OCR to actually use
-+ Return: power setting for HCD based on card's OCR, zero indicates unsupported
-+ Notes:
-+
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+static SLOT_VOLTAGE_MASK GetPowerSetting(PSDHCD pHcd, UINT32 *pOCRvalue)
-+{
-+ UINT32 ocrMask;
-+ SLOT_VOLTAGE_MASK hcdVoltage = 0;
-+ SLOT_VOLTAGE_MASK hcdVMask;
-+ INT i;
-+
-+ /* check preferred value */
-+ ocrMask = ConvertVoltageCapsToOCRMask(pHcd->SlotVoltagePreferred);
-+ if (ocrMask & *pOCRvalue) {
-+ /* using preferred voltage */
-+ *pOCRvalue = GetUsableOCRValue(*pOCRvalue, ocrMask);
-+ hcdVoltage = pHcd->SlotVoltagePreferred;
-+ } else {
-+ /* walk through the slot voltage caps and find a match */
-+ for (i = 0; i < 8; i++) {
-+ hcdVMask = (1 << i);
-+ if (hcdVMask & pHcd->SlotVoltageCaps) {
-+ ocrMask = ConvertVoltageCapsToOCRMask((SLOT_VOLTAGE_MASK)(pHcd->SlotVoltageCaps & hcdVMask));
-+ if (ocrMask & *pOCRvalue) {
-+ /* found a match */
-+ *pOCRvalue = GetUsableOCRValue(*pOCRvalue, ocrMask);
-+ hcdVoltage = pHcd->SlotVoltageCaps & hcdVMask;
-+ break;
-+ }
-+ }
-+ }
-+ }
-+
-+ return hcdVoltage;
-+}
-+
-+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ TestPresence - test the presence of a card/function
-+ Input: pHcd - HCD object
-+ TestType - type of test to perform
-+ Output: pReq - Request to use (optional)
-+ Return:
-+ Notes:
-+
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+SDIO_STATUS TestPresence(PSDHCD pHcd,
-+ CARD_INFO_FLAGS TestType,
-+ PSDREQUEST pReq)
-+{
-+ SDIO_STATUS status = SDIO_STATUS_ERROR;
-+
-+ switch (TestType) {
-+ case CARD_SDIO:
-+ /* issue CMD5 */
-+ status = _IssueSimpleBusRequest(pHcd,CMD5,0,
-+ SDREQ_FLAGS_RESP_SDIO_R4 | SDREQ_FLAGS_RESP_SKIP_SPI_FILT,pReq);
-+ break;
-+ case CARD_SD:
-+ if (IS_HCD_BUS_MODE_SPI(pHcd)) {
-+ /* ACMD41 just starts initialization when in SPI mode, argument is ignored
-+ * Note: In SPI mode ACMD41 uses an R1 response */
-+ status = _IssueSimpleBusRequest(pHcd,ACMD41,0,
-+ SDREQ_FLAGS_APP_CMD | SDREQ_FLAGS_RESP_R1,pReq);
-+
-+ } else {
-+ /* issue ACMD41 with OCR value of zero */
-+ /* ACMD41 on SD uses an R3 response */
-+ status = _IssueSimpleBusRequest(pHcd,ACMD41,0,
-+ SDREQ_FLAGS_APP_CMD | SDREQ_FLAGS_RESP_R3,pReq);
-+ }
-+ break;
-+ case CARD_MMC:
-+ /* issue CMD1 */
-+ if (IS_HCD_BUS_MODE_SPI(pHcd)) {
-+ /* note: in SPI mode an R1 response is used */
-+ status = _IssueSimpleBusRequest(pHcd,CMD1,0,SDREQ_FLAGS_RESP_R1,pReq);
-+ } else {
-+ status = _IssueSimpleBusRequest(pHcd,CMD1,0,SDREQ_FLAGS_RESP_R3,pReq);
-+ }
-+ break;
-+ default:
-+ DBG_ASSERT(FALSE);
-+ break;
-+ }
-+
-+ return status;
-+}
-+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ ReadOCR - read the OCR
-+ Input: pHcd - HCD object
-+ ReadType - type of read to perform
-+ OCRValue - OCR value to use as an argument
-+ Output: pReq - Request to use
-+ pOCRValueRd - OCR value read back (can be NULL)
-+ Return:
-+ Notes:
-+
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+static SDIO_STATUS ReadOCR(PSDHCD pHcd,
-+ CARD_INFO_FLAGS ReadType,
-+ PSDREQUEST pReq,
-+ UINT32 OCRValue,
-+ UINT32 *pOCRValueRd)
-+{
-+ SDIO_STATUS status = SDIO_STATUS_ERROR;
-+
-+ switch (ReadType) {
-+ case CARD_SDIO:
-+ /* CMD5 for SDIO cards */
-+ if (IS_HCD_BUS_MODE_SPI(pHcd)) {
-+ /* skip the SPI filter, we will decode the response here */
-+ status = _IssueSimpleBusRequest(pHcd,CMD5,
-+ OCRValue,
-+ SDREQ_FLAGS_RESP_SDIO_R4 |
-+ SDREQ_FLAGS_RESP_SKIP_SPI_FILT,
-+ pReq);
-+ } else {
-+ /* native SD */
-+ status = _IssueSimpleBusRequest(pHcd,CMD5,
-+ OCRValue,
-+ SDREQ_FLAGS_RESP_SDIO_R4,
-+ pReq);
-+ }
-+ break;
-+ case CARD_SD:
-+ if (IS_HCD_BUS_MODE_SPI(pHcd)) {
-+ /* CMD58 is used to read the OCR */
-+ status = _IssueSimpleBusRequest(pHcd,CMD58,
-+ 0, /* argument ignored */
-+ (SDREQ_FLAGS_RESP_R3 | SDREQ_FLAGS_RESP_SKIP_SPI_FILT),
-+ pReq);
-+ } else {
-+ /* SD Native uses ACMD41 */
-+ status = _IssueSimpleBusRequest(pHcd,ACMD41,
-+ OCRValue,
-+ SDREQ_FLAGS_APP_CMD | SDREQ_FLAGS_RESP_R3,
-+ pReq);
-+ }
-+ break;
-+ case CARD_MMC:
-+ if (IS_HCD_BUS_MODE_SPI(pHcd)) {
-+ /* CMD58 is used to read the OCR */
-+ status = _IssueSimpleBusRequest(pHcd,CMD58,
-+ 0, /* argument ignored */
-+ (SDREQ_FLAGS_RESP_R3 | SDREQ_FLAGS_RESP_SKIP_SPI_FILT),
-+ pReq);
-+ } else {
-+ /* MMC Native uses CMD1 */
-+ status = _IssueSimpleBusRequest(pHcd,CMD1,
-+ OCRValue, SDREQ_FLAGS_RESP_R3,
-+ pReq);
-+ }
-+ break;
-+ default:
-+ DBG_ASSERT(FALSE);
-+ break;
-+ }
-+
-+ if (SDIO_SUCCESS(status) && (pOCRValueRd != NULL)) {
-+ *pOCRValueRd = 0;
-+ /* someone wants the OCR read back */
-+ switch (ReadType) {
-+ case CARD_SDIO:
-+ if (IS_HCD_BUS_MODE_SPI(pHcd)) {
-+ *pOCRValueRd = SPI_SDIO_R4_GET_OCR(pReq->Response);
-+ } else {
-+ *pOCRValueRd = SD_SDIO_R4_GET_OCR(pReq->Response);
-+ }
-+ break;
-+ case CARD_SD:
-+ case CARD_MMC:
-+ if (IS_HCD_BUS_MODE_SPI(pHcd)) {
-+ *pOCRValueRd = SPI_R3_GET_OCR(pReq->Response);
-+ } else {
-+ *pOCRValueRd = SD_R3_GET_OCR(pReq->Response);
-+ }
-+ break;
-+ default:
-+ DBG_ASSERT(FALSE);
-+ break;
-+ }
-+ }
-+ return status;
-+}
-+
-+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ PollCardReady - poll card till it's ready
-+ Input: pHcd - HCD object
-+ OCRValue - OCR value to poll with
-+ PollType - polling type (based on card type)
-+ Output:
-+ Return:
-+ Notes:
-+
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+SDIO_STATUS PollCardReady(PSDHCD pHcd, UINT32 OCRValue, CARD_INFO_FLAGS PollType)
-+{
-+ INT cardReadyRetry;
-+ SDIO_STATUS status;
-+ PSDREQUEST pReq;
-+
-+ if (!((PollType == CARD_SDIO) || (PollType == CARD_SD) || (PollType == CARD_MMC))) {
-+ DBG_ASSERT(FALSE);
-+ return SDIO_STATUS_INVALID_PARAMETER;
-+ }
-+
-+ pReq = AllocateRequest();
-+ if (NULL == pReq) {
-+ return SDIO_STATUS_NO_RESOURCES;
-+ }
-+
-+ status = SDIO_STATUS_SUCCESS;
-+ cardReadyRetry = pBusContext->CardReadyPollingRetry;
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: Polling card ready, Using OCR:0x%8.8X, Poll Type:0x%X\n",
-+ OCRValue,PollType));
-+
-+ /* now issue CMD with the actual OCR as an argument until the card is ready */
-+ while (cardReadyRetry) {
-+ if (IS_HCD_BUS_MODE_SPI(pHcd) && !(PollType == CARD_SDIO)) {
-+ if (PollType == CARD_MMC) {
-+ /* under SPI mode for MMC cards, we need to issue CMD1 and
-+ * check the response for the "in-idle" bit */
-+ status = _IssueSimpleBusRequest(pHcd,
-+ CMD1,
-+ 0,
-+ SDREQ_FLAGS_RESP_R1 | SDREQ_FLAGS_RESP_SKIP_SPI_FILT,
-+ pReq);
-+ } else if (PollType == CARD_SD) {
-+ /* under SPI mode for SD cards, we need to issue ACMD41 and
-+ * check the response for the "in-idle" bit */
-+ status = _IssueSimpleBusRequest(pHcd,
-+ ACMD41,
-+ 0,
-+ SDREQ_FLAGS_RESP_R1 |
-+ SDREQ_FLAGS_APP_CMD |
-+ SDREQ_FLAGS_RESP_SKIP_SPI_FILT,
-+ pReq);
-+ } else {
-+ DBG_ASSERT(FALSE);
-+ }
-+ } else {
-+ /* for SD/MMC in native mode and SDIO (all modes) we need to read the OCR register */
-+ /* read the OCR using the supplied OCR value as an argument, we don't care about the
-+ * actual OCR read-back, but we are interested in the response */
-+ status = ReadOCR(pHcd,PollType,pReq,OCRValue,NULL);
-+ }
-+
-+ if (!SDIO_SUCCESS(status)) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to issue CMD to poll ready \n"));
-+ break;
-+ }
-+ if (PollType == CARD_SDIO) {
-+ if (IS_HCD_BUS_MODE_SPI(pHcd)) {
-+ if (SPI_SDIO_R4_IS_CARD_READY(pReq->Response)) {
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: SDIO Card Ready! (SPI) \n"));
-+ break;
-+ }
-+ } else {
-+ if (SD_SDIO_R4_IS_CARD_READY(pReq->Response)) {
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: SDIO Card Ready! \n"));
-+ break;
-+ }
-+ }
-+ } else if ((PollType == CARD_SD) || (PollType == CARD_MMC)) {
-+ if (IS_HCD_BUS_MODE_SPI(pHcd)) {
-+ /* check response when MMC or SD cards operate in SPI mode */
-+ if (!(GET_SPI_R1_RESP_TOKEN(pReq->Response) & SPI_CS_STATE_IDLE)) {
-+ /* card is no longer in idle */
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: SD/MMC Card (SPI mode) is ready! \n"));
-+ break;
-+ }
-+ } else {
-+ /* check the OCR busy bit */
-+ if (SD_R3_IS_CARD_READY(pReq->Response)) {
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: SD/MMC (Native Mode) Card Ready! \n"));
-+ break;
-+ }
-+ }
-+ } else {
-+ DBG_ASSERT(FALSE);
-+ }
-+ cardReadyRetry--;
-+ /* delay */
-+ status = OSSleep(OCR_READY_CHECK_DELAY_MS);
-+ if (!SDIO_SUCCESS(status)){
-+ break;
-+ }
-+ }
-+
-+ if (0 == cardReadyRetry) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Card Ready timeout! \n"));
-+ status = SDIO_STATUS_DEVICE_ERROR;
-+ }
-+
-+ FreeRequest(pReq);
-+
-+ return status;
-+}
-+
-+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ AdjustSlotPower - adjust slot power
-+ Input: pHcd - HCD object
-+ Output: pOCRvalue - ocr value to use
-+ Return:
-+ Notes:
-+
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+static SDIO_STATUS AdjustSlotPower(PSDHCD pHcd, UINT32 *pOCRvalue)
-+{
-+ SDCONFIG_POWER_CTRL_DATA pwrSetting;
-+ SDIO_STATUS status = SDIO_STATUS_SUCCESS;
-+
-+ ZERO_OBJECT(pwrSetting);
-+ DBG_PRINT(SDDBG_TRACE,
-+ ("SDIO Bus Driver: Adjusting Slot Power, Requesting adjustment for OCR:0x%8.8X \n",
-+ *pOCRvalue));
-+
-+ do {
-+ pwrSetting.SlotPowerEnable = TRUE;
-+ /* get optimal power setting */
-+ pwrSetting.SlotPowerVoltageMask = GetPowerSetting(pHcd, pOCRvalue);
-+ if (0 == pwrSetting.SlotPowerVoltageMask) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: No matching voltage for OCR \n"));
-+ status = SDIO_STATUS_DEVICE_ERROR;
-+ break;
-+ }
-+
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: Slot Pwr Mask 0x%X for OCR:0x%8.8X \n",
-+ pwrSetting.SlotPowerVoltageMask,*pOCRvalue));
-+ status = _IssueConfig(pHcd,SDCONFIG_POWER_CTRL,&pwrSetting,sizeof(pwrSetting));
-+ if (!SDIO_SUCCESS(status)) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to set power in hcd \n"));
-+ break;
-+ }
-+ /* delay for power to settle */
-+ OSSleep(pBusContext->PowerSettleDelay);
-+ /* save off for drivers */
-+ pHcd->CardProperties.CardVoltage = pwrSetting.SlotPowerVoltageMask;
-+
-+ } while (FALSE);
-+
-+ return status;
-+}
-+
-+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ ConvertEncodedTransSpeed - convert encoded TRANS_SPEED value to a clock rate
-+ Input: TransSpeedValue - encoded transfer speed value
-+ Output:
-+ Return: appropriate SD clock rate
-+ Notes: This function returns a rate of 0, if it could not be determined.
-+ This function can check tran speed values for SD,SDIO and MMC cards
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+static SD_BUSCLOCK_RATE ConvertEncodedTransSpeed(UINT8 TransSpeedValue)
-+{
-+ SD_BUSCLOCK_RATE transfMul = 0;
-+ UINT8 timeVal = 0;
-+
-+ switch (TransSpeedValue & TRANSFER_UNIT_MULTIPIER_MASK) {
-+ case 0:
-+ transfMul = 10000;
-+ break;
-+ case 1:
-+ transfMul = 100000;
-+ break;
-+ case 2:
-+ transfMul = 1000000;
-+ break;
-+ case 3:
-+ transfMul = 10000000;
-+ break;
-+ default:
-+ transfMul = 0;
-+ DBG_PRINT(SDDBG_WARN, ("SDIO Bus Driver: Card transfer multipler is wrong (val=0x%X)! \n",
-+ TransSpeedValue));
-+ break;
-+ }
-+
-+ switch ((TransSpeedValue & TIME_VALUE_MASK) >> TIME_VALUE_SHIFT) {
-+ case 1: timeVal = 10; break;
-+ case 2: timeVal = 12; break;
-+ case 3: timeVal = 13; break;
-+ case 4: timeVal = 15; break;
-+ case 5: timeVal = 20; break;
-+ case 6: timeVal = 25; break;
-+ case 7: timeVal = 30; break;
-+ case 8: timeVal = 35; break;
-+ case 9: timeVal = 40; break;
-+ case 10: timeVal = 45; break;
-+ case 11: timeVal = 50; break;
-+ case 12: timeVal = 55; break;
-+ case 13: timeVal = 60; break;
-+ case 14: timeVal = 70; break;
-+ case 15: timeVal = 80; break;
-+ default: timeVal = 0;
-+ DBG_PRINT(SDDBG_WARN, ("SDIO Bus Driver: Card time value is wrong (val=0x%X)! \n",
-+ TransSpeedValue));
-+ break;
-+ }
-+
-+ if ((transfMul != 0) && (timeVal != 0)) {
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: Card Reported Max: %d Hz (0x%X) \n",
-+ (timeVal*transfMul), TransSpeedValue));
-+ return timeVal*transfMul;
-+ }
-+
-+ return 0;
-+}
-+
-+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ SelectDeselectCard - Select or deselect a card
-+ Input: pHcd - HCD object
-+ Select - select the card
-+ Output:
-+ Return: status
-+ Notes:
-+
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+static SDIO_STATUS SelectDeselectCard(PSDHCD pHcd, BOOL Select)
-+{
-+ SDIO_STATUS status;
-+
-+ if (IS_HCD_BUS_MODE_SPI(pHcd)) {
-+ /* SPI mode cards do not support selection */
-+ status = SDIO_STATUS_SUCCESS;
-+ } else {
-+ if (!Select) {
-+ /* deselect, note that deselecting a card does not return a response */
-+ status = _IssueSimpleBusRequest(pHcd,
-+ CMD7,0,
-+ SDREQ_FLAGS_NO_RESP,NULL);
-+ } else {
-+ /* select */
-+ status = _IssueSimpleBusRequest(pHcd,
-+ CMD7,(pHcd->CardProperties.RCA << 16),
-+ SDREQ_FLAGS_RESP_R1B,NULL);
-+ }
-+ }
-+
-+ if (!SDIO_SUCCESS(status)) {
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: Failed to %s card, RCA:0x%X Err:%d \n",
-+ (Select ? "Select":"Deselect"), pHcd->CardProperties.RCA, status));
-+ }
-+ return status;
-+}
-+
-+/* reorder a buffer by swapping MSB with LSB */
-+static void ReorderBuffer(UINT8 *pBuffer, INT Bytes)
-+{
-+ UINT8 *pEnd;
-+ UINT8 temp;
-+
-+ DBG_ASSERT(!(Bytes & 1));
-+ /* point to the end */
-+ pEnd = &pBuffer[Bytes - 1];
-+ /* divide in half */
-+ Bytes = Bytes >> 1;
-+
-+ while (Bytes) {
-+ temp = *pBuffer;
-+ /* swap bytes */
-+ *pBuffer = *pEnd;
-+ *pEnd = temp;
-+ pBuffer++;
-+ pEnd--;
-+ Bytes--;
-+ }
-+}
-+
-+#define ADJUST_OPER_CLOCK(pBusMode,Clock) \
-+ (pBusMode)->ClockRate = min((SD_BUSCLOCK_RATE)(Clock),(pBusMode)->ClockRate)
-+#define ADJUST_OPER_BLOCK_LEN(pCaps,Length) \
-+ (pCaps)->OperBlockLenLimit = min((UINT16)(Length),(pCaps)->OperBlockLenLimit)
-+#define ADJUST_OPER_BLOCK_COUNT(pCaps,Count) \
-+ (pCaps)->OperBlockCountLimit = min((UINT16)(Count),(pCaps)->OperBlockCountLimit)
-+
-+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ GetBusParameters - Get bus parameters for a card
-+ Input: pHcd - HCD object
-+ pBusMode - current bus mode on entry
-+ Output: pBusMode - new adjusted bus mode
-+ Return: status
-+ Notes:
-+
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+static SDIO_STATUS GetBusParameters(PSDHCD pHcd, PSDCONFIG_BUS_MODE_DATA pBusMode)
-+{
-+ SDIO_STATUS status = SDIO_STATUS_SUCCESS;
-+ UINT8 temp;
-+ UINT32 tplAddr;
-+ struct SDIO_FUNC_EXT_COMMON_TPL func0ext;
-+ UINT8 scrRegister[SD_SCR_BYTES];
-+ SD_BUSCLOCK_RATE cardReportedRate = 0;
-+ PSDREQUEST pReq = NULL;
-+ BOOL spiMode = FALSE;
-+
-+
-+ if (SDCONFIG_GET_BUSWIDTH(pBusMode->BusModeFlags) == SDCONFIG_BUS_WIDTH_SPI) {
-+ spiMode = TRUE;
-+ }
-+
-+ if (!spiMode) {
-+ /* set highest bus mode bus driver is allowing (non-SPI), the code below will
-+ * adjust to lower or equal settings */
-+ pBusMode->BusModeFlags = pBusContext->DefaultBusMode;
-+ }
-+ /* set operational parameters */
-+ pBusMode->ClockRate = pBusContext->DefaultOperClock;
-+ pHcd->CardProperties.OperBlockLenLimit = pBusContext->DefaultOperBlockLen;
-+ pHcd->CardProperties.OperBlockCountLimit = pBusContext->DefaultOperBlockCount;
-+
-+ /* adjust operational block counts and length to match HCD */
-+ ADJUST_OPER_BLOCK_LEN(&pHcd->CardProperties,pHcd->MaxBytesPerBlock);
-+ ADJUST_OPER_BLOCK_COUNT(&pHcd->CardProperties,pHcd->MaxBlocksPerTrans);
-+ /* limit operational clock to the max clock rate */
-+ ADJUST_OPER_CLOCK(pBusMode,pHcd->MaxClockRate);
-+
-+ if (!spiMode) {
-+ /* check HCD bus mode */
-+ if (!(pHcd->Attributes & SDHCD_ATTRIB_BUS_4BIT) ||
-+ ((pHcd->CardProperties.Flags & CARD_SDIO) &&
-+ (pHcd->Attributes & SDHCD_ATTRIB_NO_4BIT_IRQ)) ) {
-+
-+ if (pHcd->Attributes & SDHCD_ATTRIB_BUS_4BIT) {
-+ DBG_PRINT(SDDBG_WARN,
-+ ("SDIO Card Detected, but host does not support IRQs in 4 bit mode - dropping to 1 bit. \n"));
-+ }
-+ /* force to 1 bit mode */
-+ SDCONFIG_SET_BUS_WIDTH(pBusMode->BusModeFlags, SDCONFIG_BUS_WIDTH_1_BIT);
-+ }
-+ }
-+
-+ /* now do various card inquiries to drop the bus mode or clock
-+ * none of these checks can raise the bus mode or clock higher that what
-+ * was initialized above */
-+ do {
-+ if (pHcd->CardProperties.Flags & (CARD_SD | CARD_MMC)) {
-+ /* allocate a request for response data we'll need */
-+ pReq = AllocateRequest();
-+ if (NULL == pReq) {
-+ status = SDIO_STATUS_NO_RESOURCES;
-+ break;
-+ }
-+ }
-+
-+ if (!spiMode && (pHcd->CardProperties.Flags & CARD_MMC)) {
-+ /* MMC cards all run in 1 bit mode */
-+ SDCONFIG_SET_BUS_WIDTH(pBusMode->BusModeFlags, SDCONFIG_BUS_WIDTH_1_BIT);
-+ }
-+
-+ if (pHcd->CardProperties.Flags & CARD_SD) {
-+ DBG_ASSERT(pReq != NULL);
-+ DBG_PRINT(SDDBG_TRACE, ("Getting SCR from SD Card..\n"));
-+ /* read SCR (requires data transfer) to get supported modes */
-+ status = _IssueBusRequestBd(pHcd,ACMD51,0,
-+ SDREQ_FLAGS_RESP_R1 | SDREQ_FLAGS_APP_CMD |
-+ SDREQ_FLAGS_DATA_TRANS,
-+ pReq,&scrRegister,SD_SCR_BYTES);
-+ if (!SDIO_SUCCESS(status)) {
-+ DBG_PRINT(SDDBG_WARN, ("SD card does not have SCR. \n"));
-+ if (!spiMode) {
-+ /* switch it to 1 bit mode */
-+ SDCONFIG_SET_BUS_WIDTH(pBusMode->BusModeFlags, SDCONFIG_BUS_WIDTH_1_BIT);
-+ }
-+ status = SDIO_STATUS_SUCCESS;
-+ } else {
-+ /* we have to reorder this buffer since the SCR is sent MSB first on the data
-+ * data bus */
-+ ReorderBuffer(scrRegister,SD_SCR_BYTES);
-+ /* got the SCR */
-+ DBG_PRINT(SDDBG_TRACE, ("SD SCR StructRev:0x%X, Flags:0x%X \n",
-+ GET_SD_SCR_STRUCT_VER(scrRegister),
-+ GET_SD_SCR_BUSWIDTHS_FLAGS(scrRegister)));
-+ /* set the revision */
-+ switch (GET_SD_SCR_SDSPEC_VER(scrRegister)) {
-+ case SCR_SD_SPEC_1_00:
-+ DBG_PRINT(SDDBG_TRACE, ("SD Spec Revision 1.01 \n"));
-+ pHcd->CardProperties.SD_MMC_Revision = SD_REVISION_1_01;
-+ break;
-+ case SCR_SD_SPEC_1_10:
-+ DBG_PRINT(SDDBG_TRACE, ("SD Spec Revision 1.10 \n"));
-+ pHcd->CardProperties.SD_MMC_Revision = SD_REVISION_1_10;
-+ break;
-+ default:
-+ DBG_PRINT(SDDBG_WARN, ("SD Spec Revision is greater than 1.10 \n"));
-+ pHcd->CardProperties.SD_MMC_Revision = SD_REVISION_1_10;
-+ break;
-+ }
-+
-+ if (!(GET_SD_SCR_BUSWIDTHS(scrRegister) & SCR_BUS_SUPPORTS_4_BIT)) {
-+ if (!spiMode) {
-+ DBG_PRINT(SDDBG_WARN, ("SD SCR reports 1bit only Mode \n"));
-+ /* switch it to 1 bit mode */
-+ SDCONFIG_SET_BUS_WIDTH(pBusMode->BusModeFlags, SDCONFIG_BUS_WIDTH_1_BIT);
-+ }
-+ }
-+ }
-+ }
-+
-+ if (pHcd->CardProperties.Flags & (CARD_SD | CARD_MMC)) {
-+ DBG_ASSERT(pReq != NULL);
-+ /* de-select the card in order to get the CSD */
-+ status = SelectDeselectCard(pHcd,FALSE);
-+ if (!SDIO_SUCCESS(status)) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to deselect card before getting CSD \n"));
-+ break;
-+ }
-+ /* Get CSD for SD or MMC cards */
-+ if (spiMode) {
-+ /* in SPI mode, getting the CSD requires a read data transfer */
-+ status = _IssueBusRequestBd(pHcd,CMD9,0,
-+ SDREQ_FLAGS_RESP_R1 | SDREQ_FLAGS_DATA_TRANS,
-+ pReq,
-+ pHcd->CardProperties.CardCSD,
-+ MAX_CSD_CID_BYTES);
-+ if (SDIO_SUCCESS(status)) {
-+ /* when the CSD is sent over in SPI data mode, it comes to us in MSB first
-+ * and thus is not ordered correctly as defined in the SD spec */
-+ ReorderBuffer(pHcd->CardProperties.CardCSD,MAX_CSD_CID_BYTES);
-+ }
-+ } else {
-+ status = _IssueSimpleBusRequest(pHcd,
-+ CMD9,
-+ (pHcd->CardProperties.RCA << 16),
-+ SDREQ_FLAGS_RESP_R2,
-+ pReq);
-+ if (SDIO_SUCCESS(status)) {
-+ /* save the CSD */
-+ memcpy(pHcd->CardProperties.CardCSD,pReq->Response,MAX_CARD_RESPONSE_BYTES);
-+ }
-+ }
-+
-+ if (!SDIO_SUCCESS(status)) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to get CSD, Err:%d \n",
-+ status));
-+ break;
-+ }
-+ /* for MMC cards, the spec version is in the CSD */
-+ if (pHcd->CardProperties.Flags & CARD_MMC) {
-+ DBG_PRINT(SDDBG_TRACE, ("MMC Spec version : (0x%2.2X) \n",
-+ GET_MMC_SPEC_VERSION(pHcd->CardProperties.CardCSD)));
-+ switch (GET_MMC_SPEC_VERSION(pHcd->CardProperties.CardCSD)) {
-+ case MMC_SPEC_1_0_TO_1_2:
-+ case MMC_SPEC_1_4:
-+ case MMC_SPEC_2_0_TO_2_2:
-+ DBG_PRINT(SDDBG_WARN, ("MMC Spec version less than 3.1 \n"));
-+ pHcd->CardProperties.SD_MMC_Revision = MMC_REVISION_1_0_2_2;
-+ break;
-+ case MMC_SPEC_3_1:
-+ DBG_PRINT(SDDBG_TRACE, ("MMC Spec version 3.1 \n"));
-+ pHcd->CardProperties.SD_MMC_Revision = MMC_REVISION_3_1;
-+ break;
-+ case MMC_SPEC_4_0_TO_4_1:
-+ DBG_PRINT(SDDBG_TRACE, ("MMC Spec version 4.0-4.1 \n"));
-+ pHcd->CardProperties.SD_MMC_Revision = MMC_REVISION_4_0;
-+ break;
-+ default:
-+ pHcd->CardProperties.SD_MMC_Revision = MMC_REVISION_3_1;
-+ DBG_PRINT(SDDBG_WARN, ("MMC Spec version greater than 4.1\n"));
-+ break;
-+ }
-+ }
-+ /* re-select the card */
-+ status = SelectDeselectCard(pHcd,TRUE);
-+ if (!SDIO_SUCCESS(status)) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to re-select card after getting CSD \n"));
-+ break;
-+ }
-+ }
-+
-+ if ((pHcd->CardProperties.Flags & CARD_SD) &&
-+ !(pHcd->CardProperties.Flags & CARD_SDIO) &&
-+ SDDEVICE_IS_SD_REV_GTEQ_1_10(pHcd->pPseudoDev) &&
-+ (pHcd->Attributes & SDHCD_ATTRIB_SD_HIGH_SPEED) &&
-+ !spiMode) {
-+ UINT32 arg;
-+ PUINT8 pSwitchStatusBlock = KernelAlloc(SD_SWITCH_FUNC_STATUS_BLOCK_BYTES);
-+
-+ if (NULL == pSwitchStatusBlock) {
-+ status = SDIO_STATUS_NO_RESOURCES;
-+ break;
-+ }
-+
-+ arg = SD_SWITCH_FUNC_ARG_GROUP_CHECK(SD_SWITCH_HIGH_SPEED_GROUP,
-+ SD_SWITCH_HIGH_SPEED_FUNC_NO);
-+
-+ /* for 1.10 SD cards, check if high speed mode is supported */
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: Checking SD Card for switchable functions (CMD6 arg:0x%X)\n",arg));
-+
-+ /* issue simple data transfer request to read the switch status */
-+ status = _IssueBusRequestBd(pHcd,
-+ CMD6,
-+ arg,
-+ SDREQ_FLAGS_RESP_R1 | SDREQ_FLAGS_DATA_TRANS,
-+ pReq,
-+ pSwitchStatusBlock,
-+ SD_SWITCH_FUNC_STATUS_BLOCK_BYTES);
-+
-+ if (SDIO_SUCCESS(status)) {
-+ UINT16 switchGroupMask;
-+ /* need to reorder this since cards send this MSB first */
-+ ReorderBuffer(pSwitchStatusBlock,SD_SWITCH_FUNC_STATUS_BLOCK_BYTES);
-+ switchGroupMask = SD_SWITCH_FUNC_STATUS_GET_GRP_BIT_MASK(pSwitchStatusBlock,SD_SWITCH_HIGH_SPEED_GROUP);
-+ DBG_PRINT(SDDBG_TRACE, ("SD Card Switch Status Group1 Mask:0x%X Max Current:%d\n",
-+ switchGroupMask, SD_SWITCH_FUNC_STATUS_GET_MAX_CURRENT(pSwitchStatusBlock) ));
-+ if (SD_SWITCH_FUNC_STATUS_GET_MAX_CURRENT(pSwitchStatusBlock) == 0) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: SD Switch Status block has zero max current \n"));
-+ SDLIB_PrintBuffer(pSwitchStatusBlock,
-+ SD_SWITCH_FUNC_STATUS_BLOCK_BYTES,
-+ "SDIO Bus Driver: SD Switch Status Block Error");
-+ } else {
-+ /* check HS support */
-+ if (switchGroupMask & (1 << SD_SWITCH_HIGH_SPEED_FUNC_NO)) {
-+ DBG_PRINT(SDDBG_TRACE, ("SD Card Supports High Speed Mode\n"));
-+ /* set the rate, this will override the CSD value */
-+ cardReportedRate = SD_HS_MAX_BUS_CLOCK;
-+ pBusMode->BusModeFlags |= SDCONFIG_BUS_MODE_SD_HS;
-+ }
-+ }
-+ } else {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to get SD Switch Status block (%d)\n", status));
-+ /* just fall through, we'll handle this like a normal SD card */
-+ status = SDIO_STATUS_SUCCESS;
-+ }
-+
-+ KernelFree(pSwitchStatusBlock);
-+ }
-+
-+ if ((pHcd->CardProperties.Flags & CARD_MMC) &&
-+ SDDEVICE_IS_MMC_REV_GTEQ_4_0(pHcd->pPseudoDev) &&
-+ (pHcd->Attributes & SDHCD_ATTRIB_MMC_HIGH_SPEED) &&
-+ !spiMode) {
-+ /* for MMC cards, get the Extended CSD to get the High speed and
-+ * wide bus paramaters */
-+
-+ PUINT8 pExtData = KernelAlloc(MMC_EXT_CSD_SIZE);
-+
-+ if (NULL == pExtData) {
-+ status = SDIO_STATUS_NO_RESOURCES;
-+ break;
-+ }
-+ /* issue simple data transfer request to read the extended CSD */
-+ status = _IssueBusRequestBd(pHcd,MMC_CMD8,0,
-+ SDREQ_FLAGS_RESP_R1 | SDREQ_FLAGS_DATA_TRANS,
-+ pReq,
-+ pExtData,
-+ MMC_EXT_CSD_SIZE);
-+ if (SDIO_SUCCESS(status)) {
-+ DBG_PRINT(SDDBG_TRACE, ("MMC Ext CSD Version: 0x%X Card Type: 0x%X\n",
-+ pExtData[MMC_EXT_VER_OFFSET],pExtData[MMC_EXT_CARD_TYPE_OFFSET]));
-+ /* check HS support */
-+ if (pExtData[MMC_EXT_CARD_TYPE_OFFSET] & MMC_EXT_CARD_TYPE_HS_52) {
-+ /* try 52 Mhz */
-+ cardReportedRate = 52000000;
-+ pBusMode->BusModeFlags |= SDCONFIG_BUS_MODE_MMC_HS;
-+ } else if (pExtData[MMC_EXT_CARD_TYPE_OFFSET] & MMC_EXT_CARD_TYPE_HS_26) {
-+ /* try 26MHZ */
-+ cardReportedRate = 26000000;
-+ pBusMode->BusModeFlags |= SDCONFIG_BUS_MODE_MMC_HS;
-+ } else {
-+ /* doesn't report high speed capable */
-+ cardReportedRate = 0;
-+ }
-+
-+ if (cardReportedRate && !spiMode) {
-+ /* figure out the bus mode */
-+ if (pHcd->Attributes & SDHCD_ATTRIB_BUS_MMC8BIT) {
-+ SDCONFIG_SET_BUS_WIDTH(pBusMode->BusModeFlags, SDCONFIG_BUS_WIDTH_MMC8_BIT);
-+ } else if (pHcd->Attributes & SDHCD_ATTRIB_BUS_4BIT) {
-+ SDCONFIG_SET_BUS_WIDTH(pBusMode->BusModeFlags, SDCONFIG_BUS_WIDTH_4_BIT);
-+ } else {
-+ /* we leave it to default to 1 bit mode */
-+ }
-+ }
-+ } else {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to get MMC Extended CSD \n"));
-+ /* just fall through, we'll do without the extended information
-+ * and run it like a legacy MMC card */
-+ status = SDIO_STATUS_SUCCESS;
-+ }
-+
-+ KernelFree(pExtData);
-+ }
-+
-+ if (pHcd->CardProperties.Flags & (CARD_SD | CARD_MMC)) {
-+
-+ if (0 == cardReportedRate) {
-+ /* extract rate from CSD only if it was not set by earlier tests */
-+ cardReportedRate = ConvertEncodedTransSpeed(
-+ GET_SD_CSD_TRANS_SPEED(pHcd->CardProperties.CardCSD));
-+ /* fall through and test for zero again */
-+ }
-+
-+ if (cardReportedRate != 0) {
-+ /* adjust clock based on what the card can handle */
-+ ADJUST_OPER_CLOCK(pBusMode,cardReportedRate);
-+ } else {
-+ /* something is wrong with the CSD */
-+ if (DBG_GET_DEBUG_LEVEL() >= SDDBG_TRACE) {
-+ SDLIB_PrintBuffer(pHcd->CardProperties.CardCSD,
-+ MAX_CARD_RESPONSE_BYTES,
-+ "SDIO Bus Driver: CSD Dump");
-+ }
-+ /* can't figure out the card rate, so set reasonable defaults */
-+ if (pHcd->CardProperties.Flags & CARD_SD) {
-+ ADJUST_OPER_CLOCK(pBusMode,SD_MAX_BUS_CLOCK);
-+ } else {
-+ ADJUST_OPER_CLOCK(pBusMode,MMC_MAX_BUS_CLOCK);
-+ }
-+ }
-+ }
-+
-+ /* note, we do SDIO card "after" SD in case this is a combo card */
-+ if (pHcd->CardProperties.Flags & CARD_SDIO) {
-+ /* read card capabilities */
-+ status = Cmd52ReadByteCommon(pHcd->pPseudoDev,
-+ SDIO_CARD_CAPS_REG,
-+ &pHcd->CardProperties.SDIOCaps);
-+ if (!SDIO_SUCCESS(status)) {
-+ break;
-+ }
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Card Caps: 0x%X \n",pHcd->CardProperties.SDIOCaps));
-+ if (pHcd->CardProperties.SDIOCaps & SDIO_CAPS_LOW_SPEED) {
-+ /* adjust max clock for LS device */
-+ ADJUST_OPER_CLOCK(pBusMode,SDIO_LOW_SPEED_MAX_BUS_CLOCK);
-+ /* adjust bus if LS device does not support 4 bit mode */
-+ if (!(pHcd->CardProperties.SDIOCaps & SDIO_CAPS_4BIT_LS)) {
-+ if (!spiMode) {
-+ /* low speed device does not support 4 bit mode, force us to 1 bit */
-+ SDCONFIG_SET_BUS_WIDTH(pBusMode->BusModeFlags,
-+ SDCONFIG_BUS_WIDTH_1_BIT);
-+ }
-+ }
-+ }
-+
-+ /* check if 1.2 card supports high speed mode, checking HCD as well*/
-+ if (SDDEVICE_IS_SDIO_REV_GTEQ_1_20(pHcd->pPseudoDev) &&
-+ (pHcd->Attributes & SDHCD_ATTRIB_SD_HIGH_SPEED) &&
-+ !spiMode) {
-+ UCHAR hsControl = 0;
-+
-+ status = Cmd52ReadByteCommon(pHcd->pPseudoDev,
-+ SDIO_HS_CONTROL_REG,
-+ &hsControl);
-+
-+ if (!SDIO_SUCCESS(status)) {
-+ DBG_PRINT(SDDBG_TRACE,
-+ ("SDIO Failed to read high speed control (%d) \n",status));
-+ /* reset status and continue */
-+ status = SDIO_STATUS_SUCCESS;
-+ } else {
-+ if (hsControl & SDIO_HS_CONTROL_SHS) {
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Card Supports High Speed Mode\n"));
-+ pBusMode->BusModeFlags |= SDCONFIG_BUS_MODE_SD_HS;
-+ }
-+ }
-+
-+ }
-+
-+ cardReportedRate = 0;
-+ temp = sizeof(func0ext);
-+ tplAddr = pHcd->CardProperties.CommonCISPtr;
-+ /* get the FUNCE tuple */
-+ status = SDLIB_FindTuple(pHcd->pPseudoDev,
-+ CISTPL_FUNCE,
-+ &tplAddr,
-+ (PUINT8)&func0ext,
-+ &temp);
-+ if (!SDIO_SUCCESS(status) || (temp < sizeof(func0ext))) {
-+ DBG_PRINT(SDDBG_WARN, ("SDIO Function 0 Ext. Tuple Missing (Got size:%d) \n", temp));
-+ /* reset status */
-+ status = SDIO_STATUS_SUCCESS;
-+ } else {
-+ /* convert encoded value to rate */
-+ cardReportedRate = ConvertEncodedTransSpeed(func0ext.MaxTransSpeed);
-+ }
-+
-+ if (cardReportedRate != 0) {
-+ if (pBusMode->BusModeFlags & SDCONFIG_BUS_MODE_SD_HS) {
-+ if (cardReportedRate <= SD_MAX_BUS_CLOCK) {
-+ DBG_PRINT(SDDBG_WARN,
-+ ("SDIO Function tuple reports clock:%d Hz, with advertised High Speed support \n", cardReportedRate));
-+ /* back off high speed support */
-+ pBusMode->BusModeFlags &= ~SDCONFIG_BUS_MODE_SD_HS;
-+ }
-+ } else {
-+ if (cardReportedRate > SD_MAX_BUS_CLOCK) {
-+ DBG_PRINT(SDDBG_WARN,
-+ ("SDIO Function tuple reports clock:%d Hz, without advertising High Speed support..using 25Mhz \n", cardReportedRate));
-+ cardReportedRate = SD_MAX_BUS_CLOCK;
-+ }
-+ }
-+ /* adjust clock based on what the card can handle */
-+ ADJUST_OPER_CLOCK(pBusMode,cardReportedRate);
-+
-+ } else {
-+ /* set a reasonable default */
-+ ADJUST_OPER_CLOCK(pBusMode,SD_MAX_BUS_CLOCK);
-+ }
-+ }
-+ } while (FALSE);
-+
-+ if (pReq != NULL) {
-+ FreeRequest(pReq);
-+ }
-+ return status;
-+}
-+
-+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ SetOperationalBusMode - set operational bus mode
-+ Input: pDevice - pDevice that is requesting the change
-+ pBusMode - operational bus mode
-+ Output: pBusMode - on return will have the actual clock rate set
-+ Return: status
-+ Notes:
-+
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+SDIO_STATUS SetOperationalBusMode(PSDDEVICE pDevice,
-+ PSDCONFIG_BUS_MODE_DATA pBusMode)
-+{
-+ SDIO_STATUS status = SDIO_STATUS_SUCCESS;
-+ UCHAR regData;
-+ UINT32 arg;
-+ UINT32 switcharg;
-+ PSDHCD pHcd = pDevice->pHcd;
-+
-+ /* synchronize access for updating bus mode settings */
-+ status = SemaphorePendInterruptable(&pDevice->pHcd->ConfigureOpsSem);
-+ if (!SDIO_SUCCESS(status)) {
-+ return status;
-+ }
-+
-+ do {
-+
-+ if (!IS_CARD_PRESENT(pHcd)) {
-+ /* for an empty slot (a Pseudo dev was passed in) we still allow the
-+ * bus mode to be set for the card detect
-+ * polling */
-+ status = _IssueConfig(pHcd,SDCONFIG_BUS_MODE_CTRL,pBusMode,sizeof(SDCONFIG_BUS_MODE_DATA));
-+ if (!SDIO_SUCCESS(status)) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to set bus mode in hcd : Err:%d \n",
-+ status));
-+ }
-+ /* nothing more to do */
-+ break;
-+ }
-+
-+
-+ if ((pBusMode->BusModeFlags == SDDEVICE_GET_BUSMODE_FLAGS(pDevice)) &&
-+ (pBusMode->ClockRate == SDDEVICE_GET_OPER_CLOCK(pDevice))) {
-+ DBG_PRINT(SDDBG_TRACE,
-+ ("SDIO Bus Driver: Bus mode already set, nothing to do\n"));
-+ pBusMode->ActualClockRate = SDDEVICE_GET_OPER_CLOCK(pDevice);
-+ break;
-+ }
-+
-+ if (pBusMode->BusModeFlags & SDCONFIG_BUS_MODE_MMC_HS) {
-+ if (!(pHcd->Attributes & SDHCD_ATTRIB_MMC_HIGH_SPEED)) {
-+ status = SDIO_STATUS_INVALID_PARAMETER;
-+ DBG_PRINT(SDDBG_ERROR,
-+ ("SDIO Bus Driver: HCD does not support MMC High Speed\n"));
-+ break;
-+ }
-+ }
-+
-+ if (pBusMode->BusModeFlags & SDCONFIG_BUS_MODE_SD_HS) {
-+ if (!(pHcd->Attributes & SDHCD_ATTRIB_SD_HIGH_SPEED)) {
-+ status = SDIO_STATUS_INVALID_PARAMETER;
-+ DBG_PRINT(SDDBG_ERROR,
-+ ("SDIO Bus Driver: HCD does not support SD High Speed\n"));
-+ break;
-+ }
-+ }
-+
-+ /* before we set the operational clock and mode, configure the clock for high
-+ * speed mode on the card , if necessary */
-+ if ((pHcd->CardProperties.Flags & CARD_MMC) &&
-+ (pBusMode->BusModeFlags & SDCONFIG_BUS_MODE_MMC_HS) &&
-+ !(SDDEVICE_GET_BUSMODE_FLAGS(pDevice) & SDCONFIG_BUS_MODE_MMC_HS)) {
-+
-+ switcharg = MMC_SWITCH_BUILD_ARG(MMC_SWITCH_CMD_SET0,
-+ MMC_SWITCH_WRITE_BYTE,
-+ MMC_EXT_HS_TIMING_OFFSET,
-+ MMC_EXT_HS_TIMING_ENABLE);
-+ status = _IssueSimpleBusRequest(pHcd,
-+ MMC_CMD_SWITCH,
-+ switcharg,
-+ SDREQ_FLAGS_RESP_R1B,
-+ NULL);
-+ if (!SDIO_SUCCESS(status)) {
-+ DBG_PRINT(SDDBG_ERROR,
-+ ("SDIO Bus Driver: Failed to switch MMC High Speed Mode (arg:0x%X): %d \n",
-+ switcharg, status));
-+ break;
-+ }
-+
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: High Speed MMC enabled (arg:0x%X)\n",
-+ switcharg));
-+ }
-+
-+ /* before setting bus mode and clock in the HCD, switch card to high speed mode
-+ * if necessary */
-+ if ((pHcd->CardProperties.Flags & CARD_SD) &&
-+ (pBusMode->BusModeFlags & SDCONFIG_BUS_MODE_SD_HS) &&
-+ !(SDDEVICE_GET_BUSMODE_FLAGS(pDevice) & SDCONFIG_BUS_MODE_SD_HS)) {
-+ UINT32 arg;
-+ PUINT8 pSwitchStatusBlock;
-+
-+ pSwitchStatusBlock = KernelAlloc(SD_SWITCH_FUNC_STATUS_BLOCK_BYTES);
-+
-+ if (NULL == pSwitchStatusBlock) {
-+ status = SDIO_STATUS_NO_RESOURCES;
-+ break;
-+ }
-+
-+ /* set high speed group */
-+ arg = SD_SWITCH_FUNC_ARG_GROUP_SET(SD_SWITCH_HIGH_SPEED_GROUP,
-+ SD_SWITCH_HIGH_SPEED_FUNC_NO);
-+
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: Setting SD Card for High Speed mode (CMD6 arg:0x%X)\n",arg));
-+
-+ /* issue simple data transfer request to switch modes */
-+ status = _IssueBusRequestBd(pHcd,
-+ CMD6,
-+ arg,
-+ SDREQ_FLAGS_RESP_R1 | SDREQ_FLAGS_DATA_TRANS,
-+ NULL,
-+ pSwitchStatusBlock,
-+ SD_SWITCH_FUNC_STATUS_BLOCK_BYTES);
-+
-+ if (SDIO_SUCCESS(status)) {
-+ ReorderBuffer(pSwitchStatusBlock,SD_SWITCH_FUNC_STATUS_BLOCK_BYTES);
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: SD High Speed Result, Got Max Current:%d mA, SwitchResult:0x%X \n",
-+ SD_SWITCH_FUNC_STATUS_GET_MAX_CURRENT(pSwitchStatusBlock),
-+ SDSwitchGetSwitchResult(pSwitchStatusBlock, SD_SWITCH_HIGH_SPEED_GROUP)));
-+ if (SD_SWITCH_FUNC_STATUS_GET_MAX_CURRENT(pSwitchStatusBlock) == 0) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Error in Status Block after High Speed Switch (current==0) \n"));
-+ status = SDIO_STATUS_DEVICE_ERROR;
-+ }
-+ if (SDSwitchGetSwitchResult(pSwitchStatusBlock, SD_SWITCH_HIGH_SPEED_GROUP) !=
-+ SD_SWITCH_HIGH_SPEED_FUNC_NO) {
-+ DBG_PRINT(SDDBG_ERROR,
-+ ("SDIO Bus Driver: Error in Status Block after High Speed Switch (Group1 did not switch) \n"));
-+ status = SDIO_STATUS_DEVICE_ERROR;
-+ }
-+ if (SDIO_SUCCESS(status)) {
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: SD High Speed Mode Enabled \n"));
-+ } else {
-+ SDLIB_PrintBuffer(pSwitchStatusBlock,
-+ SD_SWITCH_FUNC_STATUS_BLOCK_BYTES,
-+ "SDIO Bus Driver: SD Switch Status Block Error");
-+ }
-+ } else {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to Set SD High Speed Mode (%d) \n",status));
-+ }
-+ KernelFree(pSwitchStatusBlock);
-+
-+ if (!SDIO_SUCCESS(status)) {
-+ break;
-+ }
-+ }
-+
-+ /* enable/disable high speed mode for SDIO card */
-+ if (pHcd->CardProperties.Flags & CARD_SDIO) {
-+ BOOL doSet = TRUE;
-+
-+ if ((pBusMode->BusModeFlags & SDCONFIG_BUS_MODE_SD_HS) &&
-+ !(SDDEVICE_GET_BUSMODE_FLAGS(pDevice) & SDCONFIG_BUS_MODE_SD_HS)) {
-+ /* enable */
-+ regData = SDIO_HS_CONTROL_EHS;
-+ } else if (!(pBusMode->BusModeFlags & SDCONFIG_BUS_MODE_SD_HS) &&
-+ (SDDEVICE_GET_BUSMODE_FLAGS(pDevice) & SDCONFIG_BUS_MODE_SD_HS)) {
-+ /* disable */
-+ regData = 0;
-+ } else {
-+ /* do nothing */
-+ doSet = FALSE;
-+ }
-+
-+ if (doSet) {
-+ status = Cmd52WriteByteCommon(pDevice,
-+ SDIO_HS_CONTROL_REG,
-+ &regData);
-+
-+ if (!SDIO_SUCCESS(status)) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to %s HS mode in SDIO card : Err:%d\n",
-+ (SDIO_HS_CONTROL_EHS == regData) ? "enable":"disable" , status));
-+ break;
-+ } else {
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver:SDIO Card %s for High Speed mode \n",
-+ (SDIO_HS_CONTROL_EHS == regData) ? "enabled":"disabled" ));
-+ }
-+ }
-+ }
-+
-+ /* use synchronize-with-bus request version, this may have been requested by a
-+ * function driver */
-+ status = SDLIB_IssueConfig(pDevice,
-+ SDCONFIG_BUS_MODE_CTRL,
-+ pBusMode,
-+ sizeof(SDCONFIG_BUS_MODE_DATA));
-+
-+ if (!SDIO_SUCCESS(status)) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to set bus mode in hcd : Err:%d \n",
-+ status));
-+ break;
-+ }
-+
-+ /* check requested bus width against the current mode */
-+ if (SDCONFIG_GET_BUSWIDTH(pBusMode->BusModeFlags) ==
-+ SDCONFIG_GET_BUSWIDTH(pHcd->CardProperties.BusMode)) {
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: Bus mode set, no width change\n"));
-+ break;
-+ }
-+
-+ if (SDCONFIG_GET_BUSWIDTH(pBusMode->BusModeFlags) == SDCONFIG_BUS_WIDTH_SPI) {
-+ /* nothing more to do for SPI */
-+ break;
-+ }
-+
-+ /* set the bus width for SD and combo cards */
-+ if (pHcd->CardProperties.Flags & CARD_SD) {
-+ if (SDCONFIG_GET_BUSWIDTH(pBusMode->BusModeFlags) == SDCONFIG_BUS_WIDTH_4_BIT) {
-+ /* turn off card detect resistor */
-+ status = _IssueSimpleBusRequest(pHcd,
-+ ACMD42,
-+ 0, /* disable CD */
-+ SDREQ_FLAGS_APP_CMD | SDREQ_FLAGS_RESP_R1,
-+ NULL);
-+ if (!SDIO_SUCCESS(status)) {
-+ DBG_PRINT(SDDBG_WARN, ("SDIO Bus Driver: Failed to disable CD Res: %d \n",
-+ status)); /* this should be okay */
-+ }
-+ arg = SD_ACMD6_BUS_WIDTH_4_BIT;
-+ } else {
-+ /* don't need to turn off CD in 1 bit mode, just set mode */
-+ arg = SD_ACMD6_BUS_WIDTH_1_BIT;
-+
-+ }
-+ /* set the bus width */
-+ status = _IssueSimpleBusRequest(pHcd,
-+ ACMD6,
-+ arg, /* set bus mode */
-+ SDREQ_FLAGS_APP_CMD | SDREQ_FLAGS_RESP_R1,
-+ NULL);
-+ if (!SDIO_SUCCESS(status)) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to set bus width: %d \n",
-+ status));
-+ break;
-+ }
-+ }
-+ /* set bus width for SDIO cards */
-+ if (pHcd->CardProperties.Flags & CARD_SDIO) {
-+ /* default */
-+ regData = CARD_DETECT_DISABLE | SDIO_BUS_WIDTH_1_BIT;
-+
-+ if (SDCONFIG_GET_BUSWIDTH(pBusMode->BusModeFlags) == SDCONFIG_BUS_WIDTH_4_BIT) {
-+ /* turn off card detect resistor and set buswidth */
-+ regData = CARD_DETECT_DISABLE | SDIO_BUS_WIDTH_4_BIT;
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: Enabling 4 bit mode on card \n"));
-+ } else {
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: Enabling 1 bit mode on card \n"));
-+ }
-+ status = Cmd52WriteByteCommon(pDevice,
-+ SDIO_BUS_IF_REG,
-+ &regData);
-+ if (!SDIO_SUCCESS(status)) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to set bus mode in Card : Err:%d\n",
-+ status));
-+ break;
-+ }
-+
-+ /* check for 4-bit interrupt detect mode */
-+ if ((SDCONFIG_GET_BUSWIDTH(pBusMode->BusModeFlags) == SDCONFIG_BUS_WIDTH_4_BIT) &&
-+ (pHcd->CardProperties.SDIOCaps & SDIO_CAPS_INT_MULTI_BLK) &&
-+ (pHcd->Attributes & SDHCD_ATTRIB_MULTI_BLK_IRQ)) {
-+ /* enable interrupts between blocks, this doesn't actually turn on interrupts
-+ * it merely allows interrupts to be asserted in the inter-block gap */
-+ pHcd->CardProperties.SDIOCaps |= SDIO_CAPS_ENB_INT_MULTI_BLK;
-+
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: 4-Bit Multi-blk Interrupt support enabled\n"));
-+ } else {
-+ /* make sure this is disabled */
-+ pHcd->CardProperties.SDIOCaps &= ~SDIO_CAPS_ENB_INT_MULTI_BLK;
-+ }
-+
-+ status = Cmd52WriteByteCommon(pDevice,
-+ SDIO_CARD_CAPS_REG,
-+ &pHcd->CardProperties.SDIOCaps);
-+ if (!SDIO_SUCCESS(status)) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to update Card Caps register Err:%d\n",
-+ status));
-+ break;
-+ }
-+ }
-+
-+ /* set data bus width for MMC */
-+ if (pHcd->CardProperties.Flags & CARD_MMC) {
-+ UINT8 buswidth = 0;
-+
-+ if (SDCONFIG_GET_BUSWIDTH(pBusMode->BusModeFlags) == SDCONFIG_BUS_WIDTH_4_BIT) {
-+ buswidth = MMC_EXT_BUS_WIDTH_4_BIT;
-+ } else if (SDCONFIG_GET_BUSWIDTH(pBusMode->BusModeFlags) == SDCONFIG_BUS_WIDTH_MMC8_BIT) {
-+ buswidth = MMC_EXT_BUS_WIDTH_8_BIT;
-+ } else {
-+ /* normal 1 bit mode .. nothing to do */
-+ break;
-+ }
-+ /* now set the bus mode on the card */
-+ switcharg = MMC_SWITCH_BUILD_ARG(MMC_SWITCH_CMD_SET0,
-+ MMC_SWITCH_WRITE_BYTE,
-+ MMC_EXT_BUS_WIDTH_OFFSET,
-+ buswidth);
-+
-+ status = _IssueSimpleBusRequest(pHcd,
-+ MMC_CMD_SWITCH,
-+ switcharg,
-+ SDREQ_FLAGS_RESP_R1B,
-+ NULL);
-+ if (!SDIO_SUCCESS(status)) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to set MMC bus width (arg:0x%X): %d \n",
-+ switcharg, status));
-+ break;
-+ }
-+
-+ if (SDCONFIG_GET_BUSWIDTH(pBusMode->BusModeFlags) == SDCONFIG_BUS_WIDTH_4_BIT) {
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: 4 bit MMC mode enabled (arg:0x%X) \n",
-+ switcharg));
-+ } else if (SDCONFIG_GET_BUSWIDTH(pBusMode->BusModeFlags) == SDCONFIG_BUS_WIDTH_MMC8_BIT) {
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: 8-Bit MMC mode enabled (arg:0x%X) \n",
-+ switcharg));
-+ }
-+ }
-+
-+ } while (FALSE);
-+
-+ if (SDIO_SUCCESS(status)) {
-+ /* set the operating mode */
-+ pHcd->CardProperties.BusMode = pBusMode->BusModeFlags;
-+ /* set the actual clock rate */
-+ pHcd->CardProperties.OperBusClock = pBusMode->ActualClockRate;
-+ }
-+
-+ SemaphorePost(&pDevice->pHcd->ConfigureOpsSem);
-+
-+ return status;
-+}
-+
-+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ CardInitSetup - setup host for card initialization
-+ Input: pHcd - HCD object
-+ Output:
-+ Return:
-+ Notes:
-+
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+SDIO_STATUS CardInitSetup(PSDHCD pHcd)
-+{
-+ SDCONFIG_INIT_CLOCKS_DATA initClocks;
-+ SDCONFIG_BUS_MODE_DATA busMode;
-+ UINT32 OCRvalue;
-+ SDIO_STATUS status = SDIO_STATUS_SUCCESS;
-+
-+ ZERO_OBJECT(initClocks);
-+ ZERO_OBJECT(busMode);
-+ /* setup defaults */
-+ initClocks.NumberOfClocks = SDMMC_MIN_INIT_CLOCKS;
-+ busMode.ClockRate = SD_INIT_BUS_CLOCK;
-+
-+ /* check for SPI only */
-+ if (pHcd->Attributes & SDHCD_ATTRIB_BUS_SPI) {
-+ /* SPI cards startup in non-CRC mode with the exception of CMD0, the
-+ * HCDs must issue CMD0 with the correct CRC , the spec shows that a
-+ * CMD 0 sequence is 0x40,0x00,0x00,0x00,0x00,0x95 */
-+ busMode.BusModeFlags = SDCONFIG_BUS_WIDTH_SPI | SDCONFIG_BUS_MODE_SPI_NO_CRC;
-+ }
-+ /* check if host supports 1 bit mode */
-+ /* TODO : if host supports power switching, we can
-+ * could initialize cards in SPI mode first */
-+ if (pHcd->Attributes & SDHCD_ATTRIB_BUS_1BIT) {
-+ busMode.BusModeFlags = SDCONFIG_BUS_WIDTH_1_BIT;
-+ }
-+
-+ /* set initial VDD, starting at the highest allowable voltage and working
-+ * our way down */
-+ if (pHcd->SlotVoltageCaps & SLOT_POWER_3_3V) {
-+ OCRvalue = SD_OCR_3_2_TO_3_3_VDD;
-+ } else if (pHcd->SlotVoltageCaps & SLOT_POWER_3_0V) {
-+ OCRvalue = SD_OCR_2_9_TO_3_0_VDD;
-+ } else if (pHcd->SlotVoltageCaps & SLOT_POWER_2_8V) {
-+ OCRvalue = SD_OCR_2_7_TO_2_8_VDD;
-+ } else if (pHcd->SlotVoltageCaps & SLOT_POWER_2_0V) {
-+ OCRvalue = SD_OCR_1_9_TO_2_0_VDD;
-+ } else if (pHcd->SlotVoltageCaps & SLOT_POWER_1_8V) {
-+ OCRvalue = SD_OCR_1_7_TO_1_8_VDD;
-+ } else if (pHcd->SlotVoltageCaps & SLOT_POWER_1_6V) {
-+ OCRvalue = SD_OCR_1_6_TO_1_7_VDD;
-+ } else {
-+ DBG_ASSERT(FALSE);
-+ OCRvalue = 0;
-+ }
-+
-+ do {
-+ /* power up the card */
-+ status = AdjustSlotPower(pHcd, &OCRvalue);
-+ if (!SDIO_SUCCESS(status)) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to adjust slot power \n"));
-+ break;
-+ }
-+ status = SetOperationalBusMode(pHcd->pPseudoDev,&busMode);
-+ if (!SDIO_SUCCESS(status)) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to set bus mode \n"));
-+ break;
-+ }
-+ status = _IssueConfig(pHcd,SDCONFIG_SEND_INIT_CLOCKS,&initClocks,sizeof(initClocks));
-+ if (!SDIO_SUCCESS(status)) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to send init clocks in hcd \n"));
-+ break;
-+ }
-+
-+ } while(FALSE);
-+
-+ return status;
-+}
-+
-+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ SDInitializeCard - initialize card
-+ Input: pHcd - HCD object
-+ Output: pProperties - card properties
-+ Return:
-+ Notes:
-+
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+SDIO_STATUS SDInitializeCard(PSDHCD pHcd)
-+{
-+ SDCONFIG_BUS_MODE_DATA busMode;
-+ SDIO_STATUS status = SDIO_STATUS_SUCCESS;
-+ PSDREQUEST pReq = NULL;
-+ UINT32 OCRvalue;
-+ UINT32 tplAddr;
-+ UINT8 temp;
-+ struct SDIO_MANFID_TPL manfid;
-+ SDCONFIG_WP_VALUE wpValue;
-+ UINT8 cisBuffer[3];
-+
-+ OCRvalue = 0;
-+
-+ do {
-+ if (IS_HCD_BUS_MODE_SPI(pHcd)) {
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: Initializing card in SPI mode \n"));
-+ } else {
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: Initializing card in MMC/SD mode \n"));
-+ }
-+
-+ pReq = AllocateRequest();
-+ if (NULL == pReq) {
-+ status = SDIO_STATUS_NO_RESOURCES;
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: failed to allocate bus request \n"));
-+ break;
-+ }
-+ memset(pReq, 0, sizeof(SDREQUEST));
-+
-+ status = CardInitSetup(pHcd);
-+ if (!SDIO_SUCCESS(status)) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to setup card \n"));
-+ break;
-+ }
-+ status = _IssueConfig(pHcd,SDCONFIG_GET_WP,&wpValue,sizeof(wpValue));
-+ if (!SDIO_SUCCESS(status)) {
-+ DBG_PRINT(SDDBG_WARN, ("SDIO Bus Driver: host doesn't support Write Protect \n"));
-+ } else {
-+ if (wpValue) {
-+ pHcd->CardProperties.Flags |= CARD_SD_WP;
-+ DBG_PRINT(SDDBG_WARN, ("SDIO Bus Driver: SD WP switch is on \n"));
-+ }
-+ }
-+
-+ if (!(pHcd->Attributes & SDHCD_ATTRIB_SLOT_POLLING) &&
-+ IS_HCD_BUS_MODE_SPI(pHcd)) {
-+ /* for non-slot polling HCDs operating in SPI mode
-+ * issue CMD0 to reset card state and to place the card
-+ * in SPI mode. If slot polling is used, the polling thread
-+ * will have already issued a CMD0 to place the card in SPI mode*/
-+ if (IS_HCD_BUS_MODE_SPI(pHcd)) {
-+ INT ii = 256;
-+ status = SDIO_STATUS_ERROR;
-+ /* if the CMD0 fails, retry it. Some cards have a hard time getting into SPI mode.*/
-+ while ((!SDIO_SUCCESS(status)) && (ii-- >= 0)) {
-+ status = _IssueSimpleBusRequest(pHcd,CMD0,0,SDREQ_FLAGS_RESP_R1,pReq);
-+ OSSleep(20);
-+ }
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: cmd0 go SPI retries:(256) %d\n", ii));
-+
-+ } else {
-+ status = _IssueSimpleBusRequest(pHcd,CMD0,0,SDREQ_FLAGS_NO_RESP,pReq);
-+ }
-+ if (!SDIO_SUCCESS(status)) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: go-idle failed! \n"));
-+ break;
-+ }
-+ }
-+
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: Looking for SDIO.. \n"));
-+ /* check for SDIO card by trying to read it's OCR */
-+ status = ReadOCR(pHcd,CARD_SDIO,pReq,0,&OCRvalue);
-+ if (SDIO_SUCCESS(status)) {
-+ /* we got a response, this is an SDIO card */
-+ if (IS_HCD_BUS_MODE_SPI(pHcd)) {
-+ /* handle SPI */
-+ pHcd->CardProperties.IOFnCount = SPI_SDIO_R4_GET_IO_FUNC_COUNT(pReq->Response);
-+ if (SPI_SDIO_R4_IS_MEMORY_PRESENT(pReq->Response)) {
-+ /* flag an SD function exists */
-+ pHcd->CardProperties.Flags |= CARD_SD;
-+ }
-+ } else {
-+ /* handle native SD */
-+ pHcd->CardProperties.IOFnCount = SD_SDIO_R4_GET_IO_FUNC_COUNT(pReq->Response);
-+ if (SD_SDIO_R4_IS_MEMORY_PRESENT(pReq->Response)) {
-+ /* flag an SD function exists */
-+ pHcd->CardProperties.Flags |= CARD_SD;
-+ }
-+
-+ }
-+ if (0 == pHcd->CardProperties.IOFnCount) {
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: SDIO Card reports no functions \n"));
-+ status = SDIO_STATUS_DEVICE_ERROR;
-+ pHcd->CardProperties.Flags = 0;
-+ break;
-+ }
-+ pHcd->CardProperties.Flags |= CARD_SDIO;
-+
-+ DBG_PRINT(SDDBG_TRACE,
-+ ("SDIO Bus Driver: SDIO Card, Functions: %d Card Info Flags:0x%X OCR:0x%8.8X\n",
-+ pHcd->CardProperties.IOFnCount, pHcd->CardProperties.Flags, OCRvalue));
-+ /* adjust slot power for this SDIO card */
-+ status = AdjustSlotPower(pHcd, &OCRvalue);
-+ if (!SDIO_SUCCESS(status)) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to set power in hcd \n"));
-+ break;
-+ }
-+ /* poll for SDIO card ready */
-+ status = PollCardReady(pHcd,OCRvalue,CARD_SDIO);
-+ if (!SDIO_SUCCESS(status)) {
-+ break;
-+ }
-+ } else if (status != SDIO_STATUS_BUS_RESP_TIMEOUT){
-+ /* major error in hcd, bail */
-+ break;
-+ }
-+
-+ /* check if this is an SDIO-only card before continuing */
-+ if (!(pHcd->CardProperties.Flags & CARD_SD) && (pHcd->CardProperties.Flags & CARD_SDIO)) {
-+ /* this is an SDIO card with no memory function */
-+ goto prepareCard;
-+ }
-+
-+ if (!(pHcd->CardProperties.Flags & CARD_SDIO)) {
-+ /* issue go idle only if we did not find an SDIO function in our earlier test */
-+ if (IS_HCD_BUS_MODE_SPI(pHcd)) {
-+ status = _IssueSimpleBusRequest(pHcd,CMD0,0,SDREQ_FLAGS_RESP_R1,pReq);
-+ } else {
-+ status = _IssueSimpleBusRequest(pHcd,CMD0,0,SDREQ_FLAGS_NO_RESP,pReq);
-+ }
-+ if (!SDIO_SUCCESS(status)) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: go-idle failed! \n"));
-+ break;
-+ }
-+ }
-+
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: Looking for SD Memory.. \n"));
-+ /* SD Memory Card checking */
-+ /* test for present of SD card (stand-alone or combo card) */
-+ status = TestPresence(pHcd, CARD_SD, pReq);
-+ if (SDIO_SUCCESS(status)) {
-+ /* there is an SD Card present, could be part of a combo system */
-+ pHcd->CardProperties.Flags |= CARD_SD;
-+ if (0 == OCRvalue) {
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: SD Memory card detected. \n"));
-+ /* no OCR value on entry this is a stand-alone card, go and get it*/
-+ status = ReadOCR(pHcd,CARD_SD,pReq,0,&OCRvalue);
-+ if (!SDIO_SUCCESS(status) || (OCRvalue == 0)) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to get OCR (status:%d) \n",
-+ status));
-+ break;
-+ }
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: SD Card Reports OCR:0x%8.8X \n", OCRvalue));
-+ status = AdjustSlotPower(pHcd, &OCRvalue);
-+ if (!SDIO_SUCCESS(status)) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to adjust power \n"));
-+ break;
-+ }
-+ } else {
-+ DBG_ASSERT((pHcd->CardProperties.Flags & (CARD_SD | CARD_SDIO)));
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: SDIO Combo Card detected \n"));
-+ }
-+ /* poll for SD card ready */
-+ status = PollCardReady(pHcd,OCRvalue,CARD_SD);
-+ if (!SDIO_SUCCESS(status)) {
-+ /* check if this card has an SDIO function */
-+ if (pHcd->CardProperties.Flags & CARD_SDIO) {
-+ DBG_PRINT(SDDBG_WARN, ("SDIO Bus Driver: Combo Detected but SD memory function failed \n"));
-+ /* allow SDIO functions to load normally */
-+ status = SDIO_STATUS_SUCCESS;
-+ /* remove SD flag */
-+ pHcd->CardProperties.Flags &= ~CARD_SD;
-+ } else {
-+ break;
-+ }
-+ } else {
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: SD Memory ready. \n"));
-+ }
-+ /* we're done, no need to check for MMC */
-+ goto prepareCard;
-+ } else if (status != SDIO_STATUS_BUS_RESP_TIMEOUT){
-+ /* major error in hcd, bail */
-+ break;
-+ }
-+
-+ /* MMC card checking */
-+ /* if we get here, these better not be set */
-+ DBG_ASSERT(!(pHcd->CardProperties.Flags & (CARD_SD | CARD_SDIO)));
-+ /* issue go idle */
-+ if (IS_HCD_BUS_MODE_SPI(pHcd)) {
-+ status = _IssueSimpleBusRequest(pHcd,CMD0,0,SDREQ_FLAGS_RESP_R1,pReq);
-+ } else {
-+ status = _IssueSimpleBusRequest(pHcd,CMD0,0,SDREQ_FLAGS_NO_RESP,pReq);
-+ }
-+ if (!SDIO_SUCCESS(status)) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: go-idle failed! \n"));
-+ break;
-+ }
-+
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: Looking for MMC.. \n"));
-+ status = TestPresence(pHcd, CARD_MMC, pReq);
-+ if (!SDIO_SUCCESS(status)) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: unknown card detected \n"));
-+ break;
-+ }
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: MMC Card Detected \n"));
-+ pHcd->CardProperties.Flags |= CARD_MMC;
-+ /* read the OCR value */
-+ status = ReadOCR(pHcd,CARD_MMC,pReq,0,&OCRvalue);
-+ if (!SDIO_SUCCESS(status) || (OCRvalue == 0)) {
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: Failed to get OCR (status:%d)",
-+ status));
-+ break;
-+ }
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: MMC Card Reports OCR:0x%8.8X \n", OCRvalue));
-+ /* adjust power */
-+ status = AdjustSlotPower(pHcd, &OCRvalue);
-+ if (!SDIO_SUCCESS(status)) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to adjust power \n"));
-+ break;
-+ }
-+ /* poll for MMC card ready */
-+ status = PollCardReady(pHcd,OCRvalue,CARD_MMC);
-+ if (!SDIO_SUCCESS(status)) {
-+ break;
-+ }
-+ /* fall through and prepare MMC card */
-+
-+prepareCard:
-+ /* we're done figuring out what was inserted, and setting up
-+ * optimal slot voltage, now we need to prepare the card */
-+ if (!IS_HCD_BUS_MODE_SPI(pHcd) &&
-+ (pHcd->CardProperties.Flags & (CARD_SD | CARD_MMC))) {
-+ /* non-SPI SD or MMC cards need to be moved to the "ident" state before we can get the
-+ * RCA or select the card using the new RCA */
-+ status = _IssueSimpleBusRequest(pHcd,CMD2,0,SDREQ_FLAGS_RESP_R2,pReq);
-+ if (!SDIO_SUCCESS(status)){
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: failed to move SD/MMC card into ident state \n"));
-+ break;
-+ }
-+ }
-+
-+ if (!IS_HCD_BUS_MODE_SPI(pHcd)) {
-+ /* non-SPI mode cards need their RCA's setup */
-+ if (pHcd->CardProperties.Flags & (CARD_SD | CARD_SDIO)) {
-+ /* issue CMD3 to get RCA on SD/SDIO cards */
-+ status = _IssueSimpleBusRequest(pHcd,CMD3,0,SDREQ_FLAGS_RESP_R6,pReq);
-+ if (!SDIO_SUCCESS(status)){
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: failed to get RCA for SD/SDIO card \n"));
-+ break;
-+ }
-+ pHcd->CardProperties.RCA = SD_R6_GET_RCA(pReq->Response);
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: SD/SDIO RCA:0x%X \n",
-+ pHcd->CardProperties.RCA));
-+ } else if (pHcd->CardProperties.Flags & CARD_MMC) {
-+ /* for MMC cards, we have to assign a relative card address */
-+ /* just a non-zero number */
-+ pHcd->CardProperties.RCA = 1;
-+ /* issue CMD3 to set the RCA for MMC cards */
-+ status = _IssueSimpleBusRequest(pHcd,
-+ CMD3,(pHcd->CardProperties.RCA << 16),
-+ SDREQ_FLAGS_RESP_R1,pReq);
-+ if (!SDIO_SUCCESS(status)){
-+ DBG_PRINT(SDDBG_ERROR,
-+ ("SDIO Bus Driver: failed to set RCA for MMC card! (err=%d) \n",status));
-+ break;
-+ }
-+ } else {
-+ DBG_ASSERT(FALSE);
-+ }
-+ }
-+ /* select the card in order to get the rest of the card info, applies
-+ * to SDIO/SD/MMC cards*/
-+ status = SelectDeselectCard(pHcd, TRUE);
-+ if (!SDIO_SUCCESS(status)) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: failed to select card! \n"));
-+ break;
-+ }
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver, Card now Selected.. \n"));
-+
-+ if (pHcd->CardProperties.Flags & CARD_SDIO) {
-+ /* read SDIO revision register */
-+ status = Cmd52ReadByteCommon(pHcd->pPseudoDev, CCCR_SDIO_REVISION_REG, &temp);
-+ if (!SDIO_SUCCESS(status)) {
-+ break;
-+ }
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Revision Reg: 0x%X \n", temp));
-+ switch (temp & SDIO_REV_MASK) {
-+ case SDIO_REV_1_00:
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Spec Revision 1.00 \n"));
-+ pHcd->CardProperties.SDIORevision = SDIO_REVISION_1_00;
-+ break;
-+ case SDIO_REV_1_10:
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Spec Revision 1.10 \n"));
-+ pHcd->CardProperties.SDIORevision = SDIO_REVISION_1_10;
-+ break;
-+ case SDIO_REV_1_20:
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Spec Revision 1.20 \n"));
-+ pHcd->CardProperties.SDIORevision = SDIO_REVISION_1_20;
-+ break;
-+ default:
-+ DBG_PRINT(SDDBG_WARN, ("SDIO Warning: unknown SDIO revision, treating like 1.0 device \n"));
-+ pHcd->CardProperties.SDIORevision = SDIO_REVISION_1_00;
-+ break;
-+ }
-+ /* get the common CIS ptr */
-+ status = Cmd52ReadMultipleCommon(pHcd->pPseudoDev,
-+ SDIO_CMN_CIS_PTR_LOW_REG,
-+ cisBuffer,
-+ 3);
-+ if (!SDIO_SUCCESS(status)) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to get CIS ptr, Err:%d", status));
-+ break;
-+ }
-+ /* this is endian-safe*/
-+ pHcd->CardProperties.CommonCISPtr = ((UINT32)cisBuffer[0]) |
-+ (((UINT32)cisBuffer[1]) << 8) |
-+ (((UINT32)cisBuffer[2]) << 16);
-+
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Card CIS Ptr: 0x%X \n", pHcd->CardProperties.CommonCISPtr));
-+ temp = sizeof(manfid);
-+ tplAddr = pHcd->CardProperties.CommonCISPtr;
-+ /* get the MANFID tuple */
-+ status = SDLIB_FindTuple(pHcd->pPseudoDev,
-+ CISTPL_MANFID,
-+ &tplAddr,
-+ (PUINT8)&manfid,
-+ &temp);
-+ if (!SDIO_SUCCESS(status)) {
-+ DBG_PRINT(SDDBG_WARN, ("SDIO Bus Driver: Failed to get MANFID tuple err:%d \n", status));
-+ status = SDIO_STATUS_SUCCESS;
-+ } else {
-+ /* save this off so that it can be copied into each SDIO Func's SDDEVICE structure */
-+ pHcd->CardProperties.SDIO_ManufacturerCode =
-+ CT_LE16_TO_CPU_ENDIAN(manfid.ManufacturerCode);
-+ pHcd->CardProperties.SDIO_ManufacturerID =
-+ CT_LE16_TO_CPU_ENDIAN(manfid.ManufacturerInfo);
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO MANFID:0x%X, MANFINFO:0x%X \n",
-+ pHcd->CardProperties.SDIO_ManufacturerID,
-+ pHcd->CardProperties.SDIO_ManufacturerCode));
-+ }
-+
-+ if (pHcd->CardProperties.SDIORevision >= SDIO_REVISION_1_10) {
-+ /* read power control */
-+ status = Cmd52ReadByteCommon(pHcd->pPseudoDev, SDIO_POWER_CONTROL_REG, &temp);
-+ if (SDIO_SUCCESS(status)) {
-+ /* check for power control support which indicates the card may use more
-+ * than 200 mA */
-+ if (temp & SDIO_POWER_CONTROL_SMPC) {
-+ /* check that the host can support this. */
-+ if (pHcd->MaxSlotCurrent >= SDIO_EMPC_CURRENT_THRESHOLD) {
-+ temp = SDIO_POWER_CONTROL_EMPC;
-+ /* enable power control on the card */
-+ status = Cmd52WriteByteCommon(pHcd->pPseudoDev, SDIO_POWER_CONTROL_REG, &temp);
-+ if (!SDIO_SUCCESS(status)) {
-+ DBG_PRINT(SDDBG_ERROR,
-+ ("SDIO Busdriver: failed to enable power control (%d) \n",status));
-+ break;
-+ }
-+ /* mark that the card is high power */
-+ pHcd->CardProperties.Flags |= CARD_HIPWR;
-+
-+ DBG_PRINT(SDDBG_TRACE,
-+ ("SDIO Busdriver: Power Control Enabled on SDIO (1.10 or greater) card \n"));
-+ } else {
-+ DBG_PRINT(SDDBG_WARN,
-+ ("SDIO Busdriver: Card can operate higher than 200mA, host cannot (max:%d) \n",
-+ pHcd->MaxSlotCurrent));
-+ /* this is not fatal, the card should operate at a reduced rate */
-+ }
-+ } else {
-+ DBG_PRINT(SDDBG_TRACE,
-+ ("SDIO Busdriver: SDIO 1.10 (or greater) card draws less than 200mA \n"));
-+ }
-+ } else {
-+ DBG_PRINT(SDDBG_WARN,
-+ ("SDIO Busdriver: failed to get POWER CONTROL REG (%d) \n",status));
-+ /* fall through and continue on at reduced mode */
-+ }
-+ }
-+ }
-+ /* get the current bus parameters */
-+ busMode.BusModeFlags = pHcd->CardProperties.BusMode;
-+ busMode.ClockRate = pHcd->CardProperties.OperBusClock;
-+ /* get the rest of the bus parameters like clock and supported bus width */
-+ status = GetBusParameters(pHcd,&busMode);
-+ if (!SDIO_SUCCESS(status)) {
-+ break;
-+ }
-+
-+ if (IS_HCD_BUS_MODE_SPI(pHcd)) {
-+ /* check HCD if it wants to run without SPI CRC */
-+ if (pHcd->Attributes & SDHCD_ATTRIB_NO_SPI_CRC) {
-+ /* hcd would rather not run with CRC we don't need to tell the card since SPI mode
-+ * cards power up with CRC initially disabled */
-+ busMode.BusModeFlags |= SDCONFIG_BUS_MODE_SPI_NO_CRC;
-+ } else {
-+ /* first enable SPI CRC checking if the HCD can handle it */
-+ status = SDSPIModeEnableDisableCRC(pHcd->pPseudoDev, TRUE);
-+ if (!SDIO_SUCCESS(status)) {
-+ DBG_PRINT(SDDBG_ERROR,
-+ ("SDIO Bus Driver: Failed to set Enable SPI CRC on card \n"));
-+ break;
-+ }
-+ }
-+ }
-+
-+ status = SetOperationalBusMode(pHcd->pPseudoDev, &busMode);
-+
-+ if (!SDIO_SUCCESS(status)) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to set operational bus mode\n"));
-+ break;
-+ }
-+
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: Oper. Mode: Clock:%d, Bus:0x%X \n",
-+ pHcd->CardProperties.OperBusClock,pHcd->CardProperties.BusMode));
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: Card in TRANS state, Ready: CardInfo Flags 0x%X \n",
-+ pHcd->CardProperties.Flags));
-+
-+ } while (FALSE);
-+
-+ if (pReq != NULL) {
-+ FreeRequest(pReq);
-+ }
-+
-+ return status;
-+}
-+
-+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ SDQuerySDMMCInfo - query MMC card info
-+ Input: pDevice - device
-+ Output:
-+ Return:
-+ Notes:
-+
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+SDIO_STATUS SDQuerySDMMCInfo(PSDDEVICE pDevice)
-+{
-+ SDIO_STATUS status = SDIO_STATUS_SUCCESS;
-+ PSDREQUEST pReq = NULL;
-+ UINT8 CID[MAX_CSD_CID_BYTES];
-+
-+ do {
-+ pReq = AllocateRequest();
-+ if (NULL == pReq) {
-+ status = SDIO_STATUS_NO_RESOURCES;
-+ break;
-+ }
-+ /* de-select the card */
-+ status = SelectDeselectCard(pDevice->pHcd,FALSE);
-+ if (!SDIO_SUCCESS(status)) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to deselect card before getting CID \n"));
-+ break;
-+ }
-+
-+ if (SDDEVICE_IS_BUSMODE_SPI(pDevice)) {
-+ /* in SPI mode, getting the CSD requires a data transfer */
-+ status = _IssueBusRequestBd(pDevice->pHcd,CMD10,0,
-+ SDREQ_FLAGS_RESP_R1 | SDREQ_FLAGS_DATA_TRANS,
-+ pReq,
-+ CID,
-+ MAX_CSD_CID_BYTES);
-+ if (SDIO_SUCCESS(status)) {
-+ /* in SPI mode we need to reorder to the CID since SPI data comes in MSB first*/
-+ ReorderBuffer(CID,MAX_CSD_CID_BYTES);
-+ }
-+ } else {
-+ /* get the CID */
-+ status = _IssueSimpleBusRequest(pDevice->pHcd,
-+ CMD10,
-+ (SDDEVICE_GET_CARD_RCA(pDevice) << 16),
-+ SDREQ_FLAGS_RESP_R2,
-+ pReq);
-+ if (SDIO_SUCCESS(status)) {
-+ /* extract it from the reponse */
-+ memcpy(CID,pReq->Response,MAX_CSD_CID_BYTES);
-+ }
-+ }
-+
-+ if (!SDIO_SUCCESS(status)) {
-+ DBG_PRINT(SDDBG_WARN, ("SDQuerySDMMCInfo: failed to get CID. \n"));
-+ status = SDIO_STATUS_SUCCESS;
-+ } else {
-+ pDevice->pId[0].SDMMC_ManfacturerID = GET_SD_CID_MANFID(CID);
-+ pDevice->pId[0].SDMMC_OEMApplicationID = GET_SD_CID_OEMID(CID);
-+#if DEBUG
-+ {
-+ char pBuf[7];
-+
-+ pBuf[0] = GET_SD_CID_PN_1(CID);
-+ pBuf[1] = GET_SD_CID_PN_2(CID);
-+ pBuf[2] = GET_SD_CID_PN_3(CID);
-+ pBuf[3] = GET_SD_CID_PN_4(CID);
-+ pBuf[4] = GET_SD_CID_PN_5(CID);
-+ if (pDevice->pHcd->CardProperties.Flags & CARD_MMC) {
-+ pBuf[5] = GET_SD_CID_PN_6(CID);
-+ pBuf[6] = 0;
-+ } else {
-+ pBuf[5] = 0;
-+ }
-+ DBG_PRINT(SDDBG_TRACE, ("SDQuerySDMMCInfo: Product String: %s\n", pBuf));
-+ }
-+#endif
-+ DBG_PRINT(SDDBG_TRACE, ("SDQuerySDMMCInfo: ManfID: 0x%X, OEMID:0x%X \n",
-+ pDevice->pId[0].SDMMC_ManfacturerID, pDevice->pId[0].SDMMC_OEMApplicationID));
-+ }
-+ /* re-select card */
-+ status = SelectDeselectCard(pDevice->pHcd,TRUE);
-+ if (!SDIO_SUCCESS(status)) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to re-select card after getting CID \n"));
-+ break;
-+ }
-+ } while (FALSE);
-+
-+ if (pReq != NULL) {
-+ FreeRequest(pReq);
-+ }
-+
-+ return status;
-+}
-+
-+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ SDQuerySDIOInfo - query SDIO card info
-+ Input: pDevice - the device
-+ Output:
-+ Return:
-+ Notes:
-+
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+SDIO_STATUS SDQuerySDIOInfo(PSDDEVICE pDevice)
-+{
-+ SDIO_STATUS status = SDIO_STATUS_SUCCESS;
-+ UINT32 faddress;
-+ UINT8 fInfo;
-+ UINT32 nextTpl;
-+ UINT8 tplLength;
-+ UINT8 cisPtrBuffer[3];
-+ struct SDIO_FUNC_EXT_FUNCTION_TPL_1_1 funcTuple;
-+
-+ /* use the card-wide SDIO manufacturer code and ID previously read.*/
-+ pDevice->pId[0].SDIO_ManufacturerCode = pDevice->pHcd->CardProperties.SDIO_ManufacturerCode;
-+ pDevice->pId[0].SDIO_ManufacturerID = pDevice->pHcd->CardProperties.SDIO_ManufacturerID;
-+
-+ /* calculate function base address */
-+ faddress = CalculateFBROffset(SDDEVICE_GET_SDIO_FUNCNO(pDevice));
-+ DBG_ASSERT(faddress != 0);
-+
-+ do {
-+ status = Cmd52ReadByteCommon(pDevice,
-+ FBR_FUNC_INFO_REG_OFFSET(faddress),
-+ &fInfo);
-+ if (!SDIO_SUCCESS(status)) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to get function info, Err:%d , using Class:UNKNOWN\n", status));
-+ fInfo = 0;
-+ pDevice->pId[0].SDIO_FunctionClass = 0;
-+ status = SDIO_STATUS_SUCCESS;
-+ } else {
-+ pDevice->pId[0].SDIO_FunctionClass = fInfo & FUNC_INFO_DEVICE_CODE_MASK;
-+ }
-+
-+ if ((FUNC_INFO_DEVICE_CODE_LAST == pDevice->pId[0].SDIO_FunctionClass) &&
-+ SDDEVICE_IS_SDIO_REV_GTEQ_1_10(pDevice)) {
-+ /* if the device code is the last one, check for 1.1 revision and get the
-+ * extended code */
-+ status = Cmd52ReadByteCommon(pDevice,
-+ FBR_FUNC_EXT_DEVICE_CODE_OFFSET(faddress),
-+ &(pDevice->pId[0].SDIO_FunctionClass));
-+ if (!SDIO_SUCCESS(status)) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to get 1.1 extended DC, Err:%d\n",
-+ status));
-+ break;
-+ }
-+ }
-+
-+ /* get the function CIS ptr */
-+ status = Cmd52ReadMultipleCommon(pDevice,
-+ FBR_FUNC_CIS_LOW_OFFSET(faddress),
-+ cisPtrBuffer,
-+ 3);
-+ if (!SDIO_SUCCESS(status)) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to get FN CIS ptr, Err:%d\n", status));
-+ break;
-+ }
-+ /* endian safe */
-+ pDevice->DeviceInfo.AsSDIOInfo.FunctionCISPtr = ((UINT32)cisPtrBuffer[0]) |
-+ (((UINT32)cisPtrBuffer[1]) << 8) |
-+ (((UINT32)cisPtrBuffer[2]) << 16);
-+
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Function:%d, Class:%d FnCISPtr:0x%X \n",
-+ SDDEVICE_GET_SDIO_FUNCNO(pDevice),
-+ pDevice->pId[0].SDIO_FunctionClass,pDevice->DeviceInfo.AsSDIOInfo.FunctionCISPtr));
-+
-+ if (fInfo & FUNC_INFO_SUPPORTS_CSA_MASK) {
-+ /* get the function CSA ptr */
-+ status = Cmd52ReadMultipleCommon(pDevice,
-+ FBR_FUNC_CSA_LOW_OFFSET(faddress),
-+ cisPtrBuffer,
-+ 3);
-+ if (!SDIO_SUCCESS(status)) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to get FN CSA ptr, Err:%d \n", status));
-+ break;
-+ }
-+ /* endian safe */
-+ pDevice->DeviceInfo.AsSDIOInfo.FunctionCSAPtr = ((UINT32)cisPtrBuffer[0]) |
-+ (((UINT32)cisPtrBuffer[1]) << 8) |
-+ (((UINT32)cisPtrBuffer[2]) << 16);
-+
-+ }
-+
-+ nextTpl = SDDEVICE_GET_SDIO_FUNC_CISPTR(pDevice);
-+ /* look for the funce TPL */
-+ tplLength = sizeof(funcTuple);
-+ /* go get the func CE tuple */
-+ status = SDLIB_FindTuple(pDevice,
-+ CISTPL_FUNCE,
-+ &nextTpl,
-+ (PUINT8)&funcTuple,
-+ &tplLength);
-+
-+ if (!SDIO_SUCCESS(status)){
-+ /* handles case of bad CIS or missing tupple, allow function driver to handle */
-+ DBG_PRINT(SDDBG_WARN, ("SDIO Bus Driver: Failed to get FuncCE Tuple: %d \n", status));
-+ status = SDIO_STATUS_SUCCESS;
-+ break;
-+ }
-+ /* set the max block size */
-+ pDevice->DeviceInfo.AsSDIOInfo.FunctionMaxBlockSize =
-+ CT_LE16_TO_CPU_ENDIAN(funcTuple.CommonInfo.MaxBlockSize);
-+
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Function:%d, MaxBlocks:%d \n",
-+ SDDEVICE_GET_SDIO_FUNCNO(pDevice),
-+ pDevice->DeviceInfo.AsSDIOInfo.FunctionMaxBlockSize));
-+
-+ /* check for MANFID function tuple (SDIO 1.1 or greater) */
-+ if (SDDEVICE_IS_SDIO_REV_GTEQ_1_10(pDevice)) {
-+ struct SDIO_MANFID_TPL manfid;
-+ nextTpl = SDDEVICE_GET_SDIO_FUNC_CISPTR(pDevice);
-+ tplLength = sizeof(manfid);
-+ /* get the MANFID tuple */
-+ status = SDLIB_FindTuple(pDevice,
-+ CISTPL_MANFID,
-+ &nextTpl,
-+ (PUINT8)&manfid,
-+ &tplLength);
-+ if (SDIO_SUCCESS(status)) {
-+ /* this function has a MANFID tuple */
-+ pDevice->pId[0].SDIO_ManufacturerCode =
-+ CT_LE16_TO_CPU_ENDIAN(manfid.ManufacturerCode);
-+ pDevice->pId[0].SDIO_ManufacturerID =
-+ CT_LE16_TO_CPU_ENDIAN(manfid.ManufacturerInfo);
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO 1.1 (Function Specific) MANFID:0x%X, MANFINFO:0x%X \n",
-+ pDevice->pId[0].SDIO_ManufacturerID,
-+ pDevice->pId[0].SDIO_ManufacturerCode));
-+ } else {
-+ DBG_PRINT(SDDBG_WARN, ("SDIO 1.1, No CISTPL_MANFID Tuple in FUNC CIS \n"));
-+ status = SDIO_STATUS_SUCCESS;
-+ }
-+ }
-+ } while (FALSE);
-+
-+ return status;
-+}
-+
-+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ SDEnableFunction - enable function
-+ Input: pDevice - the device/function
-+ pEnData - enable data;
-+ Output:
-+ Return: status
-+ Notes: Note, this performs synchronous calls
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+SDIO_STATUS SDEnableFunction(PSDDEVICE pDevice, PSDCONFIG_FUNC_ENABLE_DISABLE_DATA pEnData)
-+{
-+ SDIO_STATUS status = SDIO_STATUS_SUCCESS;
-+ UINT8 registerValue;
-+ UINT8 mask;
-+ FUNC_ENABLE_TIMEOUT retry;
-+
-+ /* take the configure op lock to make this atomic */
-+ status = SemaphorePendInterruptable(&pDevice->pHcd->ConfigureOpsSem);
-+ if (!SDIO_SUCCESS(status)) {
-+ return status;
-+ }
-+
-+ status = SDIO_STATUS_INVALID_PARAMETER;
-+ do {
-+ if (!(pDevice->pHcd->CardProperties.Flags & CARD_SDIO)){
-+ /* nothing to do if it's not an SDIO card */
-+ break;
-+ }
-+
-+ if (!((SDDEVICE_GET_SDIO_FUNCNO(pDevice) >= SDIO_FIRST_FUNCTION_NUMBER) &&
-+ (SDDEVICE_GET_SDIO_FUNCNO(pDevice) <= SDIO_LAST_FUNCTION_NUMBER))){
-+ DBG_ASSERT(FALSE);
-+ break;
-+ }
-+ /* make sure there is a timeout value */
-+ if (0 == pEnData->TimeOut) {
-+ break;
-+ }
-+
-+ mask = 1 << SDDEVICE_GET_SDIO_FUNCNO(pDevice);
-+ /* read the enable register */
-+ status = Cmd52ReadByteCommon(pDevice, SDIO_ENABLE_REG, &registerValue);
-+ if (!SDIO_SUCCESS(status)){
-+ break;
-+ }
-+ if (pEnData->EnableFlags & SDCONFIG_ENABLE_FUNC) {
-+ /* set the enable register bit */
-+ registerValue |= mask;
-+ } else {
-+ /* clear the bit */
-+ registerValue &= ~mask;
-+ }
-+
-+ DBG_PRINT(SDDBG_TRACE,
-+ ("SDIO Bus Driver %s Function, Mask:0x%X Enable Reg Value:0x%2.2X\n",
-+ (pEnData->EnableFlags & SDCONFIG_ENABLE_FUNC) ? "Enabling":"Disabling",
-+ mask,
-+ registerValue));
-+
-+ /* write it back out */
-+ status = Cmd52WriteByteCommon(pDevice, SDIO_ENABLE_REG, &registerValue);
-+ if (!SDIO_SUCCESS(status)){
-+ break;
-+ }
-+ /* now poll the ready bit until it sets or clears */
-+ retry = pEnData->TimeOut;
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: Function Enable/Disable Polling: %d retries \n",
-+ retry));
-+ while (retry) {
-+ status = Cmd52ReadByteCommon(pDevice, SDIO_READY_REG, &registerValue);
-+ if (!SDIO_SUCCESS(status)){
-+ break;
-+ }
-+ if (pEnData->EnableFlags & SDCONFIG_ENABLE_FUNC) {
-+ /* if the bit is set, the device is ready */
-+ if (registerValue & mask) {
-+ /* device ready */
-+ break;
-+ }
-+ } else {
-+ if (!(registerValue & mask)) {
-+ /* device is no longer ready */
-+ break;
-+ }
-+ }
-+ /* sleep before trying again */
-+ status = OSSleep(1);
-+ if (!SDIO_SUCCESS(status)) {
-+ DBG_PRINT(SDDBG_ERROR, ("OSSleep Failed! \n"));
-+ break;
-+ }
-+ retry--;
-+ }
-+
-+ if (0 == retry) {
-+ status = SDIO_STATUS_FUNC_ENABLE_TIMEOUT;
-+ break;
-+ }
-+
-+ } while (FALSE);
-+
-+ SemaphorePost(&pDevice->pHcd->ConfigureOpsSem);
-+ return status;
-+}
-+
-+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ SDAllocFreeSlotCurrent - allocate or free slot current
-+ Input: pDevice - the device/function
-+ Allocate - Allocate current, else free
-+ pData - slotcurrent data (non-NULL if Allocate is TRUE)
-+ Output:
-+ Return: status
-+ Notes: if the function returns SDIO_STATUS_NO_RESOURCES, the pData->SlotCurrent field is
-+ updated with the available current
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+SDIO_STATUS SDAllocFreeSlotCurrent(PSDDEVICE pDevice, BOOL Allocate, PSDCONFIG_FUNC_SLOT_CURRENT_DATA pData)
-+{
-+ SDIO_STATUS status = SDIO_STATUS_SUCCESS;
-+
-+ DBG_PRINT(SDDBG_TRACE, ("+SDIO Bus Driver: SDAllocFreeSlotCurrent\n"));
-+
-+ /* take the configure op lock to make this atomic */
-+ status = SemaphorePendInterruptable(&pDevice->pHcd->ConfigureOpsSem);
-+ if (!SDIO_SUCCESS(status)) {
-+ return status;
-+ }
-+
-+ status = SDIO_STATUS_INVALID_PARAMETER;
-+ do {
-+ /* check the current budget and allocate */
-+ if (Allocate) {
-+ if (0 == pData->SlotCurrent) {
-+ /* caller must specify current requirement for the power mode */
-+ break;
-+ }
-+ if (pDevice->SlotCurrentAlloc != 0) {
-+ /* slot current has already been allocated, caller needs to free
-+ * first */
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Slot Current Already allocated! \n"));
-+ break;
-+ }
-+ if (((UINT32)pDevice->pHcd->SlotCurrentAllocated + (UINT32)pData->SlotCurrent) >
-+ (UINT32)pDevice->pHcd->MaxSlotCurrent) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Slot Current Budget exceeded, Requesting: %d, Allocated already: %d, Max: %d \n",
-+ pData->SlotCurrent, pDevice->pHcd->SlotCurrentAllocated,
-+ pDevice->pHcd->MaxSlotCurrent));
-+ status = SDIO_STATUS_NO_RESOURCES;
-+ /* return remaining */
-+ pData->SlotCurrent = pDevice->pHcd->MaxSlotCurrent -
-+ pDevice->pHcd->SlotCurrentAllocated;
-+ break;
-+ }
-+ /* bump up allocation */
-+ pDevice->pHcd->SlotCurrentAllocated += pData->SlotCurrent;
-+ /* save this off for the call to free slot current */
-+ pDevice->SlotCurrentAlloc = pData->SlotCurrent;
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: Slot Current Requested: %d, New Total: %d, Max: %d \n",
-+ pData->SlotCurrent, pDevice->pHcd->SlotCurrentAllocated,
-+ pDevice->pHcd->MaxSlotCurrent));
-+
-+ } else {
-+ if (0 == pDevice->SlotCurrentAlloc) {
-+ /* no allocation */
-+ break;
-+ }
-+ /* return the allocation back */
-+ if (pDevice->SlotCurrentAlloc <= pDevice->pHcd->SlotCurrentAllocated) {
-+ pDevice->pHcd->SlotCurrentAllocated -= pDevice->SlotCurrentAlloc;
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: Slot Current Freed: %d, New Total: %d, Max: %d \n",
-+ pDevice->SlotCurrentAlloc, pDevice->pHcd->SlotCurrentAllocated,
-+ pDevice->pHcd->MaxSlotCurrent));
-+ } else {
-+ DBG_ASSERT(FALSE);
-+ }
-+
-+ /* make sure this is zeroed */
-+ pDevice->SlotCurrentAlloc = 0;
-+ }
-+
-+ status = SDIO_STATUS_SUCCESS;
-+
-+ } while (FALSE);
-+
-+ SemaphorePost(&pDevice->pHcd->ConfigureOpsSem);
-+ DBG_PRINT(SDDBG_TRACE, ("-SDIO Bus Driver: SDAllocFreeSlotCurrent, %d\n", status));
-+ return status;
-+}
-+
-+static void RawHcdIrqControl(PSDHCD pHcd, BOOL Enable)
-+{
-+ SDIO_STATUS status;
-+ SDCONFIG_SDIO_INT_CTRL_DATA irqData;
-+ CT_DECLARE_IRQ_SYNC_CONTEXT();
-+
-+ ZERO_OBJECT(irqData);
-+
-+ status = _AcquireHcdLock(pHcd);
-+ if (!SDIO_SUCCESS(status)) {
-+ return;
-+ }
-+
-+ do {
-+ /* for raw devices, we simply enable/disable in the HCD only */
-+ if (Enable) {
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver (RAW) Unmasking Int \n"));
-+ irqData.IRQDetectMode = IRQ_DETECT_RAW;
-+ irqData.SlotIRQEnable = TRUE;
-+ } else {
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver (RAW) Masking Int \n"));
-+ irqData.SlotIRQEnable = FALSE;
-+ }
-+
-+ status = _IssueConfig(pHcd,SDCONFIG_SDIO_INT_CTRL,
-+ (PVOID)&irqData, sizeof(irqData));
-+
-+ if (!SDIO_SUCCESS(status)){
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver failed to enable/disable IRQ in (RAW) hcd :%d\n",
-+ status));
-+ }
-+
-+ } while (FALSE);
-+
-+ status = _ReleaseHcdLock(pHcd);
-+}
-+
-+static void RawHcdEnableIrqPseudoComplete(PSDREQUEST pReq)
-+{
-+ if (SDIO_SUCCESS(pReq->Status)) {
-+ RawHcdIrqControl((PSDHCD)pReq->pCompleteContext, TRUE);
-+ }
-+ FreeRequest(pReq);
-+}
-+
-+static void RawHcdDisableIrqPseudoComplete(PSDREQUEST pReq)
-+{
-+ RawHcdIrqControl((PSDHCD)pReq->pCompleteContext, FALSE);
-+ FreeRequest(pReq);
-+}
-+
-+static void HcdIrqControl(PSDHCD pHcd, BOOL Enable)
-+{
-+ SDIO_STATUS status;
-+ SDCONFIG_SDIO_INT_CTRL_DATA irqData;
-+ CT_DECLARE_IRQ_SYNC_CONTEXT();
-+
-+ ZERO_OBJECT(irqData);
-+
-+ status = _AcquireHcdLock(pHcd);
-+ if (!SDIO_SUCCESS(status)) {
-+ return;
-+ }
-+
-+ do {
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: HcdIrqControl (%s), IrqsEnabled:0x%X \n",
-+ Enable ? "Enable":"Disable",pHcd->IrqsEnabled ));
-+
-+ if (Enable) {
-+ irqData.SlotIRQEnable = TRUE;
-+ } else {
-+ irqData.SlotIRQEnable = FALSE;
-+ }
-+ /* setup HCD to enable/disable it's detection hardware */
-+ if (irqData.SlotIRQEnable) {
-+ /* set the IRQ detection mode */
-+ switch (SDCONFIG_GET_BUSWIDTH(pHcd->CardProperties.BusMode)) {
-+ case SDCONFIG_BUS_WIDTH_SPI:
-+ irqData.IRQDetectMode = IRQ_DETECT_SPI;
-+ break;
-+ case SDCONFIG_BUS_WIDTH_1_BIT:
-+ irqData.IRQDetectMode = IRQ_DETECT_1_BIT;
-+ break;
-+ case SDCONFIG_BUS_WIDTH_4_BIT:
-+ irqData.IRQDetectMode = IRQ_DETECT_4_BIT;
-+ /* check card and HCD for 4bit multi-block interrupt support */
-+ if ((pHcd->CardProperties.SDIOCaps & SDIO_CAPS_INT_MULTI_BLK) &&
-+ (pHcd->Attributes & SDHCD_ATTRIB_MULTI_BLK_IRQ)) {
-+ /* note: during initialization of the card, the mult-blk IRQ support
-+ * is enabled in card caps register */
-+ irqData.IRQDetectMode |= IRQ_DETECT_MULTI_BLK;
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver enabling IRQ in multi-block mode:\n"));
-+ }
-+ break;
-+ default:
-+ DBG_ASSERT(FALSE);
-+ break;
-+ }
-+
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver enabling IRQ in HCD Mode:0x%X\n",
-+ irqData.IRQDetectMode));
-+ }
-+
-+ status = _IssueConfig(pHcd,SDCONFIG_SDIO_INT_CTRL,
-+ (PVOID)&irqData, sizeof(irqData));
-+ if (!SDIO_SUCCESS(status)){
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver failed to enable/disable IRQ in hcd %d\n",
-+ status));
-+ }
-+
-+ } while (FALSE);
-+
-+ status = _ReleaseHcdLock(pHcd);
-+}
-+
-+static BOOL CheckWriteIntEnableSuccess(PSDREQUEST pReq)
-+{
-+ if (!SDIO_SUCCESS(pReq->Status)){
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to get write INT Enable register Err:%d\n",
-+ pReq->Status));
-+ return FALSE;
-+ }
-+
-+ if (SD_R5_GET_RESP_FLAGS(pReq->Response) & SD_R5_ERRORS) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: WriteIntEnableComplete CMD52 resp error: 0x%X \n",
-+ SD_R5_GET_RESP_FLAGS(pReq->Response)));
-+ return FALSE;
-+ }
-+
-+ return TRUE;
-+}
-+
-+static void HcdIrqEnableComplete(PSDREQUEST pReq)
-+{
-+ if (CheckWriteIntEnableSuccess(pReq)) {
-+ /* configure HCD */
-+ HcdIrqControl((PSDHCD)pReq->pCompleteContext, TRUE);
-+ }
-+ FreeRequest(pReq);
-+}
-+
-+static void HcdIrqDisableComplete(PSDREQUEST pReq)
-+{
-+ CheckWriteIntEnableSuccess(pReq);
-+ HcdIrqControl((PSDHCD)pReq->pCompleteContext, FALSE);
-+ FreeRequest(pReq);
-+}
-+
-+static void WriteIntEnableComplete(PSDREQUEST pReq)
-+{
-+ if (CheckWriteIntEnableSuccess(pReq)) {
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: Wrote INT Enable value:0x%X \n",
-+ (INT)pReq->pCompleteContext));
-+ }
-+ FreeRequest(pReq);
-+}
-+
-+static void HcdAckComplete(PSDREQUEST pReq)
-+{
-+ SDIO_STATUS status;
-+ DBG_PRINT(SDIODBG_FUNC_IRQ, ("SDIO Bus Driver: Hcd (0x%X) Irq Ack \n",
-+ (INT)pReq->pCompleteContext));
-+ /* re-arm the HCD */
-+ status = _IssueConfig((PSDHCD)pReq->pCompleteContext,SDCONFIG_SDIO_REARM_INT,NULL,0);
-+
-+ if (!SDIO_SUCCESS(status)) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: HCD Re-Arm failed : %d\n",
-+ status));
-+ }
-+ FreeRequest(pReq);
-+}
-+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ SDFunctionAckInterrupt - handle device interrupt acknowledgement
-+ Input: pDevice - the device
-+ Output:
-+ Return:
-+ Notes:
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+SDIO_STATUS SDFunctionAckInterrupt(PSDDEVICE pDevice)
-+{
-+ SDIO_STATUS status = SDIO_STATUS_SUCCESS;
-+ UCHAR mask;
-+ PSDREQUEST pReq = NULL;
-+ BOOL setHcd = FALSE;
-+ SDIO_STATUS status2;
-+ CT_DECLARE_IRQ_SYNC_CONTEXT();
-+
-+ pReq = AllocateRequest();
-+ if (NULL == pReq) {
-+ return SDIO_STATUS_NO_RESOURCES;
-+ }
-+
-+ status = _AcquireHcdLock(pDevice->pHcd);
-+
-+ if (!SDIO_SUCCESS(status)) {
-+ FreeRequest(pReq);
-+ return status;
-+ }
-+
-+ do {
-+ if (!((SDDEVICE_GET_SDIO_FUNCNO(pDevice) >= SDIO_FIRST_FUNCTION_NUMBER) &&
-+ (SDDEVICE_GET_SDIO_FUNCNO(pDevice) <= SDIO_LAST_FUNCTION_NUMBER))){
-+ status = SDIO_STATUS_INVALID_PARAMETER;
-+ DBG_ASSERT(FALSE);
-+ break;
-+ }
-+ mask = 1 << SDDEVICE_GET_SDIO_FUNCNO(pDevice);
-+ if (pDevice->pHcd->PendingIrqAcks & mask) {
-+ /* clear the ack bit in question */
-+ pDevice->pHcd->PendingIrqAcks &= ~mask;
-+ if (0 == pDevice->pHcd->PendingIrqAcks) {
-+ pDevice->pHcd->IrqProcState = SDHCD_IDLE;
-+ /* no pending acks, so re-arm if irqs are stilled enabled */
-+ if (pDevice->pHcd->IrqsEnabled) {
-+ setHcd = TRUE;
-+ /* issue pseudo request to sync this with bus requests */
-+ pReq->Status = SDIO_STATUS_SUCCESS;
-+ pReq->pCompletion = HcdAckComplete;
-+ pReq->pCompleteContext = pDevice->pHcd;
-+ pReq->Flags = SD_PSEUDO_REQ_FLAGS;
-+ }
-+ }
-+ } else {
-+ DBG_PRINT(SDDBG_WARN, ("SDIO Bus Driver: AckInterrupt: no IRQ pending on Function :%d, \n",
-+ SDDEVICE_GET_SDIO_FUNCNO(pDevice)));
-+ }
-+ } while (FALSE);
-+
-+ status2 = ReleaseHcdLock(pDevice);
-+
-+ if (pReq != NULL) {
-+ if (SDIO_SUCCESS(status) && (setHcd)) {
-+ /* issue request */
-+ IssueRequestToHCD(pDevice->pHcd,pReq);
-+ } else {
-+ FreeRequest(pReq);
-+ }
-+ }
-+
-+ return status;
-+}
-+
-+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ SDMaskUnmaskFunctionIRQ - mask/unmask function IRQ
-+ Input: pDevice - the device/function
-+ MaskInt - mask interrupt
-+ Output:
-+ Return: status
-+ Notes: Note, this function can be called from an ISR or completion context
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+SDIO_STATUS SDMaskUnmaskFunctionIRQ(PSDDEVICE pDevice, BOOL MaskInt)
-+{
-+ SDIO_STATUS status = SDIO_STATUS_SUCCESS;
-+ UINT8 mask;
-+ UINT8 controlVal;
-+ BOOL setHcd;
-+ PSDREQUEST pReq = NULL;
-+ SDIO_STATUS status2;
-+
-+ CT_DECLARE_IRQ_SYNC_CONTEXT();
-+
-+ setHcd = FALSE;
-+
-+ pReq = AllocateRequest();
-+ if (NULL == pReq) {
-+ return SDIO_STATUS_NO_RESOURCES;
-+ }
-+
-+ status = _AcquireHcdLock(pDevice->pHcd);
-+
-+ if (!SDIO_SUCCESS(status)) {
-+ FreeRequest(pReq);
-+ return status;
-+ }
-+
-+ do {
-+
-+ if (pDevice->pHcd->CardProperties.Flags & CARD_RAW) {
-+ if (!MaskInt) {
-+ if (!pDevice->pHcd->IrqsEnabled) {
-+ pReq->pCompletion = RawHcdEnableIrqPseudoComplete;
-+ setHcd = TRUE;
-+ pDevice->pHcd->IrqsEnabled = 1 << 1;
-+ }
-+ } else {
-+ if (pDevice->pHcd->IrqsEnabled) {
-+ pReq->pCompletion = RawHcdDisableIrqPseudoComplete;
-+ setHcd = TRUE;
-+ pDevice->pHcd->IrqsEnabled = 0;
-+ }
-+ }
-+
-+ if (setHcd) {
-+ /* hcd IRQ control requests must be synched with outstanding
-+ * bus requests so we issue a pseudo bus request */
-+ pReq->pCompleteContext = pDevice->pHcd;
-+ pReq->Flags = SD_PSEUDO_REQ_FLAGS;
-+ pReq->Status = SDIO_STATUS_SUCCESS;
-+ } else {
-+ /* no request to submit, just free it */
-+ FreeRequest(pReq);
-+ pReq = NULL;
-+ }
-+ /* we're done, submit the bus request if any */
-+ break;
-+ }
-+
-+ if (!(pDevice->pHcd->CardProperties.Flags & CARD_SDIO)){
-+ /* nothing to do if it's not an SDIO card */
-+ DBG_ASSERT(FALSE);
-+ status = SDIO_STATUS_INVALID_PARAMETER;
-+ break;
-+ }
-+
-+ if (!((SDDEVICE_GET_SDIO_FUNCNO(pDevice) >= SDIO_FIRST_FUNCTION_NUMBER) &&
-+ (SDDEVICE_GET_SDIO_FUNCNO(pDevice) <= SDIO_LAST_FUNCTION_NUMBER))){
-+ status = SDIO_STATUS_INVALID_PARAMETER;
-+ DBG_ASSERT(FALSE);
-+ break;
-+ }
-+
-+ mask = 1 << SDDEVICE_GET_SDIO_FUNCNO(pDevice);
-+ if (!MaskInt) {
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver Unmasking Int, Mask:0x%X\n", mask));
-+ /* check interrupts that were enabled on entry */
-+ if (0 == pDevice->pHcd->IrqsEnabled) {
-+ /* need to turn on interrupts in HCD */
-+ setHcd = TRUE;
-+ /* use this completion routine */
-+ pReq->pCompletion = HcdIrqEnableComplete;
-+ }
-+ /* set the enable bit, in the shadow register */
-+ pDevice->pHcd->IrqsEnabled |= mask;
-+ /* make sure control value includes the master enable */
-+ controlVal = pDevice->pHcd->IrqsEnabled | SDIO_INT_MASTER_ENABLE;
-+ } else {
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver Masking Int, Mask:0x%X\n", mask));
-+ /* clear the bit */
-+ pDevice->pHcd->IrqsEnabled &= ~mask;
-+ /* check and see if this clears all the bits */
-+ if (0 == pDevice->pHcd->IrqsEnabled){
-+ /* if none of the functions are enabled, clear this register */
-+ controlVal = 0;
-+ /* disable in host */
-+ setHcd = TRUE;
-+ /* use this completion routine */
-+ pReq->pCompletion = HcdIrqDisableComplete;
-+ } else {
-+ /* set control value making sure master enable is left on */
-+ controlVal = pDevice->pHcd->IrqsEnabled | SDIO_INT_MASTER_ENABLE;
-+ }
-+ }
-+
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver INT_ENABLE_REG value:0x%X\n", controlVal));
-+ /* setup bus request to update the mask register */
-+ SDIO_SET_CMD52_WRITE_ARG(pReq->Argument,0,SDIO_INT_ENABLE_REG,controlVal);
-+ pReq->Command = CMD52;
-+ pReq->Flags = SDREQ_FLAGS_TRANS_ASYNC | SDREQ_FLAGS_RESP_SDIO_R5;
-+
-+ if (setHcd) {
-+ /* make this a barrier request and set context*/
-+ pReq->Flags |= SDREQ_FLAGS_BARRIER;
-+ pReq->pCompleteContext = pDevice->pHcd;
-+ } else {
-+ /* does not require an update to the HCD */
-+ pReq->pCompleteContext = (PVOID)(UINT32)controlVal;
-+ pReq->pCompletion = WriteIntEnableComplete;
-+ }
-+
-+ } while (FALSE);
-+
-+ status2 = _ReleaseHcdLock(pDevice->pHcd);
-+
-+ if (pReq != NULL) {
-+ if (SDIO_SUCCESS(status)) {
-+ /* issue request */
-+ IssueRequestToHCD(pDevice->pHcd,pReq);
-+ } else {
-+ FreeRequest(pReq);
-+ }
-+ }
-+
-+ return status;
-+}
-+
-+
-+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ SDSPIModeEnableDisableCRC - Enable/Disable SPI Mode CRC checking
-+ Input: pDevice - the device/function
-+ Enable - Enable CRC
-+ Output:
-+ Return: status
-+ Notes: Note, this function can be called from an ISR or completion context
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+SDIO_STATUS SDSPIModeEnableDisableCRC(PSDDEVICE pDevice,BOOL Enable)
-+{
-+ SDCONFIG_BUS_MODE_DATA busMode;
-+ SDIO_STATUS status = SDIO_STATUS_SUCCESS;
-+ UINT32 cmdARG = 0;
-+
-+ if (!SDDEVICE_IS_BUSMODE_SPI(pDevice)) {
-+ return SDIO_STATUS_INVALID_PARAMETER;
-+ }
-+ //??we should make these atomic using a barrier
-+
-+ /* get the current mode and clock */
-+ busMode.BusModeFlags = pDevice->pHcd->CardProperties.BusMode;
-+ busMode.ClockRate = pDevice->pHcd->CardProperties.OperBusClock;
-+
-+ if (Enable) {
-+ /* clear the no-CRC flag */
-+ busMode.BusModeFlags &= ~SDCONFIG_BUS_MODE_SPI_NO_CRC;
-+ cmdARG = SD_CMD59_CRC_ON;
-+ } else {
-+ busMode.BusModeFlags |= SDCONFIG_BUS_MODE_SPI_NO_CRC;
-+ cmdARG = SD_CMD59_CRC_OFF;
-+ }
-+
-+ do {
-+ /* issue CMD59 to turn on/off CRC */
-+ status = _IssueSimpleBusRequest(pDevice->pHcd,
-+ CMD59,
-+ cmdARG,
-+ SDREQ_FLAGS_RESP_R1,
-+ NULL);
-+ if (!SDIO_SUCCESS(status)) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed issue CMD59 (arg=0x%X) Err:%d \n",
-+ cmdARG, status));
-+ break;
-+ }
-+ if (Enable) {
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: CRC Enabled in SPI mode \n"));
-+ } else {
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: CRC Disabled in SPI mode \n"));
-+ }
-+ status = SetOperationalBusMode(pDevice,&busMode);
-+ if (!SDIO_SUCCESS(status)) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Failed to set SPI NO CRC mode in hcd : Err:%d \n",
-+ status));
-+ break;
-+ }
-+ } while (FALSE);
-+
-+ return status;
-+}
-+
-+
-+static UINT32 ConvertSPIStatusToSDCardStatus(UINT8 SpiR1, UINT8 SpiR2)
-+{
-+ UINT32 cardStatus = 0;
-+
-+ if (SpiR1 != 0) {
-+ /* convert the error */
-+ if (SpiR1 & SPI_CS_ERASE_RESET) {
-+ cardStatus |= SD_CS_ERASE_RESET;
-+ }
-+ if (SpiR1 & SPI_CS_ILLEGAL_CMD) {
-+ cardStatus |= SD_CS_ILLEGAL_CMD_ERR;
-+ }
-+ if (SpiR1 & SPI_CS_CMD_CRC_ERR) {
-+ cardStatus |= SD_CS_PREV_CMD_CRC_ERR;
-+ }
-+ if (SpiR1 & SPI_CS_ERASE_SEQ_ERR) {
-+ cardStatus |= SD_CS_ERASE_SEQ_ERR;
-+ }
-+ if (SpiR1 & SPI_CS_ADDRESS_ERR) {
-+ cardStatus |= SD_CS_ADDRESS_ERR;
-+ }
-+ if (SpiR1 & SPI_CS_PARAM_ERR) {
-+ cardStatus |= SD_CS_CMD_OUT_OF_RANGE;
-+ }
-+ }
-+
-+ if (SpiR2 != 0) {
-+ /* convert the error */
-+ if (SpiR2 & SPI_CS_CARD_IS_LOCKED) {
-+ cardStatus |= SD_CS_CARD_LOCKED;
-+ }
-+ if (SpiR2 & SPI_CS_LOCK_UNLOCK_FAILED) {
-+ /* this bit is shared, just set both */
-+ cardStatus |= (SD_CS_LK_UNLK_FAILED | SD_CS_WP_ERASE_SKIP);
-+ }
-+ if (SpiR2 & SPI_CS_ERROR) {
-+ cardStatus |= SD_CS_GENERAL_ERR;
-+ }
-+ if (SpiR2 & SPI_CS_INTERNAL_ERROR) {
-+ cardStatus |= SD_CS_CARD_INTERNAL_ERR;
-+ }
-+ if (SpiR2 & SPI_CS_ECC_FAILED) {
-+ cardStatus |= SD_CS_ECC_FAILED;
-+ }
-+ if (SpiR2 & SPI_CS_WP_VIOLATION) {
-+ cardStatus |= SD_CS_WP_ERR;
-+ }
-+ if (SpiR2 & SPI_CS_ERASE_PARAM_ERR) {
-+ cardStatus |= SD_CS_ERASE_PARAM_ERR;
-+ }
-+ if (SpiR2 & SPI_CS_OUT_OF_RANGE) {
-+ cardStatus |= SD_CS_CMD_OUT_OF_RANGE;
-+ }
-+ }
-+
-+ return cardStatus;
-+}
-+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ ConvertSPI_Response - filter the SPI response and convert it to an SD Response
-+ Input: pReq - request
-+ Output: pReq - modified response, if pRespBuffer is not NULL
-+ pRespBuffer - converted response (optional)
-+ Return:
-+ Notes: This function converts a SPI response into an SD response. A caller
-+ can supply a buffer instead.
-+ For SPI bus operation the HCD must send the SPI response as
-+ a stream of bytes, the highest byte contains the first received byte from the
-+ card. This function only filters simple responses (R1 primarily).
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+void ConvertSPI_Response(PSDREQUEST pReq, UINT8 *pRespBuffer)
-+{
-+
-+ UINT32 cardStatus;
-+
-+ if (pReq->Flags & SDREQ_FLAGS_RESP_SPI_CONVERTED) {
-+ /* already converted */
-+ return;
-+ }
-+ if (NULL == pRespBuffer) {
-+ pRespBuffer = pReq->Response;
-+ }
-+
-+ switch (GET_SDREQ_RESP_TYPE(pReq->Flags)) {
-+ case SDREQ_FLAGS_RESP_R1:
-+ case SDREQ_FLAGS_RESP_R1B:
-+ cardStatus = ConvertSPIStatusToSDCardStatus(GET_SPI_R1_RESP_TOKEN(pReq->Response),
-+ 0);
-+ if (CMD55 == pReq->Command) {
-+ /* we emulate this since SPI does not have such a bit */
-+ cardStatus |= SD_CS_APP_CMD;
-+ }
-+ /* stuff the SD card status */
-+ SD_R1_SET_CMD_STATUS(pRespBuffer,cardStatus);
-+ /* stuff the command */
-+ SD_R1_SET_CMD(pRespBuffer,pReq->Command);
-+ pReq->Flags |= SDREQ_FLAGS_RESP_SPI_CONVERTED;
-+ break;
-+ case SDREQ_FLAGS_RESP_SDIO_R5:
-+ {
-+ UINT8 respFlags;
-+ UINT8 readData;
-+
-+ readData = GET_SPI_SDIO_R5_RESPONSE_RDATA(pReq->Response);
-+ respFlags = GET_SPI_SDIO_R5_RESP_TOKEN(pReq->Response);
-+
-+ pRespBuffer[SD_R5_RESP_FLAGS_OFFSET] = 0;
-+ if (respFlags != 0) {
-+ if (respFlags & SPI_R5_ILLEGAL_CMD) {
-+ pRespBuffer[SD_R5_RESP_FLAGS_OFFSET] |= SD_R5_ILLEGAL_CMD;
-+ }
-+ if (respFlags & SPI_R5_CMD_CRC) {
-+ pRespBuffer[SD_R5_RESP_FLAGS_OFFSET] |= SD_R5_RESP_CMD_ERR;
-+ }
-+ if (respFlags & SPI_R5_FUNC_ERR) {
-+ pRespBuffer[SD_R5_RESP_FLAGS_OFFSET] |= SD_R5_INVALID_FUNC;
-+ }
-+ if (respFlags & SPI_R5_PARAM_ERR) {
-+ pRespBuffer[SD_R5_RESP_FLAGS_OFFSET] |= SD_R5_ARG_RANGE_ERR;
-+ }
-+ }
-+ /* stuff read data */
-+ pRespBuffer[SD_SDIO_R5_READ_DATA_OFFSET] = readData;
-+ /* stuff the command */
-+ SD_R5_SET_CMD(pRespBuffer,pReq->Command);
-+ }
-+ pReq->Flags |= SDREQ_FLAGS_RESP_SPI_CONVERTED;
-+ break;
-+ case SDREQ_FLAGS_RESP_R2:
-+ /* for CMD13 and ACMD13 , SPI uses it's own R2 response format (2 bytes) */
-+ /* the issue of CMD13 needs to change the response flag to R2 */
-+ if (CMD13 == pReq->Command) {
-+ cardStatus = ConvertSPIStatusToSDCardStatus(
-+ GET_SPI_R2_RESP_TOKEN(pReq->Response),
-+ GET_SPI_R2_STATUS_TOKEN(pReq->Response));
-+ /* stuff the SD card status */
-+ SD_R1_SET_CMD_STATUS(pRespBuffer,cardStatus);
-+ /* stuff the command */
-+ SD_R1_SET_CMD(pRespBuffer,pReq->Command);
-+ pReq->Flags |= SDREQ_FLAGS_RESP_SPI_CONVERTED;
-+ break;
-+ }
-+ /* no other commands should be using R2 when using SPI, if they are
-+ * they should be bypassing the filter */
-+ DBG_ASSERT(FALSE);
-+ break;
-+ default:
-+ /* for all others:
-+ *
-+ * SDREQ_FLAGS_RESP_R6 - SPI mode does not use RCA
-+ * SDREQ_FLAGS_RESP_R3 - bus driver handles this internally
-+ * SDREQ_FLAGS_RESP_SDIO_R4 - bus driver handles this internally
-+ *
-+ */
-+ DBG_PRINT(SDDBG_ERROR, ("ConvertSPI_Response - invalid response type:0x%2.2X",
-+ GET_SDREQ_RESP_TYPE(pReq->Flags)));
-+ DBG_ASSERT(FALSE);
-+ break;
-+ }
-+}
-+
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Check an SD/MMC/SDIO response.
-+
-+ @function name: SDIO_CheckResponse
-+ @prototype: SDIO_STATUS SDIO_CheckResponse(PSDHCD pHcd, PSDREQUEST pReq, SDHCD_RESPONSE_CHECK_MODE CheckMode)
-+ @category: HD_Reference
-+
-+ @input: pHcd - the host controller definition structure.
-+ @input: pReq - request containing the response
-+ @input: CheckMode - mode
-+
-+ @return: SDIO_STATUS
-+
-+ @notes: Host controller drivers must call into this function to validate various command
-+ responses before continuing with data transfers or for decoding received SPI tokens.
-+ The CheckMode option determines the type of validation to perform.
-+ if (CheckMode == SDHCD_CHECK_DATA_TRANS_OK) :
-+ The host controller must check the card response to determine whether it
-+ is safe to perform a data transfer. This API only checks commands that
-+ involve data transfers and checks various status fields in the command response.
-+ If the card cannot accept data, this function will return a non-successful status that
-+ should be treated as a request failure. The host driver should complete the request with the
-+ returned status. Host controller should only call this function in preparation for a
-+ data transfer.
-+ if (CheckMode == SDHCD_CHECK_SPI_TOKEN) :
-+ This API checks the SPI token and returns a timeout status if the illegal command bit is
-+ set. This simulates the behavior of SD 1/4 bit operation where illegal commands result in
-+ a command timeout. A driver that supports SPI mode should pass every response to this
-+ function to determine the appropriate error status to complete the request with. If the
-+ API returns success, the response indicates that the card accepted the command.
-+
-+ @example: Checking the response before starting the data transfer :
-+ if (SDIO_SUCCESS(status) && (pReq->Flags & SDREQ_FLAGS_DATA_TRANS)) {
-+ // check the response to see if we should continue with data
-+ status = SDIO_CheckResponse(pHcd, pReq, SDHCD_CHECK_DATA_TRANS_OK);
-+ if (SDIO_SUCCESS(status)) {
-+ .... start data transfer phase
-+ } else {
-+ ... card response indicates that the card cannot handle data
-+ // set completion status
-+ pRequest->Status = status;
-+ }
-+ }
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ _SDIO_CheckResponse - check response on behalf of the host controller
-+ Input: pHcd - host controller
-+ pReq - request containing the response
-+ CheckMode - mode
-+ Output:
-+ Return: status
-+ Notes:
-+
-+ CheckMode == SDHCD_CHECK_DATA_TRANS_OK :
-+ The host controller requests a check on the response to determine whether it
-+ is okay to perform a data transfer. This function only filters on commands that
-+ involve data. Host controller should only call this function in preparation for a
-+ data transfer.
-+
-+ CheckMode == SDHCD_CHECK_SPI_TOKEN :
-+ The bus driver checks the SPI token and returns a timeout status if the illegal command bit is
-+ set. This simulates the behavior of SD native operation.
-+
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+SDIO_STATUS _SDIO_CheckResponse(PSDHCD pHcd, PSDREQUEST pReq, SDHCD_RESPONSE_CHECK_MODE CheckMode)
-+{
-+ SDIO_STATUS status = SDIO_STATUS_SUCCESS;
-+
-+ if (CheckMode == SDHCD_CHECK_DATA_TRANS_OK) {
-+ UINT32 cardStatus;
-+ UINT8 *pResponse;
-+ UINT8 convertedResponse[MAX_CARD_RESPONSE_BYTES];
-+
-+ if (!(pReq->Flags & SDREQ_FLAGS_DATA_TRANS) ||
-+ (pReq->Flags & SDREQ_FLAGS_DATA_SKIP_RESP_CHK) ||
-+ (GET_SDREQ_RESP_TYPE(pReq->Flags) == SDREQ_FLAGS_NO_RESP)) {
-+ return SDIO_STATUS_SUCCESS;
-+ }
-+ pResponse = pReq->Response;
-+ /* check SPI mode */
-+ if (IS_HCD_BUS_MODE_SPI(pHcd)) {
-+ if (!(pReq->Flags & SDREQ_FLAGS_RESP_SKIP_SPI_FILT)) {
-+ /* apply conversion */
-+ ConvertSPI_Response(pReq, NULL);
-+ } else {
-+ /* temporarily convert the response, without altering the original */
-+ ConvertSPI_Response(pReq, convertedResponse);
-+ /* point to the converted one */
-+ pResponse = convertedResponse;
-+ }
-+ }
-+
-+ switch (GET_SDREQ_RESP_TYPE(pReq->Flags)) {
-+ case SDREQ_FLAGS_RESP_R1:
-+ case SDREQ_FLAGS_RESP_R1B:
-+ cardStatus = SD_R1_GET_CARD_STATUS(pResponse);
-+ if (!(cardStatus &
-+ (SD_CS_ILLEGAL_CMD_ERR | SD_CS_CARD_INTERNAL_ERR | SD_CS_GENERAL_ERR))) {
-+ /* okay for data */
-+ break;
-+ }
-+ /* figure out what it was */
-+ if (cardStatus & SD_CS_ILLEGAL_CMD_ERR) {
-+ status = SDIO_STATUS_DATA_STATE_INVALID;
-+ } else {
-+ status = SDIO_STATUS_DATA_ERROR_UNKNOWN;
-+ }
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Check Response Error. R1 CardStatus:0x%X \n",
-+ cardStatus));
-+ break;
-+ case SDREQ_FLAGS_RESP_SDIO_R5:
-+ cardStatus = SD_R5_GET_RESP_FLAGS(pResponse);
-+ if (!(cardStatus & SD_R5_CURRENT_CMD_ERRORS)){
-+ /* all okay */
-+ break;
-+ }
-+
-+ status = ConvertCMD52ResponseToSDIOStatus((UINT8)cardStatus);
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: Check Response Error. R5 CardStatus:0x%X \n",
-+ cardStatus));
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ return status;
-+ }
-+
-+ {
-+ UINT8 spiToken;
-+
-+ /* handle SPI token validation */
-+ switch (GET_SDREQ_RESP_TYPE(pReq->Flags)) {
-+ case SDREQ_FLAGS_RESP_R2:
-+ spiToken = GET_SPI_R2_RESP_TOKEN(pReq->Response);
-+ break;
-+ case SDREQ_FLAGS_RESP_SDIO_R5:
-+ spiToken = GET_SPI_SDIO_R5_RESP_TOKEN(pReq->Response);
-+ break;
-+ case SDREQ_FLAGS_RESP_R3:
-+ spiToken = GET_SPI_R3_RESP_TOKEN(pReq->Response);
-+ break;
-+ case SDREQ_FLAGS_RESP_SDIO_R4:
-+ spiToken = GET_SPI_SDIO_R4_RESP_TOKEN(pReq->Response);
-+ break;
-+ default:
-+ /* all other tokesn are SPI R1 type */
-+ spiToken = GET_SPI_R1_RESP_TOKEN(pReq->Response);
-+ break;
-+ }
-+
-+ if ((GET_SDREQ_RESP_TYPE(pReq->Flags) == SDREQ_FLAGS_RESP_SDIO_R5) ||
-+ (GET_SDREQ_RESP_TYPE(pReq->Flags) == SDREQ_FLAGS_RESP_SDIO_R4)) {
-+ /* handle SDIO status tokens */
-+ if ((spiToken & SPI_R5_ILLEGAL_CMD) ||
-+ (spiToken & SPI_R5_CMD_CRC)) {
-+ status = SDIO_STATUS_BUS_RESP_TIMEOUT;
-+ }
-+ } else {
-+ /* handle all other status tokens */
-+ if ((spiToken & SPI_CS_ILLEGAL_CMD) ||
-+ (spiToken & SPI_CS_CMD_CRC_ERR)) {
-+ status = SDIO_STATUS_BUS_RESP_TIMEOUT;
-+ }
-+ }
-+ }
-+
-+ return status;
-+}
-+
-diff --git a/drivers/sdio/stack/busdriver/sdio_bus_os.c b/drivers/sdio/stack/busdriver/sdio_bus_os.c
-new file mode 100644
-index 0000000..dbdb955
---- /dev/null
-+++ b/drivers/sdio/stack/busdriver/sdio_bus_os.c
-@@ -0,0 +1,832 @@
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+@file: sdio_bus_os.c
-+
-+@abstract: Linux implementation module
-+
-+#notes: includes module load and unload functions
-+
-+@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
-+ *
-+ *
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+/* debug level for this module*/
-+#define DBG_DECLARE 3;
-+
-+#include <linux/sdio/ctsystem.h>
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/version.h>
-+#include <linux/init.h>
-+#include <linux/workqueue.h>
-+#include <linux/delay.h>
-+#include <linux/kthread.h>
-+#include <linux/pnp.h>
-+void pnp_remove_card_device(struct pnp_dev *dev);
-+#include <linux/sdio/sdio_busdriver.h>
-+#include <linux/sdio/sdio_lib.h>
-+#include "_busdriver.h"
-+
-+#define DESCRIPTION "SDIO Bus Driver"
-+#define AUTHOR "Atheros Communications, Inc."
-+
-+/* debug print parameter */
-+/* configuration and default parameters */
-+static int RequestRetries = SDMMC_DEFAULT_CMD_RETRIES;
-+module_param(RequestRetries, int, 0644);
-+MODULE_PARM_DESC(RequestRetries, "number of command retries");
-+static int CardReadyPollingRetry = SDMMC_DEFAULT_CARD_READY_RETRIES;
-+module_param(CardReadyPollingRetry, int, 0644);
-+MODULE_PARM_DESC(CardReadyPollingRetry, "number of card ready retries");
-+static int PowerSettleDelay = SDMMC_POWER_SETTLE_DELAY;
-+module_param(PowerSettleDelay, int, 0644);
-+MODULE_PARM_DESC(PowerSettleDelay, "delay in ms for power to settle after power changes");
-+static int DefaultOperClock = 52000000;
-+module_param(DefaultOperClock, int, 0644);
-+MODULE_PARM_DESC(DefaultOperClock, "maximum operational clock limit");
-+static int DefaultBusMode = SDCONFIG_BUS_WIDTH_4_BIT;
-+module_param(DefaultBusMode, int, 0644);
-+MODULE_PARM_DESC(DefaultBusMode, "default bus mode: see SDCONFIG_BUS_WIDTH_xxx");
-+static int RequestListSize = SDBUS_DEFAULT_REQ_LIST_SIZE;
-+module_param(RequestListSize, int, 0644);
-+MODULE_PARM_DESC(RequestListSize, "");
-+static int SignalSemListSize = SDBUS_DEFAULT_REQ_SIG_SIZE;
-+module_param(SignalSemListSize, int, 0644);
-+MODULE_PARM_DESC(SignalSemListSize, "");
-+static int CDPollingInterval = SDBUS_DEFAULT_CD_POLLING_INTERVAL;
-+module_param(CDPollingInterval, int, 0644);
-+MODULE_PARM_DESC(CDPollingInterval, "");
-+static int DefaultOperBlockLen = SDMMC_DEFAULT_BYTES_PER_BLOCK;
-+module_param(DefaultOperBlockLen, int, 0644);
-+MODULE_PARM_DESC(DefaultOperBlockLen, "operational block length");
-+static int DefaultOperBlockCount = SDMMC_DEFAULT_BLOCKS_PER_TRANS;
-+module_param(DefaultOperBlockCount, int, 0644);
-+MODULE_PARM_DESC(DefaultOperBlockCount, "operational block count");
-+static int ConfigFlags = BD_DEFAULT_CONFIG_FLAGS;
-+module_param(ConfigFlags, int, 0644);
-+MODULE_PARM_DESC(ConfigFlags, "config flags");
-+
-+static int HcdRCount = MAX_HCD_REQ_RECURSION;
-+module_param(HcdRCount, int, 0644);
-+MODULE_PARM_DESC(HcdRCount, "HCD request recursion count");
-+
-+static void CardDetect_WorkItem(
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
-+void *context);
-+#else
-+struct work_struct *ignored);
-+#endif
-+static void CardDetect_TimerFunc(unsigned long Context);
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-+static DECLARE_WORK(CardDetectPollWork, CardDetect_WorkItem
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
-+, 0);
-+#else
-+);
-+#endif
-+#endif
-+static int RegisterDriver(PSDFUNCTION pFunction);
-+static int UnregisterDriver(PSDFUNCTION pFunction);
-+
-+static struct timer_list CardDetectTimer;
-+
-+#define SDDEVICE_FROM_OSDEVICE(pOSDevice) container_of(pOSDevice, SDDEVICE, Device)
-+#define SDFUNCTION_FROM_OSDRIVER(pOSDriver) container_of(pOSDriver, SDFUNCTION, Driver)
-+
-+
-+/*
-+ * SDIO_RegisterHostController - register a host controller bus driver
-+*/
-+SDIO_STATUS SDIO_RegisterHostController(PSDHCD pHcd) {
-+ /* we are the exported verison, call the internal verison */
-+ return _SDIO_RegisterHostController(pHcd);
-+}
-+
-+/*
-+ * SDIO_UnregisterHostController - unregister a host controller bus driver
-+*/
-+SDIO_STATUS SDIO_UnregisterHostController(PSDHCD pHcd) {
-+ /* we are the exported verison, call the internal verison */
-+ return _SDIO_UnregisterHostController(pHcd);
-+}
-+
-+/*
-+ * SDIO_RegisterFunction - register a function driver
-+*/
-+SDIO_STATUS SDIO_RegisterFunction(PSDFUNCTION pFunction) {
-+ int error;
-+ SDIO_STATUS status;
-+
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO BusDriver - SDIO_RegisterFunction\n"));
-+
-+ /* since we do PnP registration first, we need to check the version */
-+ if (!CHECK_FUNCTION_DRIVER_VERSION(pFunction)) {
-+ DBG_PRINT(SDDBG_ERROR,
-+ ("SDIO Bus Driver: Function Major Version Mismatch (hcd = %d, bus driver = %d)\n",
-+ GET_SDIO_STACK_VERSION_MAJOR(pFunction), CT_SDIO_STACK_VERSION_MAJOR(g_Version)));
-+ return SDIO_STATUS_INVALID_PARAMETER;
-+ }
-+
-+ /* we are the exported verison, call the internal verison after registering with the bus
-+ we handle probes internally to the bus driver */
-+ if ((error = RegisterDriver(pFunction)) < 0) {
-+ DBG_PRINT(SDDBG_ERROR,
-+ ("SDIO BusDriver - SDIO_RegisterFunction, failed to register with system bus driver: %d\n",
-+ error));
-+ status = OSErrorToSDIOError(error);
-+ } else {
-+ status = _SDIO_RegisterFunction(pFunction);
-+ if (!SDIO_SUCCESS(status)) {
-+ UnregisterDriver(pFunction);
-+ }
-+ }
-+
-+ return status;
-+}
-+
-+/*
-+ * SDIO_UnregisterFunction - unregister a function driver
-+*/
-+SDIO_STATUS SDIO_UnregisterFunction(PSDFUNCTION pFunction) {
-+ SDIO_STATUS status;
-+ /* we are the exported verison, call the internal verison */
-+ status = _SDIO_UnregisterFunction(pFunction);
-+ UnregisterDriver(pFunction);
-+ return status;
-+}
-+
-+/*
-+ * SDIO_HandleHcdEvent - tell core an event occurred
-+*/
-+SDIO_STATUS SDIO_HandleHcdEvent(PSDHCD pHcd, HCD_EVENT Event) {
-+ /* we are the exported verison, call the internal verison */
-+ DBG_PRINT(SDIODBG_HCD_EVENTS, ("SDIO Bus Driver: SDIO_HandleHcdEvent, event type 0x%X, HCD:0x%X\n",
-+ Event, (UINT)pHcd));
-+ return _SDIO_HandleHcdEvent(pHcd, Event);
-+}
-+
-+/* get default settings */
-+SDIO_STATUS _SDIO_BusGetDefaultSettings(PBDCONTEXT pBdc)
-+{
-+ /* these defaults are module params */
-+ pBdc->RequestRetries = RequestRetries;
-+ pBdc->CardReadyPollingRetry = CardReadyPollingRetry;
-+ pBdc->PowerSettleDelay = PowerSettleDelay;
-+ pBdc->DefaultOperClock = DefaultOperClock;
-+ pBdc->DefaultBusMode = DefaultBusMode;
-+ pBdc->RequestListSize = RequestListSize;
-+ pBdc->SignalSemListSize = SignalSemListSize;
-+ pBdc->CDPollingInterval = CDPollingInterval;
-+ pBdc->DefaultOperBlockLen = DefaultOperBlockLen;
-+ pBdc->DefaultOperBlockCount = DefaultOperBlockCount;
-+ pBdc->ConfigFlags = ConfigFlags;
-+ pBdc->MaxHcdRecursion = HcdRCount;
-+ return SDIO_STATUS_SUCCESS;
-+}
-+
-+static void CardDetect_TimerFunc(unsigned long Context)
-+{
-+ DBG_PRINT(SDIODBG_CD_TIMER, ("+ SDIO BusDriver Card Detect Timer\n"));
-+
-+ /* timers run in an ISR context and cannot block or sleep, so we need
-+ * to queue a work item to call the bus driver timer notification */
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-+ if (schedule_work(&CardDetectPollWork) <= 0) {
-+ DBG_PRINT(SDDBG_ERROR, ("Failed to queue Card Detect timer!\n"));
-+ }
-+#else
-+ CardDetect_WorkItem(NULL);
-+#endif
-+ DBG_PRINT(SDIODBG_CD_TIMER, ("- SDIO BusDriver Card Detect Timer\n"));
-+}
-+
-+/*
-+ * Initialize any timers we are using
-+*/
-+SDIO_STATUS InitializeTimers(void)
-+{
-+ init_timer(&CardDetectTimer);
-+ CardDetectTimer.function = CardDetect_TimerFunc;
-+ CardDetectTimer.data = 0;
-+ return SDIO_STATUS_SUCCESS;
-+}
-+
-+/*
-+ * cleanup timers
-+*/
-+SDIO_STATUS CleanupTimers(void)
-+{
-+ del_timer(&CardDetectTimer);
-+ return SDIO_STATUS_SUCCESS;
-+}
-+
-+
-+/*
-+ * Queue a timer, Timeout is in milliseconds
-+*/
-+SDIO_STATUS QueueTimer(INT TimerID, UINT32 TimeOut)
-+{
-+ UINT32 delta;
-+
-+ /* convert timeout to ticks */
-+ delta = (TimeOut * HZ)/1000;
-+ if (delta == 0) {
-+ delta = 1;
-+ }
-+ DBG_PRINT(SDIODBG_CD_TIMER, ("SDIO BusDriver - SDIO_QueueTimer System Ticks Per Sec:%d \n",HZ));
-+ DBG_PRINT(SDIODBG_CD_TIMER, ("SDIO BusDriver - SDIO_QueueTimer TimerID: %d TimeOut:%d MS, requires %d Ticks\n",
-+ TimerID,TimeOut,delta));
-+ switch (TimerID) {
-+ case SDIOBUS_CD_TIMER_ID:
-+ CardDetectTimer.expires = jiffies + delta;
-+ add_timer(&CardDetectTimer);
-+ break;
-+ default:
-+ return SDIO_STATUS_INVALID_PARAMETER;
-+ }
-+
-+ return SDIO_STATUS_SUCCESS;
-+}
-+
-+/* check a response on behalf of the host controller, to allow it to proceed with a
-+ * data transfer */
-+SDIO_STATUS SDIO_CheckResponse(PSDHCD pHcd, PSDREQUEST pReq, SDHCD_RESPONSE_CHECK_MODE CheckMode)
-+{
-+ return _SDIO_CheckResponse(pHcd,pReq,CheckMode);
-+}
-+
-+/*
-+ * CardDetect_WorkItem - the work item for handling card detect polling interrupt
-+*/
-+static void CardDetect_WorkItem(
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
-+void *context)
-+#else
-+struct work_struct *ignored)
-+#endif
-+{
-+ /* call bus driver function */
-+ SDIO_NotifyTimerTriggered(SDIOBUS_CD_TIMER_ID);
-+}
-+
-+/*
-+ * OS_IncHcdReference - increment host controller driver reference count
-+*/
-+SDIO_STATUS Do_OS_IncHcdReference(PSDHCD pHcd)
-+{
-+ SDIO_STATUS status = SDIO_STATUS_SUCCESS;
-+
-+ do {
-+ if (NULL == pHcd->pModule) {
-+ /* hcds that are 2.3 or higher should set this */
-+ DBG_PRINT(SDDBG_WARN, ("SDIO Bus Driver: HCD:%s should set module ptr!\n",
-+ (pHcd->pName != NULL) ? pHcd->pName : "Unknown"));
-+ break;
-+ }
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-+ if (!try_module_get(pHcd->pModule)) {
-+ status = SDIO_STATUS_ERROR;
-+ }
-+#else
-+ if (!try_inc_mod_count(pHcd->pModule)) {
-+ status = SDIO_STATUS_ERROR;
-+ }
-+#endif
-+
-+ } while (FALSE);
-+
-+ if (!SDIO_SUCCESS(status)) {
-+ DBG_PRINT(SDDBG_WARN, ("SDIO Bus Driver: HCD:%s failed to get module\n",
-+ (pHcd->pName != NULL) ? pHcd->pName : "Unknown"));
-+ }
-+
-+ return status;
-+}
-+
-+/*
-+ * OS_DecHcdReference - decrement host controller driver reference count
-+*/
-+SDIO_STATUS Do_OS_DecHcdReference(PSDHCD pHcd)
-+{
-+ if (pHcd->pModule != NULL) {
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-+ module_put(pHcd->pModule);
-+#else
-+ /* 2.4 or lower */
-+ __MOD_DEC_USE_COUNT(pHcd->pModule);
-+#endif
-+ }
-+ return SDIO_STATUS_SUCCESS;
-+}
-+
-+/****************************************************************************************/
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-+#include <linux/pnp.h>
-+
-+#if !defined(CONFIG_PNP)
-+#error "CONFIG_PNP not defined"
-+#endif
-+
-+static ULONG InUseDevices = 0;
-+static spinlock_t InUseDevicesLock = SPIN_LOCK_UNLOCKED;
-+
-+static const struct pnp_device_id pnp_idtable[] = {
-+ {"SD_XXXX", 0}
-+};
-+static int sdio_get_resources(struct pnp_dev * pDev, struct pnp_resource_table * res)
-+{
-+ DBG_PRINT(SDDBG_TRACE,
-+ ("SDIO BusDriver - sdio_get_resources: %s\n",
-+ pDev->dev.bus_id));
-+ return 0;
-+}
-+static int sdio_set_resources(struct pnp_dev * pDev, struct pnp_resource_table * res)
-+{
-+ DBG_PRINT(SDDBG_TRACE,
-+ ("SDIO BusDriver - sdio_set_resources: %s\n",
-+ pDev->dev.bus_id));
-+ return 0;
-+}
-+
-+static int sdio_disable_resources(struct pnp_dev *pDev)
-+{
-+ DBG_PRINT(SDDBG_TRACE,
-+ ("SDIO BusDriver - sdio_disable_resources: %s\n",
-+ pDev->dev.bus_id));
-+ if (pDev != NULL) {
-+ pDev->active = 0;
-+ }
-+ return 0;
-+}
-+void release(struct device * pDev) {
-+ DBG_PRINT(SDDBG_TRACE,
-+ ("SDIO BusDriver - release: %s\n",
-+ pDev->bus_id));
-+ return;
-+}
-+struct pnp_protocol sdio_protocol = {
-+ .name = "SDIO",
-+ .get = sdio_get_resources,
-+ .set = sdio_set_resources,
-+ .disable = sdio_disable_resources,
-+ .dev.release = release,
-+};
-+
-+/*
-+ * driver_probe - probe for OS based driver
-+*/
-+static int driver_probe(struct pnp_dev* pOSDevice, const struct pnp_device_id *pId)
-+{
-+ PSDDEVICE pDevice = SDDEVICE_FROM_OSDEVICE(pOSDevice);
-+ PSDFUNCTION pFunction = pDevice->Device.dev.driver_data;
-+
-+ if (pFunction == NULL) {
-+ return -1;
-+ }
-+
-+ if (strcmp(pFunction->pName, pOSDevice->dev.driver->name) == 0) {
-+ DBG_PRINT(SDDBG_TRACE,
-+ ("SDIO BusDriver - driver_probe, match: %s/%s driver: %s\n",
-+ pOSDevice->dev.bus_id, pFunction->pName, pOSDevice->dev.driver->name));
-+ return 1;
-+ } else {
-+ DBG_PRINT(SDDBG_TRACE,
-+ ("SDIO BusDriver - driver_probe, no match: %s/%s driver: %s\n",
-+ pOSDevice->dev.bus_id, pFunction->pName, pOSDevice->dev.driver->name));
-+ return -1;
-+ }
-+/* if (pOSDevice->id != NULL) {
-+ if (strcmp(pOSDevice->id->id, pId->id) == 0) {
-+ DBG_PRINT(SDDBG_TRACE,
-+ ("SDIO BusDriver - driver_probe, match: %s/%s\n",
-+ pOSDevice->dev.bus_id, pId->id));
-+ return 1;
-+ }
-+ DBG_PRINT(SDDBG_TRACE,
-+ ("SDIO BusDriver - driver_probe, did not match: %s/%s/%s\n",
-+ pOSDevice->dev.bus_id, pId->id, pOSDevice->id->id));
-+ } else {
-+ DBG_PRINT(SDDBG_TRACE,
-+ ("SDIO BusDriver - driver_probe, did not match: %s/%s\n",
-+ pOSDevice->dev.bus_id, pId->id));
-+ }
-+ return -1;
-+*/
-+//?? if (pDevice->Device.dev.driver_data != NULL) {
-+//?? if (pDevice->Device.dev.driver_data == pFunction) {
-+//?? if (pDevice->Device.data != NULL) {
-+//?? if (pDevice->Device.data == pFunction) {
-+//?? DBG_PRINT(SDDBG_TRACE,
-+//?? ("SDIO BusDriver - driver_probe, match: %s\n",
-+//?? pOSDevice->dev.bus_id));
-+//?? return 1;
-+//?? }
-+//?? }
-+ DBG_PRINT(SDDBG_TRACE,
-+ ("SDIO BusDriver - driver_probe, match: %s\n",
-+ pOSDevice->dev.bus_id));
-+ return 1;
-+}
-+
-+static int RegisterDriver(PSDFUNCTION pFunction)
-+{
-+ memset(&pFunction->Driver, 0, sizeof(pFunction->Driver));
-+ pFunction->Driver.name = pFunction->pName;
-+ pFunction->Driver.probe = driver_probe;
-+ pFunction->Driver.id_table = pnp_idtable;
-+ pFunction->Driver.flags = PNP_DRIVER_RES_DO_NOT_CHANGE;
-+
-+ DBG_PRINT(SDDBG_TRACE,
-+ ("SDIO BusDriver - SDIO_RegisterFunction, registering driver: %s\n",
-+ pFunction->Driver.name));
-+ return pnp_register_driver(&pFunction->Driver);
-+}
-+
-+static int UnregisterDriver(PSDFUNCTION pFunction)
-+{
-+ DBG_PRINT(SDDBG_TRACE,
-+ ("+SDIO BusDriver - UnregisterDriver, driver: %s\n",
-+ pFunction->Driver.name));
-+ pnp_unregister_driver(&pFunction->Driver);
-+ DBG_PRINT(SDDBG_TRACE,
-+ ("-SDIO BusDriver - UnregisterDriver\n"));
-+ return 0;
-+}
-+
-+/*
-+ * OS_InitializeDevice - initialize device that will be registered
-+*/
-+SDIO_STATUS OS_InitializeDevice(PSDDEVICE pDevice, PSDFUNCTION pFunction)
-+{
-+ struct pnp_id *pFdname;
-+ memset(&pDevice->Device, 0, sizeof(pDevice->Device));
-+ pDevice->Device.dev.driver_data = (PVOID)pFunction;
-+//?? pDevice->Device.data = (PVOID)pFunction;
-+//?? pDevice->Device.dev.driver = &pFunction->Driver.driver;
-+//?? pDevice->Device.driver = &pFunction->Driver;
-+//?? pDevice->Device.dev.release = release;
-+ /* get a unique device number, must be done with locks held */
-+ spin_lock(&InUseDevicesLock);
-+ pDevice->Device.number = FirstClearBit(&InUseDevices);
-+ SetBit(&InUseDevices, pDevice->Device.number);
-+ spin_unlock(&InUseDevicesLock);
-+ pDevice->Device.capabilities = PNP_REMOVABLE | PNP_DISABLE;
-+ pDevice->Device.protocol = &sdio_protocol;
-+ pDevice->Device.active = 1;
-+
-+ pnp_init_resource_table(&pDevice->Device.res);
-+
-+ pFdname = KernelAlloc(sizeof(struct pnp_id));
-+
-+ if (NULL == pFdname) {
-+ return SDIO_STATUS_NO_RESOURCES;
-+ }
-+ /* set the id as slot number/function number */
-+ snprintf(pFdname->id, sizeof(pFdname->id), "SD_%02X%02X",
-+ pDevice->pHcd->SlotNumber, (UINT)SDDEVICE_GET_SDIO_FUNCNO(pDevice));
-+ pFdname->next = NULL;
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO BusDriver - OS_InitializeDevice adding id: %s\n",
-+ pFdname->id));
-+ pnp_add_id(pFdname, &pDevice->Device);
-+
-+ /* deal with DMA settings */
-+ if (pDevice->pHcd->pDmaDescription != NULL) {
-+ pDevice->Device.dev.dma_mask = &pDevice->pHcd->pDmaDescription->Mask;
-+ pDevice->Device.dev.coherent_dma_mask = pDevice->pHcd->pDmaDescription->Mask;
-+ }
-+
-+ return SDIO_STATUS_SUCCESS;
-+}
-+
-+/*
-+ * OS_AddDevice - must be pre-initialized with OS_InitializeDevice
-+*/
-+SDIO_STATUS OS_AddDevice(PSDDEVICE pDevice, PSDFUNCTION pFunction)
-+{
-+ int error;
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO BusDriver - OS_AddDevice adding function: %s\n",
-+ pFunction->pName));
-+ error = pnp_add_device(&pDevice->Device);
-+ if (error < 0) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO BusDriver - OS_AddDevice failed pnp_add_device: %d\n",
-+ error));
-+ }
-+ /* replace the buggy pnp's release */
-+ pDevice->Device.dev.release = release;
-+
-+ return OSErrorToSDIOError(error);
-+}
-+
-+/*
-+ * OS_RemoveDevice - unregister device with driver and bus
-+*/
-+void OS_RemoveDevice(PSDDEVICE pDevice)
-+{
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO BusDriver - OS_RemoveDevice \n"));
-+ pnp_remove_card_device(&pDevice->Device);
-+ spin_lock(&InUseDevicesLock);
-+ ClearBit(&InUseDevices, pDevice->Device.number);
-+ spin_unlock(&InUseDevicesLock);
-+
-+ if (pDevice->Device.id != NULL) {
-+ KernelFree(pDevice->Device.id);
-+ pDevice->Device.id = NULL;
-+ }
-+}
-+
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Add OS device to bus driver.
-+
-+ @function name: SDIO_BusAddOSDevice
-+ @category: HD_Reference
-+
-+ @output: pDma - descrip[tion of support DMA or NULL
-+ @output: pDriver - assigned driver object
-+ @output: pDevice - assigned device object
-+
-+ @return: SDIO_STATUS - SDIO_STATUS_SUCCESS when successful.
-+
-+ @notes: If the HCD does not register with the driver sub-system directly (like in the PCI case),
-+ then it should register with the bus driver to obtain OS dependent device objects.
-+ All input structures should be maintained throughout the life of the driver.
-+
-+ @example: getting device objects:
-+ typedef struct _SDHCD_DRIVER {
-+ OS_PNPDEVICE HcdDevice; / * the OS device for this HCD * /
-+ OS_PNPDRIVER HcdDriver; / * the OS driver for this HCD * /
-+ SDDMA_DESCRIPTION Dma; / * driver DMA description * /
-+ }SDHCD_DRIVER, *PSDHCD_DRIVER;
-+
-+ typedef struct _SDHCD_DRIVER_CONTEXT {
-+ PTEXT pDescription; / * human readable device decsription * /
-+ SDLIST DeviceList; / * the list of current devices handled by this driver * /
-+ OS_SEMAPHORE DeviceListSem; / * protection for the DeviceList * /
-+ UINT DeviceCount; / * number of devices currently installed * /
-+ SDHCD_DRIVER Driver; / * OS dependent driver specific info * /
-+ }SDHCD_DRIVER_CONTEXT, *PSDHCD_DRIVER_CONTEXT;
-+
-+ static SDHCD_DRIVER_CONTEXT HcdContext = {
-+ .pDescription = DESCRIPTION,
-+ .DeviceCount = 0,
-+ .Driver.HcdDevice.name = "sdio_xxx_hcd",
-+ .Driver.HcdDriver.name = "sdio_xxx_hcd",
-+ }
-+ .....
-+ status = SDIO_BusAddOSDevice(NULL, &HcdContext.Driver, &HcdContext.Device);
-+ if (SDIO_SUCCESS(status) {
-+ return Probe(&HcdContext.Device);
-+ }
-+ return SDIOErrorToOSError(status);
-+
-+ @see also: SDIO_BusRemoveOSDevice
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+SDIO_STATUS SDIO_BusAddOSDevice(PSDDMA_DESCRIPTION pDma, POS_PNPDRIVER pDriver, POS_PNPDEVICE pDevice)
-+{
-+ int err;
-+ struct pnp_id *pFdname;
-+ struct pnp_device_id *pFdid;
-+ static int slotNumber = 0; /* we just use an increasing count for the slots number */
-+
-+ if (pDma != NULL) {
-+ pDevice->dev.dma_mask = &pDma->Mask;
-+ pDevice->dev.coherent_dma_mask = pDma->Mask;
-+ }
-+ DBG_PRINT(SDDBG_ERROR,
-+ ("SDIO BusDriver - SDIO_GetBusOSDevice, registering driver: %s DMAmask: 0x%x\n",
-+ pDriver->name, (UINT)*pDevice->dev.dma_mask));
-+ pFdid = KernelAlloc(sizeof(struct pnp_device_id)*2);
-+ /* set the id as slot number/function number */
-+ snprintf(pFdid[0].id, sizeof(pFdid[0].id), "SD_%02X08",
-+ slotNumber++);
-+ pFdid[0].driver_data = 0;
-+ pFdid[1].id[0] = '\0';
-+ pFdid[1].driver_data = 0;
-+
-+ pDriver->id_table = pFdid;
-+ pDriver->flags = PNP_DRIVER_RES_DO_NOT_CHANGE;
-+ err = pnp_register_driver(pDriver);
-+ if (err < 0) {
-+ DBG_PRINT(SDDBG_ERROR,
-+ ("SDIO BusDriver - SDIO_GetBusOSDevice, failed registering driver: %s, err: %d\n",
-+ pDriver->name, err));
-+ return OSErrorToSDIOError(err);
-+ }
-+
-+ pDevice->protocol = &sdio_protocol;
-+ pDevice->capabilities = PNP_REMOVABLE | PNP_DISABLE;
-+ pDevice->active = 1;
-+
-+ pFdname = KernelAlloc(sizeof(struct pnp_id));
-+ /* set the id as slot number/function number */
-+ snprintf(pFdname->id, sizeof(pFdname->id), "SD_%02X08",
-+ 0); //??pDevice->pHcd->SlotNumber);//?????fix this, slotnumber isn't vaialble yet
-+ pFdname->next = NULL;
-+ pnp_add_id(pFdname, pDevice);
-+
-+ /* get a unique device number */
-+ spin_lock(&InUseDevicesLock);
-+ pDevice->number = FirstClearBit(&InUseDevices);
-+ SetBit(&InUseDevices, pDevice->number);
-+ spin_unlock(&InUseDevicesLock);
-+ pnp_init_resource_table(&pDevice->res);
-+ err = pnp_add_device(pDevice);
-+ if (err < 0) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO BusDriver - SDIO_GetBusOSDevice failed pnp_device_add: %d\n",
-+ err));
-+ pnp_unregister_driver(pDriver);
-+ }
-+ /* replace the buggy pnp's release */
-+ pDevice->dev.release = release;
-+ return OSErrorToSDIOError(err);
-+}
-+
-+/**+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Return OS device from bus driver.
-+
-+ @function name: SDIO_BusRemoveOSDevice
-+ @category: HD_Reference
-+
-+ @input: pDriver - setup PNP driver object
-+ @input: pDevice - setup PNP device object
-+
-+ @return: none
-+
-+
-+ @example: returning device objects:
-+ SDIO_BusRemoveOSDevice(&HcdContext.Driver, &HcdContext.Device);
-+
-+
-+ @see also: SDIO_BusAddOSDevice
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+void SDIO_BusRemoveOSDevice(POS_PNPDRIVER pDriver, POS_PNPDEVICE pDevice)
-+{
-+ DBG_PRINT(SDDBG_ERROR,
-+ ("SDIO BusDriver - SDIO_PutBusOSDevice, unregistering driver: %s\n",
-+ pDriver->name));
-+
-+ pnp_remove_card_device(pDevice);
-+ if (pDevice->id != NULL) {
-+ KernelFree(pDevice->id);
-+ pDevice->id = NULL;
-+ }
-+
-+ spin_lock(&InUseDevicesLock);
-+ ClearBit(&InUseDevices, pDevice->number);
-+ spin_unlock(&InUseDevicesLock);
-+
-+ pnp_unregister_driver(pDriver);
-+ if (pDriver->id_table != NULL) {
-+ KernelFree((void *)pDriver->id_table);
-+ pDriver->id_table = NULL;
-+ }
-+
-+}
-+
-+
-+/*
-+ * module init
-+*/
-+static int __init sdio_busdriver_init(void) {
-+ SDIO_STATUS status;
-+ int error;
-+ REL_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: loaded\n"));
-+ if (!SDIO_SUCCESS((status = _SDIO_BusDriverInitialize()))) {
-+ return SDIOErrorToOSError(status);
-+ }
-+ /* register the sdio bus */
-+ error = pnp_register_protocol(&sdio_protocol);
-+ if (error < 0) {
-+ REL_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: failed to register bus device, %d\n", error));
-+ _SDIO_BusDriverCleanup();
-+ return error;
-+ }
-+ return 0;
-+}
-+
-+/*
-+ * module cleanup
-+*/
-+static void __exit sdio_busdriver_cleanup(void) {
-+ REL_PRINT(SDDBG_TRACE, ("SDIO unloaded\n"));
-+ _SDIO_BusDriverCleanup();
-+ pnp_unregister_protocol(&sdio_protocol);
-+DBG_PRINT(SDDBG_TRACE,
-+ ("SDIO BusDriver - unloaded 1\n"));
-+}
-+EXPORT_SYMBOL(SDIO_BusAddOSDevice);
-+EXPORT_SYMBOL(SDIO_BusRemoveOSDevice);
-+
-+#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
-+ /* 2.4 */
-+static int RegisterDriver(PSDFUNCTION pFunction)
-+{
-+ return 0;
-+}
-+
-+static int UnregisterDriver(PSDFUNCTION pFunction)
-+{
-+ DBG_PRINT(SDDBG_TRACE,
-+ ("+-SDIO BusDriver - UnregisterDriver, driver: \n"));
-+ return 0;
-+}
-+
-+/*
-+ * OS_InitializeDevice - initialize device that will be registered
-+*/
-+SDIO_STATUS OS_InitializeDevice(PSDDEVICE pDevice, PSDFUNCTION pFunction)
-+{
-+ return SDIO_STATUS_SUCCESS;
-+}
-+
-+/*
-+ * OS_AddDevice - must be pre-initialized with OS_InitializeDevice
-+*/
-+SDIO_STATUS OS_AddDevice(PSDDEVICE pDevice, PSDFUNCTION pFunction)
-+{
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO BusDriver - OS_AddDevice adding function: %s\n",
-+ pFunction->pName));
-+ return SDIO_STATUS_SUCCESS;
-+
-+}
-+
-+/*
-+ * OS_RemoveDevice - unregister device with driver and bus
-+*/
-+void OS_RemoveDevice(PSDDEVICE pDevice)
-+{
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO BusDriver - OS_RemoveDevice \n"));
-+}
-+
-+/*
-+ * module init
-+*/
-+static int __init sdio_busdriver_init(void) {
-+ SDIO_STATUS status;
-+ REL_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: loaded\n"));
-+ if (!SDIO_SUCCESS((status = _SDIO_BusDriverInitialize()))) {
-+ return SDIOErrorToOSError(status);
-+ }
-+ return 0;
-+}
-+
-+/*
-+ * module cleanup
-+*/
-+static void __exit sdio_busdriver_cleanup(void) {
-+ REL_PRINT(SDDBG_TRACE, ("SDIO unloaded\n"));
-+ _SDIO_BusDriverCleanup();
-+}
-+#else ////KERNEL_VERSION
-+#error "unsupported kernel version: "UTS_RELEASE
-+#endif //KERNEL_VERSION
-+
-+MODULE_LICENSE("GPL and additional rights");
-+MODULE_DESCRIPTION(DESCRIPTION);
-+MODULE_AUTHOR(AUTHOR);
-+
-+module_init(sdio_busdriver_init);
-+module_exit(sdio_busdriver_cleanup);
-+EXPORT_SYMBOL(SDIO_RegisterHostController);
-+EXPORT_SYMBOL(SDIO_UnregisterHostController);
-+EXPORT_SYMBOL(SDIO_HandleHcdEvent);
-+EXPORT_SYMBOL(SDIO_CheckResponse);
-+EXPORT_SYMBOL(SDIO_RegisterFunction);
-+EXPORT_SYMBOL(SDIO_UnregisterFunction);
-diff --git a/drivers/sdio/stack/busdriver/sdio_function.c b/drivers/sdio/stack/busdriver/sdio_function.c
-new file mode 100644
-index 0000000..78b8e17
---- /dev/null
-+++ b/drivers/sdio/stack/busdriver/sdio_function.c
-@@ -0,0 +1,715 @@
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+@file: sdio_function.c
-+
-+@abstract: OS independent bus driver support for function drivers
-+
-+@notes: This file supports the interface between SDIO function drivers and the bus driver.
-+
-+@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 SDBUSDRIVER
-+#include <linux/sdio/ctsystem.h>
-+#include <linux/sdio/sdio_busdriver.h>
-+#include <linux/sdio/sdio_lib.h>
-+#include "_busdriver.h"
-+
-+static SDIO_STATUS ProbeForDevice(PSDFUNCTION pFunction);
-+
-+#ifdef CT_MAN_CODE_CHECK
-+static UINT16 ManCodeCheck = CT_MAN_CODE_CHECK;
-+#endif
-+
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Register a function driver with the bus driver.
-+
-+ @function name: SDIO_RegisterFunction
-+ @prototype: SDIO_STATUS SDIO_RegisterFunction(PSDFUNCTION pFunction)
-+ @category: PD_Reference
-+ @input: pFunction - the function definition structure.
-+
-+ @output: none
-+
-+ @return: SDIO_STATUS - SDIO_STATUS_SUCCESS when succesful.
-+
-+ @notes: Each function driver must register with the bus driver once upon loading.
-+ The calling function must be prepared to receive a Probe callback before
-+ this function returns. This will occur when an perpheral device is already
-+ pluugged in that is supported by this function.
-+ The function driver should unregister itself when exiting.
-+ The bus driver checks for possible function drivers to support a device
-+ in reverse registration order.
-+
-+ @example: Registering a function driver:
-+ //list of devices supported by this function driver
-+ static SD_PNP_INFO Ids[] = {
-+ {.SDIO_ManufacturerID = 0xaa55,
-+ .SDIO_ManufacturerCode = 0x5555,
-+ .SDIO_FunctionNo = 1},
-+ {} //list is null termintaed
-+ };
-+ static GENERIC_FUNCTION_CONTEXT FunctionContext = {
-+ .Function.pName = "sdio_generic", //name of the device
-+ .Function.Version = CT_SDIO_STACK_VERSION_CODE, // set stack version
-+ .Function.MaxDevices = 1, //maximum number of devices supported by this driver
-+ .Function.NumDevices = 0, //current number of devices, always zero to start
-+ .Function.pIds = Ids, //the list of devices supported by this device
-+ .Function.pProbe = Probe, //pointer to the function drivers Probe function
-+ // that will be called when a possibly supported device
-+ // is inserted.
-+ .Function.pRemove = Remove, //pointer to the function drivers Remove function
-+ / that will be called when a device is removed.
-+ .Function.pContext = &FunctionContext, //data value that will be passed into Probe and
-+ // Remove callbacks.
-+ };
-+ SDIO_STATUS status;
-+ status = SDIO_RegisterFunction(&FunctionContext.Function)
-+ if (!SDIO_SUCCESS(status)) {
-+ ...failed to register
-+ }
-+
-+ @see also: SDIO_UnregisterFunction
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+SDIO_STATUS _SDIO_RegisterFunction(PSDFUNCTION pFunction)
-+{
-+ SDIO_STATUS status = SDIO_STATUS_SUCCESS;
-+
-+#ifdef CT_MAN_CODE_CHECK
-+ DBG_PRINT(SDDBG_TRACE,
-+ ("SDIO Bus Driver: _SDIO_RegisterFunction: WARNING, this version is locked to Memory cards and SDIO cards with JEDEC IDs of: 0x%X\n",
-+ ManCodeCheck));
-+#else
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: _SDIO_RegisterFunction\n"));
-+#endif
-+
-+ DBG_PRINT(SDDBG_TRACE, ("+SDIO Bus Driver: Function Driver Stack Version: %d.%d \n",
-+ GET_SDIO_STACK_VERSION_MAJOR(pFunction),GET_SDIO_STACK_VERSION_MINOR(pFunction)));
-+
-+ if (!CHECK_FUNCTION_DRIVER_VERSION(pFunction)) {
-+ DBG_PRINT(SDDBG_ERROR,
-+ ("SDIO Bus Driver: Function Major Version Mismatch (hcd = %d, bus driver = %d)\n",
-+ GET_SDIO_STACK_VERSION_MAJOR(pFunction), CT_SDIO_STACK_VERSION_MAJOR(g_Version)));
-+ return SDIO_STATUS_INVALID_PARAMETER;
-+ }
-+
-+
-+ /* sanity check the driver */
-+ if ((pFunction == NULL) ||
-+ (pFunction->pProbe == NULL) ||
-+ (pFunction->pIds == NULL)) {
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: _SDIO_RegisterFunction, invalid registration data\n"));
-+ return SDIO_STATUS_INVALID_PARAMETER;
-+ }
-+ /* protect the function list and add the function */
-+ if (!SDIO_SUCCESS((status = SemaphorePendInterruptable(&pBusContext->FunctionListSem)))) {
-+ goto cleanup; /* wait interrupted */
-+ }
-+ SignalInitialize(&pFunction->CleanupReqSig);
-+ SDLIST_INIT(&pFunction->DeviceList);
-+ SDListAdd(&pBusContext->FunctionList, &pFunction->SDList);
-+ if (!SDIO_SUCCESS((status = SemaphorePost(&pBusContext->FunctionListSem)))) {
-+ goto cleanup; /* wait interrupted */
-+ }
-+
-+ /* see if we have devices for this new function driver */
-+ ProbeForDevice(pFunction);
-+
-+ return status;
-+cleanup:
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: _SDIO_RegisterFunction, error exit 0x%X\n", status));
-+ return status;
-+}
-+
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Unregister a function driver with the bus driver.
-+
-+ @function name: SDIO_UnregisterFunction
-+ @prototype: SDIO_STATUS SDIO_UnregisterFunction(PSDFUNCTION pFunction)
-+ @category: PD_Reference
-+
-+ @input: pFunction - the function definition structure.
-+
-+ @output: none
-+
-+ @return: SDIO_STATUS - SDIO_STATUS_SUCCESS when succesful.
-+
-+ @notes: Each function driver must unregister from the bus driver when the function driver
-+ exits.
-+ A function driver must disconnect from any interrupts before calling this function.
-+
-+ @example: Unregistering a function driver:
-+ SDIO_UnregisterFunction(&FunctionContext.Function);
-+
-+ @see also: SDIO_RegisterFunction
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+SDIO_STATUS _SDIO_UnregisterFunction(PSDFUNCTION pFunction)
-+{
-+ SDIO_STATUS status = SDIO_STATUS_SUCCESS;
-+ PSDDEVICE pDevice;
-+
-+ DBG_PRINT(SDDBG_TRACE, ("+SDIO Bus Driver: _SDIO_UnregisterFunction\n"));
-+
-+ /* protect the function list and synchronize with Probe() and Remove()*/
-+ if (!SDIO_SUCCESS((status = SemaphorePendInterruptable(&pBusContext->FunctionListSem)))) {
-+ goto cleanup; /* wait interrupted */
-+ }
-+ /* remove this function from the function list */
-+ SDListRemove(&pFunction->SDList);
-+ /* now remove this function as the handler for any of its devices */
-+ SDITERATE_OVER_LIST_ALLOW_REMOVE(&pFunction->DeviceList, pDevice, SDDEVICE,FuncListLink) {
-+ if (pDevice->pFunction == pFunction) {
-+ /* notify removal */
-+ NotifyDeviceRemove(pDevice);
-+ }
-+ }SDITERATE_END;
-+
-+ SignalDelete(&pFunction->CleanupReqSig);
-+
-+ if (!SDIO_SUCCESS((status = SemaphorePost(&pBusContext->FunctionListSem)))) {
-+ goto cleanup; /* wait interrupted */
-+ }
-+ DBG_PRINT(SDDBG_TRACE, ("-SDIO Bus Driver: _SDIO_UnregisterFunction\n"));
-+ return status;
-+
-+cleanup:
-+ DBG_PRINT(SDDBG_ERROR, ("-SDIO Bus Driver: _SDIO_UnregisterFunction, error exit 0x%X\n", status));
-+ return status;
-+}
-+
-+/* documentation headers only for Probe and Remove */
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: This function is called by the Busdriver when a device is inserted that can be supported by this function driver.
-+
-+ @function name: Probe
-+ @prototype: BOOL (*pProbe)(struct _SDFUNCTION *pFunction, struct _SDDEVICE *pDevice)
-+ @category: PD_Reference
-+
-+ @input: pFunction - the function definition structure that was passed to Busdriver
-+ via the SDIO_RegisterFunction.
-+ @input: pDevice - the description of the newly inserted device.
-+
-+ @output: none
-+
-+ @return: TRUE - this function driver will suport this device
-+ FALSE - this function driver will not support this device
-+
-+ @notes: The Busdriver calls the Probe function of a function driver to inform it that device is
-+ available for the function driver to control. The function driver should initialize the
-+ device and be pepared to acceopt any interrupts from the device before returning.
-+
-+ @example: Example of typical Probe function callback:
-+ static BOOL Probe(PSDFUNCTION pFunction, PSDDEVICE pDevice) {
-+ ...get the our context info passed into the SDIO_RegisterFunction
-+ PSDXXX_DRIVER_CONTEXT pFunctionContext =
-+ (PSDXXX_DRIVER_CONTEXT)pFunction->pContext;
-+ SDIO_STATUS status;
-+ //test the identification of this device and ensure we want to support it
-+ // we can test based on class, or use more specific tests on SDIO_ManufacturerID, etc.
-+ if (pDevice->pId[0].SDIO_FunctionClass == XXX) {
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO XXX Function: Probe - card matched (0x%X/0x%X/0x%X)\n",
-+ pDevice->pId[0].SDIO_ManufacturerID,
-+ pDevice->pId[0].SDIO_ManufacturerCode,
-+ pDevice->pId[0].SDIO_FunctionNo));
-+ ...
-+
-+ @see also: SDIO_RegisterFunction
-+ @see also: Remove
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+
-+BOOL FilterPnpInfo(PSDDEVICE pDevice)
-+{
-+#ifdef CT_MAN_CODE_CHECK
-+ if (pDevice->pId[0].CardFlags & CARD_SDIO) {
-+ if (pDevice->pId[0].SDIO_ManufacturerCode != ManCodeCheck) {
-+ DBG_PRINT(SDDBG_ERROR,
-+ ("SDIO Card with JEDEC ID:0x%X , not Allowed! Driver check halted. "
-+ "Please Contact sales@codetelligence.com.\n",
-+ pDevice->pId[0].SDIO_ManufacturerCode));
-+ return FALSE;
-+ }
-+ }
-+ return TRUE;
-+#else
-+ return TRUE;
-+#endif
-+}
-+
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: This function is called by the Busdriver when a device controlled by this function
-+ function driver is removed.
-+
-+ @function name: Remove
-+ @prototype: void (*pRemove)(struct _SDFUNCTION *pFunction, struct _SDDEVICE *pDevice)
-+ @category: PD_Reference
-+
-+ @input: pFunction - the function definition structure that was passed to Busdriver
-+ via the SDIO_RegisterFunction.
-+ @input: pDevice - the description of the device being removed.
-+
-+ @output: none
-+
-+ @return: none
-+
-+ @notes: The Busdriver calls the Remove function of a function driver to inform it that device it
-+ was supporting has been removed. The device has already been removed, so no further I/O
-+ to the device can be performed.
-+
-+ @example: Example of typical Remove function callback:
-+ void Remove(PSDFUNCTION pFunction, PSDDEVICE pDevice) {
-+ // get the our context info passed into the SDIO_RegisterFunction
-+ PSDXXX_DRIVER_CONTEXT pFunctionContext =
-+ (PSDXXX_DRIVER_CONTEXT)pFunction->pContext;
-+ ...free any acquired resources.
-+
-+ @see also: SDIO_RegisterFunction
-+ @see also: Probe
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+
-+/*
-+ * ProbeForFunction - look for a function driver to handle this card
-+ *
-+*/
-+SDIO_STATUS ProbeForFunction(PSDDEVICE pDevice, PSDHCD pHcd) {
-+ SDIO_STATUS status;
-+ PSDLIST pList;
-+ PSDFUNCTION pFunction;
-+
-+ DBG_PRINT(SDDBG_TRACE, ("+SDIO Bus Driver: ProbeForFunction\n"));
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: ProbeForFunction - Dump of Device PNP Data: \n"));
-+ DBG_PRINT(SDDBG_TRACE, (" Card Flags 0x%X \n", pDevice->pId[0].CardFlags));
-+ if (pDevice->pId[0].CardFlags & CARD_SDIO) {
-+ DBG_PRINT(SDDBG_TRACE, (" SDIO MANF: 0x%X \n", pDevice->pId[0].SDIO_ManufacturerID));
-+ DBG_PRINT(SDDBG_TRACE, (" SDIO MANFCODE: 0x%X \n", pDevice->pId[0].SDIO_ManufacturerCode));
-+ DBG_PRINT(SDDBG_TRACE, (" SDIO FuncNo: %d \n", pDevice->pId[0].SDIO_FunctionNo));
-+ DBG_PRINT(SDDBG_TRACE, (" SDIO FuncClass: %d \n", pDevice->pId[0].SDIO_FunctionClass));
-+ }
-+ if (pDevice->pId[0].CardFlags & (CARD_MMC | CARD_SD)) {
-+ DBG_PRINT(SDDBG_TRACE, (" SDMMC MANFID: 0x%X \n",pDevice->pId[0].SDMMC_ManfacturerID));
-+ DBG_PRINT(SDDBG_TRACE, (" SDMMC OEMID: 0x%X \n",pDevice->pId[0].SDMMC_OEMApplicationID));
-+ }
-+
-+ if (!FilterPnpInfo(pDevice)) {
-+ status = SDIO_STATUS_SUCCESS;
-+ goto cleanup;
-+ }
-+
-+ /* protect the function list */
-+ if (!SDIO_SUCCESS((status = SemaphorePendInterruptable(&pBusContext->FunctionListSem)))) {
-+ goto cleanup; /* wait interrupted */
-+ }
-+
-+ /* protect against ProbeForDevice */
-+ if (!SDIO_SUCCESS((status = SemaphorePendInterruptable(&pBusContext->DeviceListSem)))) {
-+ /* release the function list semaphore we just took */
-+ SemaphorePost(&pBusContext->FunctionListSem);
-+ goto cleanup;
-+ }
-+
-+ if (pDevice->pFunction != NULL) {
-+ /* device already has a function driver handling it */
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: ProbeForFunction, device already has function\n"));
-+ /* release function list */
-+ SemaphorePost(&pBusContext->DeviceListSem);
-+ /* release function list */
-+ SemaphorePost(&pBusContext->FunctionListSem);
-+ /* just return success */
-+ status = SDIO_STATUS_SUCCESS;
-+ goto cleanup;
-+ }
-+
-+ /* release device list */
-+ SemaphorePost(&pBusContext->DeviceListSem);
-+
-+ /* walk functions looking for one that can handle this device */
-+ SDITERATE_OVER_LIST(&pBusContext->FunctionList, pList) {
-+ pFunction = CONTAINING_STRUCT(pList, SDFUNCTION, SDList);
-+ if (pFunction->NumDevices >= pFunction->MaxDevices) {
-+ /* function can't support any more devices */
-+ continue;
-+ }
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: ProbeForFunction - checking: %s \n",
-+ pFunction->pName));
-+
-+ /* see if this function handles this device */
-+ if (IsPotentialIdMatch(pDevice->pId, pFunction->pIds)) {
-+ if (!FilterPnpInfo(pDevice)) {
-+ break;
-+ }
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: ProbeForFunction -Got Match, probing: %s \n",
-+ pFunction->pName));
-+ /* we need to setup with the OS bus driver before the probe, so probe can
-+ do OS operations. */
-+ OS_InitializeDevice(pDevice, pFunction);
-+ if (!SDIO_SUCCESS(OS_AddDevice(pDevice, pFunction))) {
-+ break;
-+ }
-+ /* close enough match, ask the function driver if it supports us */
-+ if (pFunction->pProbe(pFunction, pDevice)) {
-+ /* she accepted the device, add to list */
-+ pDevice->pFunction = pFunction;
-+ SDListAdd(&pFunction->DeviceList, &pDevice->FuncListLink);
-+ pFunction->NumDevices++;
-+ break;
-+ } else {
-+ DBG_PRINT(SDDBG_WARN, ("SDIO Bus Driver: %s did not claim the device \n",
-+ pFunction->pName));
-+ /* didn't take this device */
-+ OS_RemoveDevice(pDevice);
-+ }
-+
-+ }
-+ }
-+ if (!SDIO_SUCCESS((status = SemaphorePost(&pBusContext->FunctionListSem)))) {
-+ goto cleanup; /* wait interrupted */
-+ }
-+ DBG_PRINT(SDDBG_TRACE, ("-SDIO Bus Driver: ProbeForFunction\n"));
-+ return status;
-+cleanup:
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: ProbeForFunction, error exit 0x%X\n", status));
-+ return status;
-+}
-+
-+/*
-+ * ProbeForDevice - look for a device that this function driver supports
-+ *
-+*/
-+static SDIO_STATUS ProbeForDevice(PSDFUNCTION pFunction) {
-+ SDIO_STATUS status;
-+ PSDLIST pList;
-+ PSDDEVICE pDevice;
-+
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: ProbeForDevice\n"));
-+ if (pFunction->NumDevices >= pFunction->MaxDevices) {
-+ /* function can't support any more devices */
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: ProbeForDevice, too many devices in function\n"));
-+ return SDIO_STATUS_SUCCESS;
-+ }
-+
-+ /* protect the driver list */
-+ if (!SDIO_SUCCESS((status = SemaphorePendInterruptable(&pBusContext->DeviceListSem)))) {
-+ goto cleanup; /* wait interrupted */
-+ }
-+ /* walk device list */
-+ SDITERATE_OVER_LIST(&pBusContext->DeviceList, pList) {
-+ pDevice = CONTAINING_STRUCT(pList, SDDEVICE, SDList);
-+ if (pDevice->pFunction != NULL) {
-+ /* device already has a function driver handling it */
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: ProbeForDevice, device already has function\n"));
-+ continue;
-+ }
-+ /* see if this function handles this device */
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: ProbeForDevice, matching ID:%d %d class:%d\n",
-+ pDevice->pId[0].SDIO_ManufacturerID,
-+ pDevice->pId[0].SDIO_FunctionNo,
-+ pDevice->pId[0].SDIO_FunctionClass));
-+ if (IsPotentialIdMatch(pDevice->pId, pFunction->pIds)) {
-+ if (!FilterPnpInfo(pDevice)) {
-+ break;
-+ }
-+ /* we need to setup with the OS bus driver before the probe, so probe can
-+ do OS operations. */
-+ OS_InitializeDevice(pDevice, pFunction);
-+ if (!SDIO_SUCCESS(OS_AddDevice(pDevice, pFunction))) {
-+ break;
-+ }
-+ /* close enough match, ask the function driver if it supports us */
-+ if (pFunction->pProbe(pFunction, pDevice)) {
-+ /* she accepted the device, add to list */
-+ pDevice->pFunction = pFunction;
-+ SDListAdd(&pFunction->DeviceList, &pDevice->FuncListLink);
-+ pFunction->NumDevices++;
-+ break;
-+ } else {
-+ DBG_PRINT(SDDBG_WARN, ("SDIO Bus Driver: %s did not claim the device \n",
-+ pFunction->pName));
-+ /* didn't take this device */
-+ OS_RemoveDevice(pDevice);
-+ }
-+ }
-+ }
-+ if (!SDIO_SUCCESS((status = SemaphorePost(&pBusContext->DeviceListSem)))) {
-+ goto cleanup; /* wait interrupted */
-+ }
-+
-+ return status;
-+cleanup:
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: ProbeForDevice, error exit 0x%X\n", status));
-+ return status;
-+}
-+
-+#if 0
-+static void DumpPnpEntry(PSD_PNP_INFO pInfo)
-+{
-+ DBG_PRINT(SDDBG_TRACE, ("Function PnpInfo Dump: \n"));
-+ DBG_PRINT(SDDBG_TRACE, (" Card Flags 0x%X \n", pInfo->CardFlags));
-+ DBG_PRINT(SDDBG_TRACE, (" SDIO MANF: 0x%X \n", pInfo->SDIO_ManufacturerID));
-+ DBG_PRINT(SDDBG_TRACE, (" SDIO MANFCODE: 0x%X \n", pInfo->SDIO_ManufacturerCode));
-+ DBG_PRINT(SDDBG_TRACE, (" SDIO FuncNo: %d \n", pInfo->SDIO_FunctionNo));
-+ DBG_PRINT(SDDBG_TRACE, (" SDIO FuncClass: %d \n", pInfo->SDIO_FunctionClass));
-+ DBG_PRINT(SDDBG_TRACE, (" SDMMC MANFID: 0x%X \n", pInfo->SDMMC_ManfacturerID));
-+ DBG_PRINT(SDDBG_TRACE, (" SDMMC OEMID: 0x%X \n", pInfo->SDMMC_OEMApplicationID));
-+}
-+#endif
-+/*
-+ * IsPotentialIdMatch - test for potential device match
-+ *
-+*/
-+BOOL IsPotentialIdMatch(PSD_PNP_INFO pIdsDev, PSD_PNP_INFO pIdsFuncList) {
-+ PSD_PNP_INFO pTFn;
-+ BOOL match = FALSE;
-+
-+ for (pTFn = pIdsFuncList;!IS_LAST_SDPNPINFO_ENTRY(pTFn);pTFn++) {
-+ //DumpPnpEntry(pTFn);
-+ /* check specific SDIO Card manufacturer ID, Code and Function number */
-+ if ((pIdsDev->SDIO_ManufacturerID != 0) &&
-+ (pTFn->SDIO_ManufacturerID != 0) &&
-+ (pIdsDev->SDIO_ManufacturerID == pTFn->SDIO_ManufacturerID) &&
-+ (pIdsDev->SDIO_ManufacturerCode == pTFn->SDIO_ManufacturerCode) &&
-+ ((pIdsDev->SDIO_FunctionNo == pTFn->SDIO_FunctionNo) ||
-+ (pTFn->SDIO_FunctionNo == 0)) ) {
-+ match = TRUE;
-+ break;
-+ }
-+ /* check generic function class */
-+ if ((pIdsDev->SDIO_FunctionClass != 0) &&
-+ (pTFn->SDIO_FunctionClass != 0) &&
-+ (pIdsDev->SDIO_FunctionClass == pTFn->SDIO_FunctionClass)) {
-+ match = TRUE;
-+ break;
-+ }
-+ /* check specific SDMMC MANFID and APPLICATION ID, NOTE SANDISK
-+ * uses a MANFID of zero! */
-+ if ((pTFn->SDMMC_OEMApplicationID != 0) &&
-+ (pIdsDev->SDMMC_ManfacturerID == pTFn->SDMMC_ManfacturerID) &&
-+ (pIdsDev->SDMMC_OEMApplicationID == pTFn->SDMMC_OEMApplicationID)) {
-+ match = TRUE;
-+ break;
-+ }
-+
-+ /* check generic SD Card */
-+ if ((pIdsDev->CardFlags & CARD_SD) &&
-+ (pTFn->CardFlags & CARD_SD)){
-+ match = TRUE;
-+ break;
-+ }
-+
-+ /* check generic MMC Card */
-+ if ((pIdsDev->CardFlags & CARD_MMC) &&
-+ (pTFn->CardFlags & CARD_MMC)){
-+ match = TRUE;
-+ break;
-+ }
-+
-+ /* check raw Card */
-+ if ((pIdsDev->CardFlags & CARD_RAW) &&
-+ (pTFn->CardFlags & CARD_RAW)){
-+ match = TRUE;
-+ break;
-+ }
-+ }
-+
-+ return match;
-+}
-+
-+/*
-+ * NotifyDeviceRemove - tell function driver on this device that the device is being removed
-+ *
-+*/
-+SDIO_STATUS NotifyDeviceRemove(PSDDEVICE pDevice) {
-+ SDIO_STATUS status;
-+ SDREQUESTQUEUE cancelQueue;
-+ PSDREQUEST pReq;
-+ CT_DECLARE_IRQ_SYNC_CONTEXT();
-+
-+ InitializeRequestQueue(&cancelQueue);
-+
-+ if ((pDevice->pFunction != NULL) &&
-+ (pDevice->pFunction->pRemove != NULL)){
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: removing device 0x%X\n", (INT)pDevice));
-+ /* fail any outstanding requests for this device */
-+ /* acquire lock for request queue */
-+ status = _AcquireHcdLock(pDevice->pHcd);
-+ if (!SDIO_SUCCESS(status)) {
-+ return status;
-+ }
-+ /* mark the function to block any more requests comming down */
-+ pDevice->pFunction->Flags |= SDFUNCTION_FLAG_REMOVING;
-+ /* walk through HCD queue and remove this function's requests */
-+ SDITERATE_OVER_LIST_ALLOW_REMOVE(&pDevice->pHcd->RequestQueue.Queue, pReq, SDREQUEST, SDList) {
-+ if (pReq->pFunction == pDevice->pFunction) {
-+ /* cancel this request, as this device or function is being removed */
-+ /* note that these request are getting completed out of order */
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver - NotifyDeviceRemove: canceling req 0x%X\n", (UINT)pReq));
-+ pReq->Status = SDIO_STATUS_CANCELED;
-+ /* remove it from the HCD queue */
-+ SDListRemove(&pReq->SDList);
-+ /* add it to the cancel queue */
-+ QueueRequest(&cancelQueue, pReq);
-+ }
-+ }SDITERATE_END;
-+
-+ status = _ReleaseHcdLock(pDevice->pHcd);
-+
-+ /* now empty the cancel queue if anything is in there */
-+ while (TRUE) {
-+ pReq = DequeueRequest(&cancelQueue);
-+ if (NULL == pReq) {
-+ break;
-+ }
-+ /* complete the request */
-+ DoRequestCompletion(pReq, pDevice->pHcd);
-+ }
-+ /* re-acquire the lock to deal with the current request */
-+ status = _AcquireHcdLock(pDevice->pHcd);
-+ if (!SDIO_SUCCESS(status)) {
-+ return status;
-+ }
-+ /* now deal with the current request */
-+ pReq = GET_CURRENT_REQUEST(pDevice->pHcd);
-+ if ((pReq !=NULL) && (pReq->pFunction == pDevice->pFunction) && (pReq->pFunction != NULL)) {
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver - NotifyDeviceRemove: Outstanding Req 0x%X on HCD: 0x%X.. waiting...\n",
-+ (UINT)pReq, (UINT)pDevice->pHcd));
-+ /* the outstanding request on this device is for the function being removed */
-+ pReq->Flags |= SDREQ_FLAGS_CANCELED;
-+ /* wait for this request to get completed normally */
-+ status = _ReleaseHcdLock(pDevice->pHcd);
-+ SignalWait(&pDevice->pFunction->CleanupReqSig);
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver - NotifyDeviceRemove: Outstanding HCD Req 0x%X completed \n", (UINT)pReq));
-+ } else {
-+ /* release lock */
-+ status = _ReleaseHcdLock(pDevice->pHcd);
-+ }
-+
-+ /* synchronize with ISR SYNC Handlers */
-+ status = SemaphorePendInterruptable(&pBusContext->DeviceListSem);
-+ if (!SDIO_SUCCESS(status)) {
-+ return status;
-+ }
-+ /* call this devices Remove function */
-+ pDevice->pFunction->pRemove(pDevice->pFunction,pDevice);
-+ pDevice->pFunction->NumDevices--;
-+ /* make sure the sync handler is NULLed out */
-+ pDevice->pIrqFunction = NULL;
-+ SemaphorePost(&pBusContext->DeviceListSem);
-+
-+ OS_RemoveDevice(pDevice);
-+ /* detach this device from the function list it belongs to */
-+ SDListRemove(&pDevice->FuncListLink);
-+ pDevice->pFunction->Flags &= ~SDFUNCTION_FLAG_REMOVING;
-+ pDevice->pFunction = NULL;
-+ }
-+ return SDIO_STATUS_SUCCESS;
-+}
-+
-+
-+/*
-+ * RemoveHcdFunctions - remove all functions attached to an HCD
-+ *
-+*/
-+SDIO_STATUS RemoveHcdFunctions(PSDHCD pHcd) {
-+ SDIO_STATUS status;
-+ PSDLIST pList;
-+ PSDFUNCTION pFunction;
-+ PSDDEVICE pDevice;
-+ DBG_PRINT(SDDBG_TRACE, ("+SDIO Bus Driver: RemoveHcdFunctions\n"));
-+
-+ /* walk through the functions and remove the ones associated with this HCD */
-+ /* protect the driver list */
-+ if (!SDIO_SUCCESS((status = SemaphorePend(&pBusContext->FunctionListSem)))) {
-+ goto cleanup; /* wait interrupted */
-+ }
-+ /* mark that card is being removed */
-+ pHcd->CardProperties.CardState |= CARD_STATE_REMOVED;
-+ SDITERATE_OVER_LIST(&pBusContext->FunctionList, pList) {
-+ pFunction = CONTAINING_STRUCT(pList, SDFUNCTION, SDList);
-+ DBG_PRINT(SDDBG_TRACE, ("SDIO Bus Driver: scanning function 0x%X, %s\n", (INT)pFunction,
-+ (pFunction == NULL)?"NULL":pFunction->pName));
-+
-+ /* walk the devices on this function and look for a match */
-+ SDITERATE_OVER_LIST_ALLOW_REMOVE(&pFunction->DeviceList, pDevice, SDDEVICE,FuncListLink) {
-+ if (pDevice->pHcd == pHcd) {
-+ /* match, remove it */
-+ NotifyDeviceRemove(pDevice);
-+ }
-+ SDITERATE_END;
-+ SDITERATE_END;
-+ if (!SDIO_SUCCESS((status = SemaphorePost(&pBusContext->FunctionListSem)))) {
-+ goto cleanup; /* wait interrupted */
-+ }
-+ DBG_PRINT(SDDBG_TRACE, ("-SDIO Bus Driver: RemoveHcdFunctions\n"));
-+ return SDIO_STATUS_SUCCESS;
-+
-+cleanup:
-+ DBG_PRINT(SDDBG_ERROR, ("-SDIO Bus Driver: RemoveHcdFunctions, error exit 0x%X\n", status));
-+ return status;
-+}
-+
-+/*
-+ * RemoveAllFunctions - remove all functions attached
-+ *
-+*/
-+SDIO_STATUS RemoveAllFunctions()
-+{
-+ SDIO_STATUS status;
-+ PSDLIST pList;
-+ PSDHCD pHcd;
-+
-+ /* walk through the HCDs */
-+ /* protect the driver list */
-+ if (!SDIO_SUCCESS((status = SemaphorePend(&pBusContext->HcdListSem)))) {
-+ goto cleanup; /* wait interrupted */
-+ }
-+ SDITERATE_OVER_LIST(&pBusContext->HcdList, pList) {
-+ pHcd = CONTAINING_STRUCT(pList, SDHCD, SDList);
-+ /* remove the functions */
-+ RemoveHcdFunctions(pHcd);
-+ }
-+ if (!SDIO_SUCCESS((status = SemaphorePost(&pBusContext->HcdListSem)))) {
-+ goto cleanup; /* wait interrupted */
-+ }
-+ return SDIO_STATUS_SUCCESS;
-+cleanup:
-+ DBG_PRINT(SDDBG_ERROR, ("SDIO Bus Driver: RemoveAllFunctions, error exit 0x%X\n", status));
-+ return status;
-+}
-+
-diff --git a/drivers/sdio/stack/lib/Makefile b/drivers/sdio/stack/lib/Makefile
-new file mode 100644
-index 0000000..44fa038
---- /dev/null
-+++ b/drivers/sdio/stack/lib/Makefile
-@@ -0,0 +1,2 @@
-+obj-$(CONFIG_SDIO) += sdio_lib.o
-+sdio_lib-objs := sdio_lib_c.o sdio_lib_os.o
-diff --git a/drivers/sdio/stack/lib/_sdio_lib.h b/drivers/sdio/stack/lib/_sdio_lib.h
-new file mode 100644
-index 0000000..28762b0
---- /dev/null
-+++ b/drivers/sdio/stack/lib/_sdio_lib.h
-@@ -0,0 +1,50 @@
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+@file: _sdio_lib.h
-+
-+@abstract: SDIO Lib internal include
-+
-+#notes:
-+
-+@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 ___SDIO_LIB_H___
-+#define ___SDIO_LIB_H___
-+
-+#endif /* ___SDIO_LIB_H___*/
-diff --git a/drivers/sdio/stack/lib/sdio_lib_c.c b/drivers/sdio/stack/lib/sdio_lib_c.c
-new file mode 100644
-index 0000000..4bc5a83
---- /dev/null
-+++ b/drivers/sdio/stack/lib/sdio_lib_c.c
-@@ -0,0 +1,908 @@
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+@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);
-+ }
-+
-+
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+
-+
-diff --git a/drivers/sdio/stack/lib/sdio_lib_os.c b/drivers/sdio/stack/lib/sdio_lib_os.c
-new file mode 100644
-index 0000000..55363d0
---- /dev/null
-+++ b/drivers/sdio/stack/lib/sdio_lib_os.c
-@@ -0,0 +1,251 @@
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+@file: sdio_function_os.c
-+
-+@abstract: Linux implementation module for SDIO library
-+
-+#notes: includes module load and unload functions
-+
-+@notice: Copyright (c), 2004 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
-+ *
-+ *
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+/* debug level for this module*/
-+#define DBG_DECLARE 4;
-+#include <linux/sdio/ctsystem.h>
-+
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/kthread.h>
-+
-+#include <linux/sdio/sdio_busdriver.h>
-+#include <linux/sdio/sdio_lib.h>
-+#include "_sdio_lib.h"
-+
-+#define DESCRIPTION "SDIO Kernel Library"
-+#define AUTHOR "Atheros Communications, Inc."
-+
-+/* proxies */
-+SDIO_STATUS SDLIB_IssueCMD52(PSDDEVICE pDevice,
-+ UINT8 FuncNo,
-+ UINT32 Address,
-+ PUINT8 pData,
-+ INT ByteCount,
-+ BOOL Write)
-+{
-+ return _SDLIB_IssueCMD52(pDevice,FuncNo,Address,pData,ByteCount,Write);
-+}
-+
-+SDIO_STATUS SDLIB_FindTuple(PSDDEVICE pDevice,
-+ UINT8 Tuple,
-+ UINT32 *pTupleScanAddress,
-+ PUINT8 pBuffer,
-+ UINT8 *pLength)
-+{
-+ return _SDLIB_FindTuple(pDevice,Tuple,pTupleScanAddress,pBuffer,pLength);
-+}
-+
-+SDIO_STATUS SDLIB_IssueConfig(PSDDEVICE pDevice,
-+ SDCONFIG_COMMAND Command,
-+ PVOID pData,
-+ INT Length)
-+{
-+ return _SDLIB_IssueConfig(pDevice,Command,pData,Length);
-+}
-+
-+void SDLIB_PrintBuffer(PUCHAR pBuffer,INT Length,PTEXT pDescription)
-+{
-+ _SDLIB_PrintBuffer(pBuffer,Length,pDescription);
-+}
-+
-+SDIO_STATUS SDLIB_SetFunctionBlockSize(PSDDEVICE pDevice,
-+ UINT16 BlockSize)
-+{
-+ return _SDLIB_SetFunctionBlockSize(pDevice,BlockSize);
-+}
-+
-+void SDLIB_SetupCMD52Request(UINT8 FuncNo,
-+ UINT32 Address,
-+ BOOL Write,
-+ UINT8 WriteData,
-+ PSDREQUEST pRequest)
-+{
-+ _SDLIB_SetupCMD52Request(FuncNo,Address,Write,WriteData,pRequest);
-+}
-+
-+SDIO_STATUS SDLIB_GetDefaultOpCurrent(PSDDEVICE pDevice, SD_SLOT_CURRENT *pOpCurrent)
-+{
-+ return _SDLIB_GetDefaultOpCurrent(pDevice,pOpCurrent);
-+}
-+
-+/* helper function launcher */
-+INT HelperLaunch(PVOID pContext)
-+{
-+ INT exit;
-+ /* call function */
-+ exit = ((POSKERNEL_HELPER)pContext)->pHelperFunc((POSKERNEL_HELPER)pContext);
-+ complete_and_exit(&((POSKERNEL_HELPER)pContext)->Completion, exit);
-+ return exit;
-+}
-+
-+/*
-+ * OSCreateHelper - create a worker kernel thread
-+*/
-+SDIO_STATUS SDLIB_OSCreateHelper(POSKERNEL_HELPER pHelper,
-+ PHELPER_FUNCTION pFunction,
-+ PVOID pContext)
-+{
-+ SDIO_STATUS status = SDIO_STATUS_SUCCESS;
-+
-+ memset(pHelper,0,sizeof(OSKERNEL_HELPER));
-+
-+ do {
-+ pHelper->pContext = pContext;
-+ pHelper->pHelperFunc = pFunction;
-+ status = SignalInitialize(&pHelper->WakeSignal);
-+ if (!SDIO_SUCCESS(status)) {
-+ break;
-+ }
-+ init_completion(&pHelper->Completion);
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-+ pHelper->pTask = kthread_create(HelperLaunch,
-+ (PVOID)pHelper,
-+ "SDIO Helper");
-+ if (NULL == pHelper->pTask) {
-+ status = SDIO_STATUS_NO_RESOURCES;
-+ break;
-+ }
-+ wake_up_process(pHelper->pTask);
-+#else
-+ /* 2.4 */
-+ pHelper->pTask = kernel_thread(HelperLaunch,
-+ (PVOID)pHelper,
-+ (CLONE_FS | CLONE_FILES | SIGCHLD));
-+ if (pHelper->pTask < 0) {
-+ DBG_PRINT(SDDBG_TRACE,
-+ ("SDIO BusDriver - OSCreateHelper, failed to create thread\n"));
-+ }
-+#endif
-+
-+ } while (FALSE);
-+
-+ if (!SDIO_SUCCESS(status)) {
-+ SDLIB_OSDeleteHelper(pHelper);
-+ }
-+ return status;
-+}
-+
-+/*
-+ * OSDeleteHelper - delete thread created with OSCreateHelper
-+*/
-+void SDLIB_OSDeleteHelper(POSKERNEL_HELPER pHelper)
-+{
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-+ if (pHelper->pTask != NULL) {
-+#else
-+ /* 2.4 */
-+ if (pHelper->pTask >= 0) {
-+#endif
-+ pHelper->ShutDown = TRUE;
-+ SignalSet(&pHelper->WakeSignal);
-+ /* wait for thread to exit */
-+ wait_for_completion(&pHelper->Completion);
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-+ pHelper->pTask = NULL;
-+#else
-+ /* 2.4 */
-+ pHelper->pTask = 0;
-+#endif
-+ }
-+
-+ SignalDelete(&pHelper->WakeSignal);
-+}
-+
-+/*
-+ * module init
-+*/
-+static int __init sdio_lib_init(void) {
-+ REL_PRINT(SDDBG_TRACE, ("SDIO Library load\n"));
-+ return 0;
-+}
-+
-+/*
-+ * module cleanup
-+*/
-+static void __exit sdio_lib_cleanup(void) {
-+ REL_PRINT(SDDBG_TRACE, ("SDIO Library unload\n"));
-+}
-+
-+PSDMESSAGE_QUEUE SDLIB_CreateMessageQueue(INT MaxMessages, INT MaxMessageLength)
-+{
-+ return _CreateMessageQueue(MaxMessages,MaxMessageLength);
-+
-+}
-+void SDLIB_DeleteMessageQueue(PSDMESSAGE_QUEUE pQueue)
-+{
-+ _DeleteMessageQueue(pQueue);
-+}
-+
-+SDIO_STATUS SDLIB_PostMessage(PSDMESSAGE_QUEUE pQueue, PVOID pMessage, INT MessageLength)
-+{
-+ return _PostMessage(pQueue,pMessage,MessageLength);
-+}
-+
-+SDIO_STATUS SDLIB_GetMessage(PSDMESSAGE_QUEUE pQueue, PVOID pData, INT *pBufferLength)
-+{
-+ return _GetMessage(pQueue,pData,pBufferLength);
-+}
-+
-+MODULE_LICENSE("GPL and additional rights");
-+MODULE_DESCRIPTION(DESCRIPTION);
-+MODULE_AUTHOR(AUTHOR);
-+module_init(sdio_lib_init);
-+module_exit(sdio_lib_cleanup);
-+EXPORT_SYMBOL(SDLIB_IssueCMD52);
-+EXPORT_SYMBOL(SDLIB_FindTuple);
-+EXPORT_SYMBOL(SDLIB_IssueConfig);
-+EXPORT_SYMBOL(SDLIB_PrintBuffer);
-+EXPORT_SYMBOL(SDLIB_SetFunctionBlockSize);
-+EXPORT_SYMBOL(SDLIB_SetupCMD52Request);
-+EXPORT_SYMBOL(SDLIB_GetDefaultOpCurrent);
-+EXPORT_SYMBOL(SDLIB_OSCreateHelper);
-+EXPORT_SYMBOL(SDLIB_OSDeleteHelper);
-+EXPORT_SYMBOL(SDLIB_CreateMessageQueue);
-+EXPORT_SYMBOL(SDLIB_DeleteMessageQueue);
-+EXPORT_SYMBOL(SDLIB_PostMessage);
-+EXPORT_SYMBOL(SDLIB_GetMessage);
-diff --git a/drivers/sdio/stack/platform/Makefile b/drivers/sdio/stack/platform/Makefile
-new file mode 100644
-index 0000000..14b3612
---- /dev/null
-+++ b/drivers/sdio/stack/platform/Makefile
-@@ -0,0 +1,2 @@
-+obj-$(CONFIG_SDIO) += sdio_platform.o
-+sdio_platform-objs := sdioplatformdriver.o
-\ No newline at end of file
-diff --git a/drivers/sdio/stack/platform/sdioplatformdriver.c b/drivers/sdio/stack/platform/sdioplatformdriver.c
-new file mode 100644
-index 0000000..d5520fc
---- /dev/null
-+++ b/drivers/sdio/stack/platform/sdioplatformdriver.c
-@@ -0,0 +1,300 @@
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+@file: sdioplatformdriver.c
-+
-+@abstract: Linux implementation module for SDIO pltaform driver
-+
-+#notes:
-+
-+@notice: Copyright (c), 2006 Atheros Communications, Inc.
-+
-+@license: 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.
-+
-+
-+
-+ *
-+ * 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 DESCRIPTION "SDIO Platform Driver"
-+#define AUTHOR "Atheros Communications, Inc."
-+
-+//??for .h
-+
-+struct sdioplatform_peripheral {
-+ struct list_head node;
-+ struct sdioplatform_controller *controller;
-+ struct device dev;
-+};
-+struct sdioplatform_driver {
-+ struct device_driver drv;
-+ int (*probe)(struct sdioplatform_peripheral *);
-+ void (*remove)(struct sdioplatform_peripheral *);
-+ int (*suspend)(struct sdioplatform_peripheral *, pm_message_t);
-+ int (*resume)(struct sdioplatform_peripheral *);
-+};
-+
-+
-+struct sdioplatform_controller {
-+ struct device *dev;
-+};
-+struct sdioplatform_controller_driver {
-+ struct device_driver drv;
-+ int (*probe)(struct sdioplatform_controller *);
-+ void (*remove)(struct sdioplatform_controller *);
-+ int (*suspend)(struct sdioplatform_controller *, pm_message_t);
-+ int (*resume)(struct sdioplatform_controller *);
-+};
-+
-+
-+
-+#define device_to_sdioplatform_peripheral(d) container_of(d, struct sdioplatform_peripheral, dev)
-+#define driver_to_sdioplatform_driver(d) container_of(d, struct sdioplatform_driver, drv)
-+
-+#define device_to_sdioplatform_controller(d) container_of(d, struct sdioplatform_controller, dev)
-+#define driver_to_sdioplatform_controller_driver(d) container_of(d, struct sdioplatform_controller_driver, drv)
-+
-+#define SDIOPLATFORM_ATTR(name, fmt, args...) \
-+static ssize_t sdio_##name##_show (struct device *dev, struct device_attribute *attr, char *buf) \
-+{ \
-+ struct sdioplatform_peripheral *peripheral = device_to_sdioplatform_peripheral(dev); \
-+ return sprintf(buf, fmt, args); \
-+}
-+
-+SDIOPLATFORM_ATTR(bus_id, "%s\n", bus_id);
-+#define SDIOPLATFORM_ATTR_RO(name) __ATTR(name, S_IRUGO, sdioplatform_##name##_show, NULL)
-+
-+static struct device_attribute sdioplatform_dev_attrs[] = {
-+ SDIOPLATFORM_ATTR_RO(bus_id),
-+ __ATTR_NULL
-+};
-+
-+static struct bus_type sdioplatform_bus_type = {
-+ .name = "sdioplatform",
-+ .dev_attrs = sdioplatform_dev_attrs,
-+ .match = sdioplatform_bus_match,
-+ .hotplug = NULL,
-+ .suspend = sdioplatform_bus_suspend,
-+ .resume = sdioplatform_bus_resume,
-+};
-+
-+
-+/* controller functions */
-+static int sdioplatform_controllerdrv_probe(struct device *dev)
-+{
-+ struct sdioplatform_controller_driver *drv = driver_to_sdioplatform_controller_driver(dev->driver);
-+ struct sdioplatform_controller *controller = device_to_sdioplatform_controller(dev);
-+
-+ return drv->probe(controller);
-+}
-+
-+static int sdioplatform_controllerdrv_remove(struct device *dev)
-+{
-+ struct sdioplatform_controller_driver *drv = driver_to_sdioplatform_controller_driver(dev->driver);
-+ struct sdioplatform_controller *controller = device_to_sdioplatform_controller(dev);
-+
-+ return drv->remove(controller);
-+}
-+
-+/*
-+ * sdioplatform_register_controller_driver - register a controller driver
-+ */
-+int sdioplatform_register_controller_driver(struct sdioplatform_controller_driver *drv)
-+{
-+ drv->drv.bus = &sdioplatform_bus_type;
-+ drv->drv.probe = sdioplatform_controllerdrv_probe;
-+ drv->drv.remove = sdioplatform_controllerdrv_remove;
-+ return driver_register(&drv->drv);
-+}
-+
-+/*
-+ * sdioplatform_unregister_controller_driver - unregister a controller driver
-+ */
-+void sdioplatform_unregister_controller_driver(struct sdioplatform_driver *drv)
-+{
-+ driver_unregister(&drv->drv);
-+}
-+
-+/*
-+ * sdioplatform_add_controller - register a controller device
-+ */
-+int sdioplatform_add_controller(char *name, struct sdioplatform_controller *dev)
-+{
-+ if (!dev) {
-+ return -EINVAL;
-+ }
-+ strncpy(dev->dev.bus_id, BUS_ID_SIZE, name);
-+ return device_register(&dev->dev);
-+}
-+
-+/*
-+ * sdioplatform_remove_controller - unregister a controller device
-+ */
-+int sdioplatform_remove_controller(char *name, struct sdioplatform_controller *dev)
-+{
-+ if (!dev) {
-+ return -EINVAL;
-+ }
-+ return device_unregister(&dev->dev);
-+}
-+
-+/* peripheral functions */
-+static int sdioplatform_drv_probe(struct device *dev)
-+{
-+ struct sdioplatform_driver *drv = driver_to_sdioplatform_driver(dev->driver);
-+ struct sdioplatform_peripheral *peripheral = device_to_sdioplatform_peripheral(dev);
-+
-+ return drv->probe(peripheral);
-+}
-+
-+static int sdioplatform_controllerdrv_remove(struct device *dev)
-+{
-+ struct sdioplatform_controller_driver *drv = driver_to_sdioplatform_controller_driver(dev->driver);
-+ struct sdioplatform_controller *controller = device_to_sdioplatform_controller(dev);
-+
-+ return drv->remove(controller);
-+}
-+
-+/*
-+ * sdioplatform_register_driver - register a driver
-+ */
-+int sdioplatform_register_driver(struct sdioplatform_driver *drv)
-+{
-+ drv->drv.bus = &sdioplatform_bus_type;
-+ drv->drv.probe = sdioplatform_drv_probe;
-+ drv->drv.remove = sdioplatform_drv_remove;
-+ return driver_register(&drv->drv);
-+}
-+
-+/*
-+ * sdioplatform_unregister_driver - unregister a driver
-+ */
-+void sdioplatform_unregister_driver(struct sdioplatform_driver *drv)
-+{
-+ driver_unregister(&drv->drv);
-+}
-+
-+/*
-+ * sdioplatform_add_peripheral - register a peripheral device
-+ */
-+int sdioplatform_add_peripheral(char *name, struct sdioplatform_peripheral *dev)
-+{
-+ if (!dev) {
-+ return -EINVAL;
-+ }
-+ strncpy(dev->dev.bus_id, BUS_ID_SIZE, name);
-+ return device_register(&dev->dev);
-+}
-+
-+/*
-+ * sdioplatform_remove_peripheral - unregister a peripheral device
-+ */
-+int sdioplatform_remove_peripheral(char *name, struct sdioplatform_peripheral *dev)
-+{
-+ if (!dev) {
-+ return -EINVAL;
-+ }
-+ return device_unregister(&dev->dev);
-+}
-+
-+
-+
-+
-+
-+static int sdioplatform_bus_match(struct device *dev, struct device_driver *drv)
-+{
-+ /* probes handle the matching */
-+ return 1;
-+}
-+
-+static int sdioplatform_bus_suspend(struct device *dev, pm_message_t state)
-+{
-+ struct sdioplatform_driver *drv = driver_to_sdioplatform_driver(dev->driver);
-+ struct sdioplatform_peripheral *peripheral = device_to_sdioplatform_peripheral(dev);
-+ int ret = 0;
-+
-+ if (peripheral->driver && drv->suspend) {
-+ ret = drv->suspend(peripheral, state);
-+ }
-+ return ret;
-+}
-+
-+static int sdioplatform_bus_resume(struct device *dev)
-+{
-+ struct sdioplatform_driver *drv = driver_to_sdioplatform_driver(dev->driver);
-+ struct sdioplatform_peripheral *peripheral = device_to_sdioplatform_peripheral(dev);
-+ int ret = 0;
-+
-+ if (peripheral->driver && drv->resume) {
-+ ret = drv->resume(card);
-+ }
-+ return ret;
-+}
-+
-+/*
-+ * module init
-+*/
-+static int __init sdio_platformdriver_init(void) {
-+ int ret = bus_register(&sdioplatform_bus_type);
-+ return ret;
-+}
-+
-+/*
-+ * module cleanup
-+*/
-+static void __exit sdio_platformdriver_cleanup(void) {
-+ REL_PRINT(SDDBG_TRACE, ("SDIO unloaded\n"));
-+ _SDIO_BusDriverCleanup();
-+}
-+
-+MODULE_LICENSE("GPL");
-+MODULE_DESCRIPTION(DESCRIPTION);
-+MODULE_AUTHOR(AUTHOR);
-+
-+module_init(sdio_platformdriver_init);
-+module_exit(sdio_platformdriver_cleanup);
-+EXPORT_SYMBOL(sdioplatform_register_controller_driver);
-+EXPORT_SYMBOL(sdioplatform_unregister_controller_driver);
-+EXPORT_SYMBOL(sdioplatform_add_controller);
-+EXPORT_SYMBOL(sdioplatform_remove_controller);
-+EXPORT_SYMBOL(sdioplatform_register_driver);
-+EXPORT_SYMBOL(sdioplatform_unregister_driver);
-+EXPORT_SYMBOL(sdioplatform_add_peripheral);
-+EXPORT_SYMBOL(sdioplatform_remove_peripheral);
-+
-+
-+
-diff --git a/include/linux/sdio/_sdio_defs.h b/include/linux/sdio/_sdio_defs.h
-new file mode 100644
-index 0000000..a3f5542
---- /dev/null
-+++ b/include/linux/sdio/_sdio_defs.h
-@@ -0,0 +1,638 @@
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+@file: _sdio_defs.h
-+
-+@abstract: SD/SDIO definitions
-+
-+@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 ___SDIO_DEFS_H___
-+#define ___SDIO_DEFS_H___
-+
-+#define SD_INIT_BUS_CLOCK 100000 /* initialization clock in hz */
-+#define SPI_INIT_BUS_CLOCK 100000 /* initialization clock in hz */
-+#define SD_MAX_BUS_CLOCK 25000000 /* max clock speed in hz */
-+#define SD_HS_MAX_BUS_CLOCK 50000000 /* SD high speed max clock speed in hz */
-+#define SDIO_LOW_SPEED_MAX_BUS_CLOCK 400000 /* max low speed clock in hz */
-+#define SDMMC_MIN_INIT_CLOCKS 80 /* minimun number of initialization clocks */
-+#define SDIO_EMPC_CURRENT_THRESHOLD 300 /* SDIO 1.10 , EMPC (mA) threshold, we add some overhead */
-+
-+/* commands */
-+#define CMD0 0
-+#define CMD1 1
-+#define CMD2 2
-+#define CMD3 3
-+#define CMD4 4
-+#define CMD5 5
-+#define CMD6 6
-+#define CMD7 7
-+#define CMD9 9
-+#define CMD10 10
-+#define CMD12 12
-+#define CMD13 13
-+#define CMD15 15
-+#define CMD16 16
-+#define CMD17 17
-+#define CMD18 18
-+#define CMD24 24
-+#define CMD25 25
-+#define CMD27 27
-+#define CMD28 28
-+#define CMD29 29
-+#define CMD30 30
-+#define CMD32 32
-+#define CMD33 33
-+#define CMD38 38
-+#define CMD42 42
-+#define CMD52 52
-+#define CMD53 53
-+#define CMD55 55
-+#define CMD56 56
-+#define CMD58 58
-+#define CMD59 59
-+#define ACMD6 6
-+#define ACMD13 13
-+#define ACMD22 22
-+#define ACMD23 23
-+#define ACMD41 41
-+#define ACMD42 42
-+#define ACMD51 51
-+
-+#define SD_ACMD6_BUS_WIDTH_1_BIT 0x00
-+#define SD_ACMD6_BUS_WIDTH_4_BIT 0x02
-+
-+#define SD_CMD59_CRC_OFF 0x00000000
-+#define SD_CMD59_CRC_ON 0x00000001
-+
-+/* SD/SPI max response size */
-+#define SD_MAX_CMD_RESPONSE_BYTES SD_R2_RESPONSE_BYTES
-+
-+#define SD_R1_RESPONSE_BYTES 6
-+#define SD_R1B_RESPONSE_BYTES SD_R1_RESPONSE_BYTES
-+#define SD_R1_GET_CMD(pR) ((pR)[5] & 0xC0))
-+#define SD_R1_SET_CMD(pR,cmd) (pR)[5] = (cmd) & 0xC0
-+#define SD_R1_GET_CARD_STATUS(pR) (((UINT32)((pR)[1])) | \
-+ (((UINT32)((pR)[2])) << 8) | \
-+ (((UINT32)((pR)[3])) << 16) | \
-+ (((UINT32)((pR)[4])) << 24) )
-+#define SD_R1_SET_CMD_STATUS(pR,status) \
-+{ \
-+ (pR)[1] = (UINT8)(status); \
-+ (pR)[2] = (UINT8)((status) >> 8); \
-+ (pR)[3] = (UINT8)((status) >> 16); \
-+ (pR)[4] = (UINT8)((status) >> 24); \
-+}
-+
-+/* SD R1 card status bit masks */
-+#define SD_CS_CMD_OUT_OF_RANGE ((UINT32)(1 << 31))
-+#define SD_CS_ADDRESS_ERR (1 << 30)
-+#define SD_CS_BLK_LEN_ERR (1 << 29)
-+#define SD_CS_ERASE_SEQ_ERR (1 << 28)
-+#define SD_CS_ERASE_PARAM_ERR (1 << 27)
-+#define SD_CS_WP_ERR (1 << 26)
-+#define SD_CS_CARD_LOCKED (1 << 25)
-+#define SD_CS_LK_UNLK_FAILED (1 << 24)
-+#define SD_CS_PREV_CMD_CRC_ERR (1 << 23)
-+#define SD_CS_ILLEGAL_CMD_ERR (1 << 22)
-+#define SD_CS_ECC_FAILED (1 << 21)
-+#define SD_CS_CARD_INTERNAL_ERR (1 << 20)
-+#define SD_CS_GENERAL_ERR (1 << 19)
-+#define SD_CS_CSD_OVERWR_ERR (1 << 16)
-+#define SD_CS_WP_ERASE_SKIP (1 << 15)
-+#define SD_CS_ECC_DISABLED (1 << 14)
-+#define SD_CS_ERASE_RESET (1 << 13)
-+#define SD_CS_GET_STATE(status) (((status) >> 9) & 0x0f)
-+#define SD_CS_SET_STATE(status, state) \
-+{ \
-+ (status) &= ~(0x0F << 9); \
-+ (status) |= (state) << 9 \
-+}
-+
-+#define SD_CS_TRANSFER_ERRORS \
-+ ( SD_CS_ADDRESS_ERR | \
-+ SD_CS_BLK_LEN_ERR | \
-+ SD_CS_ERASE_SEQ_ERR | \
-+ SD_CS_ERASE_PARAM_ERR | \
-+ SD_CS_WP_ERR | \
-+ SD_CS_ECC_FAILED | \
-+ SD_CS_CARD_INTERNAL_ERR | \
-+ SD_CS_GENERAL_ERR )
-+
-+#define SD_CS_STATE_IDLE 0
-+#define SD_CS_STATE_READY 1
-+#define SD_CS_STATE_IDENT 2
-+#define SD_CS_STATE_STBY 3
-+#define SD_CS_STATE_TRANS 4
-+#define SD_CS_STATE_DATA 5
-+#define SD_CS_STATE_RCV 6
-+#define SD_CS_STATE_PRG 7
-+#define SD_CS_STATE_DIS 8
-+#define SD_CS_READY_FOR_DATA (1 << 8)
-+#define SD_CS_APP_CMD (1 << 5)
-+#define SD_CS_AKE_SEQ_ERR (1 << 3)
-+
-+/* SD R2 response */
-+#define SD_R2_RESPONSE_BYTES 17
-+#define MAX_CSD_CID_BYTES 16
-+#define SD_R2_SET_STUFF_BITS(pR) (pR)[16] = 0x3F
-+#define GET_SD_CSD_TRANS_SPEED(pR) (pR)[12]
-+#define GET_SD_CID_MANFID(pR) (pR)[15]
-+#define GET_SD_CID_PN_1(pR) (pR)[12]
-+#define GET_SD_CID_PN_2(pR) (pR)[11]
-+#define GET_SD_CID_PN_3(pR) (pR)[10]
-+#define GET_SD_CID_PN_4(pR) (pR)[9]
-+#define GET_SD_CID_PN_5(pR) (pR)[8]
-+#define GET_SD_CID_PN_6(pR) (pR)[7]
-+
-+#define GET_SD_CID_OEMID(pR) ((((UINT16)(pR)[14]) << 8 )| (UINT16)((pR)[13]))
-+#define SDMMC_OCR_VOLTAGE_MASK 0x7FFFFFFF
-+/* SD R3 response */
-+#define SD_R3_RESPONSE_BYTES 6
-+#define SD_R3_GET_OCR(pR) ((((UINT32)((pR)[1])) | \
-+ (((UINT32)((pR)[2])) << 8) | \
-+ (((UINT32)((pR)[3])) << 16) | \
-+ (((UINT32)((pR)[4])) << 24)) & SDMMC_OCR_VOLTAGE_MASK)
-+#define SD_R3_IS_CARD_READY(pR) (((pR)[4] & 0x80) == 0x80)
-+
-+/* OCR bit definitions */
-+#define SD_OCR_CARD_PWR_UP_STATUS ((UINT32)(1 << 31))
-+#define SD_OCR_3_5_TO_3_6_VDD (1 << 23)
-+#define SD_OCR_3_4_TO_3_5_VDD (1 << 22)
-+#define SD_OCR_3_3_TO_3_4_VDD (1 << 21)
-+#define SD_OCR_3_2_TO_3_3_VDD (1 << 20)
-+#define SD_OCR_3_1_TO_3_2_VDD (1 << 19)
-+#define SD_OCR_3_0_TO_3_1_VDD (1 << 18)
-+#define SD_OCR_2_9_TO_3_0_VDD (1 << 17)
-+#define SD_OCR_2_8_TO_2_9_VDD (1 << 16)
-+#define SD_OCR_2_7_TO_2_8_VDD (1 << 15)
-+#define SD_OCR_2_6_TO_2_7_VDD (1 << 14)
-+#define SD_OCR_2_5_TO_2_6_VDD (1 << 13)
-+#define SD_OCR_2_4_TO_2_5_VDD (1 << 12)
-+#define SD_OCR_2_3_TO_2_4_VDD (1 << 11)
-+#define SD_OCR_2_2_TO_2_3_VDD (1 << 10)
-+#define SD_OCR_2_1_TO_2_2_VDD (1 << 9)
-+#define SD_OCR_2_0_TO_2_1_VDD (1 << 8)
-+#define SD_OCR_1_9_TO_2_0_VDD (1 << 7)
-+#define SD_OCR_1_8_TO_1_9_VDD (1 << 6)
-+#define SD_OCR_1_7_TO_1_8_VDD (1 << 5)
-+#define SD_OCR_1_6_TO_1_7_VDD (1 << 4)
-+
-+/* SD Status data block */
-+#define SD_STATUS_DATA_BYTES 64
-+#define SDS_GET_DATA_WIDTH(buffer) ((buffer)[0] & 0xC0)
-+#define SDS_BUS_1_BIT 0x00
-+#define SDS_BUS_4_BIT 0x80
-+#define SDS_GET_SECURE_MODE(buffer) ((buffer)[0] & 0x20)
-+#define SDS_CARD_SECURE_MODE 0x20
-+#define SDS_GET_CARD_TYPE(buffer) ((buffer)[60] & 0x0F)
-+#define SDS_SD_CARD_RW 0x00
-+#define SDS_SD_CARD_ROM 0x01
-+
-+/* SD R6 response */
-+#define SD_R6_RESPONSE_BYTES 6
-+#define SD_R6_GET_RCA(pR) ((UINT16)((pR)[3]) | (((UINT16)((pR)[4])) << 8))
-+#define SD_R6_GET_CS(pR) ((UINT16)((pR)[1]) | (((UINT16)((pR)[2])) << 8))
-+
-+/* SD Configuration Register (SCR) */
-+#define SD_SCR_BYTES 8
-+#define SCR_REV_1_0 0x00
-+#define SCR_SD_SPEC_1_00 0x00
-+#define SCR_SD_SPEC_1_10 0x01
-+#define SCR_BUS_SUPPORTS_1_BIT 0x01
-+#define SCR_BUS_SUPPORTS_4_BIT 0x04
-+#define SCR_SD_SECURITY_MASK 0x70
-+#define SCR_SD_NO_SECURITY 0x00
-+#define SCR_SD_SECURITY_1_0 0x10
-+#define SCR_SD_SECURITY_2_0 0x20
-+#define SCR_DATA_STATUS_1_AFTER_ERASE 0x80
-+
-+#define GET_SD_SCR_STRUCT_VER(pB) ((pB)[7] >> 4)
-+#define GET_SD_SCR_SDSPEC_VER(pB) ((pB)[7] & 0x0F)
-+#define GET_SD_SCR_BUSWIDTHS(pB) ((pB)[6] & 0x0F)
-+#define GET_SD_SCR_BUSWIDTHS_FLAGS(pB) (pB)[6]
-+#define GET_SD_SCR_SECURITY(pB) (((pB)[6] >> 4) & 0x07)
-+#define GET_SD_SCR_DATA_STAT_AFTER_ERASE(pB) (((pB)[6] >> 7) & 0x01)
-+
-+/* SDIO R4 Response */
-+#define SD_SDIO_R4_RESPONSE_BYTES 6
-+#define SD_SDIO_R4_GET_OCR(pR) ((UINT32)((pR)[1]) | \
-+ (((UINT32)(pR)[2]) << 8) | \
-+ (((UINT32)(pR)[3]) << 16))
-+#define SD_SDIO_R4_IS_MEMORY_PRESENT(pR) (((pR)[4] & 0x08) == 0x08)
-+#define SD_SDIO_R4_GET_IO_FUNC_COUNT(pR) (((pR)[4] >> 4) & 0x07)
-+#define SD_SDIO_R4_IS_CARD_READY(pR) (((pR)[4] & 0x80) == 0x80)
-+
-+/* SDIO R5 response */
-+#define SD_SDIO_R5_RESPONSE_BYTES 6
-+#define SD_SDIO_R5_READ_DATA_OFFSET 1
-+#define SD_R5_GET_READ_DATA(pR) (pR)[SD_SDIO_R5_READ_DATA_OFFSET]
-+#define SD_R5_RESP_FLAGS_OFFSET 2
-+#define SD_R5_GET_RESP_FLAGS(pR) (pR)[SD_R5_RESP_FLAGS_OFFSET]
-+#define SD_R5_SET_CMD(pR,cmd) (pR)[5] = (cmd) & 0xC0
-+#define SD_R5_RESP_CMD_ERR (1 << 7) /* for previous cmd */
-+#define SD_R5_ILLEGAL_CMD (1 << 6)
-+#define SD_R5_GENERAL_ERR (1 << 3)
-+#define SD_R5_INVALID_FUNC (1 << 1)
-+#define SD_R5_ARG_RANGE_ERR (1 << 0)
-+#define SD_R5_CURRENT_CMD_ERRORS (SD_R5_ILLEGAL_CMD | SD_R5_GENERAL_ERR \
-+ | SD_R5_INVALID_FUNC | SD_R5_ARG_RANGE_ERR)
-+#define SD_R5_ERRORS (SD_R5_CURRENT_CMD_ERRORS)
-+
-+#define SD_R5_GET_IO_STATE(pR) (((pR)[2] >> 4) & 0x03)
-+#define SD_R5_STATE_DIS 0x00
-+#define SD_R5_STATE_CMD 0x01
-+#define SD_R5_STATE_TRN 0x02
-+
-+/* SDIO Modified R6 Response */
-+#define SD_SDIO_R6_RESPONSE_BYTES 6
-+#define SD_SDIO_R6_GET_RCA(pR) ((UINT16)((pR)[3]) | ((UINT16)((pR)[4]) << 8))
-+#define SD_SDIO_R6_GET_CSTAT(pR)((UINT16)((pR)[1]) | ((UINT16)((pR)[2]) << 8))
-+
-+/* SPI mode R1 response */
-+#define SPI_R1_RESPONSE_BYTES 1
-+#define GET_SPI_R1_RESP_TOKEN(pR) (pR)[0]
-+#define SPI_CS_STATE_IDLE 0x01
-+#define SPI_CS_ERASE_RESET (1 << 1)
-+#define SPI_CS_ILLEGAL_CMD (1 << 2)
-+#define SPI_CS_CMD_CRC_ERR (1 << 3)
-+#define SPI_CS_ERASE_SEQ_ERR (1 << 4)
-+#define SPI_CS_ADDRESS_ERR (1 << 5)
-+#define SPI_CS_PARAM_ERR (1 << 6)
-+#define SPI_CS_ERR_MASK 0x7c
-+
-+/* SPI mode R2 response */
-+#define SPI_R2_RESPONSE_BYTES 2
-+#define GET_SPI_R2_RESP_TOKEN(pR) (pR)[1]
-+#define GET_SPI_R2_STATUS_TOKEN(pR) (pR)[0]
-+/* the first response byte is defined above */
-+/* the second response byte is defined below */
-+#define SPI_CS_CARD_IS_LOCKED (1 << 0)
-+#define SPI_CS_LOCK_UNLOCK_FAILED (1 << 1)
-+#define SPI_CS_ERROR (1 << 2)
-+#define SPI_CS_INTERNAL_ERROR (1 << 3)
-+#define SPI_CS_ECC_FAILED (1 << 4)
-+#define SPI_CS_WP_VIOLATION (1 << 5)
-+#define SPI_CS_ERASE_PARAM_ERR (1 << 6)
-+#define SPI_CS_OUT_OF_RANGE (1 << 7)
-+
-+/* SPI mode R3 response */
-+#define SPI_R3_RESPONSE_BYTES 5
-+#define SPI_R3_GET_OCR(pR) ((((UINT32)((pR)[0])) | \
-+ (((UINT32)((pR)[1])) << 8) | \
-+ (((UINT32)((pR)[2])) << 16) | \
-+ (((UINT32)((pR)[3])) << 24)) & SDMMC_OCR_VOLTAGE_MASK)
-+#define SPI_R3_IS_CARD_READY(pR) (((pR)[3] & 0x80) == 0x80)
-+#define GET_SPI_R3_RESP_TOKEN(pR) (pR)[4]
-+
-+/* SPI mode SDIO R4 response */
-+#define SPI_SDIO_R4_RESPONSE_BYTES 5
-+#define SPI_SDIO_R4_GET_OCR(pR) ((UINT32)((pR)[0]) | \
-+ (((UINT32)(pR)[1]) << 8) | \
-+ (((UINT32)(pR)[2]) << 16))
-+#define SPI_SDIO_R4_IS_MEMORY_PRESENT(pR) (((pR)[3] & 0x08) == 0x08)
-+#define SPI_SDIO_R4_GET_IO_FUNC_COUNT(pR) (((pR)[3] >> 4) & 0x07)
-+#define SPI_SDIO_R4_IS_CARD_READY(pR) (((pR)[3] & 0x80) == 0x80)
-+#define GET_SPI_SDIO_R4_RESP_TOKEN(pR) (pR)[4]
-+
-+/* SPI Mode SDIO R5 response */
-+#define SPI_SDIO_R5_RESPONSE_BYTES 2
-+#define GET_SPI_SDIO_R5_RESP_TOKEN(pR) (pR)[1]
-+#define GET_SPI_SDIO_R5_RESPONSE_RDATA(pR) (pR)[0]
-+#define SPI_R5_IDLE_STATE 0x01
-+#define SPI_R5_ILLEGAL_CMD (1 << 2)
-+#define SPI_R5_CMD_CRC (1 << 3)
-+#define SPI_R5_FUNC_ERR (1 << 4)
-+#define SPI_R5_PARAM_ERR (1 << 6)
-+
-+/* SDIO COMMAND 52 Definitions */
-+#define CMD52_READ 0
-+#define CMD52_WRITE 1
-+#define CMD52_READ_AFTER_WRITE 1
-+#define CMD52_NORMAL_WRITE 0
-+#define SDIO_SET_CMD52_ARG(arg,rw,func,raw,address,writedata) \
-+ (arg) = (((rw) & 1) << 31) | \
-+ (((func) & 0x7) << 28) | \
-+ (((raw) & 1) << 27) | \
-+ (1 << 26) | \
-+ (((address) & 0x1FFFF) << 9) | \
-+ (1 << 8) | \
-+ ((writedata) & 0xFF)
-+#define SDIO_SET_CMD52_READ_ARG(arg,func,address) \
-+ SDIO_SET_CMD52_ARG(arg,CMD52_READ,(func),0,address,0x00)
-+#define SDIO_SET_CMD52_WRITE_ARG(arg,func,address,value) \
-+ SDIO_SET_CMD52_ARG(arg,CMD52_WRITE,(func),CMD52_NORMAL_WRITE,address,value)
-+
-+/* SDIO COMMAND 53 Definitions */
-+#define CMD53_READ 0
-+#define CMD53_WRITE 1
-+#define CMD53_BLOCK_BASIS 1
-+#define CMD53_BYTE_BASIS 0
-+#define CMD53_FIXED_ADDRESS 0
-+#define CMD53_INCR_ADDRESS 1
-+#define SDIO_SET_CMD53_ARG(arg,rw,func,mode,opcode,address,bytes_blocks) \
-+ (arg) = (((rw) & 1) << 31) | \
-+ (((func) & 0x7) << 28) | \
-+ (((mode) & 1) << 27) | \
-+ (((opcode) & 1) << 26) | \
-+ (((address) & 0x1FFFF) << 9) | \
-+ ((bytes_blocks) & 0x1FF)
-+
-+#define SDIO_MAX_LENGTH_BYTE_BASIS 512
-+#define SDIO_MAX_BLOCKS_BLOCK_BASIS 511
-+#define SDIO_MAX_BYTES_PER_BLOCK 2048
-+#define SDIO_COMMON_AREA_FUNCTION_NUMBER 0
-+#define SDIO_FIRST_FUNCTION_NUMBER 1
-+#define SDIO_LAST_FUNCTION_NUMBER 7
-+
-+#define CMD53_CONVERT_BYTE_BASIS_BLK_LENGTH_PARAM(b) (((b) < SDIO_MAX_LENGTH_BYTE_BASIS) ? (b) : 0)
-+#define CMD53_CONVERT_BLOCK_BASIS_BLK_COUNT_PARAM(b) (((b) <= SDIO_MAX_BLOCKS_BLOCK_BASIS) ? (b) : 0)
-+
-+
-+/* SDIO COMMON Registers */
-+
-+/* revision register */
-+#define CCCR_SDIO_REVISION_REG 0x00
-+#define CCCR_REV_MASK 0x0F
-+#define CCCR_REV_1_0 0x00
-+#define CCCR_REV_1_1 0x01
-+#define SDIO_REV_MASK 0xF0
-+#define SDIO_REV_1_00 0x00
-+#define SDIO_REV_1_10 0x10
-+#define SDIO_REV_1_20 0x20
-+/* SD physical spec revision */
-+#define SD_SPEC_REVISION_REG 0x01
-+#define SD_REV_MASK 0x0F
-+#define SD_REV_1_01 0x00
-+#define SD_REV_1_10 0x01
-+/* I/O Enable */
-+#define SDIO_ENABLE_REG 0x02
-+/* I/O Ready */
-+#define SDIO_READY_REG 0x03
-+/* Interrupt Enable */
-+#define SDIO_INT_ENABLE_REG 0x04
-+#define SDIO_INT_MASTER_ENABLE 0x01
-+#define SDIO_INT_ALL_ENABLE 0xFE
-+/* Interrupt Pending */
-+#define SDIO_INT_PENDING_REG 0x05
-+#define SDIO_INT_PEND_MASK 0xFE
-+/* I/O Abort */
-+#define SDIO_IO_ABORT_REG 0x06
-+#define SDIO_IO_RESET (1 << 3)
-+/* Bus Interface */
-+#define SDIO_BUS_IF_REG 0x07
-+#define CARD_DETECT_DISABLE 0x80
-+#define SDIO_BUS_WIDTH_1_BIT 0x00
-+#define SDIO_BUS_WIDTH_4_BIT 0x02
-+/* Card Capabilities */
-+#define SDIO_CARD_CAPS_REG 0x08
-+#define SDIO_CAPS_CMD52_WHILE_DATA 0x01 /* card can issue CMD52 while data transfer */
-+#define SDIO_CAPS_MULTI_BLOCK 0x02 /* card supports multi-block data transfers */
-+#define SDIO_CAPS_READ_WAIT 0x04 /* card supports read-wait protocol */
-+#define SDIO_CAPS_SUSPEND_RESUME 0x08 /* card supports I/O function suspend/resume */
-+#define SDIO_CAPS_INT_MULTI_BLK 0x10 /* interrupts between multi-block data capable */
-+#define SDIO_CAPS_ENB_INT_MULTI_BLK 0x20 /* enable ints between muli-block data */
-+#define SDIO_CAPS_LOW_SPEED 0x40 /* low speed card */
-+#define SDIO_CAPS_4BIT_LS 0x80 /* 4 bit low speed card */
-+/* Common CIS pointer */
-+#define SDIO_CMN_CIS_PTR_LOW_REG 0x09
-+#define SDIO_CMN_CIS_PTR_MID_REG 0x0a
-+#define SDIO_CMN_CIS_PTR_HI_REG 0x0b
-+/* Bus suspend */
-+#define SDIO_BUS_SUSPEND_REG 0x0c
-+#define SDIO_FUNC_SUSPEND_STATUS_MASK 0x01 /* selected function is suspended */
-+#define SDIO_SUSPEND_FUNCTION 0x02 /* suspend the current selected function */
-+/* Function select (for bus suspension) */
-+#define SDIO_FUNCTION_SELECT_REG 0x0d
-+#define SDIO_SUSPEND_FUNCTION_0 0x00
-+#define SDIO_SUSPEND_MEMORY_FUNC_MASK 0x08
-+/* Function Execution */
-+#define SDIO_FUNCTION_EXEC_REG 0x0e
-+#define SDIO_MEMORY_FUNC_EXEC_MASK 0x01
-+/* Function Ready */
-+#define SDIO_FUNCTION_READY_REG 0x0f
-+#define SDIO_MEMORY_FUNC_BUSY_MASK 0x01
-+
-+/* power control 1.10 only */
-+#define SDIO_POWER_CONTROL_REG 0x12
-+#define SDIO_POWER_CONTROL_SMPC 0x01
-+#define SDIO_POWER_CONTROL_EMPC 0x02
-+
-+/* high speed control , 1.20 only */
-+#define SDIO_HS_CONTROL_REG 0x13
-+#define SDIO_HS_CONTROL_SHS 0x01
-+#define SDIO_HS_CONTROL_EHS 0x02
-+
-+/* Function Base Registers */
-+#define xFUNCTION_FBR_OFFSET(funcNo) (0x100*(funcNo))
-+/* offset calculation that does not use multiplication */
-+static INLINE UINT32 CalculateFBROffset(UCHAR FuncNo) {
-+ UCHAR i = FuncNo;
-+ UINT32 offset = 0;
-+ while (i) {
-+ offset += 0x100;
-+ i--;
-+ }
-+ return offset;
-+}
-+/* Function info */
-+#define FBR_FUNC_INFO_REG_OFFSET(fbr) ((fbr) + 0x00)
-+#define FUNC_INFO_SUPPORTS_CSA_MASK 0x40
-+#define FUNC_INFO_ENABLE_CSA 0x80
-+#define FUNC_INFO_DEVICE_CODE_MASK 0x0F
-+#define FUNC_INFO_DEVICE_CODE_LAST 0x0F
-+#define FBR_FUNC_EXT_DEVICE_CODE_OFFSET(fbr) ((fbr) + 0x01)
-+/* Function Power selection */
-+#define FBR_FUNC_POWER_SELECT_OFFSET(fbr) ((fbr) + 0x02)
-+#define FUNC_POWER_SELECT_SPS 0x01
-+#define FUNC_POWER_SELECT_EPS 0x02
-+/* Function CIS ptr */
-+#define FBR_FUNC_CIS_LOW_OFFSET(fbr) ((fbr) + 0x09)
-+#define FBR_FUNC_CIS_MID_OFFSET(fbr) ((fbr) + 0x0a)
-+#define FBR_FUNC_CIS_HI_OFFSET(fbr) ((fbr) + 0x0b)
-+/* Function CSA ptr */
-+#define FBR_FUNC_CSA_LOW_OFFSET(fbr) ((fbr) + 0x0c)
-+#define FBR_FUNC_CSA_MID_OFFSET(fbr) ((fbr) + 0x0d)
-+#define FBR_FUNC_CSA_HI_OFFSET(fbr) ((fbr) + 0x0e)
-+/* Function CSA data window */
-+#define FBR_FUNC_CSA_DATA_OFFSET(fbr) ((fbr) + 0x0f)
-+/* Function Block Size Control */
-+#define FBR_FUNC_BLK_SIZE_LOW_OFFSET(fbr) ((fbr) + 0x10)
-+#define FBR_FUNC_BLK_SIZE_HI_OFFSET(fbr) ((fbr) + 0x11)
-+#define SDIO_CIS_AREA_BEGIN 0x00001000
-+#define SDIO_CIS_AREA_END 0x00017fff
-+/* Tuple definitions */
-+#define CISTPL_NULL 0x00
-+#define CISTPL_CHECKSUM 0x10
-+#define CISTPL_VERS_1 0x15
-+#define CISTPL_ALTSTR 0x16
-+#define CISTPL_MANFID 0x20
-+#define CISTPL_FUNCID 0x21
-+#define CISTPL_FUNCE 0x22
-+#define CISTPL_VENDOR 0x91
-+#define CISTPL_END 0xff
-+#define CISTPL_LINK_END 0xff
-+
-+
-+/* these structures must be packed */
-+
-+/* Manufacturer ID tuple */
-+struct SDIO_MANFID_TPL {
-+ UINT16 ManufacturerCode; /* jedec code */
-+ UINT16 ManufacturerInfo; /* manufacturer specific code */
-+}CT_PACK_STRUCT;
-+
-+/* Function ID Tuple */
-+struct SDIO_FUNC_ID_TPL {
-+ UINT8 DeviceCode; /* device code */
-+ UINT8 InitMask; /* system initialization mask (not used) */
-+}CT_PACK_STRUCT;
-+
-+ /* Extended Function Tuple (Common) */
-+struct SDIO_FUNC_EXT_COMMON_TPL {
-+ UINT8 Type; /* type */
-+ UINT16 Func0_MaxBlockSize; /* max function 0 block transfer size */
-+ UINT8 MaxTransSpeed; /* max transfer speed (encoded) */
-+#define TRANSFER_UNIT_MULTIPIER_MASK 0x07
-+#define TIME_VALUE_MASK 0x78
-+#define TIME_VALUE_SHIFT 3
-+}CT_PACK_STRUCT;
-+
-+/* Extended Function Tuple (Per Function) */
-+struct SDIO_FUNC_EXT_FUNCTION_TPL {
-+ UINT8 Type; /* type */
-+#define SDIO_FUNC_INFO_WAKEUP_SUPPORT 0x01
-+ UINT8 FunctionInfo; /* function info */
-+ UINT8 SDIORev; /* revision */
-+ UINT32 CardPSN; /* product serial number */
-+ UINT32 CSASize; /* CSA size */
-+ UINT8 CSAProperties; /* CSA properties */
-+ UINT16 MaxBlockSize; /* max block size for block transfers */
-+ UINT32 FunctionOCR; /* optimal function OCR */
-+ UINT8 OpMinPwr; /* operational min power */
-+ UINT8 OpAvgPwr; /* operational average power */
-+ UINT8 OpMaxPwr; /* operation maximum power */
-+ UINT8 SbMinPwr; /* standby minimum power */
-+ UINT8 SbAvgPwr; /* standby average power */
-+ UINT8 SbMaxPwr; /* standby maximum power */
-+ UINT16 MinBandWidth; /* minimum bus bandwidth */
-+ UINT16 OptBandWidth; /* optimalbus bandwitdh */
-+}CT_PACK_STRUCT;
-+
-+struct SDIO_FUNC_EXT_FUNCTION_TPL_1_1 {
-+ struct SDIO_FUNC_EXT_FUNCTION_TPL CommonInfo; /* from 1.0*/
-+ UINT16 EnableTimeOut; /* timeout for enable */
-+ UINT16 OperPwrMaxPwr;
-+ UINT16 OperPwrAvgPwr;
-+ UINT16 HiPwrMaxPwr;
-+ UINT16 HiPwrAvgPwr;
-+ UINT16 LowPwrMaxPwr;
-+ UINT16 LowPwrAvgPwr;
-+}CT_PACK_STRUCT;
-+
-+static INLINE SDIO_STATUS ConvertCMD52ResponseToSDIOStatus(UINT8 CMD52ResponseFlags) {
-+ if (!(CMD52ResponseFlags & SD_R5_ERRORS)) {
-+ return SDIO_STATUS_SUCCESS;
-+ }
-+ if (CMD52ResponseFlags & SD_R5_ILLEGAL_CMD) {
-+ return SDIO_STATUS_DATA_STATE_INVALID;
-+ } else if (CMD52ResponseFlags & SD_R5_INVALID_FUNC) {
-+ return SDIO_STATUS_INVALID_FUNC;
-+ } else if (CMD52ResponseFlags & SD_R5_ARG_RANGE_ERR) {
-+ return SDIO_STATUS_FUNC_ARG_ERROR;
-+ } else {
-+ return SDIO_STATUS_DATA_ERROR_UNKNOWN;
-+ }
-+}
-+
-+/* CMD6 mode switch definitions */
-+
-+#define SD_SWITCH_FUNC_CHECK 0
-+#define SD_SWITCH_FUNC_SET ((UINT32)(1 << 31))
-+#define SD_FUNC_NO_SELECT_MASK 0x00FFFFFF
-+#define SD_SWITCH_GRP_1 0
-+#define SD_SWITCH_GRP_2 1
-+#define SD_SWITCH_GRP_3 2
-+#define SD_SWITCH_GRP_4 3
-+#define SD_SWITCH_GRP_5 4
-+#define SD_SWITCH_GRP_6 5
-+
-+#define SD_SWITCH_HIGH_SPEED_GROUP SD_SWITCH_GRP_1
-+#define SD_SWITCH_HIGH_SPEED_FUNC_NO 1
-+
-+#define SD_SWITCH_MAKE_SHIFT(grp) ((grp) * 4)
-+
-+#define SD_SWITCH_MAKE_GRP_PATTERN(FuncGrp,FuncNo) \
-+ ((SD_FUNC_NO_SELECT_MASK & (~(0xF << SD_SWITCH_MAKE_SHIFT(FuncGrp)))) | \
-+ (((FuncNo) & 0xF) << SD_SWITCH_MAKE_SHIFT(FuncGrp))) \
-+
-+#define SD_SWITCH_FUNC_ARG_GROUP_CHECK(FuncGrp,FuncNo) \
-+ (SD_SWITCH_FUNC_CHECK | SD_SWITCH_MAKE_GRP_PATTERN(FuncGrp,FuncNo))
-+
-+#define SD_SWITCH_FUNC_ARG_GROUP_SET(FuncGrp,FuncNo) \
-+ (SD_SWITCH_FUNC_SET | SD_SWITCH_MAKE_GRP_PATTERN(FuncGrp,FuncNo))
-+
-+#define SD_SWITCH_FUNC_STATUS_BLOCK_BYTES 64
-+
-+#define SD_SWITCH_FUNC_STATUS_GET_GRP_BIT_MASK(pBuffer,FuncGrp) \
-+ (USHORT)((pBuffer)[50 + ((FuncGrp)*2)] | ((pBuffer)[51 + ((FuncGrp)*2)] << 8))
-+
-+#define SD_SWITCH_FUNC_STATUS_GET_MAX_CURRENT(pBuffer) \
-+ (USHORT)((pBuffer)[62] | ((pBuffer)[63] << 8))
-+
-+static INLINE UINT8 SDSwitchGetSwitchResult(PUINT8 pBuffer, UINT8 FuncGrp)
-+{
-+ switch (FuncGrp) {
-+ case 0:
-+ return (pBuffer[47] & 0xF);
-+ case 1:
-+ return (pBuffer[47] >> 4);
-+ case 2:
-+ return (pBuffer[48] & 0xF);
-+ case 3:
-+ return (pBuffer[48] >> 4);
-+ case 4:
-+ return (pBuffer[49] & 0xF);
-+ case 5:
-+ return (pBuffer[49] >> 4);
-+ default:
-+ return 0xF;
-+ }
-+}
-+
-+#endif
-diff --git a/include/linux/sdio/ctsystem.h b/include/linux/sdio/ctsystem.h
-new file mode 100644
-index 0000000..4f72739
---- /dev/null
-+++ b/include/linux/sdio/ctsystem.h
-@@ -0,0 +1,115 @@
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+@file: cpsystem.h
-+
-+@abstract: common system include file.
-+
-+@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_H___
-+#define __CPSYSTEM_H___
-+
-+/* SDIO stack status defines */
-+/* < 0 error, >0 warning, 0 success */
-+#define SDIO_IS_WARNING(status) ((status) > 0)
-+#define SDIO_IS_ERROR(status) ((status) < 0)
-+#define SDIO_SUCCESS(status) ((SDIO_STATUS)(status) >= 0)
-+#define SDIO_STATUS_SUCCESS 0
-+#define SDIO_STATUS_ERROR -1
-+#define SDIO_STATUS_INVALID_PARAMETER -2
-+#define SDIO_STATUS_PENDING 3
-+#define SDIO_STATUS_DEVICE_NOT_FOUND -4
-+#define SDIO_STATUS_DEVICE_ERROR -5
-+#define SDIO_STATUS_INTERRUPTED -6
-+#define SDIO_STATUS_NO_RESOURCES -7
-+#define SDIO_STATUS_CANCELED -8
-+#define SDIO_STATUS_BUFFER_TOO_SMALL -9
-+#define SDIO_STATUS_NO_MORE_MESSAGES -10
-+#define SDIO_STATUS_BUS_RESP_TIMEOUT -20 /* response timed-out */
-+#define SDIO_STATUS_BUS_READ_TIMEOUT -21 /* read data timed-out */
-+#define SDIO_STATUS_BUS_READ_CRC_ERR -22 /* data CRC failed */
-+#define SDIO_STATUS_BUS_WRITE_ERROR -23 /* write failed */
-+#define SDIO_STATUS_BUS_RESP_CRC_ERR -24 /* response received with a CRC error */
-+#define SDIO_STATUS_INVALID_TUPLE_LENGTH -25 /* tuple length was invalid */
-+#define SDIO_STATUS_TUPLE_NOT_FOUND -26 /* tuple could not be found */
-+#define SDIO_STATUS_CIS_OUT_OF_RANGE -27 /* CIS is out of range in the tuple scan */
-+#define SDIO_STATUS_FUNC_ENABLE_TIMEOUT -28 /* card timed out enabling or disabling */
-+#define SDIO_STATUS_DATA_STATE_INVALID -29 /* card is in an invalid state for data */
-+#define SDIO_STATUS_DATA_ERROR_UNKNOWN -30 /* card cannot process data transfer */
-+#define SDIO_STATUS_INVALID_FUNC -31 /* sdio request is not valid for the function */
-+#define SDIO_STATUS_FUNC_ARG_ERROR -32 /* sdio request argument is invalid or out of range */
-+#define SDIO_STATUS_INVALID_COMMAND -33 /* SD COMMAND is invalid for the card state */
-+#define SDIO_STATUS_SDREQ_QUEUE_FAILED -34 /* request failed to insert into queue */
-+#define SDIO_STATUS_BUS_RESP_TIMEOUT_SHIFTABLE -35 /* response timed-out, possibily shiftable to correct */
-+#define SDIO_STATUS_UNSUPPORTED -36 /* not supported */
-+#define SDIO_STATUS_PROGRAM_TIMEOUT -37 /* memory card programming timeout */
-+#define SDIO_STATUS_PROGRAM_STATUS_ERROR -38 /* memory card programming errors */
-+
-+#include <linux/sdio/ctsystem_linux.h>
-+
-+/* get structure from contained field */
-+#define CONTAINING_STRUCT(address, struct_type, field_name)\
-+ ((struct_type *)((ULONG_PTR)(address) - (ULONG_PTR)(&((struct_type *)0)->field_name)))
-+
-+#define ZERO_OBJECT(obj) memset(&(obj),0,sizeof(obj))
-+#define ZERO_POBJECT(pObj) memset((pObj),0,sizeof(*(pObj)))
-+
-+
-+/* bit field support functions */
-+static INLINE void SetBit(PULONG pField, UINT position) {
-+ *pField |= 1 << position;
-+}
-+static INLINE void ClearBit(PULONG pField, UINT position) {
-+ *pField &= ~(1 << position);
-+}
-+static INLINE BOOL IsBitSet(PULONG pField, UINT position) {
-+ return (*pField & (1 << position));
-+}
-+static INLINE INT FirstClearBit(PULONG pField) {
-+ UINT ii;
-+ for(ii = 0; ii < sizeof(ULONG)*8; ii++) {
-+ if (!IsBitSet(pField, ii)) {
-+ return ii;
-+ }
-+ }
-+ /* no clear bits found */
-+ return -1;
-+}
-+
-+#endif /* __CPSYSTEM_H___ */
-diff --git a/include/linux/sdio/ctsystem_linux.h b/include/linux/sdio/ctsystem_linux.h
-new file mode 100644
-index 0000000..0de89a6
---- /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___ */
-+
-diff --git a/include/linux/sdio/mmc_defs.h b/include/linux/sdio/mmc_defs.h
-new file mode 100644
-index 0000000..576ebd7
---- /dev/null
-+++ b/include/linux/sdio/mmc_defs.h
-@@ -0,0 +1,103 @@
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+@file: mmc_defs.h
-+
-+@abstract: MMC definitions not already defined in _sdio_defs.h
-+
-+@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 ___MMC_DEFS_H___
-+#define ___MMC_DEFS_H___
-+
-+#define MMC_MAX_BUS_CLOCK 20000000 /* max clock speed in hz */
-+#define MMC_HS_MAX_BUS_CLOCK 52000000 /* MMC PLUS (high speed) max clock rate in hz */
-+
-+/* R2 (CSD) macros */
-+#define GET_MMC_CSD_TRANS_SPEED(pR) (pR)[12]
-+#define GET_MMC_SPEC_VERSION(pR) (((pR)[15] >> 2) & 0x0F)
-+#define MMC_SPEC_1_0_TO_1_2 0x00
-+#define MMC_SPEC_1_4 0x01
-+#define MMC_SPEC_2_0_TO_2_2 0x02
-+#define MMC_SPEC_3_1 0x03
-+#define MMC_SPEC_4_0_TO_4_1 0x04
-+
-+#define MMC_CMD_SWITCH 6
-+#define MMC_CMD8 8
-+
-+#define MMC_SWITCH_CMD_SET 0
-+#define MMC_SWITCH_SET_BITS 1
-+#define MMC_SWITCH_CLEAR_BITS 2
-+#define MMC_SWITCH_WRITE_BYTE 3
-+#define MMC_SWITCH_CMD_SET0 0
-+#define MMC_SWITCH_BUILD_ARG(cmdset,access,index,value) \
-+ (((cmdset) & 0x07) | (((access) & 0x03) << 24) | (((index) & 0xFF) << 16) | (((value) & 0xFF) << 8))
-+
-+#define MMC_EXT_CSD_SIZE 512
-+
-+#define MMC_EXT_S_CMD_SET_OFFSET 504
-+#define MMC_EXT_MIN_PERF_W_8_52_OFFSET 210
-+#define MMC_EXT_MIN_PERF_R_8_52_OFFSET 209
-+#define MMC_EXT_MIN_PERF_W_8_26_4_52_OFFSET 208
-+#define MMC_EXT_MIN_PERF_R_8_26_4_52_OFFSET 207
-+#define MMC_EXT_MIN_PERF_W_4_26_OFFSET 206
-+#define MMC_EXT_MIN_PERF_R_4_56_OFFSET 205
-+#define MMC_EXT_PWR_CL_26_360_OFFSET 203
-+#define MMC_EXT_PWR_CL_52_360_OFFSET 202
-+#define MMC_EXT_PWR_CL_26_195_OFFSET 201
-+#define MMC_EXT_PWR_CL_52_195_OFFSET 200
-+#define MMC_EXT_GET_PWR_CLASS(reg) ((reg) & 0xF)
-+#define MMC_EXT_MAX_PWR_CLASSES 16
-+#define MMC_EXT_CARD_TYPE_OFFSET 196
-+#define MMC_EXT_CARD_TYPE_HS_52 (1 << 1)
-+#define MMC_EXT_CARD_TYPE_HS_26 (1 << 0)
-+#define MMC_EXT_CSD_VER_OFFSET 194
-+#define MMC_EXT_VER_OFFSET 192
-+#define MMC_EXT_VER_1_0 0
-+#define MMC_EXT_VER_1_1 1
-+#define MMC_EXT_CMD_SET_OFFSET 191
-+#define MMC_EXT_CMD_SET_REV_OFFSET 189
-+#define MMC_EXT_PWR_CLASS_OFFSET 187
-+#define MMC_EXT_HS_TIMING_OFFSET 185
-+#define MMC_EXT_HS_TIMING_ENABLE 0x01
-+#define MMC_EXT_BUS_WIDTH_OFFSET 183
-+#define MMC_EXT_BUS_WIDTH_1_BIT 0x00
-+#define MMC_EXT_BUS_WIDTH_4_BIT 0x01
-+#define MMC_EXT_BUS_WIDTH_8_BIT 0x02
-+
-+#endif
-diff --git a/include/linux/sdio/sdio_busdriver.h b/include/linux/sdio/sdio_busdriver.h
-new file mode 100644
-index 0000000..b431d3d
---- /dev/null
-+++ b/include/linux/sdio/sdio_busdriver.h
-@@ -0,0 +1,1435 @@
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+@file: sdio_busdriver.h
-+
-+@abstract: include file for registration of SDIO function drivers
-+ and SDIO host controller bus drivers.
-+
-+@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 __SDIO_BUSDRIVER_H___
-+#define __SDIO_BUSDRIVER_H___
-+
-+typedef UINT8 CT_VERSION_CODE;
-+#define CT_SDIO_STACK_VERSION_CODE ((CT_VERSION_CODE)0x26) /* version code that must be set in various structures */
-+#define CT_SDIO_STACK_VERSION_MAJOR(v) (((v) & 0xF0) >> 4)
-+#define CT_SDIO_STACK_VERSION_MINOR(v) (((v) & 0x0F))
-+#define SET_SDIO_STACK_VERSION(p) (p)->Version = CT_SDIO_STACK_VERSION_CODE
-+#define GET_SDIO_STACK_VERSION(p) (p)->Version
-+#define GET_SDIO_STACK_VERSION_MAJOR(p) CT_SDIO_STACK_VERSION_MAJOR(GET_SDIO_STACK_VERSION(p))
-+#define GET_SDIO_STACK_VERSION_MINOR(p) CT_SDIO_STACK_VERSION_MINOR(GET_SDIO_STACK_VERSION(p))
-+#include "sdlist.h"
-+
-+/* card flags */
-+typedef UINT16 CARD_INFO_FLAGS;
-+#define CARD_MMC 0x0001 /* Multi-media card */
-+#define CARD_SD 0x0002 /* SD-Memory present */
-+#define CARD_SDIO 0x0004 /* SDIO present */
-+#define CARD_RAW 0x0008 /* Raw card */
-+#define CARD_COMBO (CARD_SD | CARD_SDIO) /* SDIO with SD */
-+#define CARD_TYPE_MASK 0x000F /* card type mask */
-+#define CARD_SD_WP 0x0010 /* SD WP on */
-+#define CARD_PSEUDO 0x0020 /* pseudo card (internal use) */
-+#define CARD_HIPWR 0x0040 /* card can use more than 200mA (SDIO 1.1 or greater)*/
-+#define GET_CARD_TYPE(flags) ((flags) & CARD_TYPE_MASK)
-+
-+/* bus mode and clock rate */
-+typedef UINT32 SD_BUSCLOCK_RATE; /* clock rate in hz */
-+typedef UINT16 SD_BUSMODE_FLAGS;
-+#define SDCONFIG_BUS_WIDTH_RESERVED 0x00
-+#define SDCONFIG_BUS_WIDTH_SPI 0x01
-+#define SDCONFIG_BUS_WIDTH_1_BIT 0x02
-+#define SDCONFIG_BUS_WIDTH_4_BIT 0x03
-+#define SDCONFIG_BUS_WIDTH_MMC8_BIT 0x04
-+#define SDCONFIG_BUS_WIDTH_MASK 0x0F
-+#define SDCONFIG_SET_BUS_WIDTH(flags,width) \
-+{ \
-+ (flags) &= ~SDCONFIG_BUS_WIDTH_MASK; \
-+ (flags) |= (width); \
-+}
-+#define SDCONFIG_GET_BUSWIDTH(flags) ((flags) & SDCONFIG_BUS_WIDTH_MASK)
-+#define SDCONFIG_BUS_MODE_SPI_NO_CRC 0x40 /* SPI bus is operating with NO CRC */
-+#define SDCONFIG_BUS_MODE_SD_HS 0x80 /* set interface to SD high speed mode */
-+#define SDCONFIG_BUS_MODE_MMC_HS 0x20 /* set interface to MMC high speed mode */
-+
-+typedef UINT16 SD_SLOT_CURRENT; /* slot current in mA */
-+
-+typedef UINT8 SLOT_VOLTAGE_MASK; /* slot voltage */
-+#define SLOT_POWER_3_3V 0x01
-+#define SLOT_POWER_3_0V 0x02
-+#define SLOT_POWER_2_8V 0x04
-+#define SLOT_POWER_2_0V 0x08
-+#define SLOT_POWER_1_8V 0x10
-+#define SLOT_POWER_1_6V 0x20
-+
-+#define MAX_CARD_RESPONSE_BYTES 17
-+
-+/* plug and play information for SD cards */
-+typedef struct _SD_PNP_INFO {
-+ UINT16 SDIO_ManufacturerCode; /* JEDEC Code */
-+ UINT16 SDIO_ManufacturerID; /* manf-specific ID */
-+ UINT8 SDIO_FunctionNo; /* function number 1-7 */
-+ UINT8 SDIO_FunctionClass; /* function class */
-+ UINT8 SDMMC_ManfacturerID; /* card CID's MANF-ID */
-+ UINT16 SDMMC_OEMApplicationID; /* card CID's OEMAPP-ID */
-+ CARD_INFO_FLAGS CardFlags; /* card flags */
-+}SD_PNP_INFO, *PSD_PNP_INFO;
-+
-+#define IS_LAST_SDPNPINFO_ENTRY(id)\
-+ (((id)->SDIO_ManufacturerCode == 0) &&\
-+ ((id)->SDIO_ManufacturerID == 0) &&\
-+ ((id)->SDIO_FunctionNo == 0) &&\
-+ ((id)->SDIO_FunctionClass == 0) &&\
-+ ((id)->SDMMC_OEMApplicationID == 0) && \
-+ ((id)->CardFlags == 0))
-+
-+/* card properties */
-+typedef struct _CARD_PROPERTIES {
-+ UINT8 IOFnCount; /* number of I/O functions */
-+ UINT8 SDIORevision; /* SDIO revision */
-+#define SDIO_REVISION_1_00 0x00
-+#define SDIO_REVISION_1_10 0x01
-+#define SDIO_REVISION_1_20 0x02
-+ UINT8 SD_MMC_Revision; /* SD or MMC revision */
-+#define SD_REVISION_1_01 0x00
-+#define SD_REVISION_1_10 0x01
-+#define MMC_REVISION_1_0_2_2 0x00
-+#define MMC_REVISION_3_1 0x01
-+#define MMC_REVISION_4_0 0x02
-+ UINT16 SDIO_ManufacturerCode; /* JEDEC Code */
-+ UINT16 SDIO_ManufacturerID; /* manf-specific ID */
-+ UINT32 CommonCISPtr; /* common CIS ptr */
-+ UINT16 RCA; /* relative card address */
-+ UINT8 SDIOCaps; /* SDIO card capabilities (refer to SDIO spec for decoding) */
-+ UINT8 CardCSD[MAX_CARD_RESPONSE_BYTES]; /* for SD/MMC cards */
-+ CARD_INFO_FLAGS Flags; /* card flags */
-+ SD_BUSCLOCK_RATE OperBusClock; /* operational bus clock (based on HCD limit)*/
-+ SD_BUSMODE_FLAGS BusMode; /* current card bus mode */
-+ UINT16 OperBlockLenLimit; /* operational bytes per block length limit*/
-+ UINT16 OperBlockCountLimit; /* operational number of blocks per transfer limit */
-+ UINT8 CardState; /* card state flags */
-+ SLOT_VOLTAGE_MASK CardVoltage; /* card operational voltage */
-+#define CARD_STATE_REMOVED 0x01
-+}CARD_PROPERTIES, *PCARD_PROPERTIES;
-+
-+/* SDREQUEST request flags */
-+typedef UINT32 SDREQUEST_FLAGS;
-+/* write operation */
-+#define SDREQ_FLAGS_DATA_WRITE 0x8000
-+/* has data (read or write) */
-+#define SDREQ_FLAGS_DATA_TRANS 0x4000
-+/* command is an atomic APP command, requiring CMD55 to be issued */
-+#define SDREQ_FLAGS_APP_CMD 0x2000
-+/* transfer should be handled asynchronously */
-+#define SDREQ_FLAGS_TRANS_ASYNC 0x1000
-+/* host should skip the SPI response filter for this command */
-+#define SDREQ_FLAGS_RESP_SKIP_SPI_FILT 0x0800
-+/* host should skip the response check for this data transfer */
-+#define SDREQ_FLAGS_DATA_SKIP_RESP_CHK 0x0400
-+/* flag requesting a CMD12 be automatically issued by host controller */
-+#define SDREQ_FLAGS_AUTO_CMD12 0x0200
-+/* flag indicating that the data buffer meets HCD's DMA restrictions */
-+#define SDREQ_FLAGS_DATA_DMA 0x0010
-+/* indicate to host that this is a short and quick transfer, the HCD may optimize
-+ * this request to reduce interrupt overhead */
-+#define SDREQ_FLAGS_DATA_SHORT_TRANSFER 0x00010000
-+/* indicate to the host that this is a raw request */
-+#define SDREQ_FLAGS_RAW 0x00020000
-+/* auto data transfer status check for MMC and Memory cards */
-+#define SDREQ_FLAGS_AUTO_TRANSFER_STATUS 0x00100000
-+
-+#define SDREQ_FLAGS_UNUSED1 0x00200000
-+#define SDREQ_FLAGS_UNUSED2 0x00400000
-+#define SDREQ_FLAGS_UNUSED3 0x00800000
-+#define SDREQ_FLAGS_UNUSED4 0x01000000
-+#define SDREQ_FLAGS_UNUSED5 0x02000000
-+
-+/* the following flags are internal use only */
-+#define SDREQ_FLAGS_FORCE_DEFERRED_COMPLETE 0x0100
-+/* flag indicating that response has been converted (internal use) */
-+#define SDREQ_FLAGS_RESP_SPI_CONVERTED 0x0040
-+/* request was cancelled - internal use only */
-+#define SDREQ_FLAGS_CANCELED 0x0020
-+/* a barrier operation */
-+#define SDREQ_FLAGS_BARRIER 0x00040000
-+/* a pseudo bus request */
-+#define SDREQ_FLAGS_PSEUDO 0x00080000
-+/* queue to the head */
-+#define SDREQ_FLAGS_QUEUE_HEAD 0x04000000
-+
-+#define SDREQ_FLAGS_I_UNUSED1 0x08000000
-+#define SDREQ_FLAGS_I_UNUSED2 0x10000000
-+#define SDREQ_FLAGS_I_UNUSED3 0x20000000
-+#define SDREQ_FLAGS_I_UNUSED4 0x40000000
-+#define SDREQ_FLAGS_I_UNUSED5 0x80000000
-+
-+/* response type mask */
-+#define SDREQ_FLAGS_RESP_MASK 0x000F
-+#define GET_SDREQ_RESP_TYPE(flags) ((flags) & SDREQ_FLAGS_RESP_MASK)
-+#define IS_SDREQ_WRITE_DATA(flags) ((flags) & SDREQ_FLAGS_DATA_WRITE)
-+#define IS_SDREQ_DATA_TRANS(flags) ((flags) & SDREQ_FLAGS_DATA_TRANS)
-+#define IS_SDREQ_RAW(flags) ((flags) & SDREQ_FLAGS_RAW)
-+#define IS_SDREQ_FORCE_DEFERRED_COMPLETE(flags) ((flags) & SDREQ_FLAGS_FORCE_DEFERRED_COMPLETE)
-+#define SDREQ_FLAGS_NO_RESP 0x0000
-+#define SDREQ_FLAGS_RESP_R1 0x0001
-+#define SDREQ_FLAGS_RESP_R1B 0x0002
-+#define SDREQ_FLAGS_RESP_R2 0x0003
-+#define SDREQ_FLAGS_RESP_R3 0x0004
-+#define SDREQ_FLAGS_RESP_MMC_R4 0x0005 /* not supported, for future use */
-+#define SDREQ_FLAGS_RESP_MMC_R5 0x0006 /* not supported, for future use */
-+#define SDREQ_FLAGS_RESP_R6 0x0007
-+#define SDREQ_FLAGS_RESP_SDIO_R4 0x0008
-+#define SDREQ_FLAGS_RESP_SDIO_R5 0x0009
-+
-+struct _SDREQUEST;
-+struct _SDFUNCTION;
-+
-+typedef void (*PSDEQUEST_COMPLETION)(struct _SDREQUEST *);
-+
-+/* defines SD/MMC and SDIO requests for the RAW-mode API */
-+typedef struct _SDREQUEST {
-+ SDLIST SDList; /* internal use list*/
-+ UINT32 Argument; /* SD/SDIO/MMC 32 bit argument */
-+ SDREQUEST_FLAGS Flags; /* request flags */
-+ ATOMIC_FLAGS InternalFlags; /* internal use flags */
-+ UINT8 Command; /* SD/SDIO/MMC 8 bit command */
-+ UINT8 Response[MAX_CARD_RESPONSE_BYTES]; /* buffer for CMD response */
-+ UINT16 BlockCount; /* number of blocks to send/rcv */
-+ UINT16 BlockLen; /* length of each block */
-+ UINT16 DescriptorCount; /* number of DMA descriptor entries in pDataBuffer if DMA */
-+ PVOID pDataBuffer; /* starting address of buffer (or ptr to PSDDMA_DESCRIPTOR*/
-+ UINT32 DataRemaining; /* number of bytes remaining in the transfer (internal use) */
-+ PVOID pHcdContext; /* internal use context */
-+ PSDEQUEST_COMPLETION pCompletion; /* function driver completion routine */
-+ PVOID pCompleteContext; /* function driver completion context */
-+ SDIO_STATUS Status; /* completion status */
-+ struct _SDFUNCTION* pFunction; /* function driver that generated request (internal use)*/
-+ INT RetryCount; /* number of times to retry on error, non-data cmds only */
-+ PVOID pBdRsv1; /* reserved */
-+ PVOID pBdRsv2;
-+ PVOID pBdRsv3;
-+}SDREQUEST, *PSDREQUEST;
-+
-+ /* a request queue */
-+typedef struct _SDREQUESTQUEUE {
-+ SDLIST Queue; /* the queue of requests */
-+ BOOL Busy; /* busy flag */
-+}SDREQUESTQUEUE, *PSDREQUESTQUEUE;
-+
-+
-+typedef UINT16 SDCONFIG_COMMAND;
-+/* SDCONFIG request flags */
-+/* get operation */
-+#define SDCONFIG_FLAGS_DATA_GET 0x8000
-+/* put operation */
-+#define SDCONFIG_FLAGS_DATA_PUT 0x4000
-+/* host controller */
-+#define SDCONFIG_FLAGS_HC_CONFIG 0x2000
-+/* both */
-+#define SDCONFIG_FLAGS_DATA_BOTH (SDCONFIG_FLAGS_DATA_GET | SDCONFIG_FLAGS_DATA_PUT)
-+/* no data */
-+#define SDCONFIG_FLAGS_DATA_NONE 0x0000
-+
-+/* SDCONFIG commands */
-+#define SDCONFIG_GET_HCD_DEBUG (SDCONFIG_FLAGS_HC_CONFIG | SDCONFIG_FLAGS_DATA_GET | 275)
-+#define SDCONFIG_SET_HCD_DEBUG (SDCONFIG_FLAGS_HC_CONFIG | SDCONFIG_FLAGS_DATA_PUT | 276)
-+
-+/* custom hcd commands */
-+#define SDCONFIG_GET_HOST_CUSTOM (SDCONFIG_FLAGS_HC_CONFIG | SDCONFIG_FLAGS_DATA_GET | 300)
-+#define SDCONFIG_PUT_HOST_CUSTOM (SDCONFIG_FLAGS_HC_CONFIG | SDCONFIG_FLAGS_DATA_PUT | 301)
-+
-+/* function commands */
-+#define SDCONFIG_FUNC_ENABLE_DISABLE (SDCONFIG_FLAGS_DATA_PUT | 18)
-+#define SDCONFIG_FUNC_UNMASK_IRQ (SDCONFIG_FLAGS_DATA_NONE | 21)
-+#define SDCONFIG_FUNC_MASK_IRQ (SDCONFIG_FLAGS_DATA_NONE | 22)
-+#define SDCONFIG_FUNC_ACK_IRQ (SDCONFIG_FLAGS_DATA_NONE | 23)
-+#define SDCONFIG_FUNC_SPI_MODE_DISABLE_CRC (SDCONFIG_FLAGS_DATA_NONE | 24)
-+#define SDCONFIG_FUNC_SPI_MODE_ENABLE_CRC (SDCONFIG_FLAGS_DATA_NONE | 25)
-+#define SDCONFIG_FUNC_ALLOC_SLOT_CURRENT (SDCONFIG_FLAGS_DATA_PUT | 26)
-+#define SDCONFIG_FUNC_FREE_SLOT_CURRENT (SDCONFIG_FLAGS_DATA_NONE | 27)
-+#define SDCONFIG_FUNC_CHANGE_BUS_MODE (SDCONFIG_FLAGS_DATA_BOTH | 28)
-+#define SDCONFIG_FUNC_CHANGE_BUS_MODE_ASYNC (SDCONFIG_FLAGS_DATA_BOTH | 29)
-+#define SDCONFIG_FUNC_NO_IRQ_PEND_CHECK (SDCONFIG_FLAGS_DATA_NONE | 30)
-+
-+typedef UINT8 FUNC_ENABLE_DISABLE_FLAGS;
-+typedef UINT32 FUNC_ENABLE_TIMEOUT;
-+
-+ /* function enable */
-+typedef struct _SDCONFIG_FUNC_ENABLE_DISABLE_DATA {
-+#define SDCONFIG_DISABLE_FUNC 0x0000
-+#define SDCONFIG_ENABLE_FUNC 0x0001
-+ FUNC_ENABLE_DISABLE_FLAGS EnableFlags; /* enable flags*/
-+ FUNC_ENABLE_TIMEOUT TimeOut; /* timeout in milliseconds */
-+ void (*pOpComplete)(PVOID Context, SDIO_STATUS status); /* reserved */
-+ PVOID pOpCompleteContext; /* reserved */
-+}SDCONFIG_FUNC_ENABLE_DISABLE_DATA, *PSDCONFIG_FUNC_ENABLE_DISABLE_DATA;
-+
-+ /* slot current allocation data */
-+typedef struct _SDCONFIG_FUNC_SLOT_CURRENT_DATA {
-+ SD_SLOT_CURRENT SlotCurrent; /* slot current to request in mA*/
-+}SDCONFIG_FUNC_SLOT_CURRENT_DATA, *PSDCONFIG_FUNC_SLOT_CURRENT_DATA;
-+
-+/* slot bus mode configuration */
-+typedef struct _SDCONFIG_BUS_MODE_DATA {
-+ SD_BUSCLOCK_RATE ClockRate; /* clock rate in Hz */
-+ SD_BUSMODE_FLAGS BusModeFlags; /* bus mode flags */
-+ SD_BUSCLOCK_RATE ActualClockRate; /* actual rate in KHz */
-+}SDCONFIG_BUS_MODE_DATA, *PSDCONFIG_BUS_MODE_DATA;
-+
-+/* defines configuration requests for the HCD */
-+typedef struct _SDCONFIG {
-+ SDCONFIG_COMMAND Cmd; /* configuration command */
-+ PVOID pData; /* configuration data */
-+ INT DataLength; /* config data length */
-+}SDCONFIG, *PSDCONFIG;
-+
-+#define SET_SDCONFIG_CMD_INFO(pHdr,cmd,pC,len) \
-+{ \
-+ (pHdr)->Cmd = (cmd); \
-+ (pHdr)->pData = (PVOID)(pC); \
-+ (pHdr)->DataLength = (len); \
-+}
-+
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Get a pointer to the configuration command data.
-+
-+ @function name: GET_SDCONFIG_CMD
-+ @prototype: UNIT16 GET_SDCONFIG_CMD (PSDCONFIG pCommand)
-+ @category: HD_Reference
-+
-+ @input: pCommand - config command structure.
-+
-+ @return: command code
-+
-+ @notes: Implemented as a macro. This macro returns the command code for this
-+ configuration request.
-+
-+ @example: getting the command code:
-+ cmd = GET_SDCONFIG_CMD(pConfig);
-+ switch (cmd) {
-+ case SDCONFIG_GET_WP:
-+ .. get write protect switch position
-+ break;
-+ ...
-+ }
-+
-+ @see also: GET_SDCONFIG_CMD_LEN, GET_SDCONFIG_CMD_DATA
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+#define GET_SDCONFIG_CMD(pBuffer) ((pBuffer)->Cmd)
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Get a pointer to the configuration command data.
-+
-+ @function name: GET_SDCONFIG_CMD_LEN
-+ @prototype: INT GET_SDCONFIG_CMD_LEN (PSDCONFIG pCommand)
-+ @category: HD_Reference
-+
-+ @input: pCommand - config command structure.
-+
-+ @return: length of config command data
-+
-+ @notes: Implemented as a macro. Host controller drivers can use this macro to extract
-+ the number of bytes of command specific data. This can be used to validate the
-+ config data buffer size.
-+
-+ @example: getting the data length:
-+ length = GET_SDCONFIG_CMD_LEN(pConfig);
-+ if (length < CUSTOM_COMMAND_XXX_SIZE) {
-+ ... invalid length
-+ }
-+
-+ @see also: GET_SDCONFIG_CMD, GET_SDCONFIG_CMD_DATA
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+#define GET_SDCONFIG_CMD_LEN(pBuffer) ((pBuffer)->DataLength)
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Get a pointer to the configuration command data.
-+
-+ @function name: GET_SDCONFIG_CMD_DATA
-+ @prototype: (casted ptr) GET_SDCONFIG_CMD_DATA (type, PSDCONFIG pCommand)
-+ @category: HD_Reference
-+
-+ @input: type - pointer type to cast the returned pointer to.
-+ pCommand - config command structure.
-+
-+ @return: type-casted pointer to the command's data
-+
-+ @notes: Implemented as a macro. Host controller drivers can use this macro to extract
-+ a pointer to the command specific data in an HCD configuration request.
-+
-+ @example: getting the pointer:
-+ // get interrupt control data
-+ pIntControl = GET_SDCONFIG_CMD_DATA(PSDCONFIG_SDIO_INT_CTRL_DATA,pConfig);
-+ if (pIntControl->SlotIRQEnable) {
-+ ... enable slot IRQ detection
-+ }
-+
-+ @see also: GET_SDCONFIG_CMD, GET_SDCONFIG_CMD_LEN
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+#define GET_SDCONFIG_CMD_DATA(type,pBuffer) ((type)((pBuffer)->pData))
-+#define IS_SDCONFIG_CMD_GET(pBuffer) ((pBuffer)->Cmd & SDCONFIG_FLAGS_DATA_GET)
-+#define IS_SDCONFIG_CMD_PUT(pBuffer) ((pBuffer)->Cmd & SDCONFIG_FLAGS_DATA_PUT)
-+
-+struct _SDDEVICE;
-+struct _SDHCD;
-+
-+typedef UINT8 SD_FUNCTION_FLAGS;
-+#define SDFUNCTION_FLAG_REMOVING 0x01
-+
-+/* function driver registration structure */
-+typedef struct _SDFUNCTION {
-+ CT_VERSION_CODE Version; /* version code of the SDIO stack */
-+ SDLIST SDList; /* internal use list*/
-+ PTEXT pName; /* name of registering driver */
-+ UINT MaxDevices; /* maximum number of devices supported by this function */
-+ UINT NumDevices; /* number of devices supported by this function */
-+ PSD_PNP_INFO pIds; /* null terminated table of supported devices*/
-+ BOOL (*pProbe)(struct _SDFUNCTION *pFunction, struct _SDDEVICE *pDevice);/* New device inserted */
-+ /* Device removed (NULL if not a hot-plug capable driver) */
-+ void (*pRemove)(struct _SDFUNCTION *pFunction, struct _SDDEVICE *pDevice);
-+ SDIO_STATUS (*pSuspend)(struct _SDFUNCTION *pFunction, SDPOWER_STATE state); /* Device suspended */
-+ SDIO_STATUS (*pResume)(struct _SDFUNCTION *pFunction); /* Device woken up */
-+ /* Enable wake event */
-+ SDIO_STATUS (*pWake) (struct _SDFUNCTION *pFunction, SDPOWER_STATE state, BOOL enable);
-+ PVOID pContext; /* function driver use data */
-+ OS_PNPDRIVER Driver; /* driver registration with base system */
-+ SDLIST DeviceList; /* the list of devices this driver is using*/
-+ OS_SIGNAL CleanupReqSig; /* wait for requests completion on cleanup (internal use) */
-+ SD_FUNCTION_FLAGS Flags; /* internal flags (internal use) */
-+}SDFUNCTION, *PSDFUNCTION;
-+
-+typedef UINT8 HCD_EVENT;
-+
-+ /* device info for SDIO functions */
-+typedef struct _SDIO_DEVICE_INFO {
-+ UINT32 FunctionCISPtr; /* function's CIS ptr */
-+ UINT32 FunctionCSAPtr; /* function's CSA ptr */
-+ UINT16 FunctionMaxBlockSize; /* function's reported max block size */
-+}SDIO_DEVICE_INFO, *PSDIO_DEVICE_INFO;
-+
-+ /* device info for SD/MMC card functions */
-+typedef struct _SDMMC_INFO{
-+ UINT8 Unused; /* reserved */
-+}SDMMC_INFO, *PSDMMC_INFO;
-+
-+ /* union of SDIO function and device info */
-+typedef union _SDDEVICE_INFO {
-+ SDIO_DEVICE_INFO AsSDIOInfo;
-+ SDMMC_INFO AsSDMMCInfo;
-+}SDDEVICE_INFO, *PSDDEVICE_INFO;
-+
-+
-+typedef UINT8 SD_DEVICE_FLAGS;
-+#define SDDEVICE_FLAG_REMOVING 0x01
-+
-+/* inserted device description, describes an inserted card */
-+typedef struct _SDDEVICE {
-+ SDLIST SDList; /* internal use list*/
-+ SDLIST FuncListLink; /* internal use list */
-+ /* read/write request function */
-+ SDIO_STATUS (*pRequest)(struct _SDDEVICE *pDev, PSDREQUEST req);
-+ /* get/set configuration */
-+ SDIO_STATUS (*pConfigure)(struct _SDDEVICE *pDev, PSDCONFIG config);
-+ PSDREQUEST (*AllocRequest)(struct _SDDEVICE *pDev); /* allocate a request */
-+ void (*FreeRequest)(struct _SDDEVICE *pDev, PSDREQUEST pReq); /* free the request */
-+ void (*pIrqFunction)(PVOID pContext); /* interrupt routine, synchronous calls allowed */
-+ void (*pIrqAsyncFunction)(PVOID pContext); /* async IRQ function , asynch only calls */
-+ PVOID IrqContext; /* irq context */
-+ PVOID IrqAsyncContext; /* irq async context */
-+ PSDFUNCTION pFunction; /* function driver supporting this device */
-+ struct _SDHCD *pHcd; /* host controller this device is on (internal use) */
-+ SDDEVICE_INFO DeviceInfo; /* device info */
-+ SD_PNP_INFO pId[1]; /* id of this device */
-+ OS_PNPDEVICE Device; /* device registration with base system */
-+ SD_SLOT_CURRENT SlotCurrentAlloc; /* allocated slot current for this device/function (internal use) */
-+ SD_DEVICE_FLAGS Flags; /* internal use flags */
-+ CT_VERSION_CODE Version; /* version code of the bus driver */
-+}SDDEVICE, *PSDDEVICE;
-+
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Get SDIO Bus Driver Version Major number
-+
-+ @function name: SDDEVICE_GET_VERSION_MAJOR
-+ @prototype: INT SDDEVICE_GET_VERSION_MAJOR(PSDDEVICE pDevice)
-+ @category: PD_Reference
-+
-+ @input: pDevice - the target device for this request
-+
-+ @output: none
-+
-+ @return: integer value for the major version
-+
-+ @notes: Implemented as a macro.
-+
-+ @see also: SDDEVICE_GET_VERSION_MINOR
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+#define SDDEVICE_GET_VERSION_MAJOR(pDev) (GET_SDIO_STACK_VERSION_MAJOR(pDev))
-+
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Get SDIO Bus Driver Version Minor number
-+
-+ @function name: SDDEVICE_GET_VERSION_MINOR
-+ @prototype: INT SDDEVICE_GET_VERSION_MINOR(PSDDEVICE pDevice)
-+ @category: PD_Reference
-+
-+ @input: pDevice - the target device for this request
-+
-+ @output: none
-+
-+ @return: integer value for the minor version
-+
-+ @notes: Implemented as a macro.
-+
-+ @see also: SDDEVICE_GET_VERSION_MAJOR
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+#define SDDEVICE_GET_VERSION_MINOR(pDev) (GET_SDIO_STACK_VERSION_MINOR(pDev))
-+
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Test the SDIO revision for greater than or equal to 1.10
-+
-+ @function name: SDDEVICE_IS_SDIO_REV_GTEQ_1_10
-+ @prototype: BOOL SDDEVICE_IS_SDIO_REV_GTEQ_1_10(PSDDEVICE pDevice)
-+ @category: PD_Reference
-+
-+ @input: pDevice - the target device for this request
-+
-+ @output: none
-+
-+ @return: TRUE if the revision is greater than or equal to 1.10
-+
-+ @notes: Implemented as a macro.
-+
-+ @see also: SDDEVICE_IS_SD_REV_GTEQ_1_10
-+ @see also: SDDEVICE_IS_MMC_REV_GTEQ_4_0
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+#define SDDEVICE_IS_SDIO_REV_GTEQ_1_10(pDev) ((pDev)->pHcd->CardProperties.SDIORevision >= SDIO_REVISION_1_10)
-+
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Test the SDIO revision for greater than or equal to 1.20
-+
-+ @function name: SDDEVICE_IS_SDIO_REV_GTEQ_1_20
-+ @prototype: BOOL SDDEVICE_IS_SDIO_REV_GTEQ_1_20(PSDDEVICE pDevice)
-+ @category: PD_Reference
-+
-+ @input: pDevice - the target device for this request
-+
-+ @output: none
-+
-+ @return: TRUE if the revision is greater than or equal to 1.20
-+
-+ @notes: Implemented as a macro.
-+
-+ @see also: SDDEVICE_IS_SD_REV_GTEQ_1_10
-+ @see also: SDDEVICE_IS_SDIO_REV_GTEQ_1_10
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+#define SDDEVICE_IS_SDIO_REV_GTEQ_1_20(pDev) ((pDev)->pHcd->CardProperties.SDIORevision >= SDIO_REVISION_1_20)
-+
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Test the SD revision for greater than or equal to 1.10
-+
-+ @function name: SDDEVICE_IS_SD_REV_GTEQ_1_10
-+ @prototype: BOOL SDDEVICE_IS_SD_REV_GTEQ_1_10(PSDDEVICE pDevice)
-+ @category: PD_Reference
-+
-+ @input: pDevice - the target device for this request
-+
-+ @output: none
-+
-+ @return: TRUE if the revision is greater than or equal to 1.10
-+
-+ @notes: Implemented as a macro.
-+
-+ @see also: SDDEVICE_IS_SDIO_REV_GTEQ_1_10
-+ @see also: SDDEVICE_IS_MMC_REV_GTEQ_4_0
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+#define SDDEVICE_IS_SD_REV_GTEQ_1_10(pDev) ((pDev)->pHcd->CardProperties.SD_MMC_Revision >= SD_REVISION_1_10)
-+
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Test the MMC revision for greater than or equal to 4.0
-+
-+ @function name: SDDEVICE_IS_MMC_REV_GTEQ_4_0
-+ @prototype: BOOL SDDEVICE_IS_MMC_REV_GTEQ_4_0(PSDDEVICE pDevice)
-+ @category: PD_Reference
-+
-+ @input: pDevice - the target device for this request
-+
-+ @output: none
-+
-+ @return: TRUE if the revision is greater than or equal to 4.0
-+
-+ @notes: Implemented as a macro.
-+
-+ @see also: SDDEVICE_IS_SDIO_REV_GTEQ_1_10
-+ @see also: SDDEVICE_IS_SD_REV_GTEQ_1_10
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+#define SDDEVICE_IS_MMC_REV_GTEQ_4_0(pDev) ((pDev)->pHcd->CardProperties.SD_MMC_Revision >= MMC_REVISION_4_0)
-+
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Test for write protect enabled
-+
-+ @function name: SDDEVICE_IS_CARD_WP_ON
-+ @prototype: BOOL SDDEVICE_IS_CARD_WP_ON(PSDDEVICE pDevice)
-+ @category: PD_Reference
-+
-+ @input: pDevice - the target device for this request
-+
-+ @output: none
-+
-+ @return: TRUE if device is write protected.
-+
-+ @notes: Implemented as a macro.
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+#define SDDEVICE_IS_CARD_WP_ON(pDev) ((pDev)->pHcd->CardProperties.Flags & CARD_SD_WP)
-+
-+
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Get the device's manufacturer specific ID
-+
-+ @function name: SDDEVICE_GET_SDIO_MANFID
-+ @prototype: UINT16 SDDEVICE_GET_SDIO_MANFID(PSDDEVICE pDevice)
-+ @category: PD_Reference
-+
-+ @input: pDevice - the target device for this request
-+
-+ @output: none
-+
-+ @return: function number
-+
-+ @notes: Implemented as a macro.
-+
-+ @see also: SDDEVICE_GET_SDIO_MANFCODE
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+#define SDDEVICE_GET_SDIO_MANFID(pDev) (pDev)->pId[0].SDIO_ManufacturerID
-+
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Get the device's manufacturer code
-+
-+ @function name: SDDEVICE_GET_SDIO_MANFCODE
-+ @prototype: UINT16 SDDEVICE_GET_SDIO_MANFCODE(PSDDEVICE pDevice)
-+ @category: PD_Reference
-+
-+ @input: pDevice - the target device for this request
-+
-+ @output: none
-+
-+ @return: function number
-+
-+ @notes: Implemented as a macro.
-+
-+ @see also: SDDEVICE_GET_SDIO_MANFID
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+#define SDDEVICE_GET_SDIO_MANFCODE(pDev) (pDev)->pId[0].SDIO_ManufacturerCode
-+
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Get the device's function number
-+
-+ @function name: SDDEVICE_GET_SDIO_FUNCNO
-+ @prototype: UINT8 SDDEVICE_GET_SDIO_FUNCNO(PSDDEVICE pDevice)
-+ @category: PD_Reference
-+
-+ @input: pDevice - the target device for this request
-+
-+ @output: none
-+
-+ @return: function number
-+
-+ @notes: Implemented as a macro.
-+
-+ @see also: SDDEVICE_GET_SDIO_FUNC_CLASS
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+#define SDDEVICE_GET_SDIO_FUNCNO(pDev) (pDev)->pId[0].SDIO_FunctionNo
-+
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Get the functions's class
-+
-+ @function name: SDDEVICE_GET_SDIO_FUNC_CLASS
-+ @prototype: UINT8 SDDEVICE_GET_SDIO_FUNC_CLASS(PSDDEVICE pDevice)
-+ @category: PD_Reference
-+
-+ @input: pDevice - the target device for this request
-+
-+ @output: none
-+
-+ @return: class number
-+
-+ @notes: Implemented as a macro.
-+
-+ @see also: SDDEVICE_GET_SDIO_FUNCNO
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+#define SDDEVICE_GET_SDIO_FUNC_CLASS(pDev) (pDev)->pId[0].SDIO_FunctionClass
-+
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Get the functions's Card Information Structure pointer
-+
-+ @function name: SDDEVICE_GET_SDIO_FUNC_CISPTR
-+ @prototype: UINT32 SDDEVICE_GET_SDIO_FUNC_CISPTR(PSDDEVICE pDevice)
-+ @category: PD_Reference
-+
-+ @input: pDevice - the target device for this request
-+
-+ @output: none
-+
-+ @return: CIS offset
-+
-+ @notes: Implemented as a macro.
-+
-+ @see also: SDDEVICE_GET_SDIO_FUNC_CSAPTR
-+ @see also: SDDEVICE_GET_SDIO_COMMON_CISPTR
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+#define SDDEVICE_GET_SDIO_FUNC_CISPTR(pDev)(pDev)->DeviceInfo.AsSDIOInfo.FunctionCISPtr
-+
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Get the functions's Code Stoarge Area pointer
-+
-+ @function name: SDDEVICE_GET_SDIO_FUNC_CSAPTR
-+ @prototype: UINT32 SDDEVICE_GET_SDIO_FUNC_CSAPTR(PSDDEVICE pDevice)
-+ @category: PD_Reference
-+
-+ @input: pDevice - the target device for this request
-+
-+ @output: none
-+
-+ @return: CSA offset
-+
-+ @notes: Implemented as a macro.
-+
-+ @see also: SDDEVICE_GET_SDIO_FUNC_CISPTR
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+#define SDDEVICE_GET_SDIO_FUNC_CSAPTR(pDev)(pDev)->DeviceInfo.AsSDIOInfo.FunctionCSAPtr
-+
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Get the functions's maximum reported block size
-+
-+ @function name: SDDEVICE_GET_SDIO_FUNC_MAXBLKSIZE
-+ @prototype: UINT16 SDDEVICE_GET_SDIO_FUNC_MAXBLKSIZE(PSDDEVICE pDevice)
-+ @category: PD_Reference
-+
-+ @input: pDevice - the target device for this request
-+
-+ @output: none
-+
-+ @return: block size
-+
-+ @notes: Implemented as a macro.
-+
-+ @see also:
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+#define SDDEVICE_GET_SDIO_FUNC_MAXBLKSIZE(pDev) (pDev)->DeviceInfo.AsSDIOInfo.FunctionMaxBlockSize
-+
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Get the common Card Information Structure pointer
-+
-+ @function name: SDDEVICE_GET_SDIO_COMMON_CISPTR
-+ @prototype: UINT32 SDDEVICE_GET_SDIO_COMMON_CISPTR(PSDDEVICE pDevice)
-+ @category: PD_Reference
-+
-+ @input: pDevice - the target device for this request
-+
-+ @output: none
-+
-+ @return: Common CIS Address (in SDIO address space)
-+
-+ @notes: Implemented as a macro.
-+
-+ @see also: SDDEVICE_GET_SDIO_FUNC_CSAPTR
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+#define SDDEVICE_GET_SDIO_COMMON_CISPTR(pDev) (pDev)->pHcd->CardProperties.CommonCISPtr
-+
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Get the card capabilities
-+
-+ @function name: SDDEVICE_GET_SDIO_CARD_CAPS
-+ @prototype: UINT8 SDDEVICE_GET_SDIO_CARD_CAPS(PSDDEVICE pDevice)
-+ @category: PD_Reference
-+
-+ @input: pDevice - the target device for this request
-+
-+ @output: none
-+
-+ @return: 8-bit card capabilities register
-+
-+ @notes: Implemented as a macro. Refer to SDIO spec for decoding.
-+
-+ @see also: SDDEVICE_GET_CARD_FLAGS
-+ @see also: SDDEVICE_GET_SDIOCARD_CAPS
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+#define SDDEVICE_GET_SDIO_CARD_CAPS(pDev) (pDev)->pHcd->CardProperties.SDIOCaps
-+
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Get the card flags
-+
-+ @function name: SDDEVICE_GET_CARD_FLAGS
-+ @prototype: CARD_INFO_FLAGS SDDEVICE_GET_CARD_FLAGS(PSDDEVICE pDevice)
-+ @category: PD_Reference
-+
-+ @input: pDevice - the target device for this request
-+
-+ @output: none
-+
-+ @return: flags
-+
-+ @notes: Implemented as a macro.
-+
-+ @example: Get card type:
-+ CARD_INFO_FLAGS flags;
-+ flags = SDDEVICE_GET_CARD_FLAGS(pDevice);
-+ switch(GET_CARD_TYPE(flags)) {
-+ case CARD_MMC: // Multi-media card
-+ ...
-+ case CARD_SD: // SD-Memory present
-+ ...
-+ case CARD_SDIO: // SDIO card present
-+ ...
-+ case CARD_COMBO: //SDIO card with SD
-+ ...
-+ }
-+ if (flags & CARD_SD_WP) {
-+ ...SD write protect on
-+ }
-+
-+ @see also: SDDEVICE_GET_SDIO_CARD_CAPS
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+#define SDDEVICE_GET_CARD_FLAGS(pDev) (pDev)->pHcd->CardProperties.Flags
-+
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Get the Relative Card Address register
-+
-+ @function name: SDDEVICE_GET_CARD_RCA
-+ @prototype: UINT16 SDDEVICE_GET_CARD_RCA(PSDDEVICE pDevice)
-+ @category: PD_Reference
-+
-+ @input: pDevice - the target device for this request
-+
-+ @output: none
-+
-+ @return: register address
-+
-+ @notes: Implemented as a macro. Refer to SDIO spec for decoding.
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+#define SDDEVICE_GET_CARD_RCA(pDev) (pDev)->pHcd->CardProperties.RCA
-+
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Get operational bus clock
-+
-+ @function name: SDDEVICE_GET_OPER_CLOCK
-+ @prototype: SD_BUSCLOCK_RATE SDDEVICE_GET_OPER_CLOCK(PSDDEVICE pDevice)
-+ @category: PD_Reference
-+
-+ @input: pDevice - the target device for this request
-+
-+ @output: none
-+
-+ @return: clock rate
-+
-+ @notes: Implemented as a macro. Returns the current bus clock rate.
-+ This may be lower than reported by the card due to Host Controller,
-+ Bus driver, or power management limitations.
-+
-+ @see also: SDDEVICE_GET_MAX_CLOCK
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+#define SDDEVICE_GET_OPER_CLOCK(pDev) (pDev)->pHcd->CardProperties.OperBusClock
-+
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Get maximum bus clock
-+
-+ @function name: SDDEVICE_GET_MAX_CLOCK
-+ @prototype: SD_BUSCLOCK_RATE SDDEVICE_GET_MAX_CLOCK(PSDDEVICE pDevice)
-+ @category: PD_Reference
-+
-+ @input: pDevice - the target device for this request
-+
-+ @output: none
-+
-+ @return: clock rate
-+
-+ @notes: To obtain the current maximum clock rate use SDDEVICE_GET_OPER_CLOCK().
-+ This rate my be lower than the host controllers maximum obtained using
-+ SDDEVICE_GET_MAX_CLOCK().
-+
-+ @see also: SDDEVICE_GET_OPER_CLOCK
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+#define SDDEVICE_GET_MAX_CLOCK(pDev) (pDev)->pHcd->MaxClockRate
-+
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Get operational maximum block length.
-+
-+ @function name: SDDEVICE_GET_OPER_BLOCK_LEN
-+ @prototype: UINT16 SDDEVICE_GET_OPER_BLOCK_LEN(PSDDEVICE pDevice)
-+ @category: PD_Reference
-+
-+ @input: pDevice - the target device for this request
-+
-+ @output: none
-+
-+ @return: block size in bytes
-+
-+ @notes: Implemented as a macro. Returns the maximum current block length.
-+ This may be lower than reported by the card due to Host Controller,
-+ Bus driver, or power management limitations.
-+
-+ @see also: SDDEVICE_GET_MAX_BLOCK_LEN
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+#define SDDEVICE_GET_OPER_BLOCK_LEN(pDev) (pDev)->pHcd->CardProperties.OperBlockLenLimit
-+
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Get maximum block length.
-+
-+ @function name: SDDEVICE_GET_MAX_BLOCK_LEN
-+ @prototype: UINT16 SDDEVICE_GET_MAX_BLOCK_LEN(PSDDEVICE pDevice)
-+ @category: PD_Reference
-+
-+ @input: pDevice - the target device for this request
-+
-+ @output: none
-+
-+ @return: block size in bytes
-+
-+ @notes: Implemented as a macro. Use SDDEVICE_GET_OPER_BLOCK_LEN to obtain
-+ the current block length.
-+
-+ @see also: SDDEVICE_GET_OPER_BLOCK_LEN
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+#define SDDEVICE_GET_MAX_BLOCK_LEN(pDev) (pDev)->pHcd->MaxBytesPerBlock
-+
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Get operational maximum block count.
-+
-+ @function name: SDDEVICE_GET_OPER_BLOCKS
-+ @prototype: UINT16 SDDEVICE_GET_OPER_BLOCKS(PSDDEVICE pDevice)
-+ @category: PD_Reference
-+
-+ @input: pDevice - the target device for this request
-+
-+ @output: none
-+
-+ @return: maximum number of blocks per transaction.
-+
-+ @notes: Implemented as a macro. Returns the maximum current block count.
-+ This may be lower than reported by the card due to Host Controller,
-+ Bus driver, or power management limitations.
-+
-+ @see also: SDDEVICE_GET_MAX_BLOCK_LEN
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+#define SDDEVICE_GET_OPER_BLOCKS(pDev) (pDev)->pHcd->CardProperties.OperBlockCountLimit
-+
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Get maximum block count.
-+
-+ @function name: SDDEVICE_GET_MAX_BLOCKS
-+ @prototype: UINT16 SDDEVICE_GET_MAX_BLOCKS(PSDDEVICE pDevice)
-+ @category: PD_Reference
-+
-+ @input: pDevice - the target device for this request
-+
-+ @output: none
-+
-+ @return: maximum number of blocks per transaction.
-+
-+ @notes: Implemented as a macro. Use SDDEVICE_GET_OPER_BLOCKS to obtain
-+ the current block count.
-+
-+ @see also: SDDEVICE_GET_OPER_BLOCKS
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+#define SDDEVICE_GET_MAX_BLOCKS(pDev) (pDev)->pHcd->MaxBlocksPerTrans
-+
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Get applied slot voltage
-+
-+ @function name: SDDEVICE_GET_SLOT_VOLTAGE_MASK
-+ @prototype: SLOT_VOLTAGE_MASK SDDEVICE_GET_SLOT_VOLTAGE_MASK(PSDDEVICE pDevice)
-+ @category: PD_Reference
-+
-+ @input: pDevice - the target device for this request
-+
-+ @output: none
-+
-+ @return: slot voltage mask
-+
-+ @notes: This function returns the applied voltage on the slot. The voltage value is a
-+ mask having the following values:
-+ SLOT_POWER_3_3V
-+ SLOT_POWER_3_0V
-+ SLOT_POWER_2_8V
-+ SLOT_POWER_2_0V
-+ SLOT_POWER_1_8V
-+ SLOT_POWER_1_6V
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+#define SDDEVICE_GET_SLOT_VOLTAGE_MASK(pDev) (pDev)->pHcd->CardProperties.CardVoltage
-+
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Get the Card Specific Data Register.
-+
-+ @function name: SDDEVICE_GET_CARDCSD
-+ @prototype: PUINT8 SDDEVICE_GET_CARDCSD(PSDDEVICE pDevice)
-+ @category: PD_Reference
-+
-+ @input: pDevice - the target device for this request
-+
-+ @output: none
-+
-+ @return: UINT8 CardCSD[MAX_CARD_RESPONSE_BYTES] array of CSD data.
-+
-+ @notes: Implemented as a macro.
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+#define SDDEVICE_GET_CARDCSD(pDev) (pDev)->pHcd->CardProperties.CardCSD
-+
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Get the bus mode flags
-+
-+ @function name: SDDEVICE_GET_BUSMODE_FLAGS
-+ @prototype: SD_BUSMODE_FLAGS SDDEVICE_GET_BUSMODE_FLAGS(PSDDEVICE pDevice)
-+ @category: PD_Reference
-+
-+ @input: pDevice - the target device for this request
-+
-+ @output: none
-+
-+ @return:
-+
-+ @notes: Implemented as a macro. This function returns the raw bus mode flags. This
-+ is useful for function drivers that wish to override the bus clock without
-+ modifying the current bus mode.
-+
-+ @see also: SDDEVICE_GET_BUSWIDTH
-+ @see also: SDCONFIG_BUS_MODE_CTRL
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+#define SDDEVICE_GET_BUSMODE_FLAGS(pDev) (pDev)->pHcd->CardProperties.BusMode
-+
-+
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Get the bus width.
-+
-+ @function name: SDDEVICE_GET_BUSWIDTH
-+ @prototype: UINT8 SDDEVICE_GET_BUSWIDTH(PSDDEVICE pDevice)
-+ @category: PD_Reference
-+
-+ @input: pDevice - the target device for this request
-+
-+ @output: none
-+
-+ @return: bus width: SDCONFIG_BUS_WIDTH_SPI, SDCONFIG_BUS_WIDTH_1_BIT, SDCONFIG_BUS_WIDTH_4_BIT
-+
-+ @notes: Implemented as a macro.
-+
-+ @see also: SDDEVICE_IS_BUSMODE_SPI
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+#define SDDEVICE_GET_BUSWIDTH(pDev) SDCONFIG_GET_BUSWIDTH((pDev)->pHcd->CardProperties.BusMode)
-+
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Is bus in SPI mode.
-+
-+ @function name: SDDEVICE_IS_BUSMODE_SPI
-+ @prototype: BOOL SDDEVICE_IS_BUSMODE_SPI(PSDDEVICE pDevice)
-+ @category: PD_Reference
-+
-+ @input: pDevice - the target device for this request
-+
-+ @output: none
-+
-+ @return: TRUE, SPI mode.
-+
-+ @notes: Implemented as a macro.
-+
-+ @see also: SDDEVICE_GET_BUSWIDTH
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+#define SDDEVICE_IS_BUSMODE_SPI(pDev) (SDDEVICE_GET_BUSWIDTH(pDev) == SDCONFIG_BUS_WIDTH_SPI)
-+
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Send a request to a device.
-+
-+ @function name: SDDEVICE_CALL_REQUEST_FUNC
-+ @prototype: SDIO_STATUS SDDEVICE_CALL_REQUEST_FUNC(PSDDEVICE pDevice, PSDREQUEST pRequest)
-+ @category: PD_Reference
-+
-+ @input: pDevice - the target device for this request
-+ @input: pRequest - the request to be sent
-+
-+ @output: none
-+
-+ @return: SDIO_STATUS
-+
-+ @notes: Sends a request to the specified device. If the request is successfully sent, then
-+ the response flags can be checked to detemine the result of the request.
-+
-+ @example: Example of sending a request to a device:
-+ PSDREQUEST pReq = NULL;
-+ //allocate a request
-+ pReq = SDDeviceAllocRequest(pDevice);
-+ if (NULL == pReq) {
-+ return SDIO_STATUS_NO_RESOURCES;
-+ }
-+ //initialize the request
-+ SDLIB_SetupCMD52Request(FuncNo, Address, Write, *pData, pReq);
-+ //send the request to the target
-+ status = SDDEVICE_CALL_REQUEST_FUNC(pDevice,pReq);
-+ if (!SDIO_SUCCESS(status)) {
-+ break;
-+ }
-+ //check the request response (based on the request type)
-+ if (SD_R5_GET_RESP_FLAGS(pReq->Response) & SD_R5_ERRORS) {
-+ ...
-+ }
-+ if (!Write) {
-+ // store the byte
-+ *pData = SD_R5_GET_READ_DATA(pReq->Response);
-+ }
-+ //free the request
-+ SDDeviceFreeRequest(pDevice,pReq);
-+ ...
-+
-+ @see also: SDDeviceAllocRequest
-+ @see also: SDDEVICE_CALL_CONFIG_FUNC
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+#define SDDEVICE_CALL_REQUEST_FUNC(pDev,pReq) (pDev)->pRequest((pDev),(pReq))
-+
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Send configuration to a device.
-+
-+ @function name: SDDEVICE_CALL_CONFIG_FUNC
-+ @prototype: SDIO_STATUS SDDEVICE_CALL_CONFIG_FUNC(PSDDEVICE pDevice, PSDCONFIG pConfigure)
-+ @category: PD_Reference
-+
-+ @input: pDevice - the target device for this request
-+ @input: pConfigure - configuration request
-+
-+ @output: none
-+
-+ @return: SDIO_STATUS
-+
-+ @notes: Sends a configuration request to the specified device.
-+
-+ @example: Example of sending a request to a device:
-+ SDCONFIG configHdr;
-+ SDCONFIG_FUNC_ENABLE_DISABLE_DATA fData;
-+ fData.EnableFlags = SDCONFIG_ENABLE_FUNC;
-+ fData.TimeOut = 500;
-+ SET_SDCONFIG_CMD_INFO(&configHdr, SDCONFIG_FUNC_ENABLE_DISABLE, fData, sizeof(fData));
-+ return SDDEVICE_CALL_CONFIG_FUNC(pDevice, &configHdr);
-+
-+ @see also: SDLIB_IssueConfig
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+#define SDDEVICE_CALL_CONFIG_FUNC(pDev,pCfg) (pDev)->pConfigure((pDev),(pCfg))
-+
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Allocate a request structure.
-+
-+ @function name: SDDeviceAllocRequest
-+ @prototype: PSDREQUEST SDDeviceAllocRequest(PSDDEVICE pDevice)
-+ @category: PD_Reference
-+
-+ @input: pDevice - the target device for this request
-+
-+ @output: none
-+
-+ @return: request pointer or NULL if not available.
-+
-+ @notes: This function must not be called in a non-schedulable (interrupts off) context.
-+ Allocating memory on some OSes may block.
-+
-+ @see also: SDDEVICE_CALL_REQUEST_FUNC
-+ @see also: SDDeviceFreeRequest
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+#define SDDeviceAllocRequest(pDev) (pDev)->AllocRequest((pDev))
-+
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Free a request structure.
-+
-+ @function name: SDDeviceFreeRequest
-+ @prototype: void SDDeviceFreeRequest(PSDDEVICE pDevice, PSDREQUEST pRequest)
-+ @category: PD_Reference
-+
-+ @input: pDevice - the target device for this request
-+ @input: pRequest - request allocated by SDDeviceAllocRequest().
-+
-+ @output: none
-+
-+ @return: none
-+
-+ @notes: This function must not be called in a non-schedulable (interrupts off) context.
-+ Freeing memory on some OSes may block.
-+
-+ @see also: SDDEVICE_CALL_REQUEST_FUNC
-+ @see also: SDDeviceAllocRequest
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+#define SDDeviceFreeRequest(pDev,pReq) (pDev)->FreeRequest((pDev),pReq)
-+
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Register an interrupt handler for a device.
-+
-+ @function name: SDDEVICE_SET_IRQ_HANDLER
-+ @prototype: void SDDEVICE_SET_IRQ_HANDLER(PSDDEVICE pDevice,
-+ void (*pIrqFunction)(PVOID pContext),
-+ PVOID pContext)
-+ @category: PD_Reference
-+
-+ @input: pDevice - the target device for this request
-+ @input: pIrqFunction - the interrupt function to execute.
-+ @input: pContext - context value passed into interrupt routine.
-+
-+ @output: none
-+
-+ @return: none
-+
-+ @notes: The registered routine will be called upon each card interrupt.
-+ The interrupt function should acknowledge the interrupt when it is
-+ ready to handle more interrupts using:
-+ SDLIB_IssueConfig(pDevice, SDCONFIG_FUNC_ACK_IRQ, NULL, 0);
-+ The interrupt handler can perform synchronous request calls.
-+
-+ @see also: SDDEVICE_SET_ASYNC_IRQ_HANDLER
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+#define SDDEVICE_SET_IRQ_HANDLER(pDev,pFn,pContext) \
-+{ \
-+ (pDev)->pIrqFunction = (pFn); \
-+ (pDev)->IrqContext = (PVOID)(pContext); \
-+}
-+
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Register an asynchronous interrupt handler for a device.
-+
-+ @function name: SDDEVICE_SET_ASYNC_IRQ_HANDLER
-+ @prototype: void SDDEVICE_SET_ASYNC_IRQ_HANDLER(PSDDEVICE pDevice,
-+ void (*pIrqAsyncFunction)(PVOID pContext),
-+ PVOID pContext)
-+ @category: PD_Reference
-+
-+ @input: pDevice - the target device for this request
-+ @input: pIrqAsyncFunction - the interrupt function to execute.
-+ @input: pContext - context value passed into interrupt routine.
-+
-+ @output: none
-+
-+ @return: none
-+
-+ @notes: The registered routine will be called upon each card interrupt.
-+ The interrupt function should acknowledge the interrupt when it is
-+ ready to handle more interrupts using:
-+ SDLIB_IssueConfig(pDevice, SDCONFIG_FUNC_ACK_IRQ, NULL, 0);
-+ The interrupt handler can not perform any synchronous request calls.
-+ Using this call provides a faster interrupt dispatch, but limits all
-+ requests to asynchronous mode.
-+
-+ @see also: SDDEVICE_SET_IRQ_HANDLER
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+#define SDDEVICE_SET_ASYNC_IRQ_HANDLER(pDev,pFn,pContext) \
-+{ \
-+ (pDev)->pIrqAsyncFunction = (pFn); \
-+ (pDev)->IrqAsyncContext = (PVOID)(pContext); \
-+}
-+
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Get the SDIO capabilities rgeister.
-+
-+ @function name: SDDEVICE_GET_SDIOCARD_CAPS
-+ @prototype: UINT8 SDDEVICE_GET_SDIOCARD_CAPS(PSDDEVICE pDevice)
-+ @category: PD_Reference
-+
-+ @input: pDevice - the target device for this request
-+
-+ @output: none
-+
-+ @return: SD capabilities
-+
-+ @notes: See SD specification for decoding of these capabilities.
-+
-+ @see also: SDDEVICE_GET_SDIO_CARD_CAPS
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+#define SDDEVICE_GET_SDIOCARD_CAPS(pDev) (pDev)->pHcd->CardProperties.SDIOCaps
-+
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Get HCD driver name
-+
-+ @function name: SDDEVICE_GET_HCDNAME
-+ @prototype: PTEXT SDDEVICE_GET_HCDNAME(PSDDEVICE pDevice)
-+ @category: PD_Reference
-+
-+ @input: pDevice - the target device for this request
-+
-+ @output: none
-+
-+ @return: pointer to a string containing the name of the underlying HCD
-+
-+ @notes: Implemented as a macro.
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+#define SDDEVICE_GET_HCDNAME(pDev) (pDev)->pHcd->pName
-+
-+
-+#define SDDEVICE_CALL_IRQ_HANDLER(pDev) (pDev)->pIrqFunction((pDev)->IrqContext)
-+#define SDDEVICE_CALL_IRQ_ASYNC_HANDLER(pDev) (pDev)->pIrqAsyncFunction((pDev)->IrqAsyncContext)
-+
-+
-+#define SDDEVICE_SET_SDIO_FUNCNO(pDev,Num) (pDev)->pId[0].SDIO_FunctionNo = (Num)
-+#define SDDEVICE_IS_CARD_REMOVED(pDev) ((pDev)->pHcd->CardProperties.CardState & \
-+ CARD_STATE_REMOVED)
-+
-+
-+typedef enum _SDHCD_IRQ_PROC_STATE {
-+ SDHCD_IDLE = 0,
-+ SDHCD_IRQ_PENDING = 1,
-+ SDHCD_IRQ_HELPER = 2
-+}SDHCD_IRQ_PROC_STATE, *PSDHCD_IRQ_PROC_STATE;
-+
-+/* host controller bus driver registration structure */
-+typedef struct _SDHCD {
-+ CT_VERSION_CODE Version; /* version code of the SDIO stack */
-+ SDLIST SDList; /* internal use list*/
-+ PTEXT pName; /* name of registering host/slot driver */
-+ UINT32 Attributes; /* attributes of host controller */
-+ UINT16 MaxBytesPerBlock; /* max bytes per block */
-+ UINT16 MaxBlocksPerTrans; /* max blocks per transaction */
-+ SD_SLOT_CURRENT MaxSlotCurrent; /* max current per slot in milli-amps */
-+ UINT8 SlotNumber; /* sequential slot number for this HCD, set by bus driver */
-+ SD_BUSCLOCK_RATE MaxClockRate; /* max clock rate in hz */
-+ SLOT_VOLTAGE_MASK SlotVoltageCaps; /* slot voltage capabilities */
-+ SLOT_VOLTAGE_MASK SlotVoltagePreferred; /* preferred slot voltage */
-+ PVOID pContext; /* host controller driver use data */
-+ SDIO_STATUS (*pRequest)(struct _SDHCD *pHcd);
-+ /* get/set configuration */
-+ SDIO_STATUS (*pConfigure)(struct _SDHCD *pHcd, PSDCONFIG pConfig);
-+ /* everything below this line is for bus driver use */
-+ OS_SEMAPHORE ConfigureOpsSem; /* semaphore to make specific configure ops atomic, internal use */
-+ OS_CRITICALSECTION HcdCritSection; /* critical section to protect hcd data structures (internal use) */
-+ SDREQUESTQUEUE RequestQueue; /* request queue, internal use */
-+ PSDREQUEST pCurrentRequest; /* current request we are working on */
-+ CARD_PROPERTIES CardProperties; /* properties for the currently inserted card*/
-+ OSKERNEL_HELPER SDIOIrqHelper; /* synch IRQ helper, internal use */
-+ SDDEVICE *pPseudoDev; /* pseudo device used for initialization (internal use) */
-+ UINT8 PendingHelperIrqs; /* IRQ helper pending IRQs */
-+ UINT8 PendingIrqAcks; /* pending IRQ acks from function drivers */
-+ UINT8 IrqsEnabled; /* current irq enabled mask */
-+ SDHCD_IRQ_PROC_STATE IrqProcState; /* irq processing state */
-+ POS_DEVICE pDevice; /* device registration with base system */
-+ SD_SLOT_CURRENT SlotCurrentAllocated; /* slot current allocated (internal use ) */
-+ ATOMIC_FLAGS HcdFlags; /* HCD Flags */
-+#define HCD_REQUEST_CALL_BIT 0
-+#define HCD_IRQ_NO_PEND_CHECK 1 /* HCD flag to bypass interrupt pending register
-+ check, typically done on single function cards */
-+ SDREQUESTQUEUE CompletedRequestQueue; /* completed request queue, internal use */
-+ PSDDMA_DESCRIPTION pDmaDescription; /* description of HCD's DMA capabilities */
-+ POS_MODULE pModule; /* OS-specific module information */
-+ INT Recursion; /* recursion level */
-+ PVOID Reserved1;
-+ PVOID Reserved2;
-+}SDHCD, *PSDHCD;
-+
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Get a pointer to the HCD's DMA description
-+
-+ @function name: SDGET_DMA_DESCRIPTION
-+ @prototype: PSDDMA_DESCRIPTION SDGET_DMA_DESCRIPTION(PSDDEVICE pDevice)
-+ @category: PD_Reference
-+
-+ @input: pDevice - device structure
-+
-+ @return: PSDDMA_DESCRIPTION or NULL if no DMA support
-+
-+ @notes: Implemented as a macro.
-+
-+ @example: getting the current request:
-+ PSDDMA_DESCRIPTION pDmaDescrp = SDGET_DMA_DESCRIPTION(pDevice);
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+#define SDGET_DMA_DESCRIPTION(pDevice) (pDevice)->pHcd->pDmaDescription
-+
-+
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Get the logical slot number the device is assigned to.
-+
-+ @function name: SDDEVICE_GET_SLOT_NUMBER
-+ @prototype: UINT8 SDDEVICE_GET_SLOT_NUMBER(PSDDEVICE pDevice)
-+ @category: PD_Reference
-+
-+ @input: pDevice - device structure
-+
-+ @return: unsigned number representing the slot number
-+
-+ @notes: Implemented as a macro. This value is unique for each physical slot in the system
-+ and assigned by the bus driver. Devices on a multi-function card will share the same
-+ slot number.
-+
-+ @example: getting the slot number:
-+ UINT8 thisSlot = SDDEVICE_GET_SLOT_NUMBER(pDevice);
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+#define SDDEVICE_GET_SLOT_NUMBER(pDevice) (pDevice)->pHcd->SlotNumber
-+
-+/* for function use */
-+SDIO_STATUS SDIO_RegisterFunction(PSDFUNCTION pFunction);
-+SDIO_STATUS SDIO_UnregisterFunction(PSDFUNCTION pFunction);
-+
-+#include "sdio_hcd_defs.h"
-+#endif /* __SDIO_BUSDRIVER_H___ */
-diff --git a/include/linux/sdio/sdio_hcd_defs.h b/include/linux/sdio/sdio_hcd_defs.h
-new file mode 100644
-index 0000000..1782469
---- /dev/null
-+++ b/include/linux/sdio/sdio_hcd_defs.h
-@@ -0,0 +1,219 @@
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+@file: sdio_hcd_defs.h
-+
-+@abstract: host controller driver definitions
-+
-+@notice: Copyright (c), 2005-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 __SDIO_HCD_DEFS_H___
-+#define __SDIO_HCD_DEFS_H___
-+
-+ /* write protect switch position data */
-+typedef UINT8 SDCONFIG_WP_VALUE;
-+
-+ /* HC commands */
-+#define SDCONFIG_SEND_INIT_CLOCKS (SDCONFIG_FLAGS_HC_CONFIG | SDCONFIG_FLAGS_DATA_PUT | 1)
-+#define SDCONFIG_SDIO_INT_CTRL (SDCONFIG_FLAGS_HC_CONFIG | SDCONFIG_FLAGS_DATA_PUT | 2)
-+#define SDCONFIG_SDIO_REARM_INT (SDCONFIG_FLAGS_HC_CONFIG | SDCONFIG_FLAGS_DATA_NONE | 3)
-+#define SDCONFIG_BUS_MODE_CTRL (SDCONFIG_FLAGS_HC_CONFIG | SDCONFIG_FLAGS_DATA_BOTH | 4)
-+#define SDCONFIG_POWER_CTRL (SDCONFIG_FLAGS_HC_CONFIG | SDCONFIG_FLAGS_DATA_PUT | 5)
-+#define SDCONFIG_GET_WP (SDCONFIG_FLAGS_HC_CONFIG | SDCONFIG_FLAGS_DATA_GET | 6)
-+
-+ /* slot init clocks control */
-+typedef struct _SDCONFIG_INIT_CLOCKS_DATA {
-+ UINT16 NumberOfClocks; /* number of clocks to issue in the current bus mode*/
-+}SDCONFIG_INIT_CLOCKS_DATA, *PSDCONFIG_INIT_CLOCKS_DATA;
-+
-+/* slot power control */
-+typedef struct _SDCONFIG_POWER_CTRL_DATA {
-+ BOOL SlotPowerEnable; /* turn on/off slot power */
-+ SLOT_VOLTAGE_MASK SlotPowerVoltageMask; /* slot power voltage mask */
-+}SDCONFIG_POWER_CTRL_DATA, *PSDCONFIG_POWER_CTRL_DATA;
-+
-+typedef UINT8 SDIO_IRQ_MODE_FLAGS;
-+/* SDIO Interrupt control */
-+typedef struct _SDCONFIG_SDIO_INT_CTRL_DATA {
-+ BOOL SlotIRQEnable; /* turn on/off Slot IRQ detection */
-+ SDIO_IRQ_MODE_FLAGS IRQDetectMode; /* slot IRQ detect mode , only valid if Enabled = TRUE */
-+#define IRQ_DETECT_RAW 0x00
-+#define IRQ_DETECT_MULTI_BLK 0x01
-+#define IRQ_DETECT_4_BIT 0x02
-+#define IRQ_DETECT_1_BIT 0x04
-+#define IRQ_DETECT_SPI 0x08
-+}SDCONFIG_SDIO_INT_CTRL_DATA, *PSDCONFIG_SDIO_INT_CTRL_DATA;
-+
-+/* card insert */
-+#define EVENT_HCD_ATTACH 1
-+/* card remove */
-+#define EVENT_HCD_DETACH 2
-+/* card slot interrupt */
-+#define EVENT_HCD_SDIO_IRQ_PENDING 3
-+/* transfer done */
-+#define EVENT_HCD_TRANSFER_DONE 4
-+/* (internal use only) */
-+#define EVENT_HCD_CD_POLLING 5
-+/* NOP */
-+#define EVENT_HCD_NOP 0
-+
-+/* attrib_flags */
-+#define SDHCD_ATTRIB_SUPPORTS_POWER 0x0001 /* host controller driver supports power managment */
-+#define SDHCD_ATTRIB_BUS_1BIT 0x0002 /* SD Native 1 - bit mode */
-+#define SDHCD_ATTRIB_BUS_4BIT 0x0004 /* SD Native 4 - bit mode */
-+#define SDHCD_ATTRIB_BUS_SPI 0x0008 /* SPI mode capable */
-+#define SDHCD_ATTRIB_READ_WAIT 0x0010 /* read wait supported (SD-only) */
-+#define SDHCD_ATTRIB_MULTI_BLK_IRQ 0x0020 /* interrupts between multi-block capable (SD-only) */
-+#define SDHCD_ATTRIB_BUS_MMC8BIT 0x0040 /* MMC 8-bit */
-+#define SDHCD_ATTRIB_SLOT_POLLING 0x0080 /* requires slot polling for Card Detect */
-+#define SDHCD_ATTRIB_POWER_SWITCH 0x0100 /* host has power switch control, must be set if SPI
-+ mode can be switched to 1 or 4 bit mode */
-+#define SDHCD_ATTRIB_NO_SPI_CRC 0x0200 /* when in SPI mode,
-+ host wants to run without SPI CRC */
-+#define SDHCD_ATTRIB_AUTO_CMD12 0x0400 /* host controller supports auto CMD12 */
-+#define SDHCD_ATTRIB_NO_4BIT_IRQ 0x0800 /* host controller does not support 4 bit IRQ mode*/
-+#define SDHCD_ATTRIB_RAW_MODE 0x1000 /* host controller is a raw mode hcd*/
-+#define SDHCD_ATTRIB_SD_HIGH_SPEED 0x2000 /* host controller supports SD high speed interface */
-+#define SDHCD_ATTRIB_MMC_HIGH_SPEED 0x4000 /* host controller supports MMC high speed interface */
-+
-+#define IS_CARD_PRESENT(pHcd) ((pHcd)->CardProperties.Flags & CARD_TYPE_MASK)
-+#define SET_CURRENT_REQUEST(pHcd,Req) (pHcd)->pCurrentRequest = (Req)
-+#define IS_HCD_RAW(pHcd) ((pHcd)->Attributes & SDHCD_ATTRIB_RAW_MODE)
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Get a pointer to the current bus request for a host controller
-+
-+ @function name: GET_CURRENT_REQUEST
-+ @prototype: PSDREQUEST GET_CURRENT_REQUEST (PSDHCD pHcd)
-+ @category: HD_Reference
-+
-+ @input: pHcd - host structure
-+
-+ @return: current SD/SDIO bus request being worked on
-+
-+ @notes: Implemented as a macro. This macro returns the current SD request that is
-+ being worked on.
-+
-+ @example: getting the current request:
-+ pReq = GET_CURRENT_REQUEST(&pHct->Hcd);
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+#define GET_CURRENT_REQUEST(pHcd) (pHcd)->pCurrentRequest
-+#define GET_CURRENT_BUS_WIDTH(pHcd) SDCONFIG_GET_BUSWIDTH((pHcd)->CardProperties.BusMode)
-+
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Get host controller's current operational bus clock
-+
-+ @function name: SDHCD_GET_OPER_CLOCK
-+ @prototype: SD_BUSCLOCK_RATE SDHCD_GET_OPER_CLOCK(PSDHCD pHcd)
-+ @category: HD_Reference
-+
-+ @input: pHcd - the registered host structure
-+
-+ @output: none
-+
-+ @return: clock rate
-+
-+ @notes: Implemented as a macro. Returns the current bus clock rate.
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+#define SDHCD_GET_OPER_CLOCK(pHcd) (pHcd)->CardProperties.OperBusClock
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Is host controller operating in SPI mode
-+
-+ @function name: IS_HCD_BUS_MODE_SPI
-+ @prototype: BOOL IS_HCD_BUS_MODE_SPI (PSDHCD pHcd)
-+ @category: HD_Reference
-+
-+ @input: pHcd - host structure
-+
-+ @return: TRUE if in SPI mode
-+
-+ @notes: Implemented as a macro. Host controllers that operate in SPI mode
-+ dynamically can use this macro to check for SPI operation.
-+
-+ @example: testing for SPI mode:
-+ if (IS_HCD_BUS_MODE_SPI(&pHct->Hcd)) {
-+ .. in spi mode
-+ }
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+#define IS_HCD_BUS_MODE_SPI(pHcd) (GET_CURRENT_BUS_WIDTH(pHcd) == SDCONFIG_BUS_WIDTH_SPI)
-+
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Is host controller using SPI in non-CRC mode
-+
-+ @function name: IS_HCD_BUS_MODE_SPI_NO_CRC
-+ @prototype: BOOL IS_HCD_BUS_MODE_SPI_NO_CRC(PSDHCD pHcd)
-+ @category: HD_Reference
-+
-+ @input: pHcd - host structure
-+
-+ @return: TRUE if CRC mode is off
-+
-+ @notes: Implemented as a macro. SPI-capable cards and systems can operate in
-+ non-CRC protected mode. In this mode the host controller should ignore
-+ CRC fields and/or disable CRC generation when issuing command or data
-+ packets. This option is useful for software based SPI mode where CRC
-+ should be turned off in order to reduce processing overhead.
-+
-+ @example: test for non-CRC SPI mode:
-+ if (IS_HCD_BUS_MODE_SPI_NO_CRC(&pHct->Hcd)) {
-+ .. disable CRC checking in hardware.
-+ }
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+#define IS_HCD_BUS_MODE_SPI_NO_CRC(pHcd) ((pHcd)->CardProperties.BusMode & \
-+ SDCONFIG_BUS_MODE_SPI_NO_CRC)
-+
-+typedef UINT8 SDHCD_RESPONSE_CHECK_MODE;
-+/* have SDIO core check the response token and see if it is okay to continue with
-+ * the data portion */
-+#define SDHCD_CHECK_DATA_TRANS_OK 0x01
-+/* have SDIO core check the SPI token received */
-+#define SDHCD_CHECK_SPI_TOKEN 0x02
-+
-+/* prototypes */
-+/* for HCD use */
-+SDIO_STATUS SDIO_RegisterHostController(PSDHCD pHcd);
-+SDIO_STATUS SDIO_UnregisterHostController(PSDHCD pHcd);
-+SDIO_STATUS SDIO_HandleHcdEvent(PSDHCD pHcd, HCD_EVENT Event);
-+SDIO_STATUS SDIO_CheckResponse(PSDHCD pHcd, PSDREQUEST pReq, SDHCD_RESPONSE_CHECK_MODE CheckMode);
-+SDIO_STATUS SDIO_BusAddOSDevice(PSDDMA_DESCRIPTION pDma, POS_PNPDRIVER pDriver, POS_PNPDEVICE pDevice);
-+void SDIO_BusRemoveOSDevice(POS_PNPDRIVER pDriver, POS_PNPDEVICE pDevice);
-+
-+#endif /* __SDIO_BUSDRIVER_H___ */
-diff --git a/include/linux/sdio/sdio_lib.h b/include/linux/sdio/sdio_lib.h
-new file mode 100644
-index 0000000..ac0cbd7
---- /dev/null
-+++ b/include/linux/sdio/sdio_lib.h
-@@ -0,0 +1,270 @@
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+@file: sdio_lib.h
-+
-+@abstract: SDIO Library include
-+
-+#notes:
-+
-+@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 __SDIO_LIB_H___
-+#define __SDIO_LIB_H___
-+
-+#ifdef UNDER_CE
-+#include "wince\sdio_lib_wince.h"
-+#endif /* WINCE */
-+
-+#define CMD52_DO_READ FALSE
-+#define CMD52_DO_WRITE TRUE
-+
-+ /* read/write macros to any function */
-+#define Cmd52WriteByteFunc(pDev,Func,Address,pValue) \
-+ SDLIB_IssueCMD52((pDev),(Func),(Address),(pValue),1,CMD52_DO_WRITE)
-+#define Cmd52ReadByteFunc(pDev,Func,Address,pValue) \
-+ SDLIB_IssueCMD52((pDev),(Func),(Address),pValue,1,CMD52_DO_READ)
-+#define Cmd52ReadMultipleFunc(pDev,Func, Address, pBuf,length) \
-+ SDLIB_IssueCMD52((pDev),(Func),(Address),(pBuf),(length),CMD52_DO_READ)
-+
-+ /* macros to access common registers */
-+#define Cmd52WriteByteCommon(pDev, Address, pValue) \
-+ Cmd52WriteByteFunc((pDev),0,(Address),(pValue))
-+#define Cmd52ReadByteCommon(pDev, Address, pValue) \
-+ Cmd52ReadByteFunc((pDev),0,(Address),(pValue))
-+#define Cmd52ReadMultipleCommon(pDev, Address, pBuf,length) \
-+ Cmd52ReadMultipleFunc((pDev),0,(Address),(pBuf),(length))
-+
-+#define SDLIB_SetupCMD52RequestAsync(f,a,w,wd,pR) \
-+{ \
-+ SDLIB_SetupCMD52Request((f),(a),(w),(wd),(pR)); \
-+ (pR)->Flags |= SDREQ_FLAGS_TRANS_ASYNC; \
-+}
-+
-+ /* a message block */
-+typedef struct _SDMESSAGE_BLOCK {
-+ SDLIST SDList; /* list entry */
-+ INT MessageLength; /* number of bytes in this message */
-+ UINT8 MessageStart[1]; /* message start */
-+}SDMESSAGE_BLOCK, *PSDMESSAGE_BLOCK;
-+
-+ /* message queue */
-+typedef struct _SDMESSAGE_QUEUE {
-+ SDLIST MessageList; /* message list */
-+ OS_CRITICALSECTION MessageCritSection; /* message semaphore */
-+ SDLIST FreeMessageList; /* free message list */
-+ INT MaxMessageLength; /* max message block length */
-+}SDMESSAGE_QUEUE, *PSDMESSAGE_QUEUE;
-+
-+/* internal library prototypes that can be proxied */
-+SDIO_STATUS _SDLIB_IssueCMD52(PSDDEVICE pDevice,
-+ UINT8 FuncNo,
-+ UINT32 Address,
-+ PUINT8 pData,
-+ INT ByteCount,
-+ BOOL Write);
-+SDIO_STATUS _SDLIB_FindTuple(PSDDEVICE pDevice,
-+ UINT8 Tuple,
-+ UINT32 *pTupleScanAddress,
-+ PUINT8 pBuffer,
-+ UINT8 *pLength);
-+SDIO_STATUS _SDLIB_IssueConfig(PSDDEVICE pDevice,
-+ SDCONFIG_COMMAND Command,
-+ PVOID pData,
-+ INT Length);
-+void _SDLIB_PrintBuffer(PUCHAR pBuffer, INT Length,PTEXT pDescription);
-+void _SDLIB_SetupCMD52Request(UINT8 FuncNo,
-+ UINT32 Address,
-+ BOOL Write,
-+ UINT8 WriteData,
-+ PSDREQUEST pRequest);
-+SDIO_STATUS _SDLIB_SetFunctionBlockSize(PSDDEVICE pDevice,
-+ UINT16 BlockSize);
-+
-+SDIO_STATUS _SDLIB_GetDefaultOpCurrent(PSDDEVICE pDevice,
-+ SD_SLOT_CURRENT *pOpCurrent);
-+PSDMESSAGE_QUEUE _CreateMessageQueue(INT MaxMessages, INT MaxMessageLength);
-+void _DeleteMessageQueue(PSDMESSAGE_QUEUE pQueue);
-+SDIO_STATUS _PostMessage(PSDMESSAGE_QUEUE pQueue, PVOID pMessage, INT MessageLength);
-+SDIO_STATUS _GetMessage(PSDMESSAGE_QUEUE pQueue, PVOID pData, INT *pBufferLength);
-+
-+#ifdef CTSYSTEM_NO_FUNCTION_PROXIES
-+ /* OS port requires no proxy functions, use methods directly from the library */
-+#define SDLIB_IssueCMD52 _SDLIB_IssueCMD52
-+#define SDLIB_SetupCMD52Request _SDLIB_SetupCMD52Request
-+#define SDLIB_FindTuple _SDLIB_FindTuple
-+#define SDLIB_IssueConfig _SDLIB_IssueConfig
-+#define SDLIB_SetFunctionBlockSize _SDLIB_SetFunctionBlockSize
-+#define SDLIB_GetDefaultOpCurrent _SDLIB_GetDefaultOpCurrent
-+#define SDLIB_CreateMessageQueue _CreateMessageQueue
-+#define SDLIB_DeleteMessageQueue _DeleteMessageQueue
-+#define SDLIB_PostMessage _PostMessage
-+#define SDLIB_GetMessage _GetMessage
-+#define SDLIB_PrintBuffer _SDLIB_PrintBuffer
-+#else
-+
-+/* proxied versions */
-+SDIO_STATUS SDLIB_IssueCMD52(PSDDEVICE pDevice,
-+ UINT8 FuncNo,
-+ UINT32 Address,
-+ PUINT8 pData,
-+ INT ByteCount,
-+ BOOL Write);
-+
-+void SDLIB_SetupCMD52Request(UINT8 FuncNo,
-+ UINT32 Address,
-+ BOOL Write,
-+ UINT8 WriteData,
-+ PSDREQUEST pRequest);
-+
-+SDIO_STATUS SDLIB_FindTuple(PSDDEVICE pDevice,
-+ UINT8 Tuple,
-+ UINT32 *pTupleScanAddress,
-+ PUINT8 pBuffer,
-+ UINT8 *pLength);
-+
-+SDIO_STATUS SDLIB_IssueConfig(PSDDEVICE pDevice,
-+ SDCONFIG_COMMAND Command,
-+ PVOID pData,
-+ INT Length);
-+
-+SDIO_STATUS SDLIB_SetFunctionBlockSize(PSDDEVICE pDevice,
-+ UINT16 BlockSize);
-+
-+void SDLIB_PrintBuffer(PUCHAR pBuffer, INT Length,PTEXT pDescription);
-+
-+SDIO_STATUS SDLIB_GetDefaultOpCurrent(PSDDEVICE pDevice, SD_SLOT_CURRENT *pOpCurrent);
-+
-+PSDMESSAGE_QUEUE SDLIB_CreateMessageQueue(INT MaxMessages, INT MaxMessageLength);
-+
-+void SDLIB_DeleteMessageQueue(PSDMESSAGE_QUEUE pQueue);
-+
-+SDIO_STATUS SDLIB_PostMessage(PSDMESSAGE_QUEUE pQueue, PVOID pMessage, INT MessageLength);
-+
-+SDIO_STATUS SDLIB_GetMessage(PSDMESSAGE_QUEUE pQueue, PVOID pData, INT *pBufferLength);
-+#endif /* CTSYSTEM_NO_FUNCTION_PROXIES */
-+
-+
-+SDIO_STATUS SDLIB_OSCreateHelper(POSKERNEL_HELPER pHelper,
-+ PHELPER_FUNCTION pFunction,
-+ PVOID pContext);
-+
-+void SDLIB_OSDeleteHelper(POSKERNEL_HELPER pHelper);
-+
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Check message queue is empty
-+
-+ @function name: SDLIB_IsQueueEmpty
-+ @prototype: BOOL SDLIB_IsQueueEmpty(PSDMESSAGE_QUEUE pQueue)
-+ @category: Support_Reference
-+
-+ @input: pQueue - message queue to check
-+
-+ @return: TRUE if empty else false
-+
-+ @see also: SDLIB_CreateMessageQueue
-+
-+ @example: Check message queue :
-+ if (SDLIB_IsQueueEmpty(pInstance->pQueue)) {
-+ .. message queue is empty
-+ }
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+static INLINE BOOL SDLIB_IsQueueEmpty(PSDMESSAGE_QUEUE pQueue) {
-+ return SDLIST_IS_EMPTY(&pQueue->MessageList);
-+}
-+
-+
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Issue an I/O abort request
-+
-+ @function name: SDLIB_IssueIOAbort
-+ @prototype: SDIO_STATUS SDLIB_IssueIOAbort(PSDDEVICE pDevice)
-+ @category: PD_Reference
-+
-+ @input: pDevice - the device that is the target of this request
-+
-+ @return: SDIO_STATUS
-+
-+ @notes: This procedure can be called to issue an I/O abort request to an I/O function.
-+ This procedure cannot be used to abort a data (block) transfer already in progress.
-+ It is intended to be used when a data (block) transfer completes with an error and only if
-+ the I/O function requires an abort action. Some I/O functions may automatically
-+ recover from such failures and not require this action. This function issues
-+ the abort command synchronously and can potentially block.
-+ If an async request is required, you must allocate a request and use
-+ SDLIB_SetupIOAbortAsync() to prepare the request.
-+
-+ @example: Issuing I/O Abort synchronously :
-+ .. check status from last block operation:
-+ if (status == SDIO_STATUS_BUS_READ_TIMEOUT) {
-+ .. on failure, issue I/O abort
-+ status2 = SDLIB_IssueIOAbort(pDevice);
-+ }
-+ Issuing I/O Abort asynchronously:
-+ ... allocate a request
-+ ... setup the request:
-+ SDLIB_SetupIOAbortAsync(pDevice,pReq);
-+ pReq->pCompletion = myIOAbortCompletion;
-+ pReq->pCompleteContext = pDevice;
-+ status = SDDEVICE_CALL_REQUEST_FUNC(pDevice,pReq);
-+
-+ @see also: SDLIB_SetupIOAbortAsync
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+static INLINE SDIO_STATUS SDLIB_IssueIOAbort(PSDDEVICE pDevice) {
-+ UINT8 value = SDDEVICE_GET_SDIO_FUNCNO(pDevice);
-+ return Cmd52WriteByteCommon(pDevice,0x06,&value);
-+}
-+
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+ @function: Setup an I/O abort request for async operation
-+
-+ @function name: SDLIB_SetupIOAbortAsync
-+ @prototype: SDLIB_SetupIOAbortAsync(PSDDEVICE pDevice, PSDREQUEST pRequest)
-+ @category: PD_Reference
-+
-+ @input: pDevice - the device that is the target of this request
-+ pRequest - the request to set up
-+
-+ @see also: SDLIB_IssueIOAbort
-+
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-+#define SDLIB_SetupIOAbortAsync(pDevice, pReq) \
-+ SDLIB_SetupCMD52RequestAsync(0,0x06,TRUE,SDDEVICE_GET_SDIO_FUNCNO(pDevice),(pReq))
-+
-+
-+#endif /* __SDIO_LIB_H___*/
-diff --git a/include/linux/sdio/sdlist.h b/include/linux/sdio/sdlist.h
-new file mode 100644
-index 0000000..dc35e1c
---- /dev/null
-+++ b/include/linux/sdio/sdlist.h
-@@ -0,0 +1,141 @@
-+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+@file: sdlist.h
-+
-+@abstract: OS independent list functions
-+
-+@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 __SDLIST_H___
-+#define __SDLIST_H___
-+
-+/* list functions */
-+/* pointers for the list */
-+typedef struct _SDLIST {
-+ struct _SDLIST *pPrev;
-+ struct _SDLIST *pNext;
-+}SDLIST, *PSDLIST;
-+/*
-+ * SDLIST_INIT , circular list
-+*/
-+#define SDLIST_INIT(pList)\
-+ {(pList)->pPrev = pList; (pList)->pNext = pList;}
-+#define SDLIST_INIT_DECLARE(List)\
-+ SDLIST List = {&List, &List}
-+
-+
-+#define SDLIST_IS_EMPTY(pList) (((pList)->pPrev == (pList)) && ((pList)->pNext == (pList)))
-+#define SDLIST_GET_ITEM_AT_HEAD(pList) (pList)->pNext
-+#define SDLIST_GET_ITEM_AT_TAIL(pList) (pList)->pPrev
-+/*
-+ * SDITERATE_OVER_LIST pStart is the list, pTemp is a temp list member
-+ * NOT: do not use this function if the items in the list are deleted inside the
-+ * iteration loop
-+*/
-+#define SDITERATE_OVER_LIST(pStart, pTemp) \
-+ for((pTemp) =(pStart)->pNext; pTemp != (pStart); (pTemp) = (pTemp)->pNext)
-+
-+
-+/* safe iterate macro that allows the item to be removed from the list
-+ * the iteration continues to the next item in the list
-+ */
-+#define SDITERATE_OVER_LIST_ALLOW_REMOVE(pStart,pItem,st,offset) \
-+{ \
-+ PSDLIST pTemp; \
-+ pTemp = (pStart)->pNext; \
-+ while (pTemp != (pStart)) { \
-+ (pItem) = CONTAINING_STRUCT(pTemp,st,offset); \
-+ pTemp = pTemp->pNext; \
-+
-+#define SDITERATE_END }}
-+
-+/*
-+ * SDListInsertTail - insert pAdd to the end of the list
-+*/
-+static INLINE PSDLIST SDListInsertTail(PSDLIST pList, PSDLIST pAdd) {
-+ /* this assert catches when an item is added twice */
-+ DBG_ASSERT(pAdd->pNext != pList);
-+ /* insert at tail */
-+ pAdd->pPrev = pList->pPrev;
-+ pAdd->pNext = pList;
-+ pList->pPrev->pNext = pAdd;
-+ pList->pPrev = pAdd;
-+ return pAdd;
-+}
-+
-+/*
-+ * SDListInsertHead - insert pAdd into the head of the list
-+*/
-+static INLINE PSDLIST SDListInsertHead(PSDLIST pList, PSDLIST pAdd) {
-+ /* this assert catches when an item is added twice */
-+ DBG_ASSERT(pAdd->pPrev != pList);
-+ /* insert at head */
-+ pAdd->pPrev = pList;
-+ pAdd->pNext = pList->pNext;
-+ pList->pNext->pPrev = pAdd;
-+ pList->pNext = pAdd;
-+ return pAdd;
-+}
-+
-+#define SDListAdd(pList,pItem) SDListInsertHead((pList),(pItem))
-+/*
-+ * SDListRemove - remove pDel from list
-+*/
-+static INLINE PSDLIST SDListRemove(PSDLIST pDel) {
-+ pDel->pNext->pPrev = pDel->pPrev;
-+ pDel->pPrev->pNext = pDel->pNext;
-+ /* point back to itself just to be safe, incase remove is called again */
-+ pDel->pNext = pDel;
-+ pDel->pPrev = pDel;
-+ return pDel;
-+}
-+
-+/*
-+ * SDListRemoveItemFromHead - get a list item from the head
-+*/
-+static INLINE PSDLIST SDListRemoveItemFromHead(PSDLIST pList) {
-+ PSDLIST pItem = NULL;
-+ if (pList->pNext != pList) {
-+ pItem = pList->pNext;
-+ /* remove the first item from head */
-+ SDListRemove(pItem);
-+ }
-+ return pItem;
-+}
-+#endif /* __SDLIST_H___ */
---
-1.5.6.3
-