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