diff options
author | mokopatches <mokopatches@openmoko.org> | 2008-11-19 17:03:22 +0000 |
---|---|---|
committer | warmcat <andy@warmcat.com> | 2008-11-19 17:03:22 +0000 |
commit | e7ab2e913536616b9f17e3323a7f2b83e808a198 (patch) | |
tree | 7e56b72e9d8e1ac85e1624fd33c6218da983714c /include/linux | |
parent | 0a5a3e0ff3050d7baeeb40f50cf3ea7c174ef21e (diff) |
atheros_2_0_sdio_stack.patch
Diffstat (limited to 'include/linux')
-rw-r--r-- | include/linux/sdio/_sdio_defs.h | 638 | ||||
-rw-r--r-- | include/linux/sdio/ctsystem.h | 115 | ||||
-rw-r--r-- | include/linux/sdio/ctsystem_linux.h | 983 | ||||
-rw-r--r-- | include/linux/sdio/mmc_defs.h | 103 | ||||
-rw-r--r-- | include/linux/sdio/sdio_busdriver.h | 1435 | ||||
-rw-r--r-- | include/linux/sdio/sdio_hcd_defs.h | 219 | ||||
-rw-r--r-- | include/linux/sdio/sdio_lib.h | 270 | ||||
-rw-r--r-- | include/linux/sdio/sdlist.h | 141 |
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___ */ |