Wei Wang from Realsil contributed this driver in 2011. The following reasons lead to the removal: - This driver generates maintenance workload - Did not find minimal documentation on the web. - No blog entries about anyone using the rts5208 and rts5288 during the last years. - Did not find any device that may has it in and is still available on the market. Link: https://lore.kernel.org/linux-staging/2024100943-shank-washed-a765@gregkh/T/#t Signed-off-by: Philipp Hortmann <philipp.g.hortmann@xxxxxxxxx> --- Checked for artifacts of rts5208 in MAINTAINERS. Removed artifacts in Makefile and Kconfig. --- drivers/staging/Kconfig | 2 - drivers/staging/Makefile | 1 - drivers/staging/rts5208/Kconfig | 9 - drivers/staging/rts5208/Makefile | 5 - drivers/staging/rts5208/TODO | 7 - drivers/staging/rts5208/general.c | 25 - drivers/staging/rts5208/general.h | 19 - drivers/staging/rts5208/ms.c | 4311 -------------------- drivers/staging/rts5208/ms.h | 214 - drivers/staging/rts5208/rtsx.c | 987 ----- drivers/staging/rts5208/rtsx.h | 164 - drivers/staging/rts5208/rtsx_card.c | 1151 ------ drivers/staging/rts5208/rtsx_card.h | 1087 ----- drivers/staging/rts5208/rtsx_chip.c | 2161 ---------- drivers/staging/rts5208/rtsx_chip.h | 987 ----- drivers/staging/rts5208/rtsx_scsi.c | 3279 --------------- drivers/staging/rts5208/rtsx_scsi.h | 131 - drivers/staging/rts5208/rtsx_sys.h | 36 - drivers/staging/rts5208/rtsx_transport.c | 768 ---- drivers/staging/rts5208/rtsx_transport.h | 57 - drivers/staging/rts5208/sd.c | 4717 ---------------------- drivers/staging/rts5208/sd.h | 289 -- drivers/staging/rts5208/spi.c | 906 ----- drivers/staging/rts5208/spi.h | 52 - drivers/staging/rts5208/xd.c | 2145 ---------- drivers/staging/rts5208/xd.h | 176 - 26 files changed, 23686 deletions(-) delete mode 100644 drivers/staging/rts5208/Kconfig delete mode 100644 drivers/staging/rts5208/Makefile delete mode 100644 drivers/staging/rts5208/TODO delete mode 100644 drivers/staging/rts5208/general.c delete mode 100644 drivers/staging/rts5208/general.h delete mode 100644 drivers/staging/rts5208/ms.c delete mode 100644 drivers/staging/rts5208/ms.h delete mode 100644 drivers/staging/rts5208/rtsx.c delete mode 100644 drivers/staging/rts5208/rtsx.h delete mode 100644 drivers/staging/rts5208/rtsx_card.c delete mode 100644 drivers/staging/rts5208/rtsx_card.h delete mode 100644 drivers/staging/rts5208/rtsx_chip.c delete mode 100644 drivers/staging/rts5208/rtsx_chip.h delete mode 100644 drivers/staging/rts5208/rtsx_scsi.c delete mode 100644 drivers/staging/rts5208/rtsx_scsi.h delete mode 100644 drivers/staging/rts5208/rtsx_sys.h delete mode 100644 drivers/staging/rts5208/rtsx_transport.c delete mode 100644 drivers/staging/rts5208/rtsx_transport.h delete mode 100644 drivers/staging/rts5208/sd.c delete mode 100644 drivers/staging/rts5208/sd.h delete mode 100644 drivers/staging/rts5208/spi.c delete mode 100644 drivers/staging/rts5208/spi.h delete mode 100644 drivers/staging/rts5208/xd.c delete mode 100644 drivers/staging/rts5208/xd.h diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index fcdd559a8acf..027c566bbf85 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -30,8 +30,6 @@ source "drivers/staging/rtl8723bs/Kconfig" source "drivers/staging/rtl8712/Kconfig" -source "drivers/staging/rts5208/Kconfig" - source "drivers/staging/octeon/Kconfig" source "drivers/staging/vt6655/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 4a84c4848664..728d5f5e46c1 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -5,7 +5,6 @@ obj-y += media/ obj-$(CONFIG_FB_OLPC_DCON) += olpc_dcon/ obj-$(CONFIG_RTL8723BS) += rtl8723bs/ obj-$(CONFIG_R8712U) += rtl8712/ -obj-$(CONFIG_RTS5208) += rts5208/ obj-$(CONFIG_OCTEON_ETHERNET) += octeon/ obj-$(CONFIG_VT6655) += vt6655/ obj-$(CONFIG_VT6656) += vt6656/ diff --git a/drivers/staging/rts5208/Kconfig b/drivers/staging/rts5208/Kconfig deleted file mode 100644 index b864023d3ccb..000000000000 --- a/drivers/staging/rts5208/Kconfig +++ /dev/null @@ -1,9 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -config RTS5208 - tristate "Realtek PCI-E Card Reader RTS5208/5288 support" - depends on PCI && SCSI - help - Say Y here to include driver code to support the Realtek - PCI-E card reader rts5208/rts5288. - - If this driver is compiled as a module, it will be named rts5208. diff --git a/drivers/staging/rts5208/Makefile b/drivers/staging/rts5208/Makefile deleted file mode 100644 index 3c9e9797d3d9..000000000000 --- a/drivers/staging/rts5208/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -obj-$(CONFIG_RTS5208) := rts5208.o - -rts5208-y := rtsx.o rtsx_chip.o rtsx_transport.o rtsx_scsi.o \ - rtsx_card.o general.o sd.o xd.o ms.o spi.o diff --git a/drivers/staging/rts5208/TODO b/drivers/staging/rts5208/TODO deleted file mode 100644 index 9cec0d8dd0b6..000000000000 --- a/drivers/staging/rts5208/TODO +++ /dev/null @@ -1,7 +0,0 @@ -TODO: -- use kernel coding style -- checkpatch.pl fixes -- We will use the stack in drivers/mmc to implement - rts5208/5288 in the future - -Micky Ching <micky_ching@xxxxxxxxxxxxxx> diff --git a/drivers/staging/rts5208/general.c b/drivers/staging/rts5208/general.c deleted file mode 100644 index 0f912b011064..000000000000 --- a/drivers/staging/rts5208/general.c +++ /dev/null @@ -1,25 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Driver for Realtek PCI-Express card reader - * - * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. - * - * Author: - * Wei WANG (wei_wang@xxxxxxxxxxxxxx) - * Micky Ching (micky_ching@xxxxxxxxxxxxxx) - */ - -#include "general.h" - -int bit1cnt_long(u32 data) -{ - int i, cnt = 0; - - for (i = 0; i < 32; i++) { - if (data & 0x01) - cnt++; - data >>= 1; - } - return cnt; -} - diff --git a/drivers/staging/rts5208/general.h b/drivers/staging/rts5208/general.h deleted file mode 100644 index 53e2dbabf04b..000000000000 --- a/drivers/staging/rts5208/general.h +++ /dev/null @@ -1,19 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Driver for Realtek PCI-Express card reader - * - * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. - * - * Author: - * Wei WANG (wei_wang@xxxxxxxxxxxxxx) - * Micky Ching (micky_ching@xxxxxxxxxxxxxx) - */ - -#ifndef __RTSX_GENERAL_H -#define __RTSX_GENERAL_H - -#include "rtsx.h" - -int bit1cnt_long(u32 data); - -#endif /* __RTSX_GENERAL_H */ diff --git a/drivers/staging/rts5208/ms.c b/drivers/staging/rts5208/ms.c deleted file mode 100644 index bfeb5873bf3b..000000000000 --- a/drivers/staging/rts5208/ms.c +++ /dev/null @@ -1,4311 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Driver for Realtek PCI-Express card reader - * - * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. - * - * Author: - * Wei WANG (wei_wang@xxxxxxxxxxxxxx) - * Micky Ching (micky_ching@xxxxxxxxxxxxxx) - */ - -#include <linux/blkdev.h> -#include <linux/kthread.h> -#include <linux/sched.h> -#include <linux/vmalloc.h> - -#include "rtsx.h" -#include "ms.h" - -static inline void ms_set_err_code(struct rtsx_chip *chip, u8 err_code) -{ - struct ms_info *ms_card = &chip->ms_card; - - ms_card->err_code = err_code; -} - -static inline int ms_check_err_code(struct rtsx_chip *chip, u8 err_code) -{ - struct ms_info *ms_card = &chip->ms_card; - - return (ms_card->err_code == err_code); -} - -static int ms_parse_err_code(struct rtsx_chip *chip) -{ - return STATUS_FAIL; -} - -static int ms_transfer_tpc(struct rtsx_chip *chip, u8 trans_mode, - u8 tpc, u8 cnt, u8 cfg) -{ - struct ms_info *ms_card = &chip->ms_card; - int retval; - u8 *ptr; - - dev_dbg(rtsx_dev(chip), "%s: tpc = 0x%x\n", __func__, tpc); - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TPC, 0xFF, tpc); - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_BYTE_CNT, 0xFF, cnt); - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, cfg); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, - 0x01, PINGPONG_BUFFER); - - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, - 0xFF, MS_TRANSFER_START | trans_mode); - rtsx_add_cmd(chip, CHECK_REG_CMD, MS_TRANSFER, - MS_TRANSFER_END, MS_TRANSFER_END); - - rtsx_add_cmd(chip, READ_REG_CMD, MS_TRANS_CFG, 0, 0); - - retval = rtsx_send_cmd(chip, MS_CARD, 5000); - if (retval < 0) { - rtsx_clear_ms_error(chip); - ms_set_err_code(chip, MS_TO_ERROR); - return ms_parse_err_code(chip); - } - - ptr = rtsx_get_cmd_data(chip) + 1; - - if (!(tpc & 0x08)) { /* Read Packet */ - if (*ptr & MS_CRC16_ERR) { - ms_set_err_code(chip, MS_CRC16_ERROR); - return ms_parse_err_code(chip); - } - } else { /* Write Packet */ - if (CHK_MSPRO(ms_card) && !(*ptr & 0x80)) { - if (*ptr & (MS_INT_ERR | MS_INT_CMDNK)) { - ms_set_err_code(chip, MS_CMD_NK); - return ms_parse_err_code(chip); - } - } - } - - if (*ptr & MS_RDY_TIMEOUT) { - rtsx_clear_ms_error(chip); - ms_set_err_code(chip, MS_TO_ERROR); - return ms_parse_err_code(chip); - } - - return STATUS_SUCCESS; -} - -static int ms_transfer_data(struct rtsx_chip *chip, u8 trans_mode, - u8 tpc, u16 sec_cnt, u8 cfg, bool mode_2k, - int use_sg, void *buf, int buf_len) -{ - int retval; - u8 val, err_code = 0; - enum dma_data_direction dir; - - if (!buf || !buf_len) - return STATUS_FAIL; - - if (trans_mode == MS_TM_AUTO_READ) { - dir = DMA_FROM_DEVICE; - err_code = MS_FLASH_READ_ERROR; - } else if (trans_mode == MS_TM_AUTO_WRITE) { - dir = DMA_TO_DEVICE; - err_code = MS_FLASH_WRITE_ERROR; - } else { - return STATUS_FAIL; - } - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TPC, 0xFF, tpc); - rtsx_add_cmd(chip, WRITE_REG_CMD, - MS_SECTOR_CNT_H, 0xFF, (u8)(sec_cnt >> 8)); - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_SECTOR_CNT_L, 0xFF, (u8)sec_cnt); - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, cfg); - - if (mode_2k) { - rtsx_add_cmd(chip, WRITE_REG_CMD, - MS_CFG, MS_2K_SECTOR_MODE, MS_2K_SECTOR_MODE); - } else { - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_CFG, MS_2K_SECTOR_MODE, 0); - } - - trans_dma_enable(dir, chip, sec_cnt * 512, DMA_512); - - rtsx_add_cmd(chip, WRITE_REG_CMD, - MS_TRANSFER, 0xFF, MS_TRANSFER_START | trans_mode); - rtsx_add_cmd(chip, CHECK_REG_CMD, - MS_TRANSFER, MS_TRANSFER_END, MS_TRANSFER_END); - - rtsx_send_cmd_no_wait(chip); - - retval = rtsx_transfer_data(chip, MS_CARD, buf, buf_len, - use_sg, dir, chip->mspro_timeout); - if (retval < 0) { - ms_set_err_code(chip, err_code); - if (retval == -ETIMEDOUT) - retval = STATUS_TIMEDOUT; - else - retval = STATUS_FAIL; - - return retval; - } - - retval = rtsx_read_register(chip, MS_TRANS_CFG, &val); - if (retval) - return retval; - - if (val & (MS_INT_CMDNK | MS_INT_ERR | MS_CRC16_ERR | MS_RDY_TIMEOUT)) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} - -static int ms_write_bytes(struct rtsx_chip *chip, - u8 tpc, u8 cnt, u8 cfg, u8 *data, int data_len) -{ - struct ms_info *ms_card = &chip->ms_card; - int retval, i; - - if (!data || data_len < cnt) - return STATUS_ERROR; - - rtsx_init_cmd(chip); - - for (i = 0; i < cnt; i++) { - rtsx_add_cmd(chip, WRITE_REG_CMD, - PPBUF_BASE2 + i, 0xFF, data[i]); - } - if (cnt % 2) - rtsx_add_cmd(chip, WRITE_REG_CMD, PPBUF_BASE2 + i, 0xFF, 0xFF); - - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TPC, 0xFF, tpc); - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_BYTE_CNT, 0xFF, cnt); - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, cfg); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, - 0x01, PINGPONG_BUFFER); - - rtsx_add_cmd(chip, WRITE_REG_CMD, - MS_TRANSFER, 0xFF, MS_TRANSFER_START | MS_TM_WRITE_BYTES); - rtsx_add_cmd(chip, CHECK_REG_CMD, - MS_TRANSFER, MS_TRANSFER_END, MS_TRANSFER_END); - - retval = rtsx_send_cmd(chip, MS_CARD, 5000); - if (retval < 0) { - u8 val = 0; - - rtsx_read_register(chip, MS_TRANS_CFG, &val); - dev_dbg(rtsx_dev(chip), "MS_TRANS_CFG: 0x%02x\n", val); - - rtsx_clear_ms_error(chip); - - if (!(tpc & 0x08)) { - if (val & MS_CRC16_ERR) { - ms_set_err_code(chip, MS_CRC16_ERROR); - return ms_parse_err_code(chip); - } - } else { - if (CHK_MSPRO(ms_card) && !(val & 0x80)) { - if (val & (MS_INT_ERR | MS_INT_CMDNK)) { - ms_set_err_code(chip, MS_CMD_NK); - return ms_parse_err_code(chip); - } - } - } - - if (val & MS_RDY_TIMEOUT) { - ms_set_err_code(chip, MS_TO_ERROR); - return ms_parse_err_code(chip); - } - - ms_set_err_code(chip, MS_TO_ERROR); - return ms_parse_err_code(chip); - } - - return STATUS_SUCCESS; -} - -static int ms_read_bytes(struct rtsx_chip *chip, - u8 tpc, u8 cnt, u8 cfg, u8 *data, int data_len) -{ - struct ms_info *ms_card = &chip->ms_card; - int retval, i; - u8 *ptr; - - if (!data) - return STATUS_ERROR; - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TPC, 0xFF, tpc); - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_BYTE_CNT, 0xFF, cnt); - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, cfg); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, - 0x01, PINGPONG_BUFFER); - - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF, - MS_TRANSFER_START | MS_TM_READ_BYTES); - rtsx_add_cmd(chip, CHECK_REG_CMD, MS_TRANSFER, - MS_TRANSFER_END, MS_TRANSFER_END); - - for (i = 0; i < data_len - 1; i++) - rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + i, 0, 0); - - if (data_len % 2) - rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + data_len, 0, 0); - else - rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + data_len - 1, - 0, 0); - - retval = rtsx_send_cmd(chip, MS_CARD, 5000); - if (retval < 0) { - u8 val = 0; - - rtsx_read_register(chip, MS_TRANS_CFG, &val); - rtsx_clear_ms_error(chip); - - if (!(tpc & 0x08)) { - if (val & MS_CRC16_ERR) { - ms_set_err_code(chip, MS_CRC16_ERROR); - return ms_parse_err_code(chip); - } - } else { - if (CHK_MSPRO(ms_card) && !(val & 0x80)) { - if (val & (MS_INT_ERR | MS_INT_CMDNK)) { - ms_set_err_code(chip, MS_CMD_NK); - return ms_parse_err_code(chip); - } - } - } - - if (val & MS_RDY_TIMEOUT) { - ms_set_err_code(chip, MS_TO_ERROR); - return ms_parse_err_code(chip); - } - - ms_set_err_code(chip, MS_TO_ERROR); - return ms_parse_err_code(chip); - } - - ptr = rtsx_get_cmd_data(chip) + 1; - - for (i = 0; i < data_len; i++) - data[i] = ptr[i]; - - if (tpc == PRO_READ_SHORT_DATA && data_len == 8) { - dev_dbg(rtsx_dev(chip), "Read format progress:\n"); - print_hex_dump_bytes(KBUILD_MODNAME ": ", DUMP_PREFIX_NONE, ptr, - cnt); - } - - return STATUS_SUCCESS; -} - -static int ms_set_rw_reg_addr(struct rtsx_chip *chip, u8 read_start, - u8 read_cnt, u8 write_start, u8 write_cnt) -{ - int retval, i; - u8 data[4]; - - data[0] = read_start; - data[1] = read_cnt; - data[2] = write_start; - data[3] = write_cnt; - - for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { - retval = ms_write_bytes(chip, SET_RW_REG_ADRS, 4, - NO_WAIT_INT, data, 4); - if (retval == STATUS_SUCCESS) - return STATUS_SUCCESS; - rtsx_clear_ms_error(chip); - } - - return STATUS_FAIL; -} - -static int ms_send_cmd(struct rtsx_chip *chip, u8 cmd, u8 cfg) -{ - u8 data[2]; - - data[0] = cmd; - data[1] = 0; - - return ms_write_bytes(chip, PRO_SET_CMD, 1, cfg, data, 1); -} - -static int ms_set_init_para(struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &chip->ms_card; - int retval; - - if (CHK_HG8BIT(ms_card)) { - if (chip->asic_code) - ms_card->ms_clock = chip->asic_ms_hg_clk; - else - ms_card->ms_clock = chip->fpga_ms_hg_clk; - - } else if (CHK_MSPRO(ms_card) || CHK_MS4BIT(ms_card)) { - if (chip->asic_code) - ms_card->ms_clock = chip->asic_ms_4bit_clk; - else - ms_card->ms_clock = chip->fpga_ms_4bit_clk; - - } else { - if (chip->asic_code) - ms_card->ms_clock = chip->asic_ms_1bit_clk; - else - ms_card->ms_clock = chip->fpga_ms_1bit_clk; - } - - retval = switch_clock(chip, ms_card->ms_clock); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = select_card(chip, MS_CARD); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} - -static int ms_switch_clock(struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &chip->ms_card; - int retval; - - retval = select_card(chip, MS_CARD); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = switch_clock(chip, ms_card->ms_clock); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} - -static int ms_pull_ctl_disable(struct rtsx_chip *chip) -{ - int retval; - - if (CHECK_PID(chip, 0x5208)) { - retval = rtsx_write_register(chip, CARD_PULL_CTL1, 0xFF, - MS_D1_PD | MS_D2_PD | MS_CLK_PD | - MS_D6_PD); - if (retval) - return retval; - - retval = rtsx_write_register(chip, CARD_PULL_CTL2, 0xFF, - MS_D3_PD | MS_D0_PD | MS_BS_PD | - XD_D4_PD); - if (retval) - return retval; - - retval = rtsx_write_register(chip, CARD_PULL_CTL3, 0xFF, - MS_D7_PD | XD_CE_PD | XD_CLE_PD | - XD_CD_PU); - if (retval) - return retval; - - retval = rtsx_write_register(chip, CARD_PULL_CTL4, 0xFF, - XD_RDY_PD | SD_D3_PD | SD_D2_PD | - XD_ALE_PD); - if (retval) - return retval; - - retval = rtsx_write_register(chip, CARD_PULL_CTL5, 0xFF, - MS_INS_PU | SD_WP_PD | SD_CD_PU | - SD_CMD_PD); - if (retval) - return retval; - - retval = rtsx_write_register(chip, CARD_PULL_CTL6, 0xFF, - MS_D5_PD | MS_D4_PD); - if (retval) - return retval; - - } else if (CHECK_PID(chip, 0x5288)) { - if (CHECK_BARO_PKG(chip, QFN)) { - retval = rtsx_write_register(chip, CARD_PULL_CTL1, - 0xFF, 0x55); - if (retval) - return retval; - - retval = rtsx_write_register(chip, CARD_PULL_CTL2, - 0xFF, 0x55); - if (retval) - return retval; - - retval = rtsx_write_register(chip, CARD_PULL_CTL3, - 0xFF, 0x4B); - if (retval) - return retval; - - retval = rtsx_write_register(chip, CARD_PULL_CTL4, - 0xFF, 0x69); - if (retval) - return retval; - } - } - - return STATUS_SUCCESS; -} - -static int ms_pull_ctl_enable(struct rtsx_chip *chip) -{ - int retval; - - rtsx_init_cmd(chip); - - if (CHECK_PID(chip, 0x5208)) { - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, - MS_D1_PD | MS_D2_PD | MS_CLK_NP | MS_D6_PD); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, - MS_D3_PD | MS_D0_PD | MS_BS_NP | XD_D4_PD); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, - MS_D7_PD | XD_CE_PD | XD_CLE_PD | XD_CD_PU); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, - XD_RDY_PD | SD_D3_PD | SD_D2_PD | XD_ALE_PD); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF, - MS_INS_PU | SD_WP_PD | SD_CD_PU | SD_CMD_PD); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, - MS_D5_PD | MS_D4_PD); - } else if (CHECK_PID(chip, 0x5288)) { - if (CHECK_BARO_PKG(chip, QFN)) { - rtsx_add_cmd(chip, WRITE_REG_CMD, - CARD_PULL_CTL1, 0xFF, 0x55); - rtsx_add_cmd(chip, WRITE_REG_CMD, - CARD_PULL_CTL2, 0xFF, 0x45); - rtsx_add_cmd(chip, WRITE_REG_CMD, - CARD_PULL_CTL3, 0xFF, 0x4B); - rtsx_add_cmd(chip, WRITE_REG_CMD, - CARD_PULL_CTL4, 0xFF, 0x29); - } - } - - retval = rtsx_send_cmd(chip, MS_CARD, 100); - if (retval < 0) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} - -static int ms_prepare_reset(struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &chip->ms_card; - int retval; - u8 oc_mask = 0; - - ms_card->ms_type = 0; - ms_card->check_ms_flow = 0; - ms_card->switch_8bit_fail = 0; - ms_card->delay_write.delay_write_flag = 0; - - ms_card->pro_under_formatting = 0; - - retval = ms_power_off_card3v3(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (!chip->ft2_fast_mode) - wait_timeout(250); - - retval = enable_card_clock(chip, MS_CARD); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (chip->asic_code) { - retval = ms_pull_ctl_enable(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } else { - retval = rtsx_write_register(chip, FPGA_PULL_CTL, - FPGA_MS_PULL_CTL_BIT | 0x20, 0); - if (retval) - return retval; - } - - if (!chip->ft2_fast_mode) { - retval = card_power_on(chip, MS_CARD); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - wait_timeout(150); - -#ifdef SUPPORT_OCP - if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) - oc_mask = MS_OC_NOW | MS_OC_EVER; - else - oc_mask = SD_OC_NOW | SD_OC_EVER; - - if (chip->ocp_stat & oc_mask) { - dev_dbg(rtsx_dev(chip), "Over current, OCPSTAT is 0x%x\n", - chip->ocp_stat); - return STATUS_FAIL; - } -#endif - } - - retval = rtsx_write_register(chip, CARD_OE, MS_OUTPUT_EN, - MS_OUTPUT_EN); - if (retval) - return retval; - - if (chip->asic_code) { - retval = rtsx_write_register(chip, MS_CFG, 0xFF, - SAMPLE_TIME_RISING | - PUSH_TIME_DEFAULT | - NO_EXTEND_TOGGLE | - MS_BUS_WIDTH_1); - if (retval) - return retval; - - } else { - retval = rtsx_write_register(chip, MS_CFG, 0xFF, - SAMPLE_TIME_FALLING | - PUSH_TIME_DEFAULT | - NO_EXTEND_TOGGLE | - MS_BUS_WIDTH_1); - if (retval) - return retval; - } - retval = rtsx_write_register(chip, MS_TRANS_CFG, 0xFF, - NO_WAIT_INT | NO_AUTO_READ_INT_REG); - if (retval) - return retval; - - retval = rtsx_write_register(chip, CARD_STOP, MS_STOP | MS_CLR_ERR, - MS_STOP | MS_CLR_ERR); - if (retval) - return retval; - - retval = ms_set_init_para(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} - -static int ms_identify_media_type(struct rtsx_chip *chip, int switch_8bit_bus) -{ - struct ms_info *ms_card = &chip->ms_card; - int retval, i; - u8 val; - - retval = ms_set_rw_reg_addr(chip, PRO_STATUS_REG, 6, SYSTEM_PARAM, 1); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { - retval = ms_transfer_tpc(chip, MS_TM_READ_BYTES, READ_REG, - 6, NO_WAIT_INT); - if (retval == STATUS_SUCCESS) - break; - } - if (i == MS_MAX_RETRY_COUNT) - return STATUS_FAIL; - - retval = rtsx_read_register(chip, PPBUF_BASE2 + 2, &val); - if (retval) - return retval; - - dev_dbg(rtsx_dev(chip), "Type register: 0x%x\n", val); - if (val != 0x01) { - if (val != 0x02) - ms_card->check_ms_flow = 1; - - return STATUS_FAIL; - } - - retval = rtsx_read_register(chip, PPBUF_BASE2 + 4, &val); - if (retval) - return retval; - - dev_dbg(rtsx_dev(chip), "Category register: 0x%x\n", val); - if (val != 0) { - ms_card->check_ms_flow = 1; - return STATUS_FAIL; - } - - retval = rtsx_read_register(chip, PPBUF_BASE2 + 5, &val); - if (retval) - return retval; - - dev_dbg(rtsx_dev(chip), "Class register: 0x%x\n", val); - if (val == 0) { - retval = rtsx_read_register(chip, PPBUF_BASE2, &val); - if (retval) - return retval; - - if (val & WRT_PRTCT) - chip->card_wp |= MS_CARD; - else - chip->card_wp &= ~MS_CARD; - - } else if ((val == 0x01) || (val == 0x02) || (val == 0x03)) { - chip->card_wp |= MS_CARD; - } else { - ms_card->check_ms_flow = 1; - return STATUS_FAIL; - } - - ms_card->ms_type |= TYPE_MSPRO; - - retval = rtsx_read_register(chip, PPBUF_BASE2 + 3, &val); - if (retval) - return retval; - - dev_dbg(rtsx_dev(chip), "IF Mode register: 0x%x\n", val); - if (val == 0) { - ms_card->ms_type &= 0x0F; - } else if (val == 7) { - if (switch_8bit_bus) - ms_card->ms_type |= MS_HG; - else - ms_card->ms_type &= 0x0F; - - } else { - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -static int ms_confirm_cpu_startup(struct rtsx_chip *chip) -{ - int retval, i, k; - u8 val; - - /* Confirm CPU StartUp */ - k = 0; - do { - if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) { - ms_set_err_code(chip, MS_NO_CARD); - return STATUS_FAIL; - } - - for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { - retval = ms_read_bytes(chip, GET_INT, 1, - NO_WAIT_INT, &val, 1); - if (retval == STATUS_SUCCESS) - break; - } - if (i == MS_MAX_RETRY_COUNT) - return STATUS_FAIL; - - if (k > 100) - return STATUS_FAIL; - - k++; - wait_timeout(100); - } while (!(val & INT_REG_CED)); - - for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { - retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); - if (retval == STATUS_SUCCESS) - break; - } - if (i == MS_MAX_RETRY_COUNT) - return STATUS_FAIL; - - if (val & INT_REG_ERR) { - if (val & INT_REG_CMDNK) - chip->card_wp |= (MS_CARD); - else - return STATUS_FAIL; - } - /* -- end confirm CPU startup */ - - return STATUS_SUCCESS; -} - -static int ms_switch_parallel_bus(struct rtsx_chip *chip) -{ - int retval, i; - u8 data[2]; - - data[0] = PARALLEL_4BIT_IF; - data[1] = 0; - for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { - retval = ms_write_bytes(chip, WRITE_REG, 1, NO_WAIT_INT, - data, 2); - if (retval == STATUS_SUCCESS) - break; - } - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} - -static int ms_switch_8bit_bus(struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &chip->ms_card; - int retval, i; - u8 data[2]; - - data[0] = PARALLEL_8BIT_IF; - data[1] = 0; - for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { - retval = ms_write_bytes(chip, WRITE_REG, 1, - NO_WAIT_INT, data, 2); - if (retval == STATUS_SUCCESS) - break; - } - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = rtsx_write_register(chip, MS_CFG, 0x98, - MS_BUS_WIDTH_8 | SAMPLE_TIME_FALLING); - if (retval) - return retval; - - ms_card->ms_type |= MS_8BIT; - retval = ms_set_init_para(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { - retval = ms_transfer_tpc(chip, MS_TM_READ_BYTES, GET_INT, - 1, NO_WAIT_INT); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -static int ms_pro_reset_flow(struct rtsx_chip *chip, int switch_8bit_bus) -{ - struct ms_info *ms_card = &chip->ms_card; - int retval, i; - - for (i = 0; i < 3; i++) { - retval = ms_prepare_reset(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = ms_identify_media_type(chip, switch_8bit_bus); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = ms_confirm_cpu_startup(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = ms_switch_parallel_bus(chip); - if (retval != STATUS_SUCCESS) { - if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) { - ms_set_err_code(chip, MS_NO_CARD); - return STATUS_FAIL; - } - continue; - } else { - break; - } - } - - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - /* Switch MS-PRO into Parallel mode */ - retval = rtsx_write_register(chip, MS_CFG, 0x18, MS_BUS_WIDTH_4); - if (retval) - return retval; - - retval = rtsx_write_register(chip, MS_CFG, PUSH_TIME_ODD, - PUSH_TIME_ODD); - if (retval) - return retval; - - retval = ms_set_init_para(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - /* If MSPro HG Card, We shall try to switch to 8-bit bus */ - if (CHK_MSHG(ms_card) && chip->support_ms_8bit && switch_8bit_bus) { - retval = ms_switch_8bit_bus(chip); - if (retval != STATUS_SUCCESS) { - ms_card->switch_8bit_fail = 1; - return STATUS_FAIL; - } - } - - return STATUS_SUCCESS; -} - -#ifdef XC_POWERCLASS -static int msxc_change_power(struct rtsx_chip *chip, u8 mode) -{ - int retval; - u8 buf[6]; - - ms_cleanup_work(chip); - - retval = ms_set_rw_reg_addr(chip, 0, 0, PRO_DATA_COUNT1, 6); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - buf[0] = 0; - buf[1] = mode; - buf[2] = 0; - buf[3] = 0; - buf[4] = 0; - buf[5] = 0; - - retval = ms_write_bytes(chip, PRO_WRITE_REG, 6, NO_WAIT_INT, buf, 6); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = ms_send_cmd(chip, XC_CHG_POWER, WAIT_INT); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = rtsx_read_register(chip, MS_TRANS_CFG, buf); - if (retval) - return retval; - - if (buf[0] & (MS_INT_CMDNK | MS_INT_ERR)) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} -#endif - -static int ms_read_attribute_info(struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &chip->ms_card; - int retval, i; - u8 val, *buf, class_code, device_type, sub_class, data[16]; - u16 total_blk = 0, blk_size = 0; -#ifdef SUPPORT_MSXC - u32 xc_total_blk = 0, xc_blk_size = 0; -#endif - u32 sys_info_addr = 0, sys_info_size; -#ifdef SUPPORT_PCGL_1P18 - u32 model_name_addr = 0, model_name_size; - int found_sys_info = 0, found_model_name = 0; -#endif - - retval = ms_set_rw_reg_addr(chip, PRO_INT_REG, 2, PRO_SYSTEM_PARAM, 7); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (CHK_MS8BIT(ms_card)) - data[0] = PARALLEL_8BIT_IF; - else - data[0] = PARALLEL_4BIT_IF; - - data[1] = 0; - - data[2] = 0x40; - data[3] = 0; - data[4] = 0; - data[5] = 0; - data[6] = 0; - data[7] = 0; - - for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { - retval = ms_write_bytes(chip, PRO_WRITE_REG, 7, NO_WAIT_INT, - data, 8); - if (retval == STATUS_SUCCESS) - break; - } - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - buf = kmalloc(64 * 512, GFP_KERNEL); - if (!buf) - return STATUS_ERROR; - - for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { - retval = ms_send_cmd(chip, PRO_READ_ATRB, WAIT_INT); - if (retval != STATUS_SUCCESS) - continue; - - retval = rtsx_read_register(chip, MS_TRANS_CFG, &val); - if (retval != STATUS_SUCCESS) { - kfree(buf); - return STATUS_FAIL; - } - if (!(val & MS_INT_BREQ)) { - kfree(buf); - return STATUS_FAIL; - } - retval = ms_transfer_data(chip, MS_TM_AUTO_READ, - PRO_READ_LONG_DATA, 0x40, WAIT_INT, - 0, 0, buf, 64 * 512); - if (retval == STATUS_SUCCESS) - break; - - rtsx_clear_ms_error(chip); - } - if (retval != STATUS_SUCCESS) { - kfree(buf); - return STATUS_FAIL; - } - - i = 0; - do { - retval = rtsx_read_register(chip, MS_TRANS_CFG, &val); - if (retval != STATUS_SUCCESS) { - kfree(buf); - return STATUS_FAIL; - } - - if ((val & MS_INT_CED) || !(val & MS_INT_BREQ)) - break; - - retval = ms_transfer_tpc(chip, MS_TM_NORMAL_READ, - PRO_READ_LONG_DATA, 0, WAIT_INT); - if (retval != STATUS_SUCCESS) { - kfree(buf); - return STATUS_FAIL; - } - - i++; - } while (i < 1024); - - if (buf[0] != 0xa5 && buf[1] != 0xc3) { - /* Signature code is wrong */ - kfree(buf); - return STATUS_FAIL; - } - - if (buf[4] < 1 || buf[4] > 12) { - kfree(buf); - return STATUS_FAIL; - } - - for (i = 0; i < buf[4]; i++) { - int cur_addr_off = 16 + i * 12; - -#ifdef SUPPORT_MSXC - if (buf[cur_addr_off + 8] == 0x10 || - buf[cur_addr_off + 8] == 0x13) { -#else - if (buf[cur_addr_off + 8] == 0x10) { -#endif - sys_info_addr = ((u32)buf[cur_addr_off + 0] << 24) | - ((u32)buf[cur_addr_off + 1] << 16) | - ((u32)buf[cur_addr_off + 2] << 8) | - buf[cur_addr_off + 3]; - sys_info_size = ((u32)buf[cur_addr_off + 4] << 24) | - ((u32)buf[cur_addr_off + 5] << 16) | - ((u32)buf[cur_addr_off + 6] << 8) | - buf[cur_addr_off + 7]; - dev_dbg(rtsx_dev(chip), "sys_info_addr = 0x%x, sys_info_size = 0x%x\n", - sys_info_addr, sys_info_size); - if (sys_info_size != 96) { - kfree(buf); - return STATUS_FAIL; - } - if (sys_info_addr < 0x1A0) { - kfree(buf); - return STATUS_FAIL; - } - if ((sys_info_size + sys_info_addr) > 0x8000) { - kfree(buf); - return STATUS_FAIL; - } - -#ifdef SUPPORT_MSXC - if (buf[cur_addr_off + 8] == 0x13) - ms_card->ms_type |= MS_XC; -#endif -#ifdef SUPPORT_PCGL_1P18 - found_sys_info = 1; -#else - break; -#endif - } -#ifdef SUPPORT_PCGL_1P18 - if (buf[cur_addr_off + 8] == 0x15) { - model_name_addr = ((u32)buf[cur_addr_off + 0] << 24) | - ((u32)buf[cur_addr_off + 1] << 16) | - ((u32)buf[cur_addr_off + 2] << 8) | - buf[cur_addr_off + 3]; - model_name_size = ((u32)buf[cur_addr_off + 4] << 24) | - ((u32)buf[cur_addr_off + 5] << 16) | - ((u32)buf[cur_addr_off + 6] << 8) | - buf[cur_addr_off + 7]; - dev_dbg(rtsx_dev(chip), "model_name_addr = 0x%x, model_name_size = 0x%x\n", - model_name_addr, model_name_size); - if (model_name_size != 48) { - kfree(buf); - return STATUS_FAIL; - } - if (model_name_addr < 0x1A0) { - kfree(buf); - return STATUS_FAIL; - } - if ((model_name_size + model_name_addr) > 0x8000) { - kfree(buf); - return STATUS_FAIL; - } - - found_model_name = 1; - } - - if (found_sys_info && found_model_name) - break; -#endif - } - - if (i == buf[4]) { - kfree(buf); - return STATUS_FAIL; - } - - class_code = buf[sys_info_addr + 0]; - device_type = buf[sys_info_addr + 56]; - sub_class = buf[sys_info_addr + 46]; -#ifdef SUPPORT_MSXC - if (CHK_MSXC(ms_card)) { - xc_total_blk = ((u32)buf[sys_info_addr + 6] << 24) | - ((u32)buf[sys_info_addr + 7] << 16) | - ((u32)buf[sys_info_addr + 8] << 8) | - buf[sys_info_addr + 9]; - xc_blk_size = ((u32)buf[sys_info_addr + 32] << 24) | - ((u32)buf[sys_info_addr + 33] << 16) | - ((u32)buf[sys_info_addr + 34] << 8) | - buf[sys_info_addr + 35]; - dev_dbg(rtsx_dev(chip), "xc_total_blk = 0x%x, xc_blk_size = 0x%x\n", - xc_total_blk, xc_blk_size); - } else { - total_blk = ((u16)buf[sys_info_addr + 6] << 8) | - buf[sys_info_addr + 7]; - blk_size = ((u16)buf[sys_info_addr + 2] << 8) | - buf[sys_info_addr + 3]; - dev_dbg(rtsx_dev(chip), "total_blk = 0x%x, blk_size = 0x%x\n", - total_blk, blk_size); - } -#else - total_blk = ((u16)buf[sys_info_addr + 6] << 8) | buf[sys_info_addr + 7]; - blk_size = ((u16)buf[sys_info_addr + 2] << 8) | buf[sys_info_addr + 3]; - dev_dbg(rtsx_dev(chip), "total_blk = 0x%x, blk_size = 0x%x\n", - total_blk, blk_size); -#endif - - dev_dbg(rtsx_dev(chip), "class_code = 0x%x, device_type = 0x%x, sub_class = 0x%x\n", - class_code, device_type, sub_class); - - memcpy(ms_card->raw_sys_info, buf + sys_info_addr, 96); -#ifdef SUPPORT_PCGL_1P18 - memcpy(ms_card->raw_model_name, buf + model_name_addr, 48); -#endif - - kfree(buf); - -#ifdef SUPPORT_MSXC - if (CHK_MSXC(ms_card)) { - if (class_code != 0x03) - return STATUS_FAIL; - } else { - if (class_code != 0x02) - return STATUS_FAIL; - } -#else - if (class_code != 0x02) - return STATUS_FAIL; -#endif - - if (device_type != 0x00) { - if (device_type == 0x01 || device_type == 0x02 || - device_type == 0x03) { - chip->card_wp |= MS_CARD; - } else { - return STATUS_FAIL; - } - } - - if (sub_class & 0xC0) - return STATUS_FAIL; - - dev_dbg(rtsx_dev(chip), "class_code: 0x%x, device_type: 0x%x, sub_class: 0x%x\n", - class_code, device_type, sub_class); - -#ifdef SUPPORT_MSXC - if (CHK_MSXC(ms_card)) { - chip->capacity[chip->card2lun[MS_CARD]] = - ms_card->capacity = xc_total_blk * xc_blk_size; - } else { - chip->capacity[chip->card2lun[MS_CARD]] = - ms_card->capacity = total_blk * blk_size; - } -#else - ms_card->capacity = total_blk * blk_size; - chip->capacity[chip->card2lun[MS_CARD]] = ms_card->capacity; -#endif - - return STATUS_SUCCESS; -} - -#ifdef SUPPORT_MAGIC_GATE -static int mg_set_tpc_para_sub(struct rtsx_chip *chip, - int type, u8 mg_entry_num); -#endif - -static int reset_ms_pro(struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &chip->ms_card; - int retval; -#ifdef XC_POWERCLASS - u8 change_power_class; - - if (chip->ms_power_class_en & 0x02) - change_power_class = 2; - else if (chip->ms_power_class_en & 0x01) - change_power_class = 1; - else - change_power_class = 0; -#endif - -#ifdef XC_POWERCLASS -retry: -#endif - retval = ms_pro_reset_flow(chip, 1); - if (retval != STATUS_SUCCESS) { - if (ms_card->switch_8bit_fail) { - retval = ms_pro_reset_flow(chip, 0); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } else { - return STATUS_FAIL; - } - } - - retval = ms_read_attribute_info(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - -#ifdef XC_POWERCLASS - if (CHK_HG8BIT(ms_card)) - change_power_class = 0; - - if (change_power_class && CHK_MSXC(ms_card)) { - u8 power_class_en = chip->ms_power_class_en; - - dev_dbg(rtsx_dev(chip), "power_class_en = 0x%x\n", - power_class_en); - dev_dbg(rtsx_dev(chip), "change_power_class = %d\n", - change_power_class); - - if (change_power_class) - power_class_en &= (1 << (change_power_class - 1)); - else - power_class_en = 0; - - if (power_class_en) { - u8 power_class_mode = - (ms_card->raw_sys_info[46] & 0x18) >> 3; - dev_dbg(rtsx_dev(chip), "power_class_mode = 0x%x", - power_class_mode); - if (change_power_class > power_class_mode) - change_power_class = power_class_mode; - if (change_power_class) { - retval = msxc_change_power(chip, - change_power_class); - if (retval != STATUS_SUCCESS) { - change_power_class--; - goto retry; - } - } - } - } -#endif - -#ifdef SUPPORT_MAGIC_GATE - retval = mg_set_tpc_para_sub(chip, 0, 0); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; -#endif - - if (CHK_HG8BIT(ms_card)) - chip->card_bus_width[chip->card2lun[MS_CARD]] = 8; - else - chip->card_bus_width[chip->card2lun[MS_CARD]] = 4; - - return STATUS_SUCCESS; -} - -static int ms_read_status_reg(struct rtsx_chip *chip) -{ - int retval; - u8 val[2]; - - retval = ms_set_rw_reg_addr(chip, STATUS_REG0, 2, 0, 0); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = ms_read_bytes(chip, READ_REG, 2, NO_WAIT_INT, val, 2); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (val[1] & (STS_UCDT | STS_UCEX | STS_UCFG)) { - ms_set_err_code(chip, MS_FLASH_READ_ERROR); - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -static int ms_read_extra_data(struct rtsx_chip *chip, - u16 block_addr, u8 page_num, u8 *buf, int buf_len) -{ - struct ms_info *ms_card = &chip->ms_card; - int retval, i; - u8 val, data[10]; - - retval = ms_set_rw_reg_addr(chip, OVERWRITE_FLAG, MS_EXTRA_SIZE, - SYSTEM_PARAM, 6); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (CHK_MS4BIT(ms_card)) { - /* Parallel interface */ - data[0] = 0x88; - } else { - /* Serial interface */ - data[0] = 0x80; - } - data[1] = 0; - data[2] = (u8)(block_addr >> 8); - data[3] = (u8)block_addr; - data[4] = 0x40; - data[5] = page_num; - - for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { - retval = ms_write_bytes(chip, WRITE_REG, 6, NO_WAIT_INT, - data, 6); - if (retval == STATUS_SUCCESS) - break; - } - if (i == MS_MAX_RETRY_COUNT) - return STATUS_FAIL; - - ms_set_err_code(chip, MS_NO_ERROR); - - for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { - retval = ms_send_cmd(chip, BLOCK_READ, WAIT_INT); - if (retval == STATUS_SUCCESS) - break; - } - if (i == MS_MAX_RETRY_COUNT) - return STATUS_FAIL; - - ms_set_err_code(chip, MS_NO_ERROR); - retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (val & INT_REG_CMDNK) { - ms_set_err_code(chip, MS_CMD_NK); - return STATUS_FAIL; - } - if (val & INT_REG_CED) { - if (val & INT_REG_ERR) { - retval = ms_read_status_reg(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = ms_set_rw_reg_addr(chip, OVERWRITE_FLAG, - MS_EXTRA_SIZE, SYSTEM_PARAM, - 6); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - } - - retval = ms_read_bytes(chip, READ_REG, MS_EXTRA_SIZE, NO_WAIT_INT, - data, MS_EXTRA_SIZE); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (buf && buf_len) { - if (buf_len > MS_EXTRA_SIZE) - buf_len = MS_EXTRA_SIZE; - memcpy(buf, data, buf_len); - } - - return STATUS_SUCCESS; -} - -static int ms_write_extra_data(struct rtsx_chip *chip, u16 block_addr, - u8 page_num, u8 *buf, int buf_len) -{ - struct ms_info *ms_card = &chip->ms_card; - int retval, i; - u8 val, data[16]; - - if (!buf || buf_len < MS_EXTRA_SIZE) - return STATUS_FAIL; - - retval = ms_set_rw_reg_addr(chip, OVERWRITE_FLAG, MS_EXTRA_SIZE, - SYSTEM_PARAM, 6 + MS_EXTRA_SIZE); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (CHK_MS4BIT(ms_card)) - data[0] = 0x88; - else - data[0] = 0x80; - - data[1] = 0; - data[2] = (u8)(block_addr >> 8); - data[3] = (u8)block_addr; - data[4] = 0x40; - data[5] = page_num; - - for (i = 6; i < MS_EXTRA_SIZE + 6; i++) - data[i] = buf[i - 6]; - - retval = ms_write_bytes(chip, WRITE_REG, (6 + MS_EXTRA_SIZE), - NO_WAIT_INT, data, 16); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = ms_send_cmd(chip, BLOCK_WRITE, WAIT_INT); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - ms_set_err_code(chip, MS_NO_ERROR); - retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (val & INT_REG_CMDNK) { - ms_set_err_code(chip, MS_CMD_NK); - return STATUS_FAIL; - } - if (val & INT_REG_CED) { - if (val & INT_REG_ERR) { - ms_set_err_code(chip, MS_FLASH_WRITE_ERROR); - return STATUS_FAIL; - } - } - - return STATUS_SUCCESS; -} - -static int ms_read_page(struct rtsx_chip *chip, u16 block_addr, u8 page_num) -{ - struct ms_info *ms_card = &chip->ms_card; - int retval; - u8 val, data[6]; - - retval = ms_set_rw_reg_addr(chip, OVERWRITE_FLAG, MS_EXTRA_SIZE, - SYSTEM_PARAM, 6); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (CHK_MS4BIT(ms_card)) - data[0] = 0x88; - else - data[0] = 0x80; - - data[1] = 0; - data[2] = (u8)(block_addr >> 8); - data[3] = (u8)block_addr; - data[4] = 0x20; - data[5] = page_num; - - retval = ms_write_bytes(chip, WRITE_REG, 6, NO_WAIT_INT, data, 6); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = ms_send_cmd(chip, BLOCK_READ, WAIT_INT); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - ms_set_err_code(chip, MS_NO_ERROR); - retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (val & INT_REG_CMDNK) { - ms_set_err_code(chip, MS_CMD_NK); - return STATUS_FAIL; - } - - if (val & INT_REG_CED) { - if (val & INT_REG_ERR) { - if (!(val & INT_REG_BREQ)) { - ms_set_err_code(chip, MS_FLASH_READ_ERROR); - return STATUS_FAIL; - } - retval = ms_read_status_reg(chip); - if (retval != STATUS_SUCCESS) - ms_set_err_code(chip, MS_FLASH_WRITE_ERROR); - - } else { - if (!(val & INT_REG_BREQ)) { - ms_set_err_code(chip, MS_BREQ_ERROR); - return STATUS_FAIL; - } - } - } - - retval = ms_transfer_tpc(chip, MS_TM_NORMAL_READ, READ_PAGE_DATA, - 0, NO_WAIT_INT); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (ms_check_err_code(chip, MS_FLASH_WRITE_ERROR)) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} - -static int ms_set_bad_block(struct rtsx_chip *chip, u16 phy_blk) -{ - struct ms_info *ms_card = &chip->ms_card; - int retval; - u8 val, data[8], extra[MS_EXTRA_SIZE]; - - retval = ms_read_extra_data(chip, phy_blk, 0, extra, MS_EXTRA_SIZE); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = ms_set_rw_reg_addr(chip, OVERWRITE_FLAG, MS_EXTRA_SIZE, - SYSTEM_PARAM, 7); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - ms_set_err_code(chip, MS_NO_ERROR); - - if (CHK_MS4BIT(ms_card)) - data[0] = 0x88; - else - data[0] = 0x80; - - data[1] = 0; - data[2] = (u8)(phy_blk >> 8); - data[3] = (u8)phy_blk; - data[4] = 0x80; - data[5] = 0; - data[6] = extra[0] & 0x7F; - data[7] = 0xFF; - - retval = ms_write_bytes(chip, WRITE_REG, 7, NO_WAIT_INT, data, 7); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = ms_send_cmd(chip, BLOCK_WRITE, WAIT_INT); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - ms_set_err_code(chip, MS_NO_ERROR); - retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (val & INT_REG_CMDNK) { - ms_set_err_code(chip, MS_CMD_NK); - return STATUS_FAIL; - } - - if (val & INT_REG_CED) { - if (val & INT_REG_ERR) { - ms_set_err_code(chip, MS_FLASH_WRITE_ERROR); - return STATUS_FAIL; - } - } - - return STATUS_SUCCESS; -} - -static int ms_erase_block(struct rtsx_chip *chip, u16 phy_blk) -{ - struct ms_info *ms_card = &chip->ms_card; - int retval, i = 0; - u8 val, data[6]; - - retval = ms_set_rw_reg_addr(chip, OVERWRITE_FLAG, MS_EXTRA_SIZE, - SYSTEM_PARAM, 6); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - ms_set_err_code(chip, MS_NO_ERROR); - - if (CHK_MS4BIT(ms_card)) - data[0] = 0x88; - else - data[0] = 0x80; - - data[1] = 0; - data[2] = (u8)(phy_blk >> 8); - data[3] = (u8)phy_blk; - data[4] = 0; - data[5] = 0; - - retval = ms_write_bytes(chip, WRITE_REG, 6, NO_WAIT_INT, data, 6); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - -ERASE_RTY: - retval = ms_send_cmd(chip, BLOCK_ERASE, WAIT_INT); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - ms_set_err_code(chip, MS_NO_ERROR); - retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (val & INT_REG_CMDNK) { - if (i < 3) { - i++; - goto ERASE_RTY; - } - - ms_set_err_code(chip, MS_CMD_NK); - ms_set_bad_block(chip, phy_blk); - return STATUS_FAIL; - } - - if (val & INT_REG_CED) { - if (val & INT_REG_ERR) { - ms_set_err_code(chip, MS_FLASH_WRITE_ERROR); - return STATUS_FAIL; - } - } - - return STATUS_SUCCESS; -} - -static void ms_set_page_status(u16 log_blk, u8 type, u8 *extra, int extra_len) -{ - if (!extra || extra_len < MS_EXTRA_SIZE) - return; - - memset(extra, 0xFF, MS_EXTRA_SIZE); - - if (type == set_PS_NG) { - /* set page status as 1:NG,and block status keep 1:OK */ - extra[0] = 0xB8; - } else { - /* set page status as 0:Data Error,and block status keep 1:OK */ - extra[0] = 0x98; - } - - extra[2] = (u8)(log_blk >> 8); - extra[3] = (u8)log_blk; -} - -static int ms_init_page(struct rtsx_chip *chip, u16 phy_blk, u16 log_blk, - u8 start_page, u8 end_page) -{ - int retval; - u8 extra[MS_EXTRA_SIZE], i; - - memset(extra, 0xff, MS_EXTRA_SIZE); - - extra[0] = 0xf8; /* Block, page OK, data erased */ - extra[1] = 0xff; - extra[2] = (u8)(log_blk >> 8); - extra[3] = (u8)log_blk; - - for (i = start_page; i < end_page; i++) { - if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) { - ms_set_err_code(chip, MS_NO_CARD); - return STATUS_FAIL; - } - - retval = ms_write_extra_data(chip, phy_blk, i, - extra, MS_EXTRA_SIZE); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -static int ms_copy_page(struct rtsx_chip *chip, u16 old_blk, u16 new_blk, - u16 log_blk, u8 start_page, u8 end_page) -{ - struct ms_info *ms_card = &chip->ms_card; - bool uncorrect_flag = false; - int retval, rty_cnt; - u8 extra[MS_EXTRA_SIZE], val, i, j, data[16]; - - dev_dbg(rtsx_dev(chip), "Copy page from 0x%x to 0x%x, logical block is 0x%x\n", - old_blk, new_blk, log_blk); - dev_dbg(rtsx_dev(chip), "start_page = %d, end_page = %d\n", - start_page, end_page); - - retval = ms_read_extra_data(chip, new_blk, 0, extra, MS_EXTRA_SIZE); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = ms_read_status_reg(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = rtsx_read_register(chip, PPBUF_BASE2, &val); - if (retval) - return retval; - - if (val & BUF_FULL) { - retval = ms_send_cmd(chip, CLEAR_BUF, WAIT_INT); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (!(val & INT_REG_CED)) { - ms_set_err_code(chip, MS_FLASH_WRITE_ERROR); - return STATUS_FAIL; - } - } - - for (i = start_page; i < end_page; i++) { - if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) { - ms_set_err_code(chip, MS_NO_CARD); - return STATUS_FAIL; - } - - retval = ms_read_extra_data(chip, old_blk, i, extra, - MS_EXTRA_SIZE); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = ms_set_rw_reg_addr(chip, OVERWRITE_FLAG, - MS_EXTRA_SIZE, SYSTEM_PARAM, 6); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - ms_set_err_code(chip, MS_NO_ERROR); - - if (CHK_MS4BIT(ms_card)) - data[0] = 0x88; - else - data[0] = 0x80; - - data[1] = 0; - data[2] = (u8)(old_blk >> 8); - data[3] = (u8)old_blk; - data[4] = 0x20; - data[5] = i; - - retval = ms_write_bytes(chip, WRITE_REG, 6, NO_WAIT_INT, - data, 6); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = ms_send_cmd(chip, BLOCK_READ, WAIT_INT); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - ms_set_err_code(chip, MS_NO_ERROR); - retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (val & INT_REG_CMDNK) { - ms_set_err_code(chip, MS_CMD_NK); - return STATUS_FAIL; - } - - if (val & INT_REG_CED) { - if (val & INT_REG_ERR) { - retval = ms_read_status_reg(chip); - if (retval != STATUS_SUCCESS) { - uncorrect_flag = true; - dev_dbg(rtsx_dev(chip), "Uncorrectable error\n"); - } else { - uncorrect_flag = false; - } - - retval = ms_transfer_tpc(chip, - MS_TM_NORMAL_READ, - READ_PAGE_DATA, - 0, NO_WAIT_INT); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (uncorrect_flag) { - ms_set_page_status(log_blk, set_PS_NG, - extra, - MS_EXTRA_SIZE); - if (i == 0) - extra[0] &= 0xEF; - - ms_write_extra_data(chip, old_blk, i, - extra, - MS_EXTRA_SIZE); - dev_dbg(rtsx_dev(chip), "page %d : extra[0] = 0x%x\n", - i, extra[0]); - MS_SET_BAD_BLOCK_FLG(ms_card); - - ms_set_page_status(log_blk, - set_PS_error, extra, - MS_EXTRA_SIZE); - ms_write_extra_data(chip, new_blk, i, - extra, - MS_EXTRA_SIZE); - continue; - } - - for (rty_cnt = 0; rty_cnt < MS_MAX_RETRY_COUNT; - rty_cnt++) { - retval = ms_transfer_tpc(chip, - MS_TM_NORMAL_WRITE, - WRITE_PAGE_DATA, - 0, NO_WAIT_INT); - if (retval == STATUS_SUCCESS) - break; - } - if (rty_cnt == MS_MAX_RETRY_COUNT) - return STATUS_FAIL; - } - - if (!(val & INT_REG_BREQ)) { - ms_set_err_code(chip, MS_BREQ_ERROR); - return STATUS_FAIL; - } - } - - retval = ms_set_rw_reg_addr(chip, OVERWRITE_FLAG, MS_EXTRA_SIZE, - SYSTEM_PARAM, (6 + MS_EXTRA_SIZE)); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - ms_set_err_code(chip, MS_NO_ERROR); - - if (CHK_MS4BIT(ms_card)) - data[0] = 0x88; - else - data[0] = 0x80; - - data[1] = 0; - data[2] = (u8)(new_blk >> 8); - data[3] = (u8)new_blk; - data[4] = 0x20; - data[5] = i; - - if ((extra[0] & 0x60) != 0x60) - data[6] = extra[0]; - else - data[6] = 0xF8; - - data[6 + 1] = 0xFF; - data[6 + 2] = (u8)(log_blk >> 8); - data[6 + 3] = (u8)log_blk; - - for (j = 4; j <= MS_EXTRA_SIZE; j++) - data[6 + j] = 0xFF; - - retval = ms_write_bytes(chip, WRITE_REG, (6 + MS_EXTRA_SIZE), - NO_WAIT_INT, data, 16); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = ms_send_cmd(chip, BLOCK_WRITE, WAIT_INT); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - ms_set_err_code(chip, MS_NO_ERROR); - retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (val & INT_REG_CMDNK) { - ms_set_err_code(chip, MS_CMD_NK); - return STATUS_FAIL; - } - - if (val & INT_REG_CED) { - if (val & INT_REG_ERR) { - ms_set_err_code(chip, MS_FLASH_WRITE_ERROR); - return STATUS_FAIL; - } - } - - if (i == 0) { - retval = ms_set_rw_reg_addr(chip, OVERWRITE_FLAG, - MS_EXTRA_SIZE, SYSTEM_PARAM, - 7); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - ms_set_err_code(chip, MS_NO_ERROR); - - if (CHK_MS4BIT(ms_card)) - data[0] = 0x88; - else - data[0] = 0x80; - - data[1] = 0; - data[2] = (u8)(old_blk >> 8); - data[3] = (u8)old_blk; - data[4] = 0x80; - data[5] = 0; - data[6] = 0xEF; - data[7] = 0xFF; - - retval = ms_write_bytes(chip, WRITE_REG, 7, - NO_WAIT_INT, data, 8); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = ms_send_cmd(chip, BLOCK_WRITE, WAIT_INT); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - ms_set_err_code(chip, MS_NO_ERROR); - retval = ms_read_bytes(chip, GET_INT, 1, - NO_WAIT_INT, &val, 1); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (val & INT_REG_CMDNK) { - ms_set_err_code(chip, MS_CMD_NK); - return STATUS_FAIL; - } - - if (val & INT_REG_CED) { - if (val & INT_REG_ERR) { - ms_set_err_code(chip, - MS_FLASH_WRITE_ERROR); - return STATUS_FAIL; - } - } - } - } - - return STATUS_SUCCESS; -} - -static int reset_ms(struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &chip->ms_card; - int retval; - u16 i, reg_addr, block_size; - u8 val, extra[MS_EXTRA_SIZE], j, *ptr; -#ifndef SUPPORT_MAGIC_GATE - u16 eblock_cnt; -#endif - - retval = ms_prepare_reset(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - ms_card->ms_type |= TYPE_MS; - - retval = ms_send_cmd(chip, MS_RESET, NO_WAIT_INT); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = ms_read_status_reg(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = rtsx_read_register(chip, PPBUF_BASE2, &val); - if (retval) - return retval; - - if (val & WRT_PRTCT) - chip->card_wp |= MS_CARD; - else - chip->card_wp &= ~MS_CARD; - - i = 0; - -RE_SEARCH: - /* Search Boot Block */ - while (i < (MAX_DEFECTIVE_BLOCK + 2)) { - if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) { - ms_set_err_code(chip, MS_NO_CARD); - return STATUS_FAIL; - } - - retval = ms_read_extra_data(chip, i, 0, extra, MS_EXTRA_SIZE); - if (retval != STATUS_SUCCESS) { - i++; - continue; - } - - if (extra[0] & BLOCK_OK) { - if (!(extra[1] & NOT_BOOT_BLOCK)) { - ms_card->boot_block = i; - break; - } - } - i++; - } - - if (i == (MAX_DEFECTIVE_BLOCK + 2)) { - dev_dbg(rtsx_dev(chip), "No boot block found!"); - return STATUS_FAIL; - } - - for (j = 0; j < 3; j++) { - retval = ms_read_page(chip, ms_card->boot_block, j); - if (retval != STATUS_SUCCESS) { - if (ms_check_err_code(chip, MS_FLASH_WRITE_ERROR)) { - i = ms_card->boot_block + 1; - ms_set_err_code(chip, MS_NO_ERROR); - goto RE_SEARCH; - } - } - } - - retval = ms_read_page(chip, ms_card->boot_block, 0); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - /* Read MS system information as sys_info */ - rtsx_init_cmd(chip); - - for (i = 0; i < 96; i++) - rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + 0x1A0 + i, 0, 0); - - retval = rtsx_send_cmd(chip, MS_CARD, 100); - if (retval < 0) - return STATUS_FAIL; - - ptr = rtsx_get_cmd_data(chip); - memcpy(ms_card->raw_sys_info, ptr, 96); - - /* Read useful block contents */ - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, READ_REG_CMD, HEADER_ID0, 0, 0); - rtsx_add_cmd(chip, READ_REG_CMD, HEADER_ID1, 0, 0); - - for (reg_addr = DISABLED_BLOCK0; reg_addr <= DISABLED_BLOCK3; - reg_addr++) - rtsx_add_cmd(chip, READ_REG_CMD, reg_addr, 0, 0); - - for (reg_addr = BLOCK_SIZE_0; reg_addr <= PAGE_SIZE_1; reg_addr++) - rtsx_add_cmd(chip, READ_REG_CMD, reg_addr, 0, 0); - - rtsx_add_cmd(chip, READ_REG_CMD, MS_device_type, 0, 0); - rtsx_add_cmd(chip, READ_REG_CMD, MS_4bit_support, 0, 0); - - retval = rtsx_send_cmd(chip, MS_CARD, 100); - if (retval < 0) - return STATUS_FAIL; - - ptr = rtsx_get_cmd_data(chip); - - dev_dbg(rtsx_dev(chip), "Boot block data:\n"); - dev_dbg(rtsx_dev(chip), "%*ph\n", 16, ptr); - - /* Block ID error - * HEADER_ID0, HEADER_ID1 - */ - if (ptr[0] != 0x00 || ptr[1] != 0x01) { - i = ms_card->boot_block + 1; - goto RE_SEARCH; - } - - /* Page size error - * PAGE_SIZE_0, PAGE_SIZE_1 - */ - if (ptr[12] != 0x02 || ptr[13] != 0x00) { - i = ms_card->boot_block + 1; - goto RE_SEARCH; - } - - if (ptr[14] == 1 || ptr[14] == 3) - chip->card_wp |= MS_CARD; - - /* BLOCK_SIZE_0, BLOCK_SIZE_1 */ - block_size = ((u16)ptr[6] << 8) | ptr[7]; - if (block_size == 0x0010) { - /* Block size 16KB */ - ms_card->block_shift = 5; - ms_card->page_off = 0x1F; - } else if (block_size == 0x0008) { - /* Block size 8KB */ - ms_card->block_shift = 4; - ms_card->page_off = 0x0F; - } - - /* BLOCK_COUNT_0, BLOCK_COUNT_1 */ - ms_card->total_block = ((u16)ptr[8] << 8) | ptr[9]; - -#ifdef SUPPORT_MAGIC_GATE - j = ptr[10]; - - if (ms_card->block_shift == 4) { /* 4MB or 8MB */ - if (j < 2) { /* Effective block for 4MB: 0x1F0 */ - ms_card->capacity = 0x1EE0; - } else { /* Effective block for 8MB: 0x3E0 */ - ms_card->capacity = 0x3DE0; - } - } else { /* 16MB, 32MB, 64MB or 128MB */ - if (j < 5) { /* Effective block for 16MB: 0x3E0 */ - ms_card->capacity = 0x7BC0; - } else if (j < 0xA) { /* Effective block for 32MB: 0x7C0 */ - ms_card->capacity = 0xF7C0; - } else if (j < 0x11) { /* Effective block for 64MB: 0xF80 */ - ms_card->capacity = 0x1EF80; - } else { /* Effective block for 128MB: 0x1F00 */ - ms_card->capacity = 0x3DF00; - } - } -#else - /* EBLOCK_COUNT_0, EBLOCK_COUNT_1 */ - eblock_cnt = ((u16)ptr[10] << 8) | ptr[11]; - - ms_card->capacity = ((u32)eblock_cnt - 2) << ms_card->block_shift; -#endif - - chip->capacity[chip->card2lun[MS_CARD]] = ms_card->capacity; - - /* Switch I/F Mode */ - if (ptr[15]) { - retval = ms_set_rw_reg_addr(chip, 0, 0, SYSTEM_PARAM, 1); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = rtsx_write_register(chip, PPBUF_BASE2, 0xFF, 0x88); - if (retval) - return retval; - - retval = rtsx_write_register(chip, PPBUF_BASE2 + 1, 0xFF, 0); - if (retval) - return retval; - - retval = ms_transfer_tpc(chip, MS_TM_WRITE_BYTES, WRITE_REG, 1, - NO_WAIT_INT); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = rtsx_write_register(chip, MS_CFG, - 0x58 | MS_NO_CHECK_INT, - MS_BUS_WIDTH_4 | - PUSH_TIME_ODD | - MS_NO_CHECK_INT); - if (retval) - return retval; - - ms_card->ms_type |= MS_4BIT; - } - - if (CHK_MS4BIT(ms_card)) - chip->card_bus_width[chip->card2lun[MS_CARD]] = 4; - else - chip->card_bus_width[chip->card2lun[MS_CARD]] = 1; - - return STATUS_SUCCESS; -} - -static int ms_init_l2p_tbl(struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &chip->ms_card; - int size, i, seg_no, retval; - u16 defect_block, reg_addr; - u8 val1, val2; - - ms_card->segment_cnt = ms_card->total_block >> 9; - dev_dbg(rtsx_dev(chip), "ms_card->segment_cnt = %d\n", - ms_card->segment_cnt); - - size = ms_card->segment_cnt * sizeof(struct zone_entry); - ms_card->segment = vzalloc(size); - if (!ms_card->segment) - return STATUS_FAIL; - - retval = ms_read_page(chip, ms_card->boot_block, 1); - if (retval != STATUS_SUCCESS) - goto INIT_FAIL; - - reg_addr = PPBUF_BASE2; - for (i = 0; i < (((ms_card->total_block >> 9) * 10) + 1); i++) { - int block_no; - - retval = rtsx_read_register(chip, reg_addr++, &val1); - if (retval != STATUS_SUCCESS) - goto INIT_FAIL; - - retval = rtsx_read_register(chip, reg_addr++, &val2); - if (retval != STATUS_SUCCESS) - goto INIT_FAIL; - - defect_block = ((u16)val1 << 8) | val2; - if (defect_block == 0xFFFF) - break; - - seg_no = defect_block / 512; - - block_no = ms_card->segment[seg_no].disable_count++; - ms_card->segment[seg_no].defect_list[block_no] = defect_block; - } - - for (i = 0; i < ms_card->segment_cnt; i++) { - ms_card->segment[i].build_flag = 0; - ms_card->segment[i].l2p_table = NULL; - ms_card->segment[i].free_table = NULL; - ms_card->segment[i].get_index = 0; - ms_card->segment[i].set_index = 0; - ms_card->segment[i].unused_blk_cnt = 0; - - dev_dbg(rtsx_dev(chip), "defective block count of segment %d is %d\n", - i, ms_card->segment[i].disable_count); - } - - return STATUS_SUCCESS; - -INIT_FAIL: - vfree(ms_card->segment); - ms_card->segment = NULL; - - return STATUS_FAIL; -} - -static u16 ms_get_l2p_tbl(struct rtsx_chip *chip, int seg_no, u16 log_off) -{ - struct ms_info *ms_card = &chip->ms_card; - struct zone_entry *segment; - - if (!ms_card->segment) - return 0xFFFF; - - segment = &ms_card->segment[seg_no]; - - if (segment->l2p_table) - return segment->l2p_table[log_off]; - - return 0xFFFF; -} - -static void ms_set_l2p_tbl(struct rtsx_chip *chip, - int seg_no, u16 log_off, u16 phy_blk) -{ - struct ms_info *ms_card = &chip->ms_card; - struct zone_entry *segment; - - if (!ms_card->segment) - return; - - segment = &ms_card->segment[seg_no]; - if (segment->l2p_table) - segment->l2p_table[log_off] = phy_blk; -} - -static void ms_set_unused_block(struct rtsx_chip *chip, u16 phy_blk) -{ - struct ms_info *ms_card = &chip->ms_card; - struct zone_entry *segment; - int seg_no; - - seg_no = (int)phy_blk >> 9; - segment = &ms_card->segment[seg_no]; - - segment->free_table[segment->set_index++] = phy_blk; - if (segment->set_index >= MS_FREE_TABLE_CNT) - segment->set_index = 0; - - segment->unused_blk_cnt++; -} - -static u16 ms_get_unused_block(struct rtsx_chip *chip, int seg_no) -{ - struct ms_info *ms_card = &chip->ms_card; - struct zone_entry *segment; - u16 phy_blk; - - segment = &ms_card->segment[seg_no]; - - if (segment->unused_blk_cnt <= 0) - return 0xFFFF; - - phy_blk = segment->free_table[segment->get_index]; - segment->free_table[segment->get_index++] = 0xFFFF; - if (segment->get_index >= MS_FREE_TABLE_CNT) - segment->get_index = 0; - - segment->unused_blk_cnt--; - - return phy_blk; -} - -static const unsigned short ms_start_idx[] = {0, 494, 990, 1486, 1982, 2478, - 2974, 3470, 3966, 4462, 4958, - 5454, 5950, 6446, 6942, 7438, - 7934}; - -static int ms_arbitrate_l2p(struct rtsx_chip *chip, u16 phy_blk, - u16 log_off, u8 us1, u8 us2) -{ - struct ms_info *ms_card = &chip->ms_card; - struct zone_entry *segment; - int seg_no; - u16 tmp_blk; - - seg_no = (int)phy_blk >> 9; - segment = &ms_card->segment[seg_no]; - tmp_blk = segment->l2p_table[log_off]; - - if (us1 != us2) { - if (us1 == 0) { - if (!(chip->card_wp & MS_CARD)) - ms_erase_block(chip, tmp_blk); - - ms_set_unused_block(chip, tmp_blk); - segment->l2p_table[log_off] = phy_blk; - } else { - if (!(chip->card_wp & MS_CARD)) - ms_erase_block(chip, phy_blk); - - ms_set_unused_block(chip, phy_blk); - } - } else { - if (phy_blk < tmp_blk) { - if (!(chip->card_wp & MS_CARD)) - ms_erase_block(chip, phy_blk); - - ms_set_unused_block(chip, phy_blk); - } else { - if (!(chip->card_wp & MS_CARD)) - ms_erase_block(chip, tmp_blk); - - ms_set_unused_block(chip, tmp_blk); - segment->l2p_table[log_off] = phy_blk; - } - } - - return STATUS_SUCCESS; -} - -static int ms_build_l2p_tbl(struct rtsx_chip *chip, int seg_no) -{ - struct ms_info *ms_card = &chip->ms_card; - struct zone_entry *segment; - bool defect_flag; - int retval, table_size, disable_cnt, i; - u16 start, end, phy_blk, log_blk, tmp_blk, idx; - u8 extra[MS_EXTRA_SIZE], us1, us2; - - dev_dbg(rtsx_dev(chip), "%s: %d\n", __func__, seg_no); - - if (!ms_card->segment) { - retval = ms_init_l2p_tbl(chip); - if (retval != STATUS_SUCCESS) - return retval; - } - - if (ms_card->segment[seg_no].build_flag) { - dev_dbg(rtsx_dev(chip), "l2p table of segment %d has been built\n", - seg_no); - return STATUS_SUCCESS; - } - - if (seg_no == 0) - table_size = 494; - else - table_size = 496; - - segment = &ms_card->segment[seg_no]; - - if (!segment->l2p_table) { - segment->l2p_table = vmalloc(array_size(table_size, 2)); - if (!segment->l2p_table) - goto BUILD_FAIL; - } - memset((u8 *)(segment->l2p_table), 0xff, array_size(table_size, 2)); - - if (!segment->free_table) { - segment->free_table = vmalloc(array_size(MS_FREE_TABLE_CNT, 2)); - if (!segment->free_table) - goto BUILD_FAIL; - } - memset((u8 *)(segment->free_table), 0xff, array_size(MS_FREE_TABLE_CNT, 2)); - - start = (u16)seg_no << 9; - end = (u16)(seg_no + 1) << 9; - - disable_cnt = segment->disable_count; - - segment->get_index = 0; - segment->set_index = 0; - segment->unused_blk_cnt = 0; - - for (phy_blk = start; phy_blk < end; phy_blk++) { - if (disable_cnt) { - defect_flag = false; - for (i = 0; i < segment->disable_count; i++) { - if (phy_blk == segment->defect_list[i]) { - defect_flag = true; - break; - } - } - if (defect_flag) { - disable_cnt--; - continue; - } - } - - retval = ms_read_extra_data(chip, phy_blk, 0, - extra, MS_EXTRA_SIZE); - if (retval != STATUS_SUCCESS) { - dev_dbg(rtsx_dev(chip), "read extra data fail\n"); - ms_set_bad_block(chip, phy_blk); - continue; - } - - if (seg_no == ms_card->segment_cnt - 1) { - if (!(extra[1] & NOT_TRANSLATION_TABLE)) { - if (!(chip->card_wp & MS_CARD)) { - retval = ms_erase_block(chip, phy_blk); - if (retval != STATUS_SUCCESS) - continue; - extra[2] = 0xff; - extra[3] = 0xff; - } - } - } - - if (!(extra[0] & BLOCK_OK)) - continue; - if (!(extra[1] & NOT_BOOT_BLOCK)) - continue; - if ((extra[0] & PAGE_OK) != PAGE_OK) - continue; - - log_blk = ((u16)extra[2] << 8) | extra[3]; - - if (log_blk == 0xFFFF) { - if (!(chip->card_wp & MS_CARD)) { - retval = ms_erase_block(chip, phy_blk); - if (retval != STATUS_SUCCESS) - continue; - } - ms_set_unused_block(chip, phy_blk); - continue; - } - - if (log_blk < ms_start_idx[seg_no] || - log_blk >= ms_start_idx[seg_no + 1]) { - if (!(chip->card_wp & MS_CARD)) { - retval = ms_erase_block(chip, phy_blk); - if (retval != STATUS_SUCCESS) - continue; - } - ms_set_unused_block(chip, phy_blk); - continue; - } - - idx = log_blk - ms_start_idx[seg_no]; - - if (segment->l2p_table[idx] == 0xFFFF) { - segment->l2p_table[idx] = phy_blk; - continue; - } - - us1 = extra[0] & 0x10; - tmp_blk = segment->l2p_table[idx]; - retval = ms_read_extra_data(chip, tmp_blk, 0, - extra, MS_EXTRA_SIZE); - if (retval != STATUS_SUCCESS) - continue; - us2 = extra[0] & 0x10; - - (void)ms_arbitrate_l2p(chip, phy_blk, - log_blk - ms_start_idx[seg_no], us1, us2); - } - - segment->build_flag = 1; - - dev_dbg(rtsx_dev(chip), "unused block count: %d\n", - segment->unused_blk_cnt); - - /* Logical Address Confirmation Process */ - if (seg_no == ms_card->segment_cnt - 1) { - if (segment->unused_blk_cnt < 2) - chip->card_wp |= MS_CARD; - } else { - if (segment->unused_blk_cnt < 1) - chip->card_wp |= MS_CARD; - } - - if (chip->card_wp & MS_CARD) - return STATUS_SUCCESS; - - for (log_blk = ms_start_idx[seg_no]; - log_blk < ms_start_idx[seg_no + 1]; log_blk++) { - idx = log_blk - ms_start_idx[seg_no]; - if (segment->l2p_table[idx] == 0xFFFF) { - phy_blk = ms_get_unused_block(chip, seg_no); - if (phy_blk == 0xFFFF) { - chip->card_wp |= MS_CARD; - return STATUS_SUCCESS; - } - retval = ms_init_page(chip, phy_blk, log_blk, 0, 1); - if (retval != STATUS_SUCCESS) - goto BUILD_FAIL; - - segment->l2p_table[idx] = phy_blk; - if (seg_no == ms_card->segment_cnt - 1) { - if (segment->unused_blk_cnt < 2) { - chip->card_wp |= MS_CARD; - return STATUS_SUCCESS; - } - } else { - if (segment->unused_blk_cnt < 1) { - chip->card_wp |= MS_CARD; - return STATUS_SUCCESS; - } - } - } - } - - /* Make boot block be the first normal block */ - if (seg_no == 0) { - for (log_blk = 0; log_blk < 494; log_blk++) { - tmp_blk = segment->l2p_table[log_blk]; - if (tmp_blk < ms_card->boot_block) { - dev_dbg(rtsx_dev(chip), "Boot block is not the first normal block.\n"); - - if (chip->card_wp & MS_CARD) - break; - - phy_blk = ms_get_unused_block(chip, 0); - retval = ms_copy_page(chip, tmp_blk, phy_blk, - log_blk, 0, - ms_card->page_off + 1); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - segment->l2p_table[log_blk] = phy_blk; - - retval = ms_set_bad_block(chip, tmp_blk); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - } - } - - return STATUS_SUCCESS; - -BUILD_FAIL: - segment->build_flag = 0; - vfree(segment->l2p_table); - segment->l2p_table = NULL; - vfree(segment->free_table); - segment->free_table = NULL; - - return STATUS_FAIL; -} - -int reset_ms_card(struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &chip->ms_card; - int seg_no = ms_card->total_block / 512 - 1; - int retval; - - memset(ms_card, 0, sizeof(struct ms_info)); - - retval = enable_card_clock(chip, MS_CARD); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = select_card(chip, MS_CARD); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - ms_card->ms_type = 0; - - retval = reset_ms_pro(chip); - if (retval != STATUS_SUCCESS) { - if (ms_card->check_ms_flow) { - retval = reset_ms(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } else { - return STATUS_FAIL; - } - } - - retval = ms_set_init_para(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (!CHK_MSPRO(ms_card)) { - /* Build table for the last segment, - * to check if L2P table block exists, erasing it - */ - retval = ms_build_l2p_tbl(chip, seg_no); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - - dev_dbg(rtsx_dev(chip), "ms_card->ms_type = 0x%x\n", ms_card->ms_type); - - return STATUS_SUCCESS; -} - -static int mspro_set_rw_cmd(struct rtsx_chip *chip, - u32 start_sec, u16 sec_cnt, u8 cmd) -{ - int retval, i; - u8 data[8]; - - data[0] = cmd; - data[1] = (u8)(sec_cnt >> 8); - data[2] = (u8)sec_cnt; - data[3] = (u8)(start_sec >> 24); - data[4] = (u8)(start_sec >> 16); - data[5] = (u8)(start_sec >> 8); - data[6] = (u8)start_sec; - data[7] = 0; - - for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { - retval = ms_write_bytes(chip, PRO_EX_SET_CMD, 7, - WAIT_INT, data, 8); - if (retval == STATUS_SUCCESS) - break; - } - if (i == MS_MAX_RETRY_COUNT) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} - -void mspro_stop_seq_mode(struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &chip->ms_card; - int retval; - - if (ms_card->seq_mode) { - retval = ms_switch_clock(chip); - if (retval != STATUS_SUCCESS) - return; - - ms_card->seq_mode = 0; - ms_card->total_sec_cnt = 0; - ms_send_cmd(chip, PRO_STOP, WAIT_INT); - - rtsx_write_register(chip, RBCTL, RB_FLUSH, RB_FLUSH); - } -} - -static inline int ms_auto_tune_clock(struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &chip->ms_card; - int retval; - - if (chip->asic_code) { - if (ms_card->ms_clock > 30) - ms_card->ms_clock -= 20; - } else { - if (ms_card->ms_clock == CLK_80) - ms_card->ms_clock = CLK_60; - else if (ms_card->ms_clock == CLK_60) - ms_card->ms_clock = CLK_40; - } - - retval = ms_switch_clock(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} - -static int mspro_rw_multi_sector(struct scsi_cmnd *srb, - struct rtsx_chip *chip, u32 start_sector, - u16 sector_cnt) -{ - struct ms_info *ms_card = &chip->ms_card; - bool mode_2k = false; - int retval; - u16 count; - u8 val, trans_mode, rw_tpc, rw_cmd; - - ms_set_err_code(chip, MS_NO_ERROR); - - ms_card->cleanup_counter = 0; - - if (CHK_MSHG(ms_card)) { - if ((start_sector % 4) || (sector_cnt % 4)) { - if (srb->sc_data_direction == DMA_FROM_DEVICE) { - rw_tpc = PRO_READ_LONG_DATA; - rw_cmd = PRO_READ_DATA; - } else { - rw_tpc = PRO_WRITE_LONG_DATA; - rw_cmd = PRO_WRITE_DATA; - } - } else { - if (srb->sc_data_direction == DMA_FROM_DEVICE) { - rw_tpc = PRO_READ_QUAD_DATA; - rw_cmd = PRO_READ_2K_DATA; - } else { - rw_tpc = PRO_WRITE_QUAD_DATA; - rw_cmd = PRO_WRITE_2K_DATA; - } - mode_2k = true; - } - } else { - if (srb->sc_data_direction == DMA_FROM_DEVICE) { - rw_tpc = PRO_READ_LONG_DATA; - rw_cmd = PRO_READ_DATA; - } else { - rw_tpc = PRO_WRITE_LONG_DATA; - rw_cmd = PRO_WRITE_DATA; - } - } - - retval = ms_switch_clock(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (srb->sc_data_direction == DMA_FROM_DEVICE) - trans_mode = MS_TM_AUTO_READ; - else - trans_mode = MS_TM_AUTO_WRITE; - - retval = rtsx_read_register(chip, MS_TRANS_CFG, &val); - if (retval) - return retval; - - if (ms_card->seq_mode) { - if (ms_card->pre_dir != srb->sc_data_direction || - ((ms_card->pre_sec_addr + ms_card->pre_sec_cnt) != - start_sector) || - (mode_2k && (ms_card->seq_mode & MODE_512_SEQ)) || - (!mode_2k && (ms_card->seq_mode & MODE_2K_SEQ)) || - !(val & MS_INT_BREQ) || - ((ms_card->total_sec_cnt + sector_cnt) > 0xFE00)) { - ms_card->seq_mode = 0; - ms_card->total_sec_cnt = 0; - if (val & MS_INT_BREQ) { - retval = ms_send_cmd(chip, PRO_STOP, WAIT_INT); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - rtsx_write_register(chip, RBCTL, RB_FLUSH, - RB_FLUSH); - } - } - } - - if (!ms_card->seq_mode) { - ms_card->total_sec_cnt = 0; - if (sector_cnt >= SEQ_START_CRITERIA) { - if ((ms_card->capacity - start_sector) > 0xFE00) - count = 0xFE00; - else - count = (u16)(ms_card->capacity - start_sector); - - if (count > sector_cnt) { - if (mode_2k) - ms_card->seq_mode = MODE_2K_SEQ; - else - ms_card->seq_mode = MODE_512_SEQ; - } - } else { - count = sector_cnt; - } - retval = mspro_set_rw_cmd(chip, start_sector, count, rw_cmd); - if (retval != STATUS_SUCCESS) { - ms_card->seq_mode = 0; - return STATUS_FAIL; - } - } - - retval = ms_transfer_data(chip, trans_mode, rw_tpc, sector_cnt, - WAIT_INT, mode_2k, scsi_sg_count(srb), - scsi_sglist(srb), scsi_bufflen(srb)); - if (retval != STATUS_SUCCESS) { - ms_card->seq_mode = 0; - rtsx_read_register(chip, MS_TRANS_CFG, &val); - rtsx_clear_ms_error(chip); - - if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) { - chip->rw_need_retry = 0; - dev_dbg(rtsx_dev(chip), "No card exist, exit %s\n", - __func__); - return STATUS_FAIL; - } - - if (val & MS_INT_BREQ) - ms_send_cmd(chip, PRO_STOP, WAIT_INT); - - if (val & (MS_CRC16_ERR | MS_RDY_TIMEOUT)) { - dev_dbg(rtsx_dev(chip), "MSPro CRC error, tune clock!\n"); - chip->rw_need_retry = 1; - ms_auto_tune_clock(chip); - } - - return retval; - } - - if (ms_card->seq_mode) { - ms_card->pre_sec_addr = start_sector; - ms_card->pre_sec_cnt = sector_cnt; - ms_card->pre_dir = srb->sc_data_direction; - ms_card->total_sec_cnt += sector_cnt; - } - - return STATUS_SUCCESS; -} - -static int mspro_read_format_progress(struct rtsx_chip *chip, - const int short_data_len) -{ - struct ms_info *ms_card = &chip->ms_card; - int retval, i; - u32 total_progress, cur_progress; - u8 cnt, tmp; - u8 data[8]; - - dev_dbg(rtsx_dev(chip), "%s, short_data_len = %d\n", __func__, - short_data_len); - - retval = ms_switch_clock(chip); - if (retval != STATUS_SUCCESS) { - ms_card->format_status = FORMAT_FAIL; - return STATUS_FAIL; - } - - retval = rtsx_read_register(chip, MS_TRANS_CFG, &tmp); - if (retval != STATUS_SUCCESS) { - ms_card->format_status = FORMAT_FAIL; - return STATUS_FAIL; - } - - if (!(tmp & MS_INT_BREQ)) { - if ((tmp & (MS_INT_CED | MS_INT_BREQ | MS_INT_CMDNK | - MS_INT_ERR)) == MS_INT_CED) { - ms_card->format_status = FORMAT_SUCCESS; - return STATUS_SUCCESS; - } - ms_card->format_status = FORMAT_FAIL; - return STATUS_FAIL; - } - - if (short_data_len >= 256) - cnt = 0; - else - cnt = (u8)short_data_len; - - retval = rtsx_write_register(chip, MS_CFG, MS_NO_CHECK_INT, - MS_NO_CHECK_INT); - if (retval != STATUS_SUCCESS) { - ms_card->format_status = FORMAT_FAIL; - return STATUS_FAIL; - } - - retval = ms_read_bytes(chip, PRO_READ_SHORT_DATA, cnt, WAIT_INT, - data, 8); - if (retval != STATUS_SUCCESS) { - ms_card->format_status = FORMAT_FAIL; - return STATUS_FAIL; - } - - total_progress = (data[0] << 24) | (data[1] << 16) | - (data[2] << 8) | data[3]; - cur_progress = (data[4] << 24) | (data[5] << 16) | - (data[6] << 8) | data[7]; - - dev_dbg(rtsx_dev(chip), "total_progress = %d, cur_progress = %d\n", - total_progress, cur_progress); - - if (total_progress == 0) { - ms_card->progress = 0; - } else { - u64 ulltmp = (u64)cur_progress * (u64)65535; - - do_div(ulltmp, total_progress); - ms_card->progress = (u16)ulltmp; - } - dev_dbg(rtsx_dev(chip), "progress = %d\n", ms_card->progress); - - for (i = 0; i < 5000; i++) { - retval = rtsx_read_register(chip, MS_TRANS_CFG, &tmp); - if (retval != STATUS_SUCCESS) { - ms_card->format_status = FORMAT_FAIL; - return STATUS_FAIL; - } - if (tmp & (MS_INT_CED | MS_INT_CMDNK | - MS_INT_BREQ | MS_INT_ERR)) - break; - - wait_timeout(1); - } - - retval = rtsx_write_register(chip, MS_CFG, MS_NO_CHECK_INT, 0); - if (retval != STATUS_SUCCESS) { - ms_card->format_status = FORMAT_FAIL; - return STATUS_FAIL; - } - - if (i == 5000) { - ms_card->format_status = FORMAT_FAIL; - return STATUS_FAIL; - } - - if (tmp & (MS_INT_CMDNK | MS_INT_ERR)) { - ms_card->format_status = FORMAT_FAIL; - return STATUS_FAIL; - } - - if (tmp & MS_INT_CED) { - ms_card->format_status = FORMAT_SUCCESS; - ms_card->pro_under_formatting = 0; - } else if (tmp & MS_INT_BREQ) { - ms_card->format_status = FORMAT_IN_PROGRESS; - } else { - ms_card->format_status = FORMAT_FAIL; - ms_card->pro_under_formatting = 0; - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -void mspro_polling_format_status(struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &chip->ms_card; - int i; - - if (ms_card->pro_under_formatting && - (rtsx_get_stat(chip) != RTSX_STAT_SS)) { - rtsx_set_stat(chip, RTSX_STAT_RUN); - - for (i = 0; i < 65535; i++) { - mspro_read_format_progress(chip, MS_SHORT_DATA_LEN); - if (ms_card->format_status != FORMAT_IN_PROGRESS) - break; - } - } -} - -int mspro_format(struct scsi_cmnd *srb, struct rtsx_chip *chip, - int short_data_len, bool quick_format) -{ - struct ms_info *ms_card = &chip->ms_card; - int retval, i; - u8 buf[8], tmp; - u16 para; - - retval = ms_switch_clock(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = ms_set_rw_reg_addr(chip, 0x00, 0x00, PRO_TPC_PARM, 0x01); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - memset(buf, 0, 2); - switch (short_data_len) { - case 32: - buf[0] = 0; - break; - case 64: - buf[0] = 1; - break; - case 128: - buf[0] = 2; - break; - case 256: - default: - buf[0] = 3; - break; - } - - for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { - retval = ms_write_bytes(chip, PRO_WRITE_REG, 1, - NO_WAIT_INT, buf, 2); - if (retval == STATUS_SUCCESS) - break; - } - if (i == MS_MAX_RETRY_COUNT) - return STATUS_FAIL; - - if (quick_format) - para = 0x0000; - else - para = 0x0001; - - retval = mspro_set_rw_cmd(chip, 0, para, PRO_FORMAT); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = rtsx_read_register(chip, MS_TRANS_CFG, &tmp); - if (retval) - return retval; - - if (tmp & (MS_INT_CMDNK | MS_INT_ERR)) - return STATUS_FAIL; - - if ((tmp & (MS_INT_BREQ | MS_INT_CED)) == MS_INT_BREQ) { - ms_card->pro_under_formatting = 1; - ms_card->progress = 0; - ms_card->format_status = FORMAT_IN_PROGRESS; - return STATUS_SUCCESS; - } - - if (tmp & MS_INT_CED) { - ms_card->pro_under_formatting = 0; - ms_card->progress = 0; - ms_card->format_status = FORMAT_SUCCESS; - set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_NO_SENSE); - return STATUS_SUCCESS; - } - - return STATUS_FAIL; -} - -static int ms_read_multiple_pages(struct rtsx_chip *chip, u16 phy_blk, - u16 log_blk, u8 start_page, u8 end_page, - u8 *buf, unsigned int *index, - unsigned int *offset) -{ - struct ms_info *ms_card = &chip->ms_card; - int retval, i; - u8 extra[MS_EXTRA_SIZE], page_addr, val, trans_cfg, data[6]; - u8 *ptr; - - retval = ms_read_extra_data(chip, phy_blk, start_page, - extra, MS_EXTRA_SIZE); - if (retval == STATUS_SUCCESS) { - if ((extra[1] & 0x30) != 0x30) { - ms_set_err_code(chip, MS_FLASH_READ_ERROR); - return STATUS_FAIL; - } - } - - retval = ms_set_rw_reg_addr(chip, OVERWRITE_FLAG, MS_EXTRA_SIZE, - SYSTEM_PARAM, 6); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (CHK_MS4BIT(ms_card)) - data[0] = 0x88; - else - data[0] = 0x80; - - data[1] = 0; - data[2] = (u8)(phy_blk >> 8); - data[3] = (u8)phy_blk; - data[4] = 0; - data[5] = start_page; - - for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { - retval = ms_write_bytes(chip, WRITE_REG, 6, NO_WAIT_INT, - data, 6); - if (retval == STATUS_SUCCESS) - break; - } - if (i == MS_MAX_RETRY_COUNT) - return STATUS_FAIL; - - ms_set_err_code(chip, MS_NO_ERROR); - - retval = ms_send_cmd(chip, BLOCK_READ, WAIT_INT); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - ptr = buf; - - for (page_addr = start_page; page_addr < end_page; page_addr++) { - ms_set_err_code(chip, MS_NO_ERROR); - - if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) { - ms_set_err_code(chip, MS_NO_CARD); - return STATUS_FAIL; - } - - retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (val & INT_REG_CMDNK) { - ms_set_err_code(chip, MS_CMD_NK); - return STATUS_FAIL; - } - if (val & INT_REG_ERR) { - if (val & INT_REG_BREQ) { - retval = ms_read_status_reg(chip); - if (retval != STATUS_SUCCESS) { - if (!(chip->card_wp & MS_CARD)) { - reset_ms(chip); - ms_set_page_status - (log_blk, set_PS_NG, - extra, - MS_EXTRA_SIZE); - ms_write_extra_data - (chip, phy_blk, - page_addr, extra, - MS_EXTRA_SIZE); - } - ms_set_err_code(chip, - MS_FLASH_READ_ERROR); - return STATUS_FAIL; - } - } else { - ms_set_err_code(chip, MS_FLASH_READ_ERROR); - return STATUS_FAIL; - } - } else { - if (!(val & INT_REG_BREQ)) { - ms_set_err_code(chip, MS_BREQ_ERROR); - return STATUS_FAIL; - } - } - - if (page_addr == (end_page - 1)) { - if (!(val & INT_REG_CED)) { - retval = ms_send_cmd(chip, BLOCK_END, WAIT_INT); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - - retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, - &val, 1); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (!(val & INT_REG_CED)) { - ms_set_err_code(chip, MS_FLASH_READ_ERROR); - return STATUS_FAIL; - } - - trans_cfg = NO_WAIT_INT; - } else { - trans_cfg = WAIT_INT; - } - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TPC, 0xFF, READ_PAGE_DATA); - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, - 0xFF, trans_cfg); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, - 0x01, RING_BUFFER); - - trans_dma_enable(DMA_FROM_DEVICE, chip, 512, DMA_512); - - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF, - MS_TRANSFER_START | MS_TM_NORMAL_READ); - rtsx_add_cmd(chip, CHECK_REG_CMD, MS_TRANSFER, - MS_TRANSFER_END, MS_TRANSFER_END); - - rtsx_send_cmd_no_wait(chip); - - retval = rtsx_transfer_data_partial(chip, MS_CARD, ptr, 512, - scsi_sg_count(chip->srb), - index, offset, - DMA_FROM_DEVICE, - chip->ms_timeout); - if (retval < 0) { - if (retval == -ETIMEDOUT) { - ms_set_err_code(chip, MS_TO_ERROR); - rtsx_clear_ms_error(chip); - return STATUS_TIMEDOUT; - } - - retval = rtsx_read_register(chip, MS_TRANS_CFG, &val); - if (retval != STATUS_SUCCESS) { - ms_set_err_code(chip, MS_TO_ERROR); - rtsx_clear_ms_error(chip); - return STATUS_TIMEDOUT; - } - if (val & (MS_CRC16_ERR | MS_RDY_TIMEOUT)) { - ms_set_err_code(chip, MS_CRC16_ERROR); - rtsx_clear_ms_error(chip); - return STATUS_FAIL; - } - } - - if (scsi_sg_count(chip->srb) == 0) - ptr += 512; - } - - return STATUS_SUCCESS; -} - -static int ms_write_multiple_pages(struct rtsx_chip *chip, u16 old_blk, - u16 new_blk, u16 log_blk, u8 start_page, - u8 end_page, u8 *buf, unsigned int *index, - unsigned int *offset) -{ - struct ms_info *ms_card = &chip->ms_card; - int retval, i; - u8 page_addr, val, data[16]; - u8 *ptr; - - if (!start_page) { - retval = ms_set_rw_reg_addr(chip, OVERWRITE_FLAG, MS_EXTRA_SIZE, - SYSTEM_PARAM, 7); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (CHK_MS4BIT(ms_card)) - data[0] = 0x88; - else - data[0] = 0x80; - - data[1] = 0; - data[2] = (u8)(old_blk >> 8); - data[3] = (u8)old_blk; - data[4] = 0x80; - data[5] = 0; - data[6] = 0xEF; - data[7] = 0xFF; - - retval = ms_write_bytes(chip, WRITE_REG, 7, NO_WAIT_INT, - data, 8); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = ms_send_cmd(chip, BLOCK_WRITE, WAIT_INT); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - ms_set_err_code(chip, MS_NO_ERROR); - retval = ms_transfer_tpc(chip, MS_TM_READ_BYTES, GET_INT, 1, - NO_WAIT_INT); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - - retval = ms_set_rw_reg_addr(chip, OVERWRITE_FLAG, MS_EXTRA_SIZE, - SYSTEM_PARAM, (6 + MS_EXTRA_SIZE)); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - ms_set_err_code(chip, MS_NO_ERROR); - - if (CHK_MS4BIT(ms_card)) - data[0] = 0x88; - else - data[0] = 0x80; - - data[1] = 0; - data[2] = (u8)(new_blk >> 8); - data[3] = (u8)new_blk; - if ((end_page - start_page) == 1) - data[4] = 0x20; - else - data[4] = 0; - - data[5] = start_page; - data[6] = 0xF8; - data[7] = 0xFF; - data[8] = (u8)(log_blk >> 8); - data[9] = (u8)log_blk; - - for (i = 0x0A; i < 0x10; i++) - data[i] = 0xFF; - - for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { - retval = ms_write_bytes(chip, WRITE_REG, 6 + MS_EXTRA_SIZE, - NO_WAIT_INT, data, 16); - if (retval == STATUS_SUCCESS) - break; - } - if (i == MS_MAX_RETRY_COUNT) - return STATUS_FAIL; - - for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { - retval = ms_send_cmd(chip, BLOCK_WRITE, WAIT_INT); - if (retval == STATUS_SUCCESS) - break; - } - if (i == MS_MAX_RETRY_COUNT) - return STATUS_FAIL; - - retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - ptr = buf; - for (page_addr = start_page; page_addr < end_page; page_addr++) { - ms_set_err_code(chip, MS_NO_ERROR); - - if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) { - ms_set_err_code(chip, MS_NO_CARD); - return STATUS_FAIL; - } - - if (val & INT_REG_CMDNK) { - ms_set_err_code(chip, MS_CMD_NK); - return STATUS_FAIL; - } - if (val & INT_REG_ERR) { - ms_set_err_code(chip, MS_FLASH_WRITE_ERROR); - return STATUS_FAIL; - } - if (!(val & INT_REG_BREQ)) { - ms_set_err_code(chip, MS_BREQ_ERROR); - return STATUS_FAIL; - } - - udelay(30); - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TPC, - 0xFF, WRITE_PAGE_DATA); - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, - 0xFF, WAIT_INT); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, - 0x01, RING_BUFFER); - - trans_dma_enable(DMA_TO_DEVICE, chip, 512, DMA_512); - - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF, - MS_TRANSFER_START | MS_TM_NORMAL_WRITE); - rtsx_add_cmd(chip, CHECK_REG_CMD, MS_TRANSFER, - MS_TRANSFER_END, MS_TRANSFER_END); - - rtsx_send_cmd_no_wait(chip); - - retval = rtsx_transfer_data_partial(chip, MS_CARD, ptr, 512, - scsi_sg_count(chip->srb), - index, offset, - DMA_TO_DEVICE, - chip->ms_timeout); - if (retval < 0) { - ms_set_err_code(chip, MS_TO_ERROR); - rtsx_clear_ms_error(chip); - - if (retval == -ETIMEDOUT) - return STATUS_TIMEDOUT; - return STATUS_FAIL; - } - - retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if ((end_page - start_page) == 1) { - if (!(val & INT_REG_CED)) { - ms_set_err_code(chip, MS_FLASH_WRITE_ERROR); - return STATUS_FAIL; - } - } else { - if (page_addr == (end_page - 1)) { - if (!(val & INT_REG_CED)) { - retval = ms_send_cmd(chip, BLOCK_END, - WAIT_INT); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - - retval = ms_read_bytes(chip, GET_INT, 1, - NO_WAIT_INT, &val, 1); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - - if (page_addr == (end_page - 1) || - page_addr == ms_card->page_off) { - if (!(val & INT_REG_CED)) { - ms_set_err_code(chip, - MS_FLASH_WRITE_ERROR); - return STATUS_FAIL; - } - } - } - - if (scsi_sg_count(chip->srb) == 0) - ptr += 512; - } - - return STATUS_SUCCESS; -} - -static int ms_finish_write(struct rtsx_chip *chip, u16 old_blk, u16 new_blk, - u16 log_blk, u8 page_off) -{ - struct ms_info *ms_card = &chip->ms_card; - int retval, seg_no; - - retval = ms_copy_page(chip, old_blk, new_blk, log_blk, - page_off, ms_card->page_off + 1); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - seg_no = old_blk >> 9; - - if (MS_TST_BAD_BLOCK_FLG(ms_card)) { - MS_CLR_BAD_BLOCK_FLG(ms_card); - ms_set_bad_block(chip, old_blk); - } else { - retval = ms_erase_block(chip, old_blk); - if (retval == STATUS_SUCCESS) - ms_set_unused_block(chip, old_blk); - } - - ms_set_l2p_tbl(chip, seg_no, log_blk - ms_start_idx[seg_no], new_blk); - - return STATUS_SUCCESS; -} - -static int ms_prepare_write(struct rtsx_chip *chip, u16 old_blk, u16 new_blk, - u16 log_blk, u8 start_page) -{ - int retval; - - if (start_page) { - retval = ms_copy_page(chip, old_blk, new_blk, log_blk, - 0, start_page); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -#ifdef MS_DELAY_WRITE -int ms_delay_write(struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &chip->ms_card; - struct ms_delay_write_tag *delay_write = &ms_card->delay_write; - int retval; - - if (delay_write->delay_write_flag) { - retval = ms_set_init_para(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - delay_write->delay_write_flag = 0; - retval = ms_finish_write(chip, - delay_write->old_phyblock, - delay_write->new_phyblock, - delay_write->logblock, - delay_write->pageoff); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} -#endif - -static inline void ms_rw_fail(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - if (srb->sc_data_direction == DMA_FROM_DEVICE) - set_sense_type(chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - else - set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); -} - -static int ms_rw_multi_sector(struct scsi_cmnd *srb, struct rtsx_chip *chip, - u32 start_sector, u16 sector_cnt) -{ - struct ms_info *ms_card = &chip->ms_card; - unsigned int lun = SCSI_LUN(srb); - int retval, seg_no; - unsigned int index = 0, offset = 0; - u16 old_blk = 0, new_blk = 0, log_blk, total_sec_cnt = sector_cnt; - u8 start_page, end_page = 0, page_cnt; - u8 *ptr; -#ifdef MS_DELAY_WRITE - struct ms_delay_write_tag *delay_write = &ms_card->delay_write; -#endif - - ms_set_err_code(chip, MS_NO_ERROR); - - ms_card->cleanup_counter = 0; - - ptr = (u8 *)scsi_sglist(srb); - - retval = ms_switch_clock(chip); - if (retval != STATUS_SUCCESS) { - ms_rw_fail(srb, chip); - return STATUS_FAIL; - } - - log_blk = (u16)(start_sector >> ms_card->block_shift); - start_page = (u8)(start_sector & ms_card->page_off); - - for (seg_no = 0; seg_no < ARRAY_SIZE(ms_start_idx) - 1; seg_no++) { - if (log_blk < ms_start_idx[seg_no + 1]) - break; - } - - if (ms_card->segment[seg_no].build_flag == 0) { - retval = ms_build_l2p_tbl(chip, seg_no); - if (retval != STATUS_SUCCESS) { - chip->card_fail |= MS_CARD; - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - return STATUS_FAIL; - } - } - - if (srb->sc_data_direction == DMA_TO_DEVICE) { -#ifdef MS_DELAY_WRITE - if (delay_write->delay_write_flag && - delay_write->logblock == log_blk && - start_page > delay_write->pageoff) { - delay_write->delay_write_flag = 0; - retval = ms_copy_page(chip, - delay_write->old_phyblock, - delay_write->new_phyblock, - log_blk, - delay_write->pageoff, start_page); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_WRITE_ERR); - return STATUS_FAIL; - } - old_blk = delay_write->old_phyblock; - new_blk = delay_write->new_phyblock; - } else if (delay_write->delay_write_flag && - (delay_write->logblock == log_blk) && - (start_page == delay_write->pageoff)) { - delay_write->delay_write_flag = 0; - old_blk = delay_write->old_phyblock; - new_blk = delay_write->new_phyblock; - } else { - retval = ms_delay_write(chip); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_WRITE_ERR); - return STATUS_FAIL; - } -#endif - old_blk = ms_get_l2p_tbl - (chip, seg_no, - log_blk - ms_start_idx[seg_no]); - new_blk = ms_get_unused_block(chip, seg_no); - if (old_blk == 0xFFFF || new_blk == 0xFFFF) { - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_WRITE_ERR); - return STATUS_FAIL; - } - - retval = ms_prepare_write(chip, old_blk, new_blk, - log_blk, start_page); - if (retval != STATUS_SUCCESS) { - if (detect_card_cd(chip, MS_CARD) != - STATUS_SUCCESS) { - set_sense_type - (chip, lun, - SENSE_TYPE_MEDIA_NOT_PRESENT); - return STATUS_FAIL; - } - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_WRITE_ERR); - return STATUS_FAIL; - } -#ifdef MS_DELAY_WRITE - } -#endif - } else { -#ifdef MS_DELAY_WRITE - retval = ms_delay_write(chip); - if (retval != STATUS_SUCCESS) { - if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) { - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_NOT_PRESENT); - return STATUS_FAIL; - } - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - return STATUS_FAIL; - } -#endif - old_blk = ms_get_l2p_tbl(chip, seg_no, - log_blk - ms_start_idx[seg_no]); - if (old_blk == 0xFFFF) { - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - return STATUS_FAIL; - } - } - - dev_dbg(rtsx_dev(chip), "seg_no = %d, old_blk = 0x%x, new_blk = 0x%x\n", - seg_no, old_blk, new_blk); - - while (total_sec_cnt) { - if ((start_page + total_sec_cnt) > (ms_card->page_off + 1)) - end_page = ms_card->page_off + 1; - else - end_page = start_page + (u8)total_sec_cnt; - - page_cnt = end_page - start_page; - - dev_dbg(rtsx_dev(chip), "start_page = %d, end_page = %d, page_cnt = %d\n", - start_page, end_page, page_cnt); - - if (srb->sc_data_direction == DMA_FROM_DEVICE) { - retval = ms_read_multiple_pages(chip, - old_blk, log_blk, - start_page, end_page, - ptr, &index, &offset); - } else { - retval = ms_write_multiple_pages(chip, old_blk, new_blk, - log_blk, start_page, - end_page, ptr, &index, - &offset); - } - - if (retval != STATUS_SUCCESS) { - toggle_gpio(chip, 1); - if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) { - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_NOT_PRESENT); - return STATUS_FAIL; - } - ms_rw_fail(srb, chip); - return STATUS_FAIL; - } - - if (srb->sc_data_direction == DMA_TO_DEVICE) { - if (end_page == (ms_card->page_off + 1)) { - retval = ms_erase_block(chip, old_blk); - if (retval == STATUS_SUCCESS) - ms_set_unused_block(chip, old_blk); - - ms_set_l2p_tbl(chip, seg_no, - log_blk - ms_start_idx[seg_no], - new_blk); - } - } - - total_sec_cnt -= page_cnt; - if (scsi_sg_count(srb) == 0) - ptr += page_cnt * 512; - - if (total_sec_cnt == 0) - break; - - log_blk++; - - for (seg_no = 0; seg_no < ARRAY_SIZE(ms_start_idx) - 1; - seg_no++) { - if (log_blk < ms_start_idx[seg_no + 1]) - break; - } - - if (ms_card->segment[seg_no].build_flag == 0) { - retval = ms_build_l2p_tbl(chip, seg_no); - if (retval != STATUS_SUCCESS) { - chip->card_fail |= MS_CARD; - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_NOT_PRESENT); - return STATUS_FAIL; - } - } - - old_blk = ms_get_l2p_tbl(chip, seg_no, - log_blk - ms_start_idx[seg_no]); - if (old_blk == 0xFFFF) { - ms_rw_fail(srb, chip); - return STATUS_FAIL; - } - - if (srb->sc_data_direction == DMA_TO_DEVICE) { - new_blk = ms_get_unused_block(chip, seg_no); - if (new_blk == 0xFFFF) { - ms_rw_fail(srb, chip); - return STATUS_FAIL; - } - } - - dev_dbg(rtsx_dev(chip), "seg_no = %d, old_blk = 0x%x, new_blk = 0x%x\n", - seg_no, old_blk, new_blk); - - start_page = 0; - } - - if (srb->sc_data_direction == DMA_TO_DEVICE) { - if (end_page < (ms_card->page_off + 1)) { -#ifdef MS_DELAY_WRITE - delay_write->delay_write_flag = 1; - delay_write->old_phyblock = old_blk; - delay_write->new_phyblock = new_blk; - delay_write->logblock = log_blk; - delay_write->pageoff = end_page; -#else - retval = ms_finish_write(chip, old_blk, new_blk, - log_blk, end_page); - if (retval != STATUS_SUCCESS) { - if (detect_card_cd(chip, MS_CARD) != - STATUS_SUCCESS) { - set_sense_type - (chip, lun, - SENSE_TYPE_MEDIA_NOT_PRESENT); - return STATUS_FAIL; - } - - ms_rw_fail(srb, chip); - return STATUS_FAIL; - } -#endif - } - } - - scsi_set_resid(srb, 0); - - return STATUS_SUCCESS; -} - -int ms_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, - u32 start_sector, u16 sector_cnt) -{ - struct ms_info *ms_card = &chip->ms_card; - int retval; - - if (CHK_MSPRO(ms_card)) - retval = mspro_rw_multi_sector(srb, chip, start_sector, - sector_cnt); - else - retval = ms_rw_multi_sector(srb, chip, start_sector, - sector_cnt); - - return retval; -} - -void ms_free_l2p_tbl(struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &chip->ms_card; - int i = 0; - - if (ms_card->segment) { - for (i = 0; i < ms_card->segment_cnt; i++) { - vfree(ms_card->segment[i].l2p_table); - ms_card->segment[i].l2p_table = NULL; - vfree(ms_card->segment[i].free_table); - ms_card->segment[i].free_table = NULL; - } - vfree(ms_card->segment); - ms_card->segment = NULL; - } -} - -#ifdef SUPPORT_MAGIC_GATE - -#ifdef READ_BYTES_WAIT_INT -static int ms_poll_int(struct rtsx_chip *chip) -{ - int retval; - u8 val; - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, CHECK_REG_CMD, MS_TRANS_CFG, MS_INT_CED, MS_INT_CED); - - retval = rtsx_send_cmd(chip, MS_CARD, 5000); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - val = *rtsx_get_cmd_data(chip); - if (val & MS_INT_ERR) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} -#endif - -#ifdef MS_SAMPLE_INT_ERR -static int check_ms_err(struct rtsx_chip *chip) -{ - int retval; - u8 val; - - retval = rtsx_read_register(chip, MS_TRANSFER, &val); - if (retval != STATUS_SUCCESS) - return 1; - if (val & MS_TRANSFER_ERR) - return 1; - - retval = rtsx_read_register(chip, MS_TRANS_CFG, &val); - if (retval != STATUS_SUCCESS) - return 1; - - if (val & (MS_INT_ERR | MS_INT_CMDNK)) - return 1; - - return 0; -} -#else -static int check_ms_err(struct rtsx_chip *chip) -{ - int retval; - u8 val; - - retval = rtsx_read_register(chip, MS_TRANSFER, &val); - if (retval != STATUS_SUCCESS) - return 1; - if (val & MS_TRANSFER_ERR) - return 1; - - return 0; -} -#endif - -static int mg_send_ex_cmd(struct rtsx_chip *chip, u8 cmd, u8 entry_num) -{ - int retval, i; - u8 data[8]; - - data[0] = cmd; - data[1] = 0; - data[2] = 0; - data[3] = 0; - data[4] = 0; - data[5] = 0; - data[6] = entry_num; - data[7] = 0; - - for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { - retval = ms_write_bytes(chip, PRO_EX_SET_CMD, 7, WAIT_INT, - data, 8); - if (retval == STATUS_SUCCESS) - break; - } - if (i == MS_MAX_RETRY_COUNT) - return STATUS_FAIL; - - if (check_ms_err(chip)) { - rtsx_clear_ms_error(chip); - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -static int mg_set_tpc_para_sub(struct rtsx_chip *chip, int type, - u8 mg_entry_num) -{ - int retval; - u8 buf[6]; - - if (type == 0) - retval = ms_set_rw_reg_addr(chip, 0, 0, PRO_TPC_PARM, 1); - else - retval = ms_set_rw_reg_addr(chip, 0, 0, PRO_DATA_COUNT1, 6); - - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - buf[0] = 0; - buf[1] = 0; - if (type == 1) { - buf[2] = 0; - buf[3] = 0; - buf[4] = 0; - buf[5] = mg_entry_num; - } - retval = ms_write_bytes(chip, PRO_WRITE_REG, (type == 0) ? 1 : 6, - NO_WAIT_INT, buf, 6); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} - -int mg_set_leaf_id(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - int retval; - int i; - unsigned int lun = SCSI_LUN(srb); - u8 buf1[32], buf2[12]; - - if (scsi_bufflen(srb) < 12) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return STATUS_FAIL; - } - - ms_cleanup_work(chip); - - retval = ms_switch_clock(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = mg_send_ex_cmd(chip, MG_SET_LID, 0); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB); - return STATUS_FAIL; - } - - memset(buf1, 0, 32); - rtsx_stor_get_xfer_buf(buf2, min_t(int, 12, scsi_bufflen(srb)), srb); - for (i = 0; i < 8; i++) - buf1[8 + i] = buf2[4 + i]; - - retval = ms_write_bytes(chip, PRO_WRITE_SHORT_DATA, 32, WAIT_INT, - buf1, 32); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB); - return STATUS_FAIL; - } - if (check_ms_err(chip)) { - set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB); - rtsx_clear_ms_error(chip); - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -int mg_get_local_EKB(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - int retval; - int bufflen; - unsigned int lun = SCSI_LUN(srb); - u8 *buf = NULL; - - ms_cleanup_work(chip); - - retval = ms_switch_clock(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - buf = kmalloc(1540, GFP_KERNEL); - if (!buf) - return STATUS_ERROR; - - buf[0] = 0x04; - buf[1] = 0x1A; - buf[2] = 0x00; - buf[3] = 0x00; - - retval = mg_send_ex_cmd(chip, MG_GET_LEKB, 0); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); - goto free_buffer; - } - - retval = ms_transfer_data(chip, MS_TM_AUTO_READ, PRO_READ_LONG_DATA, - 3, WAIT_INT, 0, 0, buf + 4, 1536); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); - rtsx_clear_ms_error(chip); - goto free_buffer; - } - if (check_ms_err(chip)) { - set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); - rtsx_clear_ms_error(chip); - retval = STATUS_FAIL; - goto free_buffer; - } - - bufflen = min_t(int, 1052, scsi_bufflen(srb)); - rtsx_stor_set_xfer_buf(buf, bufflen, srb); - -free_buffer: - kfree(buf); - return retval; -} - -int mg_chg(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &chip->ms_card; - int retval; - int bufflen; - int i; - unsigned int lun = SCSI_LUN(srb); - u8 buf[32]; - - ms_cleanup_work(chip); - - retval = ms_switch_clock(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = mg_send_ex_cmd(chip, MG_GET_ID, 0); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); - return STATUS_FAIL; - } - - retval = ms_read_bytes(chip, PRO_READ_SHORT_DATA, 32, WAIT_INT, - buf, 32); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); - return STATUS_FAIL; - } - if (check_ms_err(chip)) { - set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); - rtsx_clear_ms_error(chip); - return STATUS_FAIL; - } - - memcpy(ms_card->magic_gate_id, buf, 16); - -#ifdef READ_BYTES_WAIT_INT - retval = ms_poll_int(chip); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); - return STATUS_FAIL; - } -#endif - - retval = mg_send_ex_cmd(chip, MG_SET_RD, 0); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); - return STATUS_FAIL; - } - - bufflen = min_t(int, 12, scsi_bufflen(srb)); - rtsx_stor_get_xfer_buf(buf, bufflen, srb); - - for (i = 0; i < 8; i++) - buf[i] = buf[4 + i]; - - for (i = 0; i < 24; i++) - buf[8 + i] = 0; - - retval = ms_write_bytes(chip, PRO_WRITE_SHORT_DATA, - 32, WAIT_INT, buf, 32); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); - return STATUS_FAIL; - } - if (check_ms_err(chip)) { - set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); - rtsx_clear_ms_error(chip); - return STATUS_FAIL; - } - - ms_card->mg_auth = 0; - - return STATUS_SUCCESS; -} - -int mg_get_rsp_chg(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &chip->ms_card; - int retval; - int bufflen; - unsigned int lun = SCSI_LUN(srb); - u8 buf1[32], buf2[36]; - - ms_cleanup_work(chip); - - retval = ms_switch_clock(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = mg_send_ex_cmd(chip, MG_MAKE_RMS, 0); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); - return STATUS_FAIL; - } - - retval = ms_read_bytes(chip, PRO_READ_SHORT_DATA, 32, WAIT_INT, - buf1, 32); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); - return STATUS_FAIL; - } - if (check_ms_err(chip)) { - set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); - rtsx_clear_ms_error(chip); - return STATUS_FAIL; - } - - buf2[0] = 0x00; - buf2[1] = 0x22; - buf2[2] = 0x00; - buf2[3] = 0x00; - - memcpy(buf2 + 4, ms_card->magic_gate_id, 16); - memcpy(buf2 + 20, buf1, 16); - - bufflen = min_t(int, 36, scsi_bufflen(srb)); - rtsx_stor_set_xfer_buf(buf2, bufflen, srb); - -#ifdef READ_BYTES_WAIT_INT - retval = ms_poll_int(chip); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); - return STATUS_FAIL; - } -#endif - - return STATUS_SUCCESS; -} - -int mg_rsp(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &chip->ms_card; - int retval; - int i; - int bufflen; - unsigned int lun = SCSI_LUN(srb); - u8 buf[32]; - - ms_cleanup_work(chip); - - retval = ms_switch_clock(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = mg_send_ex_cmd(chip, MG_MAKE_KSE, 0); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); - return STATUS_FAIL; - } - - bufflen = min_t(int, 12, scsi_bufflen(srb)); - rtsx_stor_get_xfer_buf(buf, bufflen, srb); - - for (i = 0; i < 8; i++) - buf[i] = buf[4 + i]; - - for (i = 0; i < 24; i++) - buf[8 + i] = 0; - - retval = ms_write_bytes(chip, PRO_WRITE_SHORT_DATA, 32, WAIT_INT, - buf, 32); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); - return STATUS_FAIL; - } - if (check_ms_err(chip)) { - set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); - rtsx_clear_ms_error(chip); - return STATUS_FAIL; - } - - ms_card->mg_auth = 1; - - return STATUS_SUCCESS; -} - -int mg_get_ICV(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &chip->ms_card; - int retval; - int bufflen; - unsigned int lun = SCSI_LUN(srb); - u8 *buf = NULL; - - ms_cleanup_work(chip); - - retval = ms_switch_clock(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - buf = kmalloc(1028, GFP_KERNEL); - if (!buf) - return STATUS_ERROR; - - buf[0] = 0x04; - buf[1] = 0x02; - buf[2] = 0x00; - buf[3] = 0x00; - - retval = mg_send_ex_cmd(chip, MG_GET_IBD, ms_card->mg_entry_num); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - goto free_buffer; - } - - retval = ms_transfer_data(chip, MS_TM_AUTO_READ, PRO_READ_LONG_DATA, - 2, WAIT_INT, 0, 0, buf + 4, 1024); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - rtsx_clear_ms_error(chip); - goto free_buffer; - } - if (check_ms_err(chip)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - rtsx_clear_ms_error(chip); - retval = STATUS_FAIL; - goto free_buffer; - } - - bufflen = min_t(int, 1028, scsi_bufflen(srb)); - rtsx_stor_set_xfer_buf(buf, bufflen, srb); - -free_buffer: - kfree(buf); - return retval; -} - -int mg_set_ICV(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &chip->ms_card; - int retval; - int bufflen; -#ifdef MG_SET_ICV_SLOW - int i; -#endif - unsigned int lun = SCSI_LUN(srb); - u8 *buf = NULL; - - ms_cleanup_work(chip); - - retval = ms_switch_clock(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - buf = kmalloc(1028, GFP_KERNEL); - if (!buf) - return STATUS_ERROR; - - bufflen = min_t(int, 1028, scsi_bufflen(srb)); - rtsx_stor_get_xfer_buf(buf, bufflen, srb); - - retval = mg_send_ex_cmd(chip, MG_SET_IBD, ms_card->mg_entry_num); - if (retval != STATUS_SUCCESS) { - if (ms_card->mg_auth == 0) { - if ((buf[5] & 0xC0) != 0) - set_sense_type - (chip, lun, - SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB); - else - set_sense_type(chip, lun, - SENSE_TYPE_MG_WRITE_ERR); - } else { - set_sense_type(chip, lun, SENSE_TYPE_MG_WRITE_ERR); - } - goto set_ICV_finish; - } - -#ifdef MG_SET_ICV_SLOW - for (i = 0; i < 2; i++) { - udelay(50); - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TPC, - 0xFF, PRO_WRITE_LONG_DATA); - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, WAIT_INT); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, - 0x01, RING_BUFFER); - - trans_dma_enable(DMA_TO_DEVICE, chip, 512, DMA_512); - - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF, - MS_TRANSFER_START | MS_TM_NORMAL_WRITE); - rtsx_add_cmd(chip, CHECK_REG_CMD, MS_TRANSFER, - MS_TRANSFER_END, MS_TRANSFER_END); - - rtsx_send_cmd_no_wait(chip); - - retval = rtsx_transfer_data(chip, MS_CARD, buf + 4 + i * 512, - 512, 0, DMA_TO_DEVICE, 3000); - if (retval < 0 || check_ms_err(chip)) { - rtsx_clear_ms_error(chip); - if (ms_card->mg_auth == 0) { - if ((buf[5] & 0xC0) != 0) - set_sense_type - (chip, lun, - SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB); - else - set_sense_type(chip, lun, - SENSE_TYPE_MG_WRITE_ERR); - } else { - set_sense_type(chip, lun, - SENSE_TYPE_MG_WRITE_ERR); - } - retval = STATUS_FAIL; - goto set_ICV_finish; - } - } -#else - retval = ms_transfer_data(chip, MS_TM_AUTO_WRITE, PRO_WRITE_LONG_DATA, - 2, WAIT_INT, 0, 0, buf + 4, 1024); - if (retval != STATUS_SUCCESS || check_ms_err(chip)) { - rtsx_clear_ms_error(chip); - if (ms_card->mg_auth == 0) { - if ((buf[5] & 0xC0) != 0) - set_sense_type - (chip, lun, - SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB); - else - set_sense_type(chip, lun, - SENSE_TYPE_MG_WRITE_ERR); - } else { - set_sense_type(chip, lun, SENSE_TYPE_MG_WRITE_ERR); - } - goto set_ICV_finish; - } -#endif - -set_ICV_finish: - kfree(buf); - return retval; -} - -#endif /* SUPPORT_MAGIC_GATE */ - -void ms_cleanup_work(struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &chip->ms_card; - - if (CHK_MSPRO(ms_card)) { - if (ms_card->seq_mode) { - dev_dbg(rtsx_dev(chip), "MS Pro: stop transmission\n"); - mspro_stop_seq_mode(chip); - ms_card->cleanup_counter = 0; - } - if (CHK_MSHG(ms_card)) { - rtsx_write_register(chip, MS_CFG, - MS_2K_SECTOR_MODE, 0x00); - } - } -#ifdef MS_DELAY_WRITE - else if ((!CHK_MSPRO(ms_card)) && - ms_card->delay_write.delay_write_flag) { - dev_dbg(rtsx_dev(chip), "MS: delay write\n"); - ms_delay_write(chip); - ms_card->cleanup_counter = 0; - } -#endif -} - -int ms_power_off_card3v3(struct rtsx_chip *chip) -{ - int retval; - - retval = disable_card_clock(chip, MS_CARD); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (chip->asic_code) { - retval = ms_pull_ctl_disable(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } else { - retval = rtsx_write_register(chip, FPGA_PULL_CTL, - FPGA_MS_PULL_CTL_BIT | 0x20, - FPGA_MS_PULL_CTL_BIT); - if (retval) - return retval; - } - retval = rtsx_write_register(chip, CARD_OE, MS_OUTPUT_EN, 0); - if (retval) - return retval; - - if (!chip->ft2_fast_mode) { - retval = card_power_off(chip, MS_CARD); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -int release_ms_card(struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &chip->ms_card; - int retval; - -#ifdef MS_DELAY_WRITE - ms_card->delay_write.delay_write_flag = 0; -#endif - ms_card->pro_under_formatting = 0; - - chip->card_ready &= ~MS_CARD; - chip->card_fail &= ~MS_CARD; - chip->card_wp &= ~MS_CARD; - - ms_free_l2p_tbl(chip); - - memset(ms_card->raw_sys_info, 0, 96); -#ifdef SUPPORT_PCGL_1P18 - memset(ms_card->raw_model_name, 0, 48); -#endif - - retval = ms_power_off_card3v3(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} diff --git a/drivers/staging/rts5208/ms.h b/drivers/staging/rts5208/ms.h deleted file mode 100644 index 33bda9ce36b6..000000000000 --- a/drivers/staging/rts5208/ms.h +++ /dev/null @@ -1,214 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Driver for Realtek PCI-Express card reader - * - * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. - * - * Author: - * Wei WANG (wei_wang@xxxxxxxxxxxxxx) - * Micky Ching (micky_ching@xxxxxxxxxxxxxx) - */ - -#ifndef __REALTEK_RTSX_MS_H -#define __REALTEK_RTSX_MS_H - -#define MS_DELAY_WRITE - -#define MS_MAX_RETRY_COUNT 3 - -#define MS_EXTRA_SIZE 0x9 - -#define WRT_PRTCT 0x01 - -/* Error Code */ -#define MS_NO_ERROR 0x00 -#define MS_CRC16_ERROR 0x80 -#define MS_TO_ERROR 0x40 -#define MS_NO_CARD 0x20 -#define MS_NO_MEMORY 0x10 -#define MS_CMD_NK 0x08 -#define MS_FLASH_READ_ERROR 0x04 -#define MS_FLASH_WRITE_ERROR 0x02 -#define MS_BREQ_ERROR 0x01 -#define MS_NOT_FOUND 0x03 - -/* Transfer Protocol Command */ -#define READ_PAGE_DATA 0x02 -#define READ_REG 0x04 -#define GET_INT 0x07 -#define WRITE_PAGE_DATA 0x0D -#define WRITE_REG 0x0B -#define SET_RW_REG_ADRS 0x08 -#define SET_CMD 0x0E - -#define PRO_READ_LONG_DATA 0x02 -#define PRO_READ_SHORT_DATA 0x03 -#define PRO_READ_REG 0x04 -#define PRO_READ_QUAD_DATA 0x05 -#define PRO_GET_INT 0x07 -#define PRO_WRITE_LONG_DATA 0x0D -#define PRO_WRITE_SHORT_DATA 0x0C -#define PRO_WRITE_QUAD_DATA 0x0A -#define PRO_WRITE_REG 0x0B -#define PRO_SET_RW_REG_ADRS 0x08 -#define PRO_SET_CMD 0x0E -#define PRO_EX_SET_CMD 0x09 - -#ifdef SUPPORT_MAGIC_GATE - -#define MG_GET_ID 0x40 -#define MG_SET_LID 0x41 -#define MG_GET_LEKB 0x42 -#define MG_SET_RD 0x43 -#define MG_MAKE_RMS 0x44 -#define MG_MAKE_KSE 0x45 -#define MG_SET_IBD 0x46 -#define MG_GET_IBD 0x47 - -#endif - -#ifdef XC_POWERCLASS -#define XC_CHG_POWER 0x16 -#endif - -#define BLOCK_READ 0xAA -#define BLOCK_WRITE 0x55 -#define BLOCK_END 0x33 -#define BLOCK_ERASE 0x99 -#define FLASH_STOP 0xCC - -#define SLEEP 0x5A -#define CLEAR_BUF 0xC3 -#define MS_RESET 0x3C - -#define PRO_READ_DATA 0x20 -#define PRO_WRITE_DATA 0x21 -#define PRO_READ_ATRB 0x24 -#define PRO_STOP 0x25 -#define PRO_ERASE 0x26 -#define PRO_READ_2K_DATA 0x27 -#define PRO_WRITE_2K_DATA 0x28 - -#define PRO_FORMAT 0x10 -#define PRO_SLEEP 0x11 - -#define INT_REG 0x01 -#define STATUS_REG0 0x02 -#define STATUS_REG1 0x03 - -#define SYSTEM_PARAM 0x10 -#define BLOCK_ADRS 0x11 -#define CMD_PARM 0x14 -#define PAGE_ADRS 0x15 - -#define OVERWRITE_FLAG 0x16 -#define MANAGEMEN_FLAG 0x17 -#define LOGICAL_ADRS 0x18 -#define RESERVE_AREA 0x1A - -#define PRO_INT_REG 0x01 -#define PRO_STATUS_REG 0x02 -#define PRO_TYPE_REG 0x04 -#define PRO_IF_mode_REG 0x05 -#define PRO_CATEGORY_REG 0x06 -#define PRO_CLASS_REG 0x07 - -#define PRO_SYSTEM_PARAM 0x10 -#define PRO_DATA_COUNT1 0x11 -#define PRO_DATA_COUNT0 0x12 -#define PRO_DATA_ADDR3 0x13 -#define PRO_DATA_ADDR2 0x14 -#define PRO_DATA_ADDR1 0x15 -#define PRO_DATA_ADDR0 0x16 - -#define PRO_TPC_PARM 0x17 -#define PRO_CMD_PARM 0x18 - -#define INT_REG_CED 0x80 -#define INT_REG_ERR 0x40 -#define INT_REG_BREQ 0x20 -#define INT_REG_CMDNK 0x01 - -#define BLOCK_BOOT 0xC0 -#define BLOCK_OK 0x80 -#define PAGE_OK 0x60 -#define DATA_COMPL 0x10 - -#define NOT_BOOT_BLOCK 0x4 -#define NOT_TRANSLATION_TABLE 0x8 - -#define HEADER_ID0 PPBUF_BASE2 -#define HEADER_ID1 (PPBUF_BASE2 + 1) -#define DISABLED_BLOCK0 (PPBUF_BASE2 + 0x170 + 4) -#define DISABLED_BLOCK1 (PPBUF_BASE2 + 0x170 + 5) -#define DISABLED_BLOCK2 (PPBUF_BASE2 + 0x170 + 6) -#define DISABLED_BLOCK3 (PPBUF_BASE2 + 0x170 + 7) -#define BLOCK_SIZE_0 (PPBUF_BASE2 + 0x1a0 + 2) -#define BLOCK_SIZE_1 (PPBUF_BASE2 + 0x1a0 + 3) -#define BLOCK_COUNT_0 (PPBUF_BASE2 + 0x1a0 + 4) -#define BLOCK_COUNT_1 (PPBUF_BASE2 + 0x1a0 + 5) -#define EBLOCK_COUNT_0 (PPBUF_BASE2 + 0x1a0 + 6) -#define EBLOCK_COUNT_1 (PPBUF_BASE2 + 0x1a0 + 7) -#define PAGE_SIZE_0 (PPBUF_BASE2 + 0x1a0 + 8) -#define PAGE_SIZE_1 (PPBUF_BASE2 + 0x1a0 + 9) - -#define MS_device_type (PPBUF_BASE2 + 0x1D8) - -#define MS_4bit_support (PPBUF_BASE2 + 0x1D3) - -#define set_PS_NG 1 -#define set_PS_error 0 - -#define PARALLEL_8BIT_IF 0x40 -#define PARALLEL_4BIT_IF 0x00 -#define SERIAL_IF 0x80 - -#define BUF_FULL 0x10 -#define BUF_EMPTY 0x20 - -#define MEDIA_BUSY 0x80 -#define FLASH_BUSY 0x40 -#define DATA_ERROR 0x20 -#define STS_UCDT 0x10 -#define EXTRA_ERROR 0x08 -#define STS_UCEX 0x04 -#define FLAG_ERROR 0x02 -#define STS_UCFG 0x01 - -#define MS_SHORT_DATA_LEN 32 - -#define FORMAT_SUCCESS 0 -#define FORMAT_FAIL 1 -#define FORMAT_IN_PROGRESS 2 - -#define MS_SET_BAD_BLOCK_FLG(ms_card) ((ms_card)->multi_flag |= 0x80) -#define MS_CLR_BAD_BLOCK_FLG(ms_card) ((ms_card)->multi_flag &= 0x7F) -#define MS_TST_BAD_BLOCK_FLG(ms_card) ((ms_card)->multi_flag & 0x80) - -void mspro_polling_format_status(struct rtsx_chip *chip); - -void mspro_stop_seq_mode(struct rtsx_chip *chip); -int reset_ms_card(struct rtsx_chip *chip); -int ms_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, - u32 start_sector, u16 sector_cnt); -int mspro_format(struct scsi_cmnd *srb, struct rtsx_chip *chip, - int short_data_len, bool quick_format); -void ms_free_l2p_tbl(struct rtsx_chip *chip); -void ms_cleanup_work(struct rtsx_chip *chip); -int ms_power_off_card3v3(struct rtsx_chip *chip); -int release_ms_card(struct rtsx_chip *chip); -#ifdef MS_DELAY_WRITE -int ms_delay_write(struct rtsx_chip *chip); -#endif - -#ifdef SUPPORT_MAGIC_GATE -int mg_set_leaf_id(struct scsi_cmnd *srb, struct rtsx_chip *chip); -int mg_get_local_EKB(struct scsi_cmnd *srb, struct rtsx_chip *chip); -int mg_chg(struct scsi_cmnd *srb, struct rtsx_chip *chip); -int mg_get_rsp_chg(struct scsi_cmnd *srb, struct rtsx_chip *chip); -int mg_rsp(struct scsi_cmnd *srb, struct rtsx_chip *chip); -int mg_get_ICV(struct scsi_cmnd *srb, struct rtsx_chip *chip); -int mg_set_ICV(struct scsi_cmnd *srb, struct rtsx_chip *chip); -#endif - -#endif /* __REALTEK_RTSX_MS_H */ diff --git a/drivers/staging/rts5208/rtsx.c b/drivers/staging/rts5208/rtsx.c deleted file mode 100644 index c4f54c311d05..000000000000 --- a/drivers/staging/rts5208/rtsx.c +++ /dev/null @@ -1,987 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Driver for Realtek PCI-Express card reader - * - * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. - * - * Author: - * Wei WANG (wei_wang@xxxxxxxxxxxxxx) - * Micky Ching (micky_ching@xxxxxxxxxxxxxx) - */ - -#include <linux/blkdev.h> -#include <linux/kthread.h> -#include <linux/sched.h> -#include <linux/workqueue.h> - -#include "rtsx.h" -#include "ms.h" -#include "sd.h" -#include "xd.h" - -MODULE_DESCRIPTION("Realtek PCI-Express card reader rts5208/rts5288 driver"); -MODULE_LICENSE("GPL"); - -static unsigned int delay_use = 1; -module_param(delay_use, uint, 0644); -MODULE_PARM_DESC(delay_use, "seconds to delay before using a new device"); - -static int ss_en; -module_param(ss_en, int, 0644); -MODULE_PARM_DESC(ss_en, "enable selective suspend"); - -static int ss_interval = 50; -module_param(ss_interval, int, 0644); -MODULE_PARM_DESC(ss_interval, "Interval to enter ss state in seconds"); - -static int auto_delink_en; -module_param(auto_delink_en, int, 0644); -MODULE_PARM_DESC(auto_delink_en, "enable auto delink"); - -static unsigned char aspm_l0s_l1_en; -module_param(aspm_l0s_l1_en, byte, 0644); -MODULE_PARM_DESC(aspm_l0s_l1_en, "enable device aspm"); - -static int msi_en; -module_param(msi_en, int, 0644); -MODULE_PARM_DESC(msi_en, "enable msi"); - -static irqreturn_t rtsx_interrupt(int irq, void *dev_id); - -/*********************************************************************** - * Host functions - ***********************************************************************/ - -static const char *host_info(struct Scsi_Host *host) -{ - return "SCSI emulation for PCI-Express Mass Storage devices"; -} - -static int slave_alloc(struct scsi_device *sdev) -{ - /* - * Set the INQUIRY transfer length to 36. We don't use any of - * the extra data and many devices choke if asked for more or - * less than 36 bytes. - */ - sdev->inquiry_len = 36; - return 0; -} - -static int slave_configure(struct scsi_device *sdev) -{ - /* Set the SCSI level to at least 2. We'll leave it at 3 if that's - * what is originally reported. We need this to avoid confusing - * the SCSI layer with devices that report 0 or 1, but need 10-byte - * commands (ala ATAPI devices behind certain bridges, or devices - * which simply have broken INQUIRY data). - * - * NOTE: This means /dev/sg programs (ala cdrecord) will get the - * actual information. This seems to be the preference for - * programs like that. - * - * NOTE: This also means that /proc/scsi/scsi and sysfs may report - * the actual value or the modified one, depending on where the - * data comes from. - */ - if (sdev->scsi_level < SCSI_2) { - sdev->scsi_level = SCSI_2; - sdev->sdev_target->scsi_level = SCSI_2; - } - - return 0; -} - -/*********************************************************************** - * /proc/scsi/ functions - ***********************************************************************/ - -/* we use this macro to help us write into the buffer */ -#undef SPRINTF -#define SPRINTF(args...) \ - do { \ - if (pos < buffer + length) \ - pos += sprintf(pos, ## args); \ - } while (0) - -/* queue a command */ -/* This is always called with spin_lock_irq(host->host_lock) held */ -static int queuecommand_lck(struct scsi_cmnd *srb) -{ - void (*done)(struct scsi_cmnd *) = scsi_done; - struct rtsx_dev *dev = host_to_rtsx(srb->device->host); - struct rtsx_chip *chip = dev->chip; - - /* check for state-transition errors */ - if (chip->srb) { - dev_err(&dev->pci->dev, "Error: chip->srb = %p\n", - chip->srb); - return SCSI_MLQUEUE_HOST_BUSY; - } - - /* fail the command if we are disconnecting */ - if (rtsx_chk_stat(chip, RTSX_STAT_DISCONNECT)) { - dev_info(&dev->pci->dev, "Fail command during disconnect\n"); - srb->result = DID_NO_CONNECT << 16; - done(srb); - return 0; - } - - /* enqueue the command and wake up the control thread */ - chip->srb = srb; - complete(&dev->cmnd_ready); - - return 0; -} - -static DEF_SCSI_QCMD(queuecommand) - -/*********************************************************************** - * Error handling functions - ***********************************************************************/ - -/* Command timeout and abort */ -static int command_abort(struct scsi_cmnd *srb) -{ - struct Scsi_Host *host = srb->device->host; - struct rtsx_dev *dev = host_to_rtsx(host); - struct rtsx_chip *chip = dev->chip; - - spin_lock_irq(host->host_lock); - - /* Is this command still active? */ - if (chip->srb != srb) { - spin_unlock_irq(host->host_lock); - dev_info(&dev->pci->dev, "-- nothing to abort\n"); - return FAILED; - } - - rtsx_set_stat(chip, RTSX_STAT_ABORT); - - spin_unlock_irq(host->host_lock); - - /* Wait for the aborted command to finish */ - wait_for_completion(&dev->notify); - - return SUCCESS; -} - -/* - * This invokes the transport reset mechanism to reset the state of the - * device - */ -static int device_reset(struct scsi_cmnd *srb) -{ - return SUCCESS; -} - -/* - * this defines our host template, with which we'll allocate hosts - */ - -static const struct scsi_host_template rtsx_host_template = { - /* basic userland interface stuff */ - .name = CR_DRIVER_NAME, - .proc_name = CR_DRIVER_NAME, - .info = host_info, - - /* command interface -- queued only */ - .queuecommand = queuecommand, - - /* error and abort handlers */ - .eh_abort_handler = command_abort, - .eh_device_reset_handler = device_reset, - - /* queue commands only, only one command per LUN */ - .can_queue = 1, - - /* unknown initiator id */ - .this_id = -1, - - .slave_alloc = slave_alloc, - .slave_configure = slave_configure, - - /* lots of sg segments can be handled */ - .sg_tablesize = SG_ALL, - - /* limit the total size of a transfer to 120 KB */ - .max_sectors = 240, - - /* - * Scatter-gather buffers (all but the last) must have a length - * divisible by the bulk maxpacket size. Otherwise a data packet - * would end up being short, causing a premature end to the data - * transfer. Since high-speed bulk pipes have a maxpacket size - * of 512, we'll use that as the scsi device queue's DMA alignment - * mask. Guaranteeing proper alignment of the first buffer will - * have the desired effect because, except at the beginning and - * the end, scatter-gather buffers follow page boundaries. - */ - .dma_alignment = 511, - - /* emulated HBA */ - .emulated = 1, - - /* we do our own delay after a device or bus reset */ - .skip_settle_delay = 1, - - /* module management */ - .module = THIS_MODULE -}; - -static int rtsx_acquire_irq(struct rtsx_dev *dev) -{ - struct rtsx_chip *chip = dev->chip; - - dev_info(&dev->pci->dev, "%s: chip->msi_en = %d, pci->irq = %d\n", - __func__, chip->msi_en, dev->pci->irq); - - if (request_irq(dev->pci->irq, rtsx_interrupt, - chip->msi_en ? 0 : IRQF_SHARED, - CR_DRIVER_NAME, dev)) { - dev_err(&dev->pci->dev, - "rtsx: unable to grab IRQ %d, disabling device\n", - dev->pci->irq); - return -1; - } - - dev->irq = dev->pci->irq; - pci_intx(dev->pci, !chip->msi_en); - - return 0; -} - -/* - * power management - */ -static int __maybe_unused rtsx_suspend(struct device *dev_d) -{ - struct pci_dev *pci = to_pci_dev(dev_d); - struct rtsx_dev *dev = pci_get_drvdata(pci); - struct rtsx_chip *chip; - - if (!dev) - return 0; - - /* lock the device pointers */ - mutex_lock(&dev->dev_mutex); - - chip = dev->chip; - - rtsx_do_before_power_down(chip, PM_S3); - - if (dev->irq >= 0) { - free_irq(dev->irq, (void *)dev); - dev->irq = -1; - } - - if (chip->msi_en) - pci_free_irq_vectors(pci); - - device_wakeup_enable(dev_d); - - /* unlock the device pointers */ - mutex_unlock(&dev->dev_mutex); - - return 0; -} - -static int __maybe_unused rtsx_resume(struct device *dev_d) -{ - struct pci_dev *pci = to_pci_dev(dev_d); - struct rtsx_dev *dev = pci_get_drvdata(pci); - struct rtsx_chip *chip; - - if (!dev) - return 0; - - chip = dev->chip; - - /* lock the device pointers */ - mutex_lock(&dev->dev_mutex); - - pci_set_master(pci); - - if (chip->msi_en) { - if (pci_alloc_irq_vectors(pci, 1, 1, PCI_IRQ_MSI) < 0) - chip->msi_en = 0; - } - - if (rtsx_acquire_irq(dev) < 0) { - /* unlock the device pointers */ - mutex_unlock(&dev->dev_mutex); - return -EIO; - } - - rtsx_write_register(chip, HOST_SLEEP_STATE, 0x03, 0x00); - rtsx_init_chip(chip); - - /* unlock the device pointers */ - mutex_unlock(&dev->dev_mutex); - - return 0; -} - -static void rtsx_shutdown(struct pci_dev *pci) -{ - struct rtsx_dev *dev = pci_get_drvdata(pci); - struct rtsx_chip *chip; - - if (!dev) - return; - - chip = dev->chip; - - rtsx_do_before_power_down(chip, PM_S1); - - if (dev->irq >= 0) { - free_irq(dev->irq, (void *)dev); - dev->irq = -1; - } - - if (chip->msi_en) - pci_free_irq_vectors(pci); - - pci_disable_device(pci); -} - -static int rtsx_control_thread(void *__dev) -{ - struct rtsx_dev *dev = __dev; - struct rtsx_chip *chip = dev->chip; - struct Scsi_Host *host = rtsx_to_host(dev); - - for (;;) { - if (wait_for_completion_interruptible(&dev->cmnd_ready)) - break; - - /* lock the device pointers */ - mutex_lock(&dev->dev_mutex); - - /* if the device has disconnected, we are free to exit */ - if (rtsx_chk_stat(chip, RTSX_STAT_DISCONNECT)) { - dev_info(&dev->pci->dev, "-- rtsx-control exiting\n"); - mutex_unlock(&dev->dev_mutex); - break; - } - - /* lock access to the state */ - spin_lock_irq(host->host_lock); - - /* has the command aborted ? */ - if (rtsx_chk_stat(chip, RTSX_STAT_ABORT)) { - chip->srb->result = DID_ABORT << 16; - goto skip_for_abort; - } - - spin_unlock_irq(host->host_lock); - - /* reject the command if the direction indicator - * is UNKNOWN - */ - if (chip->srb->sc_data_direction == DMA_BIDIRECTIONAL) { - dev_err(&dev->pci->dev, "UNKNOWN data direction\n"); - chip->srb->result = DID_ERROR << 16; - } else if (chip->srb->device->id) { - /* reject if target != 0 or if LUN is higher than - * the maximum known LUN - */ - dev_err(&dev->pci->dev, "Bad target number (%d:%d)\n", - chip->srb->device->id, - (u8)chip->srb->device->lun); - chip->srb->result = DID_BAD_TARGET << 16; - } else if (chip->srb->device->lun > chip->max_lun) { - dev_err(&dev->pci->dev, "Bad LUN (%d:%d)\n", - chip->srb->device->id, - (u8)chip->srb->device->lun); - chip->srb->result = DID_BAD_TARGET << 16; - } else { - /* we've got a command, let's do it! */ - scsi_show_command(chip); - rtsx_invoke_transport(chip->srb, chip); - } - - /* lock access to the state */ - spin_lock_irq(host->host_lock); - - /* did the command already complete because of a disconnect? */ - if (!chip->srb) - ; /* nothing to do */ - - /* indicate that the command is done */ - else if (chip->srb->result != DID_ABORT << 16) { - scsi_done(chip->srb); - } else { -skip_for_abort: - dev_err(&dev->pci->dev, "scsi command aborted\n"); - } - - if (rtsx_chk_stat(chip, RTSX_STAT_ABORT)) { - complete(&dev->notify); - - rtsx_set_stat(chip, RTSX_STAT_IDLE); - } - - /* finished working on this command */ - chip->srb = NULL; - spin_unlock_irq(host->host_lock); - - /* unlock the device pointers */ - mutex_unlock(&dev->dev_mutex); - } /* for (;;) */ - - /* notify the exit routine that we're actually exiting now - * - * complete()/wait_for_completion() is similar to up()/down(), - * except that complete() is safe in the case where the structure - * is getting deleted in a parallel mode of execution (i.e. just - * after the down() -- that's necessary for the thread-shutdown - * case. - * - * kthread_complete_and_exit() goes even further than this -- - * it is safe in the case that the thread of the caller is going away - * (not just the structure) -- this is necessary for the module-remove - * case. This is important in preemption kernels, which transfer the - * flow of execution immediately upon a complete(). - */ - kthread_complete_and_exit(&dev->control_exit, 0); -} - -static int rtsx_polling_thread(void *__dev) -{ - struct rtsx_dev *dev = __dev; - struct rtsx_chip *chip = dev->chip; - struct sd_info *sd_card = &chip->sd_card; - struct xd_info *xd_card = &chip->xd_card; - struct ms_info *ms_card = &chip->ms_card; - - sd_card->cleanup_counter = 0; - xd_card->cleanup_counter = 0; - ms_card->cleanup_counter = 0; - - /* Wait until SCSI scan finished */ - wait_timeout((delay_use + 5) * 1000); - - for (;;) { - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(msecs_to_jiffies(POLLING_INTERVAL)); - - /* lock the device pointers */ - mutex_lock(&dev->dev_mutex); - - /* if the device has disconnected, we are free to exit */ - if (rtsx_chk_stat(chip, RTSX_STAT_DISCONNECT)) { - dev_info(&dev->pci->dev, "-- rtsx-polling exiting\n"); - mutex_unlock(&dev->dev_mutex); - break; - } - - mutex_unlock(&dev->dev_mutex); - - mspro_polling_format_status(chip); - - /* lock the device pointers */ - mutex_lock(&dev->dev_mutex); - - rtsx_polling_func(chip); - - /* unlock the device pointers */ - mutex_unlock(&dev->dev_mutex); - } - - kthread_complete_and_exit(&dev->polling_exit, 0); -} - -/* - * interrupt handler - */ -static irqreturn_t rtsx_interrupt(int irq, void *dev_id) -{ - struct rtsx_dev *dev = dev_id; - struct rtsx_chip *chip; - int retval; - u32 status; - - if (dev) - chip = dev->chip; - else - return IRQ_NONE; - - if (!chip) - return IRQ_NONE; - - spin_lock(&dev->reg_lock); - - retval = rtsx_pre_handle_interrupt(chip); - if (retval == STATUS_FAIL) { - spin_unlock(&dev->reg_lock); - if (chip->int_reg == 0xFFFFFFFF) - return IRQ_HANDLED; - return IRQ_NONE; - } - - status = chip->int_reg; - - if (dev->check_card_cd) { - if (!(dev->check_card_cd & status)) { - /* card not exist, return TRANS_RESULT_FAIL */ - dev->trans_result = TRANS_RESULT_FAIL; - if (dev->done) - complete(dev->done); - goto exit; - } - } - - if (status & (NEED_COMPLETE_INT | DELINK_INT)) { - if (status & (TRANS_FAIL_INT | DELINK_INT)) { - if (status & DELINK_INT) - RTSX_SET_DELINK(chip); - dev->trans_result = TRANS_RESULT_FAIL; - if (dev->done) - complete(dev->done); - } else if (status & TRANS_OK_INT) { - dev->trans_result = TRANS_RESULT_OK; - if (dev->done) - complete(dev->done); - } else if (status & DATA_DONE_INT) { - dev->trans_result = TRANS_NOT_READY; - if (dev->done && dev->trans_state == STATE_TRANS_SG) - complete(dev->done); - } - } - -exit: - spin_unlock(&dev->reg_lock); - return IRQ_HANDLED; -} - -/* Release all our dynamic resources */ -static void rtsx_release_resources(struct rtsx_dev *dev) -{ - dev_info(&dev->pci->dev, "-- %s\n", __func__); - - /* Tell the control thread to exit. The SCSI host must - * already have been removed so it won't try to queue - * any more commands. - */ - dev_info(&dev->pci->dev, "-- sending exit command to thread\n"); - complete(&dev->cmnd_ready); - if (dev->ctl_thread) - wait_for_completion(&dev->control_exit); - if (dev->polling_thread) - wait_for_completion(&dev->polling_exit); - - wait_timeout(200); - - if (dev->rtsx_resv_buf) { - dev->chip->host_cmds_ptr = NULL; - dev->chip->host_sg_tbl_ptr = NULL; - } - - if (dev->irq > 0) - free_irq(dev->irq, (void *)dev); - if (dev->chip->msi_en) - pci_free_irq_vectors(dev->pci); - if (dev->remap_addr) - iounmap(dev->remap_addr); - - rtsx_release_chip(dev->chip); - kfree(dev->chip); -} - -/* - * First stage of disconnect processing: stop all commands and remove - * the host - */ -static void quiesce_and_remove_host(struct rtsx_dev *dev) -{ - struct Scsi_Host *host = rtsx_to_host(dev); - struct rtsx_chip *chip = dev->chip; - - /* - * Prevent new transfers, stop the current command, and - * interrupt a SCSI-scan or device-reset delay - */ - mutex_lock(&dev->dev_mutex); - spin_lock_irq(host->host_lock); - rtsx_set_stat(chip, RTSX_STAT_DISCONNECT); - spin_unlock_irq(host->host_lock); - mutex_unlock(&dev->dev_mutex); - wake_up(&dev->delay_wait); - wait_for_completion(&dev->scanning_done); - - /* Wait some time to let other threads exist */ - wait_timeout(100); - - /* - * queuecommand won't accept any new commands and the control - * thread won't execute a previously-queued command. If there - * is such a command pending, complete it with an error. - */ - mutex_lock(&dev->dev_mutex); - if (chip->srb) { - chip->srb->result = DID_NO_CONNECT << 16; - spin_lock_irq(host->host_lock); - scsi_done(dev->chip->srb); - chip->srb = NULL; - spin_unlock_irq(host->host_lock); - } - mutex_unlock(&dev->dev_mutex); - - /* Now we own no commands so it's safe to remove the SCSI host */ - scsi_remove_host(host); -} - -/* Second stage of disconnect processing: deallocate all resources */ -static void release_everything(struct rtsx_dev *dev) -{ - rtsx_release_resources(dev); - - /* - * Drop our reference to the host; the SCSI core will free it - * when the refcount becomes 0. - */ - scsi_host_put(rtsx_to_host(dev)); -} - -/* Thread to carry out delayed SCSI-device scanning */ -static int rtsx_scan_thread(void *__dev) -{ - struct rtsx_dev *dev = __dev; - struct rtsx_chip *chip = dev->chip; - - /* Wait for the timeout to expire or for a disconnect */ - if (delay_use > 0) { - dev_info(&dev->pci->dev, - "%s: waiting for device to settle before scanning\n", - CR_DRIVER_NAME); - wait_event_interruptible_timeout - (dev->delay_wait, - rtsx_chk_stat(chip, RTSX_STAT_DISCONNECT), - delay_use * HZ); - } - - /* If the device is still connected, perform the scanning */ - if (!rtsx_chk_stat(chip, RTSX_STAT_DISCONNECT)) { - scsi_scan_host(rtsx_to_host(dev)); - dev_info(&dev->pci->dev, "%s: device scan complete\n", - CR_DRIVER_NAME); - - /* Should we unbind if no devices were detected? */ - } - - kthread_complete_and_exit(&dev->scanning_done, 0); -} - -static void rtsx_init_options(struct rtsx_chip *chip) -{ - chip->vendor_id = chip->rtsx->pci->vendor; - chip->product_id = chip->rtsx->pci->device; - chip->adma_mode = 1; - chip->lun_mc = 0; - chip->driver_first_load = 1; -#ifdef HW_AUTO_SWITCH_SD_BUS - chip->sdio_in_charge = 0; -#endif - - chip->mspro_formatter_enable = 1; - chip->ignore_sd = 0; - chip->use_hw_setting = 0; - chip->lun_mode = DEFAULT_SINGLE; - chip->auto_delink_en = auto_delink_en; - chip->ss_en = ss_en; - chip->ss_idle_period = ss_interval * 1000; - chip->remote_wakeup_en = 0; - chip->aspm_l0s_l1_en = aspm_l0s_l1_en; - chip->dynamic_aspm = 1; - chip->fpga_sd_sdr104_clk = CLK_200; - chip->fpga_sd_ddr50_clk = CLK_100; - chip->fpga_sd_sdr50_clk = CLK_100; - chip->fpga_sd_hs_clk = CLK_100; - chip->fpga_mmc_52m_clk = CLK_80; - chip->fpga_ms_hg_clk = CLK_80; - chip->fpga_ms_4bit_clk = CLK_80; - chip->fpga_ms_1bit_clk = CLK_40; - chip->asic_sd_sdr104_clk = 203; - chip->asic_sd_sdr50_clk = 98; - chip->asic_sd_ddr50_clk = 98; - chip->asic_sd_hs_clk = 98; - chip->asic_mmc_52m_clk = 98; - chip->asic_ms_hg_clk = 117; - chip->asic_ms_4bit_clk = 78; - chip->asic_ms_1bit_clk = 39; - chip->ssc_depth_sd_sdr104 = SSC_DEPTH_2M; - chip->ssc_depth_sd_sdr50 = SSC_DEPTH_2M; - chip->ssc_depth_sd_ddr50 = SSC_DEPTH_1M; - chip->ssc_depth_sd_hs = SSC_DEPTH_1M; - chip->ssc_depth_mmc_52m = SSC_DEPTH_1M; - chip->ssc_depth_ms_hg = SSC_DEPTH_1M; - chip->ssc_depth_ms_4bit = SSC_DEPTH_512K; - chip->ssc_depth_low_speed = SSC_DEPTH_512K; - chip->ssc_en = 1; - chip->sd_speed_prior = 0x01040203; - chip->sd_current_prior = 0x00010203; - chip->sd_ctl = SD_PUSH_POINT_AUTO | - SD_SAMPLE_POINT_AUTO | - SUPPORT_MMC_DDR_MODE; - chip->sd_ddr_tx_phase = 0; - chip->mmc_ddr_tx_phase = 1; - chip->sd_default_tx_phase = 15; - chip->sd_default_rx_phase = 15; - chip->pmos_pwr_on_interval = 200; - chip->sd_voltage_switch_delay = 1000; - chip->ms_power_class_en = 3; - - chip->sd_400mA_ocp_thd = 1; - chip->sd_800mA_ocp_thd = 5; - chip->ms_ocp_thd = 2; - - chip->card_drive_sel = 0x55; - chip->sd30_drive_sel_1v8 = 0x03; - chip->sd30_drive_sel_3v3 = 0x01; - - chip->do_delink_before_power_down = 1; - chip->auto_power_down = 1; - chip->polling_config = 0; - - chip->force_clkreq_0 = 1; - chip->ft2_fast_mode = 0; - - chip->sdio_retry_cnt = 1; - - chip->xd_timeout = 2000; - chip->sd_timeout = 10000; - chip->ms_timeout = 2000; - chip->mspro_timeout = 15000; - - chip->power_down_in_ss = 1; - - chip->sdr104_en = 1; - chip->sdr50_en = 1; - chip->ddr50_en = 1; - - chip->delink_stage1_step = 100; - chip->delink_stage2_step = 40; - chip->delink_stage3_step = 20; - - chip->auto_delink_in_L1 = 1; - chip->blink_led = 1; - chip->msi_en = msi_en; - chip->hp_watch_bios_hotplug = 0; - chip->max_payload = 0; - chip->phy_voltage = 0; - - chip->support_ms_8bit = 1; - chip->s3_pwr_off_delay = 1000; -} - -static int rtsx_probe(struct pci_dev *pci, - const struct pci_device_id *pci_id) -{ - struct Scsi_Host *host; - struct rtsx_dev *dev; - int err = 0; - struct task_struct *th; - - dev_dbg(&pci->dev, "Realtek PCI-E card reader detected\n"); - - err = pcim_enable_device(pci); - if (err < 0) { - dev_err(&pci->dev, "PCI enable device failed!\n"); - return err; - } - - err = pci_request_regions(pci, CR_DRIVER_NAME); - if (err < 0) { - dev_err(&pci->dev, "PCI request regions for %s failed!\n", - CR_DRIVER_NAME); - return err; - } - - /* - * Ask the SCSI layer to allocate a host structure, with extra - * space at the end for our private rtsx_dev structure. - */ - host = scsi_host_alloc(&rtsx_host_template, sizeof(*dev)); - if (!host) { - dev_err(&pci->dev, "Unable to allocate the scsi host\n"); - err = -ENOMEM; - goto scsi_host_alloc_fail; - } - - dev = host_to_rtsx(host); - memset(dev, 0, sizeof(struct rtsx_dev)); - - dev->chip = kzalloc(sizeof(*dev->chip), GFP_KERNEL); - if (!dev->chip) { - err = -ENOMEM; - goto chip_alloc_fail; - } - - spin_lock_init(&dev->reg_lock); - mutex_init(&dev->dev_mutex); - init_completion(&dev->cmnd_ready); - init_completion(&dev->control_exit); - init_completion(&dev->polling_exit); - init_completion(&dev->notify); - init_completion(&dev->scanning_done); - init_waitqueue_head(&dev->delay_wait); - - dev->pci = pci; - dev->irq = -1; - - dev_info(&pci->dev, "Resource length: 0x%x\n", - (unsigned int)pci_resource_len(pci, 0)); - dev->addr = pci_resource_start(pci, 0); - dev->remap_addr = ioremap(dev->addr, pci_resource_len(pci, 0)); - if (!dev->remap_addr) { - dev_err(&pci->dev, "ioremap error\n"); - err = -ENXIO; - goto ioremap_fail; - } - - /* - * Using "unsigned long" cast here to eliminate gcc warning in - * 64-bit system - */ - dev_info(&pci->dev, "Original address: 0x%lx, remapped address: 0x%lx\n", - (unsigned long)(dev->addr), (unsigned long)(dev->remap_addr)); - - dev->rtsx_resv_buf = dmam_alloc_coherent(&pci->dev, RTSX_RESV_BUF_LEN, - &dev->rtsx_resv_buf_addr, - GFP_KERNEL); - if (!dev->rtsx_resv_buf) { - dev_err(&pci->dev, "alloc dma buffer fail\n"); - err = -ENXIO; - goto dma_alloc_fail; - } - dev->chip->host_cmds_ptr = dev->rtsx_resv_buf; - dev->chip->host_cmds_addr = dev->rtsx_resv_buf_addr; - dev->chip->host_sg_tbl_ptr = dev->rtsx_resv_buf + HOST_CMDS_BUF_LEN; - dev->chip->host_sg_tbl_addr = dev->rtsx_resv_buf_addr + - HOST_CMDS_BUF_LEN; - - dev->chip->rtsx = dev; - - rtsx_init_options(dev->chip); - - dev_info(&pci->dev, "pci->irq = %d\n", pci->irq); - - if (dev->chip->msi_en) { - if (pci_alloc_irq_vectors(pci, 1, 1, PCI_IRQ_MSI) < 0) - dev->chip->msi_en = 0; - } - - if (rtsx_acquire_irq(dev) < 0) { - err = -EBUSY; - goto irq_acquire_fail; - } - - pci_set_master(pci); - synchronize_irq(dev->irq); - - rtsx_init_chip(dev->chip); - - /* - * set the supported max_lun and max_id for the scsi host - * NOTE: the minimal value of max_id is 1 - */ - host->max_id = 1; - host->max_lun = dev->chip->max_lun; - - /* Start up our control thread */ - th = kthread_run(rtsx_control_thread, dev, CR_DRIVER_NAME); - if (IS_ERR(th)) { - dev_err(&pci->dev, "Unable to start control thread\n"); - err = PTR_ERR(th); - goto control_thread_fail; - } - dev->ctl_thread = th; - - err = scsi_add_host(host, &pci->dev); - if (err) { - dev_err(&pci->dev, "Unable to add the scsi host\n"); - goto scsi_add_host_fail; - } - - /* Start up the thread for delayed SCSI-device scanning */ - th = kthread_run(rtsx_scan_thread, dev, "rtsx-scan"); - if (IS_ERR(th)) { - dev_err(&pci->dev, "Unable to start the device-scanning thread\n"); - complete(&dev->scanning_done); - err = PTR_ERR(th); - goto scan_thread_fail; - } - - /* Start up the thread for polling thread */ - th = kthread_run(rtsx_polling_thread, dev, "rtsx-polling"); - if (IS_ERR(th)) { - dev_err(&pci->dev, "Unable to start the device-polling thread\n"); - err = PTR_ERR(th); - goto scan_thread_fail; - } - dev->polling_thread = th; - - pci_set_drvdata(pci, dev); - - return 0; - - /* We come here if there are any problems */ -scan_thread_fail: - quiesce_and_remove_host(dev); -scsi_add_host_fail: - complete(&dev->cmnd_ready); - wait_for_completion(&dev->control_exit); -control_thread_fail: - free_irq(dev->irq, (void *)dev); - rtsx_release_chip(dev->chip); -irq_acquire_fail: - dev->chip->host_cmds_ptr = NULL; - dev->chip->host_sg_tbl_ptr = NULL; - if (dev->chip->msi_en) - pci_free_irq_vectors(dev->pci); -dma_alloc_fail: - iounmap(dev->remap_addr); -ioremap_fail: - kfree(dev->chip); -chip_alloc_fail: - dev_err(&pci->dev, "%s failed\n", __func__); - scsi_host_put(host); -scsi_host_alloc_fail: - pci_release_regions(pci); - return err; -} - -static void rtsx_remove(struct pci_dev *pci) -{ - struct rtsx_dev *dev = pci_get_drvdata(pci); - - quiesce_and_remove_host(dev); - release_everything(dev); - pci_release_regions(pci); -} - -/* PCI IDs */ -static const struct pci_device_id rtsx_ids[] = { - { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x5208), - PCI_CLASS_OTHERS << 16, 0xFF0000 }, - { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x5288), - PCI_CLASS_OTHERS << 16, 0xFF0000 }, - { 0, }, -}; - -MODULE_DEVICE_TABLE(pci, rtsx_ids); - -static SIMPLE_DEV_PM_OPS(rtsx_pm_ops, rtsx_suspend, rtsx_resume); - -/* pci_driver definition */ -static struct pci_driver rtsx_driver = { - .name = CR_DRIVER_NAME, - .id_table = rtsx_ids, - .probe = rtsx_probe, - .remove = rtsx_remove, - .driver.pm = &rtsx_pm_ops, - .shutdown = rtsx_shutdown, -}; - -module_pci_driver(rtsx_driver); diff --git a/drivers/staging/rts5208/rtsx.h b/drivers/staging/rts5208/rtsx.h deleted file mode 100644 index ec6f5b07390b..000000000000 --- a/drivers/staging/rts5208/rtsx.h +++ /dev/null @@ -1,164 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Driver for Realtek PCI-Express card reader - * - * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. - * - * Author: - * Wei WANG (wei_wang@xxxxxxxxxxxxxx) - * Micky Ching (micky_ching@xxxxxxxxxxxxxx) - */ - -#ifndef __REALTEK_RTSX_H -#define __REALTEK_RTSX_H - -#include <linux/io.h> -#include <linux/bitops.h> -#include <linux/delay.h> -#include <linux/interrupt.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/slab.h> -#include <linux/pci.h> -#include <linux/mutex.h> -#include <linux/cdrom.h> -#include <linux/workqueue.h> -#include <linux/timer.h> -#include <linux/time64.h> - -#include <scsi/scsi.h> -#include <scsi/scsi_cmnd.h> -#include <scsi/scsi_device.h> -#include <scsi/scsi_devinfo.h> -#include <scsi/scsi_eh.h> -#include <scsi/scsi_host.h> - -#define CR_DRIVER_NAME "rts5208" - -/* - * macros for easy use - */ -#define wait_timeout_x(task_state, msecs) \ -do { \ - set_current_state((task_state)); \ - schedule_timeout((msecs) * HZ / 1000); \ -} while (0) -#define wait_timeout(msecs) wait_timeout_x(TASK_INTERRUPTIBLE, (msecs)) - -#define STATE_TRANS_NONE 0 -#define STATE_TRANS_CMD 1 -#define STATE_TRANS_BUF 2 -#define STATE_TRANS_SG 3 - -#define TRANS_NOT_READY 0 -#define TRANS_RESULT_OK 1 -#define TRANS_RESULT_FAIL 2 - -#define SCSI_LUN(srb) ((srb)->device->lun) - -struct rtsx_chip; - -struct rtsx_dev { - struct pci_dev *pci; - - /* pci resources */ - unsigned long addr; - void __iomem *remap_addr; - int irq; - - /* locks */ - spinlock_t reg_lock; - - struct task_struct *ctl_thread; /* the control thread */ - struct task_struct *polling_thread; /* the polling thread */ - - /* mutual exclusion and synchronization structures */ - struct completion cmnd_ready; /* to sleep thread on */ - struct completion control_exit; /* control thread exit */ - struct completion polling_exit; /* polling thread exit */ - struct completion notify; /* thread begin/end */ - struct completion scanning_done; /* wait for scan thread */ - - wait_queue_head_t delay_wait; /* wait during scan, reset */ - struct mutex dev_mutex; - - /* host reserved buffer */ - void *rtsx_resv_buf; - dma_addr_t rtsx_resv_buf_addr; - - char trans_result; - char trans_state; - - struct completion *done; - /* Whether interrupt handler should care card cd info */ - u32 check_card_cd; - - struct rtsx_chip *chip; -}; - -/* Convert between rtsx_dev and the corresponding Scsi_Host */ -static inline struct Scsi_Host *rtsx_to_host(struct rtsx_dev *dev) -{ - return container_of((void *)dev, struct Scsi_Host, hostdata); -} - -static inline struct rtsx_dev *host_to_rtsx(struct Scsi_Host *host) -{ - return (struct rtsx_dev *)host->hostdata; -} - -#define lock_state(chip) spin_lock_irq(&((chip)->rtsx->reg_lock)) -#define unlock_state(chip) spin_unlock_irq(&((chip)->rtsx->reg_lock)) - -/* struct scsi_cmnd transfer buffer access utilities */ -enum xfer_buf_dir {TO_XFER_BUF, FROM_XFER_BUF}; - -#include "rtsx_chip.h" -#include "rtsx_transport.h" -#include "rtsx_scsi.h" -#include "rtsx_card.h" -#include "rtsx_sys.h" -#include "general.h" - -static inline void rtsx_writel(struct rtsx_chip *chip, u32 reg, u32 value) -{ - iowrite32(value, chip->rtsx->remap_addr + reg); -} - -static inline u32 rtsx_readl(struct rtsx_chip *chip, u32 reg) -{ - return ioread32(chip->rtsx->remap_addr + reg); -} - -static inline void rtsx_writew(struct rtsx_chip *chip, u32 reg, u16 value) -{ - iowrite16(value, chip->rtsx->remap_addr + reg); -} - -static inline u16 rtsx_readw(struct rtsx_chip *chip, u32 reg) -{ - return ioread16(chip->rtsx->remap_addr + reg); -} - -static inline void rtsx_writeb(struct rtsx_chip *chip, u32 reg, u8 value) -{ - iowrite8(value, chip->rtsx->remap_addr + reg); -} - -static inline u8 rtsx_readb(struct rtsx_chip *chip, u32 reg) -{ - return ioread8((chip)->rtsx->remap_addr + reg); -} - -static inline int rtsx_read_config_byte(struct rtsx_chip *chip, int where, u8 *val) -{ - return pci_read_config_byte(chip->rtsx->pci, where, val); -} - -static inline int rtsx_write_config_byte(struct rtsx_chip *chip, int where, u8 val) -{ - return pci_write_config_byte(chip->rtsx->pci, where, val); -} - -#endif /* __REALTEK_RTSX_H */ diff --git a/drivers/staging/rts5208/rtsx_card.c b/drivers/staging/rts5208/rtsx_card.c deleted file mode 100644 index 326b04756f62..000000000000 --- a/drivers/staging/rts5208/rtsx_card.c +++ /dev/null @@ -1,1151 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Driver for Realtek PCI-Express card reader - * - * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. - * - * Author: - * Wei WANG (wei_wang@xxxxxxxxxxxxxx) - * Micky Ching (micky_ching@xxxxxxxxxxxxxx) - */ - -#include <linux/blkdev.h> -#include <linux/kthread.h> -#include <linux/sched.h> -#include <linux/workqueue.h> -#include <linux/kernel.h> - -#include "rtsx.h" -#include "sd.h" -#include "xd.h" -#include "ms.h" - -void do_remaining_work(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &chip->sd_card; -#ifdef XD_DELAY_WRITE - struct xd_info *xd_card = &chip->xd_card; -#endif - struct ms_info *ms_card = &chip->ms_card; - - if (chip->card_ready & SD_CARD) { - if (sd_card->seq_mode) { - rtsx_set_stat(chip, RTSX_STAT_RUN); - sd_card->cleanup_counter++; - } else { - sd_card->cleanup_counter = 0; - } - } - -#ifdef XD_DELAY_WRITE - if (chip->card_ready & XD_CARD) { - if (xd_card->delay_write.delay_write_flag) { - rtsx_set_stat(chip, RTSX_STAT_RUN); - xd_card->cleanup_counter++; - } else { - xd_card->cleanup_counter = 0; - } - } -#endif - - if (chip->card_ready & MS_CARD) { - if (CHK_MSPRO(ms_card)) { - if (ms_card->seq_mode) { - rtsx_set_stat(chip, RTSX_STAT_RUN); - ms_card->cleanup_counter++; - } else { - ms_card->cleanup_counter = 0; - } - } else { -#ifdef MS_DELAY_WRITE - if (ms_card->delay_write.delay_write_flag) { - rtsx_set_stat(chip, RTSX_STAT_RUN); - ms_card->cleanup_counter++; - } else { - ms_card->cleanup_counter = 0; - } -#endif - } - } - - if (sd_card->cleanup_counter > POLLING_WAIT_CNT) - sd_cleanup_work(chip); - - if (xd_card->cleanup_counter > POLLING_WAIT_CNT) - xd_cleanup_work(chip); - - if (ms_card->cleanup_counter > POLLING_WAIT_CNT) - ms_cleanup_work(chip); -} - -void try_to_switch_sdio_ctrl(struct rtsx_chip *chip) -{ - u8 reg1 = 0, reg2 = 0; - - rtsx_read_register(chip, 0xFF34, ®1); - rtsx_read_register(chip, 0xFF38, ®2); - dev_dbg(rtsx_dev(chip), "reg 0xFF34: 0x%x, reg 0xFF38: 0x%x\n", - reg1, reg2); - if ((reg1 & 0xC0) && (reg2 & 0xC0)) { - chip->sd_int = 1; - rtsx_write_register(chip, SDIO_CTRL, 0xFF, - SDIO_BUS_CTRL | SDIO_CD_CTRL); - rtsx_write_register(chip, PWR_GATE_CTRL, - LDO3318_PWR_MASK, LDO_ON); - } -} - -#ifdef SUPPORT_SDIO_ASPM -void dynamic_configure_sdio_aspm(struct rtsx_chip *chip) -{ - u8 buf[12], reg; - int i; - - for (i = 0; i < 12; i++) - rtsx_read_register(chip, 0xFF08 + i, &buf[i]); - rtsx_read_register(chip, 0xFF25, ®); - if ((memcmp(buf, chip->sdio_raw_data, 12) != 0) || (reg & 0x03)) { - chip->sdio_counter = 0; - chip->sdio_idle = 0; - } else { - if (!chip->sdio_idle) { - chip->sdio_counter++; - if (chip->sdio_counter >= SDIO_IDLE_COUNT) { - chip->sdio_counter = 0; - chip->sdio_idle = 1; - } - } - } - memcpy(chip->sdio_raw_data, buf, 12); - - if (chip->sdio_idle) { - if (!chip->sdio_aspm) { - dev_dbg(rtsx_dev(chip), "SDIO enter ASPM!\n"); - rtsx_write_register(chip, ASPM_FORCE_CTL, 0xFC, - 0x30 | (chip->aspm_level[1] << 2)); - chip->sdio_aspm = 1; - } - } else { - if (chip->sdio_aspm) { - dev_dbg(rtsx_dev(chip), "SDIO exit ASPM!\n"); - rtsx_write_register(chip, ASPM_FORCE_CTL, 0xFC, 0x30); - chip->sdio_aspm = 0; - } - } -} -#endif - -void do_reset_sd_card(struct rtsx_chip *chip) -{ - int retval; - - dev_dbg(rtsx_dev(chip), "%s: %d, card2lun = 0x%x\n", __func__, - chip->sd_reset_counter, chip->card2lun[SD_CARD]); - - if (chip->card2lun[SD_CARD] >= MAX_ALLOWED_LUN_CNT) { - clear_bit(SD_NR, &chip->need_reset); - chip->sd_reset_counter = 0; - chip->sd_show_cnt = 0; - return; - } - - chip->rw_fail_cnt[chip->card2lun[SD_CARD]] = 0; - - rtsx_set_stat(chip, RTSX_STAT_RUN); - rtsx_write_register(chip, SDIO_CTRL, 0xFF, 0); - - retval = reset_sd_card(chip); - if (chip->need_release & SD_CARD) - return; - if (retval == STATUS_SUCCESS) { - clear_bit(SD_NR, &chip->need_reset); - chip->sd_reset_counter = 0; - chip->sd_show_cnt = 0; - chip->card_ready |= SD_CARD; - chip->card_fail &= ~SD_CARD; - chip->rw_card[chip->card2lun[SD_CARD]] = sd_rw; - } else { - if (chip->sd_io || chip->sd_reset_counter >= MAX_RESET_CNT) { - clear_bit(SD_NR, &chip->need_reset); - chip->sd_reset_counter = 0; - chip->sd_show_cnt = 0; - } else { - chip->sd_reset_counter++; - } - chip->card_ready &= ~SD_CARD; - chip->card_fail |= SD_CARD; - chip->capacity[chip->card2lun[SD_CARD]] = 0; - chip->rw_card[chip->card2lun[SD_CARD]] = NULL; - - rtsx_write_register(chip, CARD_OE, SD_OUTPUT_EN, 0); - if (!chip->ft2_fast_mode) - card_power_off(chip, SD_CARD); - if (chip->sd_io) { - chip->sd_int = 0; - try_to_switch_sdio_ctrl(chip); - } else { - disable_card_clock(chip, SD_CARD); - } - } -} - -void do_reset_xd_card(struct rtsx_chip *chip) -{ - int retval; - - dev_dbg(rtsx_dev(chip), "%s: %d, card2lun = 0x%x\n", __func__, - chip->xd_reset_counter, chip->card2lun[XD_CARD]); - - if (chip->card2lun[XD_CARD] >= MAX_ALLOWED_LUN_CNT) { - clear_bit(XD_NR, &chip->need_reset); - chip->xd_reset_counter = 0; - chip->xd_show_cnt = 0; - return; - } - - chip->rw_fail_cnt[chip->card2lun[XD_CARD]] = 0; - - rtsx_set_stat(chip, RTSX_STAT_RUN); - rtsx_write_register(chip, SDIO_CTRL, 0xFF, 0); - - retval = reset_xd_card(chip); - if (chip->need_release & XD_CARD) - return; - if (retval == STATUS_SUCCESS) { - clear_bit(XD_NR, &chip->need_reset); - chip->xd_reset_counter = 0; - chip->card_ready |= XD_CARD; - chip->card_fail &= ~XD_CARD; - chip->rw_card[chip->card2lun[XD_CARD]] = xd_rw; - } else { - if (chip->xd_reset_counter >= MAX_RESET_CNT) { - clear_bit(XD_NR, &chip->need_reset); - chip->xd_reset_counter = 0; - chip->xd_show_cnt = 0; - } else { - chip->xd_reset_counter++; - } - chip->card_ready &= ~XD_CARD; - chip->card_fail |= XD_CARD; - chip->capacity[chip->card2lun[XD_CARD]] = 0; - chip->rw_card[chip->card2lun[XD_CARD]] = NULL; - - rtsx_write_register(chip, CARD_OE, XD_OUTPUT_EN, 0); - if (!chip->ft2_fast_mode) - card_power_off(chip, XD_CARD); - disable_card_clock(chip, XD_CARD); - } -} - -void do_reset_ms_card(struct rtsx_chip *chip) -{ - int retval; - - dev_dbg(rtsx_dev(chip), "%s: %d, card2lun = 0x%x\n", __func__, - chip->ms_reset_counter, chip->card2lun[MS_CARD]); - - if (chip->card2lun[MS_CARD] >= MAX_ALLOWED_LUN_CNT) { - clear_bit(MS_NR, &chip->need_reset); - chip->ms_reset_counter = 0; - chip->ms_show_cnt = 0; - return; - } - - chip->rw_fail_cnt[chip->card2lun[MS_CARD]] = 0; - - rtsx_set_stat(chip, RTSX_STAT_RUN); - rtsx_write_register(chip, SDIO_CTRL, 0xFF, 0); - - retval = reset_ms_card(chip); - if (chip->need_release & MS_CARD) - return; - if (retval == STATUS_SUCCESS) { - clear_bit(MS_NR, &chip->need_reset); - chip->ms_reset_counter = 0; - chip->card_ready |= MS_CARD; - chip->card_fail &= ~MS_CARD; - chip->rw_card[chip->card2lun[MS_CARD]] = ms_rw; - } else { - if (chip->ms_reset_counter >= MAX_RESET_CNT) { - clear_bit(MS_NR, &chip->need_reset); - chip->ms_reset_counter = 0; - chip->ms_show_cnt = 0; - } else { - chip->ms_reset_counter++; - } - chip->card_ready &= ~MS_CARD; - chip->card_fail |= MS_CARD; - chip->capacity[chip->card2lun[MS_CARD]] = 0; - chip->rw_card[chip->card2lun[MS_CARD]] = NULL; - - rtsx_write_register(chip, CARD_OE, MS_OUTPUT_EN, 0); - if (!chip->ft2_fast_mode) - card_power_off(chip, MS_CARD); - disable_card_clock(chip, MS_CARD); - } -} - -static void release_sdio(struct rtsx_chip *chip) -{ - if (chip->sd_io) { - rtsx_write_register(chip, CARD_STOP, SD_STOP | SD_CLR_ERR, - SD_STOP | SD_CLR_ERR); - - if (chip->chip_insert_with_sdio) { - chip->chip_insert_with_sdio = 0; - - if (CHECK_PID(chip, 0x5288)) - rtsx_write_register(chip, 0xFE5A, 0x08, 0x00); - else - rtsx_write_register(chip, 0xFE70, 0x80, 0x00); - } - - rtsx_write_register(chip, SDIO_CTRL, SDIO_CD_CTRL, 0); - chip->sd_io = 0; - } -} - -void rtsx_power_off_card(struct rtsx_chip *chip) -{ - if ((chip->card_ready & SD_CARD) || chip->sd_io) { - sd_cleanup_work(chip); - sd_power_off_card3v3(chip); - } - - if (chip->card_ready & XD_CARD) { - xd_cleanup_work(chip); - xd_power_off_card3v3(chip); - } - - if (chip->card_ready & MS_CARD) { - ms_cleanup_work(chip); - ms_power_off_card3v3(chip); - } -} - -void rtsx_release_cards(struct rtsx_chip *chip) -{ - chip->int_reg = rtsx_readl(chip, RTSX_BIPR); - - if ((chip->card_ready & SD_CARD) || chip->sd_io) { - if (chip->int_reg & SD_EXIST) - sd_cleanup_work(chip); - release_sd_card(chip); - } - - if (chip->card_ready & XD_CARD) { - if (chip->int_reg & XD_EXIST) - xd_cleanup_work(chip); - release_xd_card(chip); - } - - if (chip->card_ready & MS_CARD) { - if (chip->int_reg & MS_EXIST) - ms_cleanup_work(chip); - release_ms_card(chip); - } -} - -void rtsx_reset_cards(struct rtsx_chip *chip) -{ - if (!chip->need_reset) - return; - - rtsx_set_stat(chip, RTSX_STAT_RUN); - - rtsx_force_power_on(chip, SSC_PDCTL | OC_PDCTL); - - rtsx_disable_aspm(chip); - - if ((chip->need_reset & SD_CARD) && chip->chip_insert_with_sdio) - clear_bit(SD_NR, &chip->need_reset); - - if (chip->need_reset & XD_CARD) { - chip->card_exist |= XD_CARD; - - if (chip->xd_show_cnt >= MAX_SHOW_CNT) - do_reset_xd_card(chip); - else - chip->xd_show_cnt++; - } - if (CHECK_PID(chip, 0x5288) && CHECK_BARO_PKG(chip, QFN)) { - if (chip->card_exist & XD_CARD) { - clear_bit(SD_NR, &chip->need_reset); - clear_bit(MS_NR, &chip->need_reset); - } - } - if (chip->need_reset & SD_CARD) { - chip->card_exist |= SD_CARD; - - if (chip->sd_show_cnt >= MAX_SHOW_CNT) { - rtsx_write_register(chip, RBCTL, RB_FLUSH, RB_FLUSH); - do_reset_sd_card(chip); - } else { - chip->sd_show_cnt++; - } - } - if (chip->need_reset & MS_CARD) { - chip->card_exist |= MS_CARD; - - if (chip->ms_show_cnt >= MAX_SHOW_CNT) - do_reset_ms_card(chip); - else - chip->ms_show_cnt++; - } -} - -void rtsx_reinit_cards(struct rtsx_chip *chip, int reset_chip) -{ - rtsx_set_stat(chip, RTSX_STAT_RUN); - - rtsx_force_power_on(chip, SSC_PDCTL | OC_PDCTL); - - if (reset_chip) - rtsx_reset_chip(chip); - - chip->int_reg = rtsx_readl(chip, RTSX_BIPR); - - if ((chip->int_reg & SD_EXIST) && (chip->need_reinit & SD_CARD)) { - release_sdio(chip); - release_sd_card(chip); - - wait_timeout(100); - - chip->card_exist |= SD_CARD; - do_reset_sd_card(chip); - } - - if ((chip->int_reg & XD_EXIST) && (chip->need_reinit & XD_CARD)) { - release_xd_card(chip); - - wait_timeout(100); - - chip->card_exist |= XD_CARD; - do_reset_xd_card(chip); - } - - if ((chip->int_reg & MS_EXIST) && (chip->need_reinit & MS_CARD)) { - release_ms_card(chip); - - wait_timeout(100); - - chip->card_exist |= MS_CARD; - do_reset_ms_card(chip); - } - - chip->need_reinit = 0; -} - -#ifdef DISABLE_CARD_INT -void card_cd_debounce(struct rtsx_chip *chip, unsigned long *need_reset, - unsigned long *need_release) -{ - u8 release_map = 0, reset_map = 0; - - chip->int_reg = rtsx_readl(chip, RTSX_BIPR); - - if (chip->card_exist) { - if (chip->card_exist & XD_CARD) { - if (!(chip->int_reg & XD_EXIST)) - release_map |= XD_CARD; - } else if (chip->card_exist & SD_CARD) { - if (!(chip->int_reg & SD_EXIST)) - release_map |= SD_CARD; - } else if (chip->card_exist & MS_CARD) { - if (!(chip->int_reg & MS_EXIST)) - release_map |= MS_CARD; - } - } else { - if (chip->int_reg & XD_EXIST) - reset_map |= XD_CARD; - else if (chip->int_reg & SD_EXIST) - reset_map |= SD_CARD; - else if (chip->int_reg & MS_EXIST) - reset_map |= MS_CARD; - } - - if (reset_map) { - int xd_cnt = 0, sd_cnt = 0, ms_cnt = 0; - int i; - - for (i = 0; i < (DEBOUNCE_CNT); i++) { - chip->int_reg = rtsx_readl(chip, RTSX_BIPR); - - if (chip->int_reg & XD_EXIST) - xd_cnt++; - else - xd_cnt = 0; - - if (chip->int_reg & SD_EXIST) - sd_cnt++; - else - sd_cnt = 0; - - if (chip->int_reg & MS_EXIST) - ms_cnt++; - else - ms_cnt = 0; - - wait_timeout(30); - } - - reset_map = 0; - if (!(chip->card_exist & XD_CARD) && - (xd_cnt > (DEBOUNCE_CNT - 1))) - reset_map |= XD_CARD; - if (!(chip->card_exist & SD_CARD) && - (sd_cnt > (DEBOUNCE_CNT - 1))) - reset_map |= SD_CARD; - if (!(chip->card_exist & MS_CARD) && - (ms_cnt > (DEBOUNCE_CNT - 1))) - reset_map |= MS_CARD; - } - - if (CHECK_PID(chip, 0x5288) && CHECK_BARO_PKG(chip, QFN)) - rtsx_write_register(chip, HOST_SLEEP_STATE, 0xC0, 0x00); - - if (need_reset) - *need_reset = reset_map; - if (need_release) - *need_release = release_map; -} -#endif - -void rtsx_init_cards(struct rtsx_chip *chip) -{ - if (RTSX_TST_DELINK(chip) && (rtsx_get_stat(chip) != RTSX_STAT_SS)) { - dev_dbg(rtsx_dev(chip), "Reset chip in polling thread!\n"); - rtsx_reset_chip(chip); - RTSX_CLR_DELINK(chip); - } - -#ifdef DISABLE_CARD_INT - card_cd_debounce(chip, &chip->need_reset, &chip->need_release); -#endif - - if (chip->need_release) { - if (CHECK_PID(chip, 0x5288) && CHECK_BARO_PKG(chip, QFN)) { - if (chip->int_reg & XD_EXIST) { - clear_bit(SD_NR, &chip->need_release); - clear_bit(MS_NR, &chip->need_release); - } - } - - if (!(chip->card_exist & SD_CARD) && !chip->sd_io) - clear_bit(SD_NR, &chip->need_release); - if (!(chip->card_exist & XD_CARD)) - clear_bit(XD_NR, &chip->need_release); - if (!(chip->card_exist & MS_CARD)) - clear_bit(MS_NR, &chip->need_release); - - dev_dbg(rtsx_dev(chip), "chip->need_release = 0x%x\n", - (unsigned int)(chip->need_release)); - -#ifdef SUPPORT_OCP - if (chip->need_release) { - if (chip->ocp_stat & (CARD_OC_NOW | CARD_OC_EVER)) - rtsx_write_register(chip, OCPCLR, - CARD_OC_INT_CLR | - CARD_OC_CLR, - CARD_OC_INT_CLR | - CARD_OC_CLR); - chip->ocp_stat = 0; - } -#endif - if (chip->need_release) { - rtsx_set_stat(chip, RTSX_STAT_RUN); - rtsx_force_power_on(chip, SSC_PDCTL | OC_PDCTL); - } - - if (chip->need_release & SD_CARD) { - clear_bit(SD_NR, &chip->need_release); - chip->card_exist &= ~SD_CARD; - chip->card_ejected &= ~SD_CARD; - chip->card_fail &= ~SD_CARD; - CLR_BIT(chip->lun_mc, chip->card2lun[SD_CARD]); - chip->rw_fail_cnt[chip->card2lun[SD_CARD]] = 0; - rtsx_write_register(chip, RBCTL, RB_FLUSH, RB_FLUSH); - - release_sdio(chip); - release_sd_card(chip); - } - - if (chip->need_release & XD_CARD) { - clear_bit(XD_NR, &chip->need_release); - chip->card_exist &= ~XD_CARD; - chip->card_ejected &= ~XD_CARD; - chip->card_fail &= ~XD_CARD; - CLR_BIT(chip->lun_mc, chip->card2lun[XD_CARD]); - chip->rw_fail_cnt[chip->card2lun[XD_CARD]] = 0; - - release_xd_card(chip); - - if (CHECK_PID(chip, 0x5288) && - CHECK_BARO_PKG(chip, QFN)) - rtsx_write_register(chip, HOST_SLEEP_STATE, - 0xC0, 0xC0); - } - - if (chip->need_release & MS_CARD) { - clear_bit(MS_NR, &chip->need_release); - chip->card_exist &= ~MS_CARD; - chip->card_ejected &= ~MS_CARD; - chip->card_fail &= ~MS_CARD; - CLR_BIT(chip->lun_mc, chip->card2lun[MS_CARD]); - chip->rw_fail_cnt[chip->card2lun[MS_CARD]] = 0; - - release_ms_card(chip); - } - - dev_dbg(rtsx_dev(chip), "chip->card_exist = 0x%x\n", - chip->card_exist); - - if (!chip->card_exist) - turn_off_led(chip, LED_GPIO); - } - - if (chip->need_reset) { - dev_dbg(rtsx_dev(chip), "chip->need_reset = 0x%x\n", - (unsigned int)(chip->need_reset)); - - rtsx_reset_cards(chip); - } - - if (chip->need_reinit) { - dev_dbg(rtsx_dev(chip), "chip->need_reinit = 0x%x\n", - (unsigned int)(chip->need_reinit)); - - rtsx_reinit_cards(chip, 0); - } -} - -int switch_ssc_clock(struct rtsx_chip *chip, int clk) -{ - int retval; - u8 n = (u8)(clk - 2), min_n, max_n; - u8 mcu_cnt, div, max_div, ssc_depth, ssc_depth_mask; - int sd_vpclk_phase_reset = 0; - - if (chip->cur_clk == clk) - return STATUS_SUCCESS; - - min_n = 60; - max_n = 120; - max_div = CLK_DIV_4; - - dev_dbg(rtsx_dev(chip), "Switch SSC clock to %dMHz (cur_clk = %d)\n", - clk, chip->cur_clk); - - if (clk <= 2 || n > max_n) - return STATUS_FAIL; - - mcu_cnt = (u8)(125 / clk + 3); - if (mcu_cnt > 7) - mcu_cnt = 7; - - div = CLK_DIV_1; - while ((n < min_n) && (div < max_div)) { - n = (n + 2) * 2 - 2; - div++; - } - dev_dbg(rtsx_dev(chip), "n = %d, div = %d\n", n, div); - - if (chip->ssc_en) { - ssc_depth = 0x01; - n -= 2; - } else { - ssc_depth = 0; - } - - ssc_depth_mask = 0x03; - - dev_dbg(rtsx_dev(chip), "ssc_depth = %d\n", ssc_depth); - - rtsx_init_cmd(chip); - rtsx_add_cmd(chip, WRITE_REG_CMD, CLK_CTL, CLK_LOW_FREQ, CLK_LOW_FREQ); - rtsx_add_cmd(chip, WRITE_REG_CMD, CLK_DIV, 0xFF, (div << 4) | mcu_cnt); - rtsx_add_cmd(chip, WRITE_REG_CMD, SSC_CTL1, SSC_RSTB, 0); - rtsx_add_cmd(chip, WRITE_REG_CMD, SSC_CTL2, ssc_depth_mask, ssc_depth); - rtsx_add_cmd(chip, WRITE_REG_CMD, SSC_DIV_N_0, 0xFF, n); - rtsx_add_cmd(chip, WRITE_REG_CMD, SSC_CTL1, SSC_RSTB, SSC_RSTB); - if (sd_vpclk_phase_reset) { - rtsx_add_cmd(chip, WRITE_REG_CMD, SD_VPCLK0_CTL, - PHASE_NOT_RESET, 0); - rtsx_add_cmd(chip, WRITE_REG_CMD, SD_VPCLK0_CTL, - PHASE_NOT_RESET, PHASE_NOT_RESET); - } - - retval = rtsx_send_cmd(chip, 0, WAIT_TIME); - if (retval < 0) - return STATUS_ERROR; - - udelay(10); - retval = rtsx_write_register(chip, CLK_CTL, CLK_LOW_FREQ, 0); - if (retval) - return retval; - - chip->cur_clk = clk; - - return STATUS_SUCCESS; -} - -int switch_normal_clock(struct rtsx_chip *chip, int clk) -{ - int retval; - u8 sel, div, mcu_cnt; - int sd_vpclk_phase_reset = 0; - - if (chip->cur_clk == clk) - return STATUS_SUCCESS; - - switch (clk) { - case CLK_20: - dev_dbg(rtsx_dev(chip), "Switch clock to 20MHz\n"); - sel = SSC_80; - div = CLK_DIV_4; - mcu_cnt = 7; - break; - - case CLK_30: - dev_dbg(rtsx_dev(chip), "Switch clock to 30MHz\n"); - sel = SSC_120; - div = CLK_DIV_4; - mcu_cnt = 7; - break; - - case CLK_40: - dev_dbg(rtsx_dev(chip), "Switch clock to 40MHz\n"); - sel = SSC_80; - div = CLK_DIV_2; - mcu_cnt = 7; - break; - - case CLK_50: - dev_dbg(rtsx_dev(chip), "Switch clock to 50MHz\n"); - sel = SSC_100; - div = CLK_DIV_2; - mcu_cnt = 6; - break; - - case CLK_60: - dev_dbg(rtsx_dev(chip), "Switch clock to 60MHz\n"); - sel = SSC_120; - div = CLK_DIV_2; - mcu_cnt = 6; - break; - - case CLK_80: - dev_dbg(rtsx_dev(chip), "Switch clock to 80MHz\n"); - sel = SSC_80; - div = CLK_DIV_1; - mcu_cnt = 5; - break; - - case CLK_100: - dev_dbg(rtsx_dev(chip), "Switch clock to 100MHz\n"); - sel = SSC_100; - div = CLK_DIV_1; - mcu_cnt = 5; - break; - - case CLK_120: - dev_dbg(rtsx_dev(chip), "Switch clock to 120MHz\n"); - sel = SSC_120; - div = CLK_DIV_1; - mcu_cnt = 5; - break; - - case CLK_150: - dev_dbg(rtsx_dev(chip), "Switch clock to 150MHz\n"); - sel = SSC_150; - div = CLK_DIV_1; - mcu_cnt = 4; - break; - - case CLK_200: - dev_dbg(rtsx_dev(chip), "Switch clock to 200MHz\n"); - sel = SSC_200; - div = CLK_DIV_1; - mcu_cnt = 4; - break; - - default: - dev_dbg(rtsx_dev(chip), "Try to switch to an illegal clock (%d)\n", - clk); - return STATUS_FAIL; - } - - retval = rtsx_write_register(chip, CLK_CTL, 0xFF, CLK_LOW_FREQ); - if (retval) - return retval; - if (sd_vpclk_phase_reset) { - retval = rtsx_write_register(chip, SD_VPCLK0_CTL, - PHASE_NOT_RESET, 0); - if (retval) - return retval; - retval = rtsx_write_register(chip, SD_VPCLK1_CTL, - PHASE_NOT_RESET, 0); - if (retval) - return retval; - } - retval = rtsx_write_register(chip, CLK_DIV, 0xFF, - (div << 4) | mcu_cnt); - if (retval) - return retval; - retval = rtsx_write_register(chip, CLK_SEL, 0xFF, sel); - if (retval) - return retval; - - if (sd_vpclk_phase_reset) { - udelay(200); - retval = rtsx_write_register(chip, SD_VPCLK0_CTL, - PHASE_NOT_RESET, PHASE_NOT_RESET); - if (retval) - return retval; - retval = rtsx_write_register(chip, SD_VPCLK1_CTL, - PHASE_NOT_RESET, PHASE_NOT_RESET); - if (retval) - return retval; - udelay(200); - } - retval = rtsx_write_register(chip, CLK_CTL, 0xFF, 0); - if (retval) - return retval; - - chip->cur_clk = clk; - - return STATUS_SUCCESS; -} - -void trans_dma_enable(enum dma_data_direction dir, struct rtsx_chip *chip, - u32 byte_cnt, u8 pack_size) -{ - if (pack_size > DMA_1024) - pack_size = DMA_512; - - rtsx_add_cmd(chip, WRITE_REG_CMD, IRQSTAT0, DMA_DONE_INT, DMA_DONE_INT); - - rtsx_add_cmd(chip, WRITE_REG_CMD, DMATC3, 0xFF, (u8)(byte_cnt >> 24)); - rtsx_add_cmd(chip, WRITE_REG_CMD, DMATC2, 0xFF, (u8)(byte_cnt >> 16)); - rtsx_add_cmd(chip, WRITE_REG_CMD, DMATC1, 0xFF, (u8)(byte_cnt >> 8)); - rtsx_add_cmd(chip, WRITE_REG_CMD, DMATC0, 0xFF, (u8)byte_cnt); - - if (dir == DMA_FROM_DEVICE) { - rtsx_add_cmd(chip, WRITE_REG_CMD, DMACTL, - 0x03 | DMA_PACK_SIZE_MASK, - DMA_DIR_FROM_CARD | DMA_EN | pack_size); - } else { - rtsx_add_cmd(chip, WRITE_REG_CMD, DMACTL, - 0x03 | DMA_PACK_SIZE_MASK, - DMA_DIR_TO_CARD | DMA_EN | pack_size); - } - - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER); -} - -int enable_card_clock(struct rtsx_chip *chip, u8 card) -{ - int retval; - u8 clk_en = 0; - - if (card & XD_CARD) - clk_en |= XD_CLK_EN; - if (card & SD_CARD) - clk_en |= SD_CLK_EN; - if (card & MS_CARD) - clk_en |= MS_CLK_EN; - - retval = rtsx_write_register(chip, CARD_CLK_EN, clk_en, clk_en); - if (retval) - return retval; - - return STATUS_SUCCESS; -} - -int disable_card_clock(struct rtsx_chip *chip, u8 card) -{ - int retval; - u8 clk_en = 0; - - if (card & XD_CARD) - clk_en |= XD_CLK_EN; - if (card & SD_CARD) - clk_en |= SD_CLK_EN; - if (card & MS_CARD) - clk_en |= MS_CLK_EN; - - retval = rtsx_write_register(chip, CARD_CLK_EN, clk_en, 0); - if (retval) - return retval; - - return STATUS_SUCCESS; -} - -int card_power_on(struct rtsx_chip *chip, u8 card) -{ - int retval; - u8 mask, val1, val2; - - if (CHECK_LUN_MODE(chip, SD_MS_2LUN) && card == MS_CARD) { - mask = MS_POWER_MASK; - val1 = MS_PARTIAL_POWER_ON; - val2 = MS_POWER_ON; - } else { - mask = SD_POWER_MASK; - val1 = SD_PARTIAL_POWER_ON; - val2 = SD_POWER_ON; - } - - rtsx_init_cmd(chip); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PWR_CTL, mask, val1); - - retval = rtsx_send_cmd(chip, 0, 100); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - udelay(chip->pmos_pwr_on_interval); - - rtsx_init_cmd(chip); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PWR_CTL, mask, val2); - - retval = rtsx_send_cmd(chip, 0, 100); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} - -int card_power_off(struct rtsx_chip *chip, u8 card) -{ - int retval; - u8 mask, val; - - if (CHECK_LUN_MODE(chip, SD_MS_2LUN) && card == MS_CARD) { - mask = MS_POWER_MASK; - val = MS_POWER_OFF; - } else { - mask = SD_POWER_MASK; - val = SD_POWER_OFF; - } - - retval = rtsx_write_register(chip, CARD_PWR_CTL, mask, val); - if (retval) - return retval; - - return STATUS_SUCCESS; -} - -int card_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, - u32 sec_addr, u16 sec_cnt) -{ - int retval; - unsigned int lun = SCSI_LUN(srb); - int i; - - if (!chip->rw_card[lun]) - return STATUS_FAIL; - - for (i = 0; i < 3; i++) { - chip->rw_need_retry = 0; - - retval = chip->rw_card[lun](srb, chip, sec_addr, sec_cnt); - if (retval != STATUS_SUCCESS) { - if (rtsx_check_chip_exist(chip) != STATUS_SUCCESS) { - rtsx_release_chip(chip); - return STATUS_FAIL; - } - if (detect_card_cd(chip, chip->cur_card) != - STATUS_SUCCESS) { - return STATUS_FAIL; - } - - if (!chip->rw_need_retry) { - dev_dbg(rtsx_dev(chip), "RW fail, but no need to retry\n"); - break; - } - } else { - chip->rw_need_retry = 0; - break; - } - - dev_dbg(rtsx_dev(chip), "Retry RW, (i = %d)\n", i); - } - - return retval; -} - -int card_share_mode(struct rtsx_chip *chip, int card) -{ - int retval; - u8 mask, value; - - if (CHECK_PID(chip, 0x5208)) { - mask = CARD_SHARE_MASK; - if (card == SD_CARD) - value = CARD_SHARE_48_SD; - else if (card == MS_CARD) - value = CARD_SHARE_48_MS; - else if (card == XD_CARD) - value = CARD_SHARE_48_XD; - else - return STATUS_FAIL; - - } else if (CHECK_PID(chip, 0x5288)) { - mask = 0x03; - if (card == SD_CARD) - value = CARD_SHARE_BAROSSA_SD; - else if (card == MS_CARD) - value = CARD_SHARE_BAROSSA_MS; - else if (card == XD_CARD) - value = CARD_SHARE_BAROSSA_XD; - else - return STATUS_FAIL; - - } else { - return STATUS_FAIL; - } - - retval = rtsx_write_register(chip, CARD_SHARE_MODE, mask, value); - if (retval) - return retval; - - return STATUS_SUCCESS; -} - -int select_card(struct rtsx_chip *chip, int card) -{ - int retval; - - if (chip->cur_card != card) { - u8 mod; - - if (card == SD_CARD) - mod = SD_MOD_SEL; - else if (card == MS_CARD) - mod = MS_MOD_SEL; - else if (card == XD_CARD) - mod = XD_MOD_SEL; - else if (card == SPI_CARD) - mod = SPI_MOD_SEL; - else - return STATUS_FAIL; - - retval = rtsx_write_register(chip, CARD_SELECT, 0x07, mod); - if (retval) - return retval; - chip->cur_card = card; - - retval = card_share_mode(chip, card); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -void toggle_gpio(struct rtsx_chip *chip, u8 gpio) -{ - u8 temp_reg; - - rtsx_read_register(chip, CARD_GPIO, &temp_reg); - temp_reg ^= (0x01 << gpio); - rtsx_write_register(chip, CARD_GPIO, 0xFF, temp_reg); -} - -void turn_on_led(struct rtsx_chip *chip, u8 gpio) -{ - if (CHECK_PID(chip, 0x5288)) - rtsx_write_register(chip, CARD_GPIO, (u8)(1 << gpio), - (u8)(1 << gpio)); - else - rtsx_write_register(chip, CARD_GPIO, (u8)(1 << gpio), 0); -} - -void turn_off_led(struct rtsx_chip *chip, u8 gpio) -{ - if (CHECK_PID(chip, 0x5288)) - rtsx_write_register(chip, CARD_GPIO, (u8)(1 << gpio), 0); - else - rtsx_write_register(chip, CARD_GPIO, (u8)(1 << gpio), - (u8)(1 << gpio)); -} - -int detect_card_cd(struct rtsx_chip *chip, int card) -{ - u32 card_cd, status; - - if (card == SD_CARD) { - card_cd = SD_EXIST; - } else if (card == MS_CARD) { - card_cd = MS_EXIST; - } else if (card == XD_CARD) { - card_cd = XD_EXIST; - } else { - dev_dbg(rtsx_dev(chip), "Wrong card type: 0x%x\n", card); - return STATUS_FAIL; - } - - status = rtsx_readl(chip, RTSX_BIPR); - if (!(status & card_cd)) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} - -int check_card_exist(struct rtsx_chip *chip, unsigned int lun) -{ - if (chip->card_exist & chip->lun2card[lun]) - return 1; - - return 0; -} - -int check_card_ready(struct rtsx_chip *chip, unsigned int lun) -{ - if (chip->card_ready & chip->lun2card[lun]) - return 1; - - return 0; -} - -int check_card_wp(struct rtsx_chip *chip, unsigned int lun) -{ - if (chip->card_wp & chip->lun2card[lun]) - return 1; - - return 0; -} - -u8 get_lun_card(struct rtsx_chip *chip, unsigned int lun) -{ - if ((chip->card_ready & chip->lun2card[lun]) == XD_CARD) - return (u8)XD_CARD; - else if ((chip->card_ready & chip->lun2card[lun]) == SD_CARD) - return (u8)SD_CARD; - else if ((chip->card_ready & chip->lun2card[lun]) == MS_CARD) - return (u8)MS_CARD; - - return 0; -} - -void eject_card(struct rtsx_chip *chip, unsigned int lun) -{ - do_remaining_work(chip); - - if ((chip->card_ready & chip->lun2card[lun]) == SD_CARD) { - release_sd_card(chip); - chip->card_ejected |= SD_CARD; - chip->card_ready &= ~SD_CARD; - chip->capacity[lun] = 0; - } else if ((chip->card_ready & chip->lun2card[lun]) == XD_CARD) { - release_xd_card(chip); - chip->card_ejected |= XD_CARD; - chip->card_ready &= ~XD_CARD; - chip->capacity[lun] = 0; - } else if ((chip->card_ready & chip->lun2card[lun]) == MS_CARD) { - release_ms_card(chip); - chip->card_ejected |= MS_CARD; - chip->card_ready &= ~MS_CARD; - chip->capacity[lun] = 0; - } -} diff --git a/drivers/staging/rts5208/rtsx_card.h b/drivers/staging/rts5208/rtsx_card.h deleted file mode 100644 index 39727371cd7a..000000000000 --- a/drivers/staging/rts5208/rtsx_card.h +++ /dev/null @@ -1,1087 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Driver for Realtek PCI-Express card reader - * - * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. - * - * Author: - * Wei WANG (wei_wang@xxxxxxxxxxxxxx) - * Micky Ching (micky_ching@xxxxxxxxxxxxxx) - */ - -#ifndef __REALTEK_RTSX_CARD_H -#define __REALTEK_RTSX_CARD_H - -#include "rtsx.h" -#include "rtsx_chip.h" -#include "rtsx_transport.h" -#include "sd.h" - -#define SSC_POWER_DOWN 0x01 -#define SD_OC_POWER_DOWN 0x02 -#define MS_OC_POWER_DOWN 0x04 -#define ALL_POWER_DOWN 0x07 -#define OC_POWER_DOWN 0x06 - -#define PMOS_STRG_MASK 0x10 -#define PMOS_STRG_800mA 0x10 -#define PMOS_STRG_400mA 0x00 - -#define POWER_OFF 0x03 -#define PARTIAL_POWER_ON 0x01 -#define POWER_ON 0x00 - -#define MS_POWER_OFF 0x0C -#define MS_PARTIAL_POWER_ON 0x04 -#define MS_POWER_ON 0x00 -#define MS_POWER_MASK 0x0C - -#define SD_POWER_OFF 0x03 -#define SD_PARTIAL_POWER_ON 0x01 -#define SD_POWER_ON 0x00 -#define SD_POWER_MASK 0x03 - -#define XD_OUTPUT_EN 0x02 -#define SD_OUTPUT_EN 0x04 -#define MS_OUTPUT_EN 0x08 -#define SPI_OUTPUT_EN 0x10 - -#define CLK_LOW_FREQ 0x01 - -#define CLK_DIV_1 0x01 -#define CLK_DIV_2 0x02 -#define CLK_DIV_4 0x03 -#define CLK_DIV_8 0x04 - -#define SSC_80 0 -#define SSC_100 1 -#define SSC_120 2 -#define SSC_150 3 -#define SSC_200 4 - -#define XD_CLK_EN 0x02 -#define SD_CLK_EN 0x04 -#define MS_CLK_EN 0x08 -#define SPI_CLK_EN 0x10 - -#define XD_MOD_SEL 1 -#define SD_MOD_SEL 2 -#define MS_MOD_SEL 3 -#define SPI_MOD_SEL 4 - -#define CHANGE_CLK 0x01 - -#define SD_CRC7_ERR 0x80 -#define SD_CRC16_ERR 0x40 -#define SD_CRC_WRITE_ERR 0x20 -#define SD_CRC_WRITE_ERR_MASK 0x1C -#define GET_CRC_TIME_OUT 0x02 -#define SD_TUNING_COMPARE_ERR 0x01 - -#define SD_RSP_80CLK_TIMEOUT 0x01 - -#define SD_CLK_TOGGLE_EN 0x80 -#define SD_CLK_FORCE_STOP 0x40 -#define SD_DAT3_STATUS 0x10 -#define SD_DAT2_STATUS 0x08 -#define SD_DAT1_STATUS 0x04 -#define SD_DAT0_STATUS 0x02 -#define SD_CMD_STATUS 0x01 - -#define SD_IO_USING_1V8 0x80 -#define SD_IO_USING_3V3 0x7F -#define TYPE_A_DRIVING 0x00 -#define TYPE_B_DRIVING 0x01 -#define TYPE_C_DRIVING 0x02 -#define TYPE_D_DRIVING 0x03 - -#define DDR_FIX_RX_DAT 0x00 -#define DDR_VAR_RX_DAT 0x80 -#define DDR_FIX_RX_DAT_EDGE 0x00 -#define DDR_FIX_RX_DAT_14_DELAY 0x40 -#define DDR_FIX_RX_CMD 0x00 -#define DDR_VAR_RX_CMD 0x20 -#define DDR_FIX_RX_CMD_POS_EDGE 0x00 -#define DDR_FIX_RX_CMD_14_DELAY 0x10 -#define SD20_RX_POS_EDGE 0x00 -#define SD20_RX_14_DELAY 0x08 -#define SD20_RX_SEL_MASK 0x08 - -#define DDR_FIX_TX_CMD_DAT 0x00 -#define DDR_VAR_TX_CMD_DAT 0x80 -#define DDR_FIX_TX_DAT_14_TSU 0x00 -#define DDR_FIX_TX_DAT_12_TSU 0x40 -#define DDR_FIX_TX_CMD_NEG_EDGE 0x00 -#define DDR_FIX_TX_CMD_14_AHEAD 0x20 -#define SD20_TX_NEG_EDGE 0x00 -#define SD20_TX_14_AHEAD 0x10 -#define SD20_TX_SEL_MASK 0x10 -#define DDR_VAR_SDCLK_POL_SWAP 0x01 - -#define SD_TRANSFER_START 0x80 -#define SD_TRANSFER_END 0x40 -#define SD_STAT_IDLE 0x20 -#define SD_TRANSFER_ERR 0x10 -#define SD_TM_NORMAL_WRITE 0x00 -#define SD_TM_AUTO_WRITE_3 0x01 -#define SD_TM_AUTO_WRITE_4 0x02 -#define SD_TM_AUTO_READ_3 0x05 -#define SD_TM_AUTO_READ_4 0x06 -#define SD_TM_CMD_RSP 0x08 -#define SD_TM_AUTO_WRITE_1 0x09 -#define SD_TM_AUTO_WRITE_2 0x0A -#define SD_TM_NORMAL_READ 0x0C -#define SD_TM_AUTO_READ_1 0x0D -#define SD_TM_AUTO_READ_2 0x0E -#define SD_TM_AUTO_TUNING 0x0F - -#define PHASE_CHANGE 0x80 -#define PHASE_NOT_RESET 0x40 - -#define DCMPS_CHANGE 0x80 -#define DCMPS_CHANGE_DONE 0x40 -#define DCMPS_ERROR 0x20 -#define DCMPS_CURRENT_PHASE 0x1F - -#define SD_CLK_DIVIDE_0 0x00 -#define SD_CLK_DIVIDE_256 0xC0 -#define SD_CLK_DIVIDE_128 0x80 -#define SD_BUS_WIDTH_1 0x00 -#define SD_BUS_WIDTH_4 0x01 -#define SD_BUS_WIDTH_8 0x02 -#define SD_ASYNC_FIFO_NOT_RST 0x10 -#define SD_20_MODE 0x00 -#define SD_DDR_MODE 0x04 -#define SD_30_MODE 0x08 - -#define SD_CLK_DIVIDE_MASK 0xC0 - -#define SD_CMD_IDLE 0x80 - -#define SD_DATA_IDLE 0x80 - -#define DCM_RESET 0x08 -#define DCM_LOCKED 0x04 -#define DCM_208M 0x00 -#define DCM_TX 0x01 -#define DCM_RX 0x02 - -#define DRP_START 0x80 -#define DRP_DONE 0x40 - -#define DRP_WRITE 0x80 -#define DRP_READ 0x00 -#define DCM_WRITE_ADDRESS_50 0x50 -#define DCM_WRITE_ADDRESS_51 0x51 -#define DCM_READ_ADDRESS_00 0x00 -#define DCM_READ_ADDRESS_51 0x51 - -#define SD_CALCULATE_CRC7 0x00 -#define SD_NO_CALCULATE_CRC7 0x80 -#define SD_CHECK_CRC16 0x00 -#define SD_NO_CHECK_CRC16 0x40 -#define SD_NO_CHECK_WAIT_CRC_TO 0x20 -#define SD_WAIT_BUSY_END 0x08 -#define SD_NO_WAIT_BUSY_END 0x00 -#define SD_CHECK_CRC7 0x00 -#define SD_NO_CHECK_CRC7 0x04 -#define SD_RSP_LEN_0 0x00 -#define SD_RSP_LEN_6 0x01 -#define SD_RSP_LEN_17 0x02 -#define SD_RSP_TYPE_R0 0x04 -#define SD_RSP_TYPE_R1 0x01 -#define SD_RSP_TYPE_R1b 0x09 -#define SD_RSP_TYPE_R2 0x02 -#define SD_RSP_TYPE_R3 0x05 -#define SD_RSP_TYPE_R4 0x05 -#define SD_RSP_TYPE_R5 0x01 -#define SD_RSP_TYPE_R6 0x01 -#define SD_RSP_TYPE_R7 0x01 - -#define SD_RSP_80CLK_TIMEOUT_EN 0x01 - -#define SAMPLE_TIME_RISING 0x00 -#define SAMPLE_TIME_FALLING 0x80 -#define PUSH_TIME_DEFAULT 0x00 -#define PUSH_TIME_ODD 0x40 -#define NO_EXTEND_TOGGLE 0x00 -#define EXTEND_TOGGLE_CHK 0x20 -#define MS_BUS_WIDTH_1 0x00 -#define MS_BUS_WIDTH_4 0x10 -#define MS_BUS_WIDTH_8 0x18 -#define MS_2K_SECTOR_MODE 0x04 -#define MS_512_SECTOR_MODE 0x00 -#define MS_TOGGLE_TIMEOUT_EN 0x00 -#define MS_TOGGLE_TIMEOUT_DISEN 0x01 -#define MS_NO_CHECK_INT 0x02 - -#define WAIT_INT 0x80 -#define NO_WAIT_INT 0x00 -#define NO_AUTO_READ_INT_REG 0x00 -#define AUTO_READ_INT_REG 0x40 -#define MS_CRC16_ERR 0x20 -#define MS_RDY_TIMEOUT 0x10 -#define MS_INT_CMDNK 0x08 -#define MS_INT_BREQ 0x04 -#define MS_INT_ERR 0x02 -#define MS_INT_CED 0x01 - -#define MS_TRANSFER_START 0x80 -#define MS_TRANSFER_END 0x40 -#define MS_TRANSFER_ERR 0x20 -#define MS_BS_STATE 0x10 -#define MS_TM_READ_BYTES 0x00 -#define MS_TM_NORMAL_READ 0x01 -#define MS_TM_WRITE_BYTES 0x04 -#define MS_TM_NORMAL_WRITE 0x05 -#define MS_TM_AUTO_READ 0x08 -#define MS_TM_AUTO_WRITE 0x0C - -#define CARD_SHARE_MASK 0x0F -#define CARD_SHARE_MULTI_LUN 0x00 -#define CARD_SHARE_NORMAL 0x00 -#define CARD_SHARE_48_XD 0x02 -#define CARD_SHARE_48_SD 0x04 -#define CARD_SHARE_48_MS 0x08 -#define CARD_SHARE_BAROSSA_XD 0x00 -#define CARD_SHARE_BAROSSA_SD 0x01 -#define CARD_SHARE_BAROSSA_MS 0x02 - -#define MS_DRIVE_8 0x00 -#define MS_DRIVE_4 0x40 -#define MS_DRIVE_12 0x80 -#define SD_DRIVE_8 0x00 -#define SD_DRIVE_4 0x10 -#define SD_DRIVE_12 0x20 -#define XD_DRIVE_8 0x00 -#define XD_DRIVE_4 0x04 -#define XD_DRIVE_12 0x08 - -#define SPI_STOP 0x01 -#define XD_STOP 0x02 -#define SD_STOP 0x04 -#define MS_STOP 0x08 -#define SPI_CLR_ERR 0x10 -#define XD_CLR_ERR 0x20 -#define SD_CLR_ERR 0x40 -#define MS_CLR_ERR 0x80 - -#define CRC_FIX_CLK (0x00 << 0) -#define CRC_VAR_CLK0 (0x01 << 0) -#define CRC_VAR_CLK1 (0x02 << 0) -#define SD30_FIX_CLK (0x00 << 2) -#define SD30_VAR_CLK0 (0x01 << 2) -#define SD30_VAR_CLK1 (0x02 << 2) -#define SAMPLE_FIX_CLK (0x00 << 4) -#define SAMPLE_VAR_CLK0 (0x01 << 4) -#define SAMPLE_VAR_CLK1 (0x02 << 4) - -#define SDIO_VER_20 0x80 -#define SDIO_VER_10 0x00 -#define SDIO_VER_CHG 0x40 -#define SDIO_BUS_AUTO_SWITCH 0x10 - -#define PINGPONG_BUFFER 0x01 -#define RING_BUFFER 0x00 - -#define RB_FLUSH 0x80 - -#define DMA_DONE_INT_EN 0x80 -#define SUSPEND_INT_EN 0x40 -#define LINK_RDY_INT_EN 0x20 -#define LINK_DOWN_INT_EN 0x10 - -#define DMA_DONE_INT 0x80 -#define SUSPEND_INT 0x40 -#define LINK_RDY_INT 0x20 -#define LINK_DOWN_INT 0x10 - -#define MRD_ERR_INT_EN 0x40 -#define MWR_ERR_INT_EN 0x20 -#define SCSI_CMD_INT_EN 0x10 -#define TLP_RCV_INT_EN 0x08 -#define TLP_TRSMT_INT_EN 0x04 -#define MRD_COMPLETE_INT_EN 0x02 -#define MWR_COMPLETE_INT_EN 0x01 - -#define MRD_ERR_INT 0x40 -#define MWR_ERR_INT 0x20 -#define SCSI_CMD_INT 0x10 -#define TLP_RX_INT 0x08 -#define TLP_TX_INT 0x04 -#define MRD_COMPLETE_INT 0x02 -#define MWR_COMPLETE_INT 0x01 - -#define MSG_RX_INT_EN 0x08 -#define MRD_RX_INT_EN 0x04 -#define MWR_RX_INT_EN 0x02 -#define CPLD_RX_INT_EN 0x01 - -#define MSG_RX_INT 0x08 -#define MRD_RX_INT 0x04 -#define MWR_RX_INT 0x02 -#define CPLD_RX_INT 0x01 - -#define MSG_TX_INT_EN 0x08 -#define MRD_TX_INT_EN 0x04 -#define MWR_TX_INT_EN 0x02 -#define CPLD_TX_INT_EN 0x01 - -#define MSG_TX_INT 0x08 -#define MRD_TX_INT 0x04 -#define MWR_TX_INT 0x02 -#define CPLD_TX_INT 0x01 - -#define DMA_RST 0x80 -#define DMA_BUSY 0x04 -#define DMA_DIR_TO_CARD 0x00 -#define DMA_DIR_FROM_CARD 0x02 -#define DMA_EN 0x01 -#define DMA_128 (0 << 4) -#define DMA_256 (1 << 4) -#define DMA_512 (2 << 4) -#define DMA_1024 (3 << 4) -#define DMA_PACK_SIZE_MASK 0x30 - -#define XD_PWR_OFF_DELAY0 0x00 -#define XD_PWR_OFF_DELAY1 0x02 -#define XD_PWR_OFF_DELAY2 0x04 -#define XD_PWR_OFF_DELAY3 0x06 -#define XD_AUTO_PWR_OFF_EN 0xF7 -#define XD_NO_AUTO_PWR_OFF 0x08 - -#define XD_TIME_RWN_1 0x00 -#define XD_TIME_RWN_STEP 0x20 -#define XD_TIME_RW_1 0x00 -#define XD_TIME_RW_STEP 0x04 -#define XD_TIME_SETUP_1 0x00 -#define XD_TIME_SETUP_STEP 0x01 - -#define XD_ECC2_UNCORRECTABLE 0x80 -#define XD_ECC2_ERROR 0x40 -#define XD_ECC1_UNCORRECTABLE 0x20 -#define XD_ECC1_ERROR 0x10 -#define XD_RDY 0x04 -#define XD_CE_EN 0xFD -#define XD_CE_DISEN 0x02 -#define XD_WP_EN 0xFE -#define XD_WP_DISEN 0x01 - -#define XD_TRANSFER_START 0x80 -#define XD_TRANSFER_END 0x40 -#define XD_PPB_EMPTY 0x20 -#define XD_RESET 0x00 -#define XD_ERASE 0x01 -#define XD_READ_STATUS 0x02 -#define XD_READ_ID 0x03 -#define XD_READ_REDUNDANT 0x04 -#define XD_READ_PAGES 0x05 -#define XD_SET_CMD 0x06 -#define XD_NORMAL_READ 0x07 -#define XD_WRITE_PAGES 0x08 -#define XD_NORMAL_WRITE 0x09 -#define XD_WRITE_REDUNDANT 0x0A -#define XD_SET_ADDR 0x0B - -#define XD_PPB_TO_SIE 0x80 -#define XD_TO_PPB_ONLY 0x00 -#define XD_BA_TRANSFORM 0x40 -#define XD_BA_NO_TRANSFORM 0x00 -#define XD_NO_CALC_ECC 0x20 -#define XD_CALC_ECC 0x00 -#define XD_IGNORE_ECC 0x10 -#define XD_CHECK_ECC 0x00 -#define XD_DIRECT_TO_RB 0x08 -#define XD_ADDR_LENGTH_0 0x00 -#define XD_ADDR_LENGTH_1 0x01 -#define XD_ADDR_LENGTH_2 0x02 -#define XD_ADDR_LENGTH_3 0x03 -#define XD_ADDR_LENGTH_4 0x04 - -#define XD_GPG 0xFF -#define XD_BPG 0x00 - -#define XD_GBLK 0xFF -#define XD_LATER_BBLK 0xF0 - -#define XD_ECC2_ALL1 0x80 -#define XD_ECC1_ALL1 0x40 -#define XD_BA2_ALL0 0x20 -#define XD_BA1_ALL0 0x10 -#define XD_BA1_BA2_EQL 0x04 -#define XD_BA2_VALID 0x02 -#define XD_BA1_VALID 0x01 - -#define XD_PGSTS_ZEROBIT_OVER4 0x00 -#define XD_PGSTS_NOT_FF 0x02 -#define XD_AUTO_CHK_DATA_STATUS 0x01 - -#define RSTB_MODE_DETECT 0x80 -#define MODE_OUT_VLD 0x40 -#define MODE_OUT_0_NONE 0x00 -#define MODE_OUT_10_NONE 0x04 -#define MODE_OUT_10_47 0x05 -#define MODE_OUT_10_180 0x06 -#define MODE_OUT_10_680 0x07 -#define MODE_OUT_16_NONE 0x08 -#define MODE_OUT_16_47 0x09 -#define MODE_OUT_16_180 0x0A -#define MODE_OUT_16_680 0x0B -#define MODE_OUT_NONE_NONE 0x0C -#define MODE_OUT_NONE_47 0x0D -#define MODE_OUT_NONE_180 0x0E -#define MODE_OUT_NONE_680 0x0F - -#define CARD_OC_INT_EN 0x20 -#define CARD_DETECT_EN 0x08 - -#define MS_DETECT_EN 0x80 -#define MS_OCP_INT_EN 0x40 -#define MS_OCP_INT_CLR 0x20 -#define MS_OC_CLR 0x10 -#define SD_DETECT_EN 0x08 -#define SD_OCP_INT_EN 0x04 -#define SD_OCP_INT_CLR 0x02 -#define SD_OC_CLR 0x01 - -#define CARD_OCP_DETECT 0x80 -#define CARD_OC_NOW 0x08 -#define CARD_OC_EVER 0x04 - -#define MS_OCP_DETECT 0x80 -#define MS_OC_NOW 0x40 -#define MS_OC_EVER 0x20 -#define SD_OCP_DETECT 0x08 -#define SD_OC_NOW 0x04 -#define SD_OC_EVER 0x02 - -#define CARD_OC_INT_CLR 0x08 -#define CARD_OC_CLR 0x02 - -#define SD_OCP_GLITCH_MASK 0x07 -#define SD_OCP_GLITCH_6_4 0x00 -#define SD_OCP_GLITCH_64 0x01 -#define SD_OCP_GLITCH_640 0x02 -#define SD_OCP_GLITCH_1000 0x03 -#define SD_OCP_GLITCH_2000 0x04 -#define SD_OCP_GLITCH_4000 0x05 -#define SD_OCP_GLITCH_8000 0x06 -#define SD_OCP_GLITCH_10000 0x07 - -#define MS_OCP_GLITCH_MASK 0x70 -#define MS_OCP_GLITCH_6_4 (0x00 << 4) -#define MS_OCP_GLITCH_64 (0x01 << 4) -#define MS_OCP_GLITCH_640 (0x02 << 4) -#define MS_OCP_GLITCH_1000 (0x03 << 4) -#define MS_OCP_GLITCH_2000 (0x04 << 4) -#define MS_OCP_GLITCH_4000 (0x05 << 4) -#define MS_OCP_GLITCH_8000 (0x06 << 4) -#define MS_OCP_GLITCH_10000 (0x07 << 4) - -#define OCP_TIME_60 0x00 -#define OCP_TIME_100 (0x01 << 3) -#define OCP_TIME_200 (0x02 << 3) -#define OCP_TIME_400 (0x03 << 3) -#define OCP_TIME_600 (0x04 << 3) -#define OCP_TIME_800 (0x05 << 3) -#define OCP_TIME_1100 (0x06 << 3) -#define OCP_TIME_MASK 0x38 - -#define MS_OCP_TIME_60 0x00 -#define MS_OCP_TIME_100 (0x01 << 4) -#define MS_OCP_TIME_200 (0x02 << 4) -#define MS_OCP_TIME_400 (0x03 << 4) -#define MS_OCP_TIME_600 (0x04 << 4) -#define MS_OCP_TIME_800 (0x05 << 4) -#define MS_OCP_TIME_1100 (0x06 << 4) -#define MS_OCP_TIME_MASK 0x70 - -#define SD_OCP_TIME_60 0x00 -#define SD_OCP_TIME_100 0x01 -#define SD_OCP_TIME_200 0x02 -#define SD_OCP_TIME_400 0x03 -#define SD_OCP_TIME_600 0x04 -#define SD_OCP_TIME_800 0x05 -#define SD_OCP_TIME_1100 0x06 -#define SD_OCP_TIME_MASK 0x07 - -#define OCP_THD_315_417 0x00 -#define OCP_THD_283_783 (0x01 << 6) -#define OCP_THD_244_946 (0x02 << 6) -#define OCP_THD_191_1080 (0x03 << 6) -#define OCP_THD_MASK 0xC0 - -#define MS_OCP_THD_450 0x00 -#define MS_OCP_THD_550 (0x01 << 4) -#define MS_OCP_THD_650 (0x02 << 4) -#define MS_OCP_THD_750 (0x03 << 4) -#define MS_OCP_THD_850 (0x04 << 4) -#define MS_OCP_THD_950 (0x05 << 4) -#define MS_OCP_THD_1050 (0x06 << 4) -#define MS_OCP_THD_1150 (0x07 << 4) -#define MS_OCP_THD_MASK 0x70 - -#define SD_OCP_THD_450 0x00 -#define SD_OCP_THD_550 0x01 -#define SD_OCP_THD_650 0x02 -#define SD_OCP_THD_750 0x03 -#define SD_OCP_THD_850 0x04 -#define SD_OCP_THD_950 0x05 -#define SD_OCP_THD_1050 0x06 -#define SD_OCP_THD_1150 0x07 -#define SD_OCP_THD_MASK 0x07 - -#define FPGA_MS_PULL_CTL_EN 0xEF -#define FPGA_SD_PULL_CTL_EN 0xF7 -#define FPGA_XD_PULL_CTL_EN1 0xFE -#define FPGA_XD_PULL_CTL_EN2 0xFD -#define FPGA_XD_PULL_CTL_EN3 0xFB - -#define FPGA_MS_PULL_CTL_BIT 0x10 -#define FPGA_SD_PULL_CTL_BIT 0x08 - -#define BLINK_EN 0x08 -#define LED_GPIO0 (0 << 4) -#define LED_GPIO1 (1 << 4) -#define LED_GPIO2 (2 << 4) - -#define SDIO_BUS_CTRL 0x01 -#define SDIO_CD_CTRL 0x02 - -#define SSC_RSTB 0x80 -#define SSC_8X_EN 0x40 -#define SSC_FIX_FRAC 0x20 -#define SSC_SEL_1M 0x00 -#define SSC_SEL_2M 0x08 -#define SSC_SEL_4M 0x10 -#define SSC_SEL_8M 0x18 - -#define SSC_DEPTH_MASK 0x07 -#define SSC_DEPTH_DISALBE 0x00 -#define SSC_DEPTH_4M 0x01 -#define SSC_DEPTH_2M 0x02 -#define SSC_DEPTH_1M 0x03 -#define SSC_DEPTH_512K 0x04 -#define SSC_DEPTH_256K 0x05 -#define SSC_DEPTH_128K 0x06 -#define SSC_DEPTH_64K 0x07 - -#define XD_D3_NP 0x00 -#define XD_D3_PD (0x01 << 6) -#define XD_D3_PU (0x02 << 6) -#define XD_D2_NP 0x00 -#define XD_D2_PD (0x01 << 4) -#define XD_D2_PU (0x02 << 4) -#define XD_D1_NP 0x00 -#define XD_D1_PD (0x01 << 2) -#define XD_D1_PU (0x02 << 2) -#define XD_D0_NP 0x00 -#define XD_D0_PD 0x01 -#define XD_D0_PU 0x02 - -#define SD_D7_NP 0x00 -#define SD_D7_PD (0x01 << 4) -#define SD_DAT7_PU (0x02 << 4) -#define SD_CLK_NP 0x00 -#define SD_CLK_PD (0x01 << 2) -#define SD_CLK_PU (0x02 << 2) -#define SD_D5_NP 0x00 -#define SD_D5_PD 0x01 -#define SD_D5_PU 0x02 - -#define MS_D1_NP 0x00 -#define MS_D1_PD (0x01 << 6) -#define MS_D1_PU (0x02 << 6) -#define MS_D2_NP 0x00 -#define MS_D2_PD (0x01 << 4) -#define MS_D2_PU (0x02 << 4) -#define MS_CLK_NP 0x00 -#define MS_CLK_PD (0x01 << 2) -#define MS_CLK_PU (0x02 << 2) -#define MS_D6_NP 0x00 -#define MS_D6_PD 0x01 -#define MS_D6_PU 0x02 - -#define XD_D7_NP 0x00 -#define XD_D7_PD (0x01 << 6) -#define XD_D7_PU (0x02 << 6) -#define XD_D6_NP 0x00 -#define XD_D6_PD (0x01 << 4) -#define XD_D6_PU (0x02 << 4) -#define XD_D5_NP 0x00 -#define XD_D5_PD (0x01 << 2) -#define XD_D5_PU (0x02 << 2) -#define XD_D4_NP 0x00 -#define XD_D4_PD 0x01 -#define XD_D4_PU 0x02 - -#define SD_D6_NP 0x00 -#define SD_D6_PD (0x01 << 6) -#define SD_D6_PU (0x02 << 6) -#define SD_D0_NP 0x00 -#define SD_D0_PD (0x01 << 4) -#define SD_D0_PU (0x02 << 4) -#define SD_D1_NP 0x00 -#define SD_D1_PD 0x01 -#define SD_D1_PU 0x02 - -#define MS_D3_NP 0x00 -#define MS_D3_PD (0x01 << 6) -#define MS_D3_PU (0x02 << 6) -#define MS_D0_NP 0x00 -#define MS_D0_PD (0x01 << 4) -#define MS_D0_PU (0x02 << 4) -#define MS_BS_NP 0x00 -#define MS_BS_PD (0x01 << 2) -#define MS_BS_PU (0x02 << 2) - -#define XD_WP_NP 0x00 -#define XD_WP_PD (0x01 << 6) -#define XD_WP_PU (0x02 << 6) -#define XD_CE_NP 0x00 -#define XD_CE_PD (0x01 << 3) -#define XD_CE_PU (0x02 << 3) -#define XD_CLE_NP 0x00 -#define XD_CLE_PD (0x01 << 1) -#define XD_CLE_PU (0x02 << 1) -#define XD_CD_PD 0x00 -#define XD_CD_PU 0x01 - -#define SD_D4_NP 0x00 -#define SD_D4_PD (0x01 << 6) -#define SD_D4_PU (0x02 << 6) - -#define MS_D7_NP 0x00 -#define MS_D7_PD (0x01 << 6) -#define MS_D7_PU (0x02 << 6) - -#define XD_RDY_NP 0x00 -#define XD_RDY_PD (0x01 << 6) -#define XD_RDY_PU (0x02 << 6) -#define XD_WE_NP 0x00 -#define XD_WE_PD (0x01 << 4) -#define XD_WE_PU (0x02 << 4) -#define XD_RE_NP 0x00 -#define XD_RE_PD (0x01 << 2) -#define XD_RE_PU (0x02 << 2) -#define XD_ALE_NP 0x00 -#define XD_ALE_PD 0x01 -#define XD_ALE_PU 0x02 - -#define SD_D3_NP 0x00 -#define SD_D3_PD (0x01 << 4) -#define SD_D3_PU (0x02 << 4) -#define SD_D2_NP 0x00 -#define SD_D2_PD (0x01 << 2) -#define SD_D2_PU (0x02 << 2) - -#define MS_INS_PD 0x00 -#define MS_INS_PU (0x01 << 7) -#define SD_WP_NP 0x00 -#define SD_WP_PD (0x01 << 5) -#define SD_WP_PU (0x02 << 5) -#define SD_CD_PD 0x00 -#define SD_CD_PU (0x01 << 4) -#define SD_CMD_NP 0x00 -#define SD_CMD_PD (0x01 << 2) -#define SD_CMD_PU (0x02 << 2) - -#define MS_D5_NP 0x00 -#define MS_D5_PD (0x01 << 2) -#define MS_D5_PU (0x02 << 2) -#define MS_D4_NP 0x00 -#define MS_D4_PD 0x01 -#define MS_D4_PU 0x02 - -#define FORCE_PM_CLOCK 0x10 -#define EN_CLOCK_PM 0x01 - -#define HOST_ENTER_S3 0x02 -#define HOST_ENTER_S1 0x01 - -#define AUX_PWR_DETECTED 0x01 - -#define PHY_DEBUG_MODE 0x01 - -#define SPI_COMMAND_BIT_8 0xE0 -#define SPI_ADDRESS_BIT_24 0x17 -#define SPI_ADDRESS_BIT_32 0x1F - -#define SPI_TRANSFER0_START 0x80 -#define SPI_TRANSFER0_END 0x40 -#define SPI_C_MODE0 0x00 -#define SPI_CA_MODE0 0x01 -#define SPI_CDO_MODE0 0x02 -#define SPI_CDI_MODE0 0x03 -#define SPI_CADO_MODE0 0x04 -#define SPI_CADI_MODE0 0x05 -#define SPI_POLLING_MODE0 0x06 - -#define SPI_TRANSFER1_START 0x80 -#define SPI_TRANSFER1_END 0x40 -#define SPI_DO_MODE1 0x00 -#define SPI_DI_MODE1 0x01 - -#define CS_POLARITY_HIGH 0x40 -#define CS_POLARITY_LOW 0x00 -#define DTO_MSB_FIRST 0x00 -#define DTO_LSB_FIRST 0x20 -#define SPI_MASTER 0x00 -#define SPI_SLAVE 0x10 -#define SPI_MODE0 0x00 -#define SPI_MODE1 0x04 -#define SPI_MODE2 0x08 -#define SPI_MODE3 0x0C -#define SPI_MANUAL 0x00 -#define SPI_HALF_AUTO 0x01 -#define SPI_AUTO 0x02 -#define SPI_EEPROM_AUTO 0x03 - -#define EDO_TIMING_MASK 0x03 -#define SAMPLE_RISING 0x00 -#define SAMPLE_DELAY_HALF 0x01 -#define SAMPLE_DELAY_ONE 0x02 -#define SAPMLE_DELAY_ONE_HALF 0x03 -#define TCS_MASK 0x0C - -#define NOT_BYPASS_SD 0x02 -#define DISABLE_SDIO_FUNC 0x04 -#define SELECT_1LUN 0x08 - -#define PWR_GATE_EN 0x01 -#define LDO3318_PWR_MASK 0x06 -#define LDO_ON 0x00 -#define LDO_SUSPEND 0x04 -#define LDO_OFF 0x06 - -#define SD_CFG1 0xFDA0 -#define SD_CFG2 0xFDA1 -#define SD_CFG3 0xFDA2 -#define SD_STAT1 0xFDA3 -#define SD_STAT2 0xFDA4 -#define SD_BUS_STAT 0xFDA5 -#define SD_PAD_CTL 0xFDA6 -#define SD_SAMPLE_POINT_CTL 0xFDA7 -#define SD_PUSH_POINT_CTL 0xFDA8 -#define SD_CMD0 0xFDA9 -#define SD_CMD1 0xFDAA -#define SD_CMD2 0xFDAB -#define SD_CMD3 0xFDAC -#define SD_CMD4 0xFDAD -#define SD_CMD5 0xFDAE -#define SD_BYTE_CNT_L 0xFDAF -#define SD_BYTE_CNT_H 0xFDB0 -#define SD_BLOCK_CNT_L 0xFDB1 -#define SD_BLOCK_CNT_H 0xFDB2 -#define SD_TRANSFER 0xFDB3 -#define SD_CMD_STATE 0xFDB5 -#define SD_DATA_STATE 0xFDB6 - -#define DCM_DRP_CTL 0xFC23 -#define DCM_DRP_TRIG 0xFC24 -#define DCM_DRP_CFG 0xFC25 -#define DCM_DRP_WR_DATA_L 0xFC26 -#define DCM_DRP_WR_DATA_H 0xFC27 -#define DCM_DRP_RD_DATA_L 0xFC28 -#define DCM_DRP_RD_DATA_H 0xFC29 -#define SD_VPCLK0_CTL 0xFC2A -#define SD_VPCLK1_CTL 0xFC2B -#define SD_DCMPS0_CTL 0xFC2C -#define SD_DCMPS1_CTL 0xFC2D -#define SD_VPTX_CTL SD_VPCLK0_CTL -#define SD_VPRX_CTL SD_VPCLK1_CTL -#define SD_DCMPS_TX_CTL SD_DCMPS0_CTL -#define SD_DCMPS_RX_CTL SD_DCMPS1_CTL - -#define CARD_CLK_SOURCE 0xFC2E - -#define CARD_PWR_CTL 0xFD50 -#define CARD_CLK_SWITCH 0xFD51 -#define CARD_SHARE_MODE 0xFD52 -#define CARD_DRIVE_SEL 0xFD53 -#define CARD_STOP 0xFD54 -#define CARD_OE 0xFD55 -#define CARD_AUTO_BLINK 0xFD56 -#define CARD_GPIO_DIR 0xFD57 -#define CARD_GPIO 0xFD58 - -#define CARD_DATA_SOURCE 0xFD5B -#define CARD_SELECT 0xFD5C -#define SD30_DRIVE_SEL 0xFD5E - -#define CARD_CLK_EN 0xFD69 - -#define SDIO_CTRL 0xFD6B - -#define FPDCTL 0xFC00 -#define PDINFO 0xFC01 - -#define CLK_CTL 0xFC02 -#define CLK_DIV 0xFC03 -#define CLK_SEL 0xFC04 - -#define SSC_DIV_N_0 0xFC0F -#define SSC_DIV_N_1 0xFC10 - -#define RCCTL 0xFC14 - -#define FPGA_PULL_CTL 0xFC1D - -#define CARD_PULL_CTL1 0xFD60 -#define CARD_PULL_CTL2 0xFD61 -#define CARD_PULL_CTL3 0xFD62 -#define CARD_PULL_CTL4 0xFD63 -#define CARD_PULL_CTL5 0xFD64 -#define CARD_PULL_CTL6 0xFD65 - -#define IRQEN0 0xFE20 -#define IRQSTAT0 0xFE21 -#define IRQEN1 0xFE22 -#define IRQSTAT1 0xFE23 -#define TLPRIEN 0xFE24 -#define TLPRISTAT 0xFE25 -#define TLPTIEN 0xFE26 -#define TLPTISTAT 0xFE27 -#define DMATC0 0xFE28 -#define DMATC1 0xFE29 -#define DMATC2 0xFE2A -#define DMATC3 0xFE2B -#define DMACTL 0xFE2C -#define BCTL 0xFE2D -#define RBBC0 0xFE2E -#define RBBC1 0xFE2F -#define RBDAT 0xFE30 -#define RBCTL 0xFE34 -#define CFGADDR0 0xFE35 -#define CFGADDR1 0xFE36 -#define CFGDATA0 0xFE37 -#define CFGDATA1 0xFE38 -#define CFGDATA2 0xFE39 -#define CFGDATA3 0xFE3A -#define CFGRWCTL 0xFE3B -#define PHYRWCTL 0xFE3C -#define PHYDATA0 0xFE3D -#define PHYDATA1 0xFE3E -#define PHYADDR 0xFE3F -#define MSGRXDATA0 0xFE40 -#define MSGRXDATA1 0xFE41 -#define MSGRXDATA2 0xFE42 -#define MSGRXDATA3 0xFE43 -#define MSGTXDATA0 0xFE44 -#define MSGTXDATA1 0xFE45 -#define MSGTXDATA2 0xFE46 -#define MSGTXDATA3 0xFE47 -#define MSGTXCTL 0xFE48 -#define PETXCFG 0xFE49 - -#define CDRESUMECTL 0xFE52 -#define WAKE_SEL_CTL 0xFE54 -#define PME_FORCE_CTL 0xFE56 -#define ASPM_FORCE_CTL 0xFE57 -#define PM_CLK_FORCE_CTL 0xFE58 -#define PERST_GLITCH_WIDTH 0xFE5C -#define CHANGE_LINK_STATE 0xFE5B -#define RESET_LOAD_REG 0xFE5E -#define HOST_SLEEP_STATE 0xFE60 -#define MAIN_PWR_OFF_CTL 0xFE70 /* RTS5208 */ - -#define NFTS_TX_CTRL 0xFE72 - -#define PWR_GATE_CTRL 0xFE75 -#define PWD_SUSPEND_EN 0xFE76 - -#define EFUSE_CONTENT 0xFE5F - -#define XD_INIT 0xFD10 -#define XD_DTCTL 0xFD11 -#define XD_CTL 0xFD12 -#define XD_TRANSFER 0xFD13 -#define XD_CFG 0xFD14 -#define XD_ADDRESS0 0xFD15 -#define XD_ADDRESS1 0xFD16 -#define XD_ADDRESS2 0xFD17 -#define XD_ADDRESS3 0xFD18 -#define XD_ADDRESS4 0xFD19 -#define XD_DAT 0xFD1A -#define XD_PAGE_CNT 0xFD1B -#define XD_PAGE_STATUS 0xFD1C -#define XD_BLOCK_STATUS 0xFD1D -#define XD_BLOCK_ADDR1_L 0xFD1E -#define XD_BLOCK_ADDR1_H 0xFD1F -#define XD_BLOCK_ADDR2_L 0xFD20 -#define XD_BLOCK_ADDR2_H 0xFD21 -#define XD_BYTE_CNT_L 0xFD22 -#define XD_BYTE_CNT_H 0xFD23 -#define XD_PARITY 0xFD24 -#define XD_ECC_BIT1 0xFD25 -#define XD_ECC_BYTE1 0xFD26 -#define XD_ECC_BIT2 0xFD27 -#define XD_ECC_BYTE2 0xFD28 -#define XD_RESERVED0 0xFD29 -#define XD_RESERVED1 0xFD2A -#define XD_RESERVED2 0xFD2B -#define XD_RESERVED3 0xFD2C -#define XD_CHK_DATA_STATUS 0xFD2D -#define XD_CATCTL 0xFD2E - -#define MS_CFG 0xFD40 -#define MS_TPC 0xFD41 -#define MS_TRANS_CFG 0xFD42 -#define MS_TRANSFER 0xFD43 -#define MS_INT_REG 0xFD44 -#define MS_BYTE_CNT 0xFD45 -#define MS_SECTOR_CNT_L 0xFD46 -#define MS_SECTOR_CNT_H 0xFD47 -#define MS_DBUS_H 0xFD48 - -#define SSC_CTL1 0xFC11 -#define SSC_CTL2 0xFC12 - -#define OCPCTL 0xFC15 -#define OCPSTAT 0xFC16 -#define OCPCLR 0xFC17 /* 5208 */ -#define OCPPARA1 0xFC18 -#define OCPPARA2 0xFC19 - -#define EFUSE_OP 0xFC20 -#define EFUSE_CTRL 0xFC21 -#define EFUSE_DATA 0xFC22 - -#define SPI_COMMAND 0xFD80 -#define SPI_ADDR0 0xFD81 -#define SPI_ADDR1 0xFD82 -#define SPI_ADDR2 0xFD83 -#define SPI_ADDR3 0xFD84 -#define SPI_CA_NUMBER 0xFD85 -#define SPI_LENGTH0 0xFD86 -#define SPI_LENGTH1 0xFD87 -#define SPI_DATA 0xFD88 -#define SPI_DATA_NUMBER 0xFD89 -#define SPI_TRANSFER0 0xFD90 -#define SPI_TRANSFER1 0xFD91 -#define SPI_CONTROL 0xFD92 -#define SPI_SIG 0xFD93 -#define SPI_TCTL 0xFD94 -#define SPI_SLAVE_NUM 0xFD95 -#define SPI_CLK_DIVIDER0 0xFD96 -#define SPI_CLK_DIVIDER1 0xFD97 - -#define SRAM_BASE 0xE600 -#define RBUF_BASE 0xF400 -#define PPBUF_BASE1 0xF800 -#define PPBUF_BASE2 0xFA00 -#define IMAGE_FLAG_ADDR0 0xCE80 -#define IMAGE_FLAG_ADDR1 0xCE81 - -#define READ_OP 1 -#define WRITE_OP 2 - -#define LCTLR 0x80 - -#define POLLING_WAIT_CNT 1 -#define IDLE_MAX_COUNT 10 -#define SDIO_IDLE_COUNT 10 - -#define DEBOUNCE_CNT 5 - -void do_remaining_work(struct rtsx_chip *chip); -void try_to_switch_sdio_ctrl(struct rtsx_chip *chip); -void do_reset_sd_card(struct rtsx_chip *chip); -void do_reset_xd_card(struct rtsx_chip *chip); -void do_reset_ms_card(struct rtsx_chip *chip); -void rtsx_power_off_card(struct rtsx_chip *chip); -void rtsx_release_cards(struct rtsx_chip *chip); -void rtsx_reset_cards(struct rtsx_chip *chip); -void rtsx_reinit_cards(struct rtsx_chip *chip, int reset_chip); -void rtsx_init_cards(struct rtsx_chip *chip); -int switch_ssc_clock(struct rtsx_chip *chip, int clk); -int switch_normal_clock(struct rtsx_chip *chip, int clk); -int enable_card_clock(struct rtsx_chip *chip, u8 card); -int disable_card_clock(struct rtsx_chip *chip, u8 card); -int card_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, - u32 sec_addr, u16 sec_cnt); -void trans_dma_enable(enum dma_data_direction dir, - struct rtsx_chip *chip, u32 byte_cnt, u8 pack_size); -void toggle_gpio(struct rtsx_chip *chip, u8 gpio); -void turn_on_led(struct rtsx_chip *chip, u8 gpio); -void turn_off_led(struct rtsx_chip *chip, u8 gpio); - -int card_share_mode(struct rtsx_chip *chip, int card); -int select_card(struct rtsx_chip *chip, int card); -int detect_card_cd(struct rtsx_chip *chip, int card); -int check_card_exist(struct rtsx_chip *chip, unsigned int lun); -int check_card_ready(struct rtsx_chip *chip, unsigned int lun); -int check_card_wp(struct rtsx_chip *chip, unsigned int lun); -void eject_card(struct rtsx_chip *chip, unsigned int lun); -u8 get_lun_card(struct rtsx_chip *chip, unsigned int lun); - -static inline u32 get_card_size(struct rtsx_chip *chip, unsigned int lun) -{ -#ifdef SUPPORT_SD_LOCK - struct sd_info *sd_card = &chip->sd_card; - - if ((get_lun_card(chip, lun) == SD_CARD) && - (sd_card->sd_lock_status & SD_LOCKED)) - return 0; - - return chip->capacity[lun]; -#else - return chip->capacity[lun]; -#endif -} - -static inline int switch_clock(struct rtsx_chip *chip, int clk) -{ - int retval = 0; - - if (chip->asic_code) - retval = switch_ssc_clock(chip, clk); - else - retval = switch_normal_clock(chip, clk); - - return retval; -} - -int card_power_on(struct rtsx_chip *chip, u8 card); -int card_power_off(struct rtsx_chip *chip, u8 card); - -static inline int card_power_off_all(struct rtsx_chip *chip) -{ - int retval; - - retval = rtsx_write_register(chip, CARD_PWR_CTL, 0x0F, 0x0F); - if (retval) - return retval; - - return STATUS_SUCCESS; -} - -static inline void rtsx_clear_xd_error(struct rtsx_chip *chip) -{ - rtsx_write_register(chip, CARD_STOP, XD_STOP | XD_CLR_ERR, - XD_STOP | XD_CLR_ERR); -} - -static inline void rtsx_clear_sd_error(struct rtsx_chip *chip) -{ - rtsx_write_register(chip, CARD_STOP, SD_STOP | SD_CLR_ERR, - SD_STOP | SD_CLR_ERR); -} - -static inline void rtsx_clear_ms_error(struct rtsx_chip *chip) -{ - rtsx_write_register(chip, CARD_STOP, MS_STOP | MS_CLR_ERR, - MS_STOP | MS_CLR_ERR); -} - -static inline void rtsx_clear_spi_error(struct rtsx_chip *chip) -{ - rtsx_write_register(chip, CARD_STOP, SPI_STOP | SPI_CLR_ERR, - SPI_STOP | SPI_CLR_ERR); -} - -#ifdef SUPPORT_SDIO_ASPM -void dynamic_configure_sdio_aspm(struct rtsx_chip *chip); -#endif - -#endif /* __REALTEK_RTSX_CARD_H */ diff --git a/drivers/staging/rts5208/rtsx_chip.c b/drivers/staging/rts5208/rtsx_chip.c deleted file mode 100644 index 6375032918d4..000000000000 --- a/drivers/staging/rts5208/rtsx_chip.c +++ /dev/null @@ -1,2161 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Driver for Realtek PCI-Express card reader - * - * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. - * - * Author: - * Wei WANG (wei_wang@xxxxxxxxxxxxxx) - * Micky Ching (micky_ching@xxxxxxxxxxxxxx) - */ - -#include <linux/blkdev.h> -#include <linux/kthread.h> -#include <linux/sched.h> -#include <linux/workqueue.h> -#include <linux/vmalloc.h> - -#include "rtsx.h" -#include "sd.h" -#include "xd.h" -#include "ms.h" - -static void rtsx_calibration(struct rtsx_chip *chip) -{ - rtsx_write_phy_register(chip, 0x1B, 0x135E); - wait_timeout(10); - rtsx_write_phy_register(chip, 0x00, 0x0280); - rtsx_write_phy_register(chip, 0x01, 0x7112); - rtsx_write_phy_register(chip, 0x01, 0x7110); - rtsx_write_phy_register(chip, 0x01, 0x7112); - rtsx_write_phy_register(chip, 0x01, 0x7113); - rtsx_write_phy_register(chip, 0x00, 0x0288); -} - -void rtsx_enable_card_int(struct rtsx_chip *chip) -{ - u32 reg = rtsx_readl(chip, RTSX_BIER); - int i; - - for (i = 0; i <= chip->max_lun; i++) { - if (chip->lun2card[i] & XD_CARD) - reg |= XD_INT_EN; - if (chip->lun2card[i] & SD_CARD) - reg |= SD_INT_EN; - if (chip->lun2card[i] & MS_CARD) - reg |= MS_INT_EN; - } - if (chip->hw_bypass_sd) - reg &= ~((u32)SD_INT_EN); - - rtsx_writel(chip, RTSX_BIER, reg); -} - -void rtsx_enable_bus_int(struct rtsx_chip *chip) -{ - u32 reg = 0; -#ifndef DISABLE_CARD_INT - int i; -#endif - - reg = TRANS_OK_INT_EN | TRANS_FAIL_INT_EN; - -#ifndef DISABLE_CARD_INT - for (i = 0; i <= chip->max_lun; i++) { - dev_dbg(rtsx_dev(chip), "lun2card[%d] = 0x%02x\n", - i, chip->lun2card[i]); - - if (chip->lun2card[i] & XD_CARD) - reg |= XD_INT_EN; - if (chip->lun2card[i] & SD_CARD) - reg |= SD_INT_EN; - if (chip->lun2card[i] & MS_CARD) - reg |= MS_INT_EN; - } - if (chip->hw_bypass_sd) - reg &= ~((u32)SD_INT_EN); -#endif - - if (chip->ic_version >= IC_VER_C) - reg |= DELINK_INT_EN; -#ifdef SUPPORT_OCP - reg |= OC_INT_EN; -#endif - if (!chip->adma_mode) - reg |= DATA_DONE_INT_EN; - - /* Enable Bus Interrupt */ - rtsx_writel(chip, RTSX_BIER, reg); - - dev_dbg(rtsx_dev(chip), "RTSX_BIER: 0x%08x\n", reg); -} - -void rtsx_disable_bus_int(struct rtsx_chip *chip) -{ - rtsx_writel(chip, RTSX_BIER, 0); -} - -static int rtsx_pre_handle_sdio_old(struct rtsx_chip *chip) -{ - int retval; - - if (chip->ignore_sd && CHK_SDIO_EXIST(chip)) { - if (chip->asic_code) { - retval = rtsx_write_register(chip, CARD_PULL_CTL5, - 0xFF, - MS_INS_PU | SD_WP_PU | - SD_CD_PU | SD_CMD_PU); - if (retval) - return retval; - } else { - retval = rtsx_write_register(chip, FPGA_PULL_CTL, - 0xFF, - FPGA_SD_PULL_CTL_EN); - if (retval) - return retval; - } - retval = rtsx_write_register(chip, CARD_SHARE_MODE, 0xFF, - CARD_SHARE_48_SD); - if (retval) - return retval; - - /* Enable SDIO internal clock */ - retval = rtsx_write_register(chip, 0xFF2C, 0x01, 0x01); - if (retval) - return retval; - - retval = rtsx_write_register(chip, SDIO_CTRL, 0xFF, - SDIO_BUS_CTRL | SDIO_CD_CTRL); - if (retval) - return retval; - - chip->sd_int = 1; - chip->sd_io = 1; - } else { - chip->need_reset |= SD_CARD; - } - - return STATUS_SUCCESS; -} - -#ifdef HW_AUTO_SWITCH_SD_BUS -static int rtsx_pre_handle_sdio_new(struct rtsx_chip *chip) -{ - u8 tmp; - bool sw_bypass_sd = false; - int retval; - - if (chip->driver_first_load) { - if (CHECK_PID(chip, 0x5288)) { - retval = rtsx_read_register(chip, 0xFE5A, &tmp); - if (retval) - return retval; - if (tmp & 0x08) - sw_bypass_sd = true; - } else if (CHECK_PID(chip, 0x5208)) { - retval = rtsx_read_register(chip, 0xFE70, &tmp); - if (retval) - return retval; - if (tmp & 0x80) - sw_bypass_sd = true; - } - } else { - if (chip->sdio_in_charge) - sw_bypass_sd = true; - } - dev_dbg(rtsx_dev(chip), "chip->sdio_in_charge = %d\n", - chip->sdio_in_charge); - dev_dbg(rtsx_dev(chip), "chip->driver_first_load = %d\n", - chip->driver_first_load); - dev_dbg(rtsx_dev(chip), "sw_bypass_sd = %d\n", - sw_bypass_sd); - - if (sw_bypass_sd) { - u8 cd_toggle_mask = 0; - - retval = rtsx_read_register(chip, TLPTISTAT, &tmp); - if (retval) - return retval; - cd_toggle_mask = 0x08; - - if (tmp & cd_toggle_mask) { - /* Disable sdio_bus_auto_switch */ - if (CHECK_PID(chip, 0x5288)) { - retval = rtsx_write_register(chip, 0xFE5A, - 0x08, 0x00); - if (retval) - return retval; - } else if (CHECK_PID(chip, 0x5208)) { - retval = rtsx_write_register(chip, 0xFE70, - 0x80, 0x00); - if (retval) - return retval; - } - - retval = rtsx_write_register(chip, TLPTISTAT, 0xFF, - tmp); - if (retval) - return retval; - - chip->need_reset |= SD_CARD; - } else { - dev_dbg(rtsx_dev(chip), "Chip inserted with SDIO!\n"); - - if (chip->asic_code) { - retval = sd_pull_ctl_enable(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } else { - retval = rtsx_write_register - (chip, FPGA_PULL_CTL, - FPGA_SD_PULL_CTL_BIT | 0x20, - 0); - if (retval) - return retval; - } - retval = card_share_mode(chip, SD_CARD); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - /* Enable sdio_bus_auto_switch */ - if (CHECK_PID(chip, 0x5288)) { - retval = rtsx_write_register(chip, 0xFE5A, - 0x08, 0x08); - if (retval) - return retval; - } else if (CHECK_PID(chip, 0x5208)) { - retval = rtsx_write_register(chip, 0xFE70, - 0x80, 0x80); - if (retval) - return retval; - } - - chip->chip_insert_with_sdio = 1; - chip->sd_io = 1; - } - } else { - retval = rtsx_write_register(chip, TLPTISTAT, 0x08, 0x08); - if (retval) - return retval; - - chip->need_reset |= SD_CARD; - } - - return STATUS_SUCCESS; -} -#endif - -static int rtsx_reset_aspm(struct rtsx_chip *chip) -{ - int ret; - - if (chip->dynamic_aspm) { - if (!CHK_SDIO_EXIST(chip) || !CHECK_PID(chip, 0x5288)) - return STATUS_SUCCESS; - - ret = rtsx_write_cfg_dw(chip, 2, 0xC0, 0xFF, - chip->aspm_l0s_l1_en); - if (ret != STATUS_SUCCESS) - return STATUS_FAIL; - - return STATUS_SUCCESS; - } - - if (CHECK_PID(chip, 0x5208)) { - ret = rtsx_write_register(chip, ASPM_FORCE_CTL, 0xFF, 0x3F); - if (ret) - return ret; - } - ret = rtsx_write_config_byte(chip, LCTLR, chip->aspm_l0s_l1_en); - if (ret != STATUS_SUCCESS) - return STATUS_FAIL; - - chip->aspm_level[0] = chip->aspm_l0s_l1_en; - if (CHK_SDIO_EXIST(chip)) { - chip->aspm_level[1] = chip->aspm_l0s_l1_en; - ret = rtsx_write_cfg_dw(chip, CHECK_PID(chip, 0x5288) ? 2 : 1, - 0xC0, 0xFF, chip->aspm_l0s_l1_en); - if (ret != STATUS_SUCCESS) - return STATUS_FAIL; - } - - chip->aspm_enabled = 1; - - return STATUS_SUCCESS; -} - -static int rtsx_enable_pcie_intr(struct rtsx_chip *chip) -{ - int ret; - - if (!chip->asic_code || !CHECK_PID(chip, 0x5208)) { - rtsx_enable_bus_int(chip); - return STATUS_SUCCESS; - } - - if (chip->phy_debug_mode) { - ret = rtsx_write_register(chip, CDRESUMECTL, 0x77, 0); - if (ret) - return ret; - rtsx_disable_bus_int(chip); - } else { - rtsx_enable_bus_int(chip); - } - - if (chip->ic_version >= IC_VER_D) { - u16 reg; - - ret = rtsx_read_phy_register(chip, 0x00, ®); - if (ret != STATUS_SUCCESS) - return STATUS_FAIL; - - reg &= 0xFE7F; - reg |= 0x80; - ret = rtsx_write_phy_register(chip, 0x00, reg); - if (ret != STATUS_SUCCESS) - return STATUS_FAIL; - - ret = rtsx_read_phy_register(chip, 0x1C, ®); - if (ret != STATUS_SUCCESS) - return STATUS_FAIL; - - reg &= 0xFFF7; - ret = rtsx_write_phy_register(chip, 0x1C, reg); - if (ret != STATUS_SUCCESS) - return STATUS_FAIL; - } - - if (chip->driver_first_load && chip->ic_version < IC_VER_C) - rtsx_calibration(chip); - - return STATUS_SUCCESS; -} - -int rtsx_reset_chip(struct rtsx_chip *chip) -{ - int retval; - - rtsx_writel(chip, RTSX_HCBAR, chip->host_cmds_addr); - - rtsx_disable_aspm(chip); - - retval = rtsx_write_register(chip, HOST_SLEEP_STATE, 0x03, 0x00); - if (retval) - return retval; - - /* Disable card clock */ - retval = rtsx_write_register(chip, CARD_CLK_EN, 0x1E, 0); - if (retval) - return retval; - -#ifdef SUPPORT_OCP - /* SSC power on, OCD power on */ - if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) { - retval = rtsx_write_register(chip, FPDCTL, OC_POWER_DOWN, 0); - if (retval) - return retval; - } else { - retval = rtsx_write_register(chip, FPDCTL, OC_POWER_DOWN, - MS_OC_POWER_DOWN); - if (retval) - return retval; - } - - retval = rtsx_write_register(chip, OCPPARA1, OCP_TIME_MASK, - OCP_TIME_800); - if (retval) - return retval; - retval = rtsx_write_register(chip, OCPPARA2, OCP_THD_MASK, - OCP_THD_244_946); - if (retval) - return retval; - retval = rtsx_write_register(chip, OCPCTL, 0xFF, - CARD_OC_INT_EN | CARD_DETECT_EN); - if (retval) - return retval; -#else - /* OC power down */ - retval = rtsx_write_register(chip, FPDCTL, OC_POWER_DOWN, - OC_POWER_DOWN); - if (retval) - return retval; -#endif - - if (!CHECK_PID(chip, 0x5288)) { - retval = rtsx_write_register(chip, CARD_GPIO_DIR, 0xFF, 0x03); - if (retval) - return retval; - } - - /* Turn off LED */ - retval = rtsx_write_register(chip, CARD_GPIO, 0xFF, 0x03); - if (retval) - return retval; - - /* Reset delink mode */ - retval = rtsx_write_register(chip, CHANGE_LINK_STATE, 0x0A, 0); - if (retval) - return retval; - - /* Card driving select */ - retval = rtsx_write_register(chip, CARD_DRIVE_SEL, 0xFF, - chip->card_drive_sel); - if (retval) - return retval; - -#ifdef LED_AUTO_BLINK - retval = rtsx_write_register(chip, CARD_AUTO_BLINK, 0xFF, - LED_BLINK_SPEED | BLINK_EN | LED_GPIO0); - if (retval) - return retval; -#endif - - if (chip->asic_code) { - /* Enable SSC Clock */ - retval = rtsx_write_register(chip, SSC_CTL1, 0xFF, - SSC_8X_EN | SSC_SEL_4M); - if (retval) - return retval; - retval = rtsx_write_register(chip, SSC_CTL2, 0xFF, 0x12); - if (retval) - return retval; - } - - /* - * Disable cd_pwr_save (u_force_rst_core_en=0, u_cd_rst_core_en=0) - * 0xFE5B - * bit[1] u_cd_rst_core_en rst_value = 0 - * bit[2] u_force_rst_core_en rst_value = 0 - * bit[5] u_mac_phy_rst_n_dbg rst_value = 1 - * bit[4] u_non_sticky_rst_n_dbg rst_value = 0 - */ - retval = rtsx_write_register(chip, CHANGE_LINK_STATE, 0x16, 0x10); - if (retval) - return retval; - - /* Enable ASPM */ - if (chip->aspm_l0s_l1_en) { - retval = rtsx_reset_aspm(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } else { - if (chip->asic_code && CHECK_PID(chip, 0x5208)) { - retval = rtsx_write_phy_register(chip, 0x07, 0x0129); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - retval = rtsx_write_config_byte(chip, LCTLR, - chip->aspm_l0s_l1_en); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - - retval = rtsx_write_config_byte(chip, 0x81, 1); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (CHK_SDIO_EXIST(chip)) { - retval = rtsx_write_cfg_dw(chip, - CHECK_PID(chip, 0x5288) ? 2 : 1, - 0xC0, 0xFF00, 0x0100); - - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - - if (CHECK_PID(chip, 0x5288) && !CHK_SDIO_EXIST(chip)) { - retval = rtsx_write_cfg_dw(chip, 2, 0xC0, 0xFFFF, 0x0103); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = rtsx_write_cfg_dw(chip, 2, 0x84, 0xFF, 0x03); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - - retval = rtsx_write_register(chip, IRQSTAT0, LINK_RDY_INT, - LINK_RDY_INT); - if (retval) - return retval; - - retval = rtsx_write_register(chip, PERST_GLITCH_WIDTH, 0xFF, 0x80); - if (retval) - return retval; - - retval = rtsx_enable_pcie_intr(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - chip->need_reset = 0; - - chip->int_reg = rtsx_readl(chip, RTSX_BIPR); - - if (chip->hw_bypass_sd) - goto nextcard; - dev_dbg(rtsx_dev(chip), "In %s, chip->int_reg = 0x%x\n", __func__, - chip->int_reg); - if (chip->int_reg & SD_EXIST) { -#ifdef HW_AUTO_SWITCH_SD_BUS - if (CHECK_PID(chip, 0x5208) && chip->ic_version < IC_VER_C) - retval = rtsx_pre_handle_sdio_old(chip); - else - retval = rtsx_pre_handle_sdio_new(chip); - - dev_dbg(rtsx_dev(chip), "chip->need_reset = 0x%x (%s)\n", - (unsigned int)(chip->need_reset), __func__); -#else /* HW_AUTO_SWITCH_SD_BUS */ - retval = rtsx_pre_handle_sdio_old(chip); -#endif /* HW_AUTO_SWITCH_SD_BUS */ - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - } else { - chip->sd_io = 0; - retval = rtsx_write_register(chip, SDIO_CTRL, - SDIO_BUS_CTRL | SDIO_CD_CTRL, 0); - if (retval) - return retval; - } - -nextcard: - if (chip->int_reg & XD_EXIST) - chip->need_reset |= XD_CARD; - if (chip->int_reg & MS_EXIST) - chip->need_reset |= MS_CARD; - if (chip->int_reg & CARD_EXIST) { - retval = rtsx_write_register(chip, SSC_CTL1, SSC_RSTB, - SSC_RSTB); - if (retval) - return retval; - } - - dev_dbg(rtsx_dev(chip), "In %s, chip->need_reset = 0x%x\n", __func__, - (unsigned int)(chip->need_reset)); - - retval = rtsx_write_register(chip, RCCTL, 0x01, 0x00); - if (retval) - return retval; - - if (CHECK_PID(chip, 0x5208) || CHECK_PID(chip, 0x5288)) { - /* Turn off main power when entering S3/S4 state */ - retval = rtsx_write_register(chip, MAIN_PWR_OFF_CTL, 0x03, - 0x03); - if (retval) - return retval; - } - - if (chip->remote_wakeup_en && !chip->auto_delink_en) { - retval = rtsx_write_register(chip, WAKE_SEL_CTL, 0x07, 0x07); - if (retval) - return retval; - if (chip->aux_pwr_exist) { - retval = rtsx_write_register(chip, PME_FORCE_CTL, - 0xFF, 0x33); - if (retval) - return retval; - } - } else { - retval = rtsx_write_register(chip, WAKE_SEL_CTL, 0x07, 0x04); - if (retval) - return retval; - retval = rtsx_write_register(chip, PME_FORCE_CTL, 0xFF, 0x30); - if (retval) - return retval; - } - - if (CHECK_PID(chip, 0x5208) && chip->ic_version >= IC_VER_D) { - retval = rtsx_write_register(chip, PETXCFG, 0x1C, 0x14); - if (retval) - return retval; - } - - if (chip->asic_code && CHECK_PID(chip, 0x5208)) { - retval = rtsx_clr_phy_reg_bit(chip, 0x1C, 2); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - - if (chip->ft2_fast_mode) { - retval = rtsx_write_register(chip, CARD_PWR_CTL, 0xFF, - MS_PARTIAL_POWER_ON | - SD_PARTIAL_POWER_ON); - if (retval) - return retval; - udelay(chip->pmos_pwr_on_interval); - retval = rtsx_write_register(chip, CARD_PWR_CTL, 0xFF, - MS_POWER_ON | SD_POWER_ON); - if (retval) - return retval; - - wait_timeout(200); - } - - /* Reset card */ - rtsx_reset_detected_cards(chip, 0); - - chip->driver_first_load = 0; - - return STATUS_SUCCESS; -} - -static inline int valid_sd_speed_prior(u32 sd_speed_prior) -{ - bool valid_para = true; - int i; - - for (i = 0; i < 4; i++) { - u8 tmp = (u8)(sd_speed_prior >> (i * 8)); - - if (tmp < 0x01 || tmp > 0x04) { - valid_para = false; - break; - } - } - - return valid_para; -} - -static inline int valid_sd_current_prior(u32 sd_current_prior) -{ - bool valid_para = true; - int i; - - for (i = 0; i < 4; i++) { - u8 tmp = (u8)(sd_current_prior >> (i * 8)); - - if (tmp > 0x03) { - valid_para = false; - break; - } - } - - return valid_para; -} - -static int rts5208_init(struct rtsx_chip *chip) -{ - int retval; - u16 reg = 0; - u8 val = 0; - - retval = rtsx_write_register(chip, CLK_SEL, 0x03, 0x03); - if (retval) - return retval; - retval = rtsx_read_register(chip, CLK_SEL, &val); - if (retval) - return retval; - chip->asic_code = val == 0 ? 1 : 0; - - if (chip->asic_code) { - retval = rtsx_read_phy_register(chip, 0x1C, ®); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - dev_dbg(rtsx_dev(chip), "Value of phy register 0x1C is 0x%x\n", - reg); - chip->ic_version = (reg >> 4) & 0x07; - chip->phy_debug_mode = reg & PHY_DEBUG_MODE ? 1 : 0; - - } else { - retval = rtsx_read_register(chip, 0xFE80, &val); - if (retval) - return retval; - chip->ic_version = val; - chip->phy_debug_mode = 0; - } - - retval = rtsx_read_register(chip, PDINFO, &val); - if (retval) - return retval; - dev_dbg(rtsx_dev(chip), "PDINFO: 0x%x\n", val); - chip->aux_pwr_exist = val & AUX_PWR_DETECTED ? 1 : 0; - - retval = rtsx_read_register(chip, 0xFE50, &val); - if (retval) - return retval; - chip->hw_bypass_sd = val & 0x01 ? 1 : 0; - - rtsx_read_config_byte(chip, 0x0E, &val); - if (val & 0x80) - SET_SDIO_EXIST(chip); - else - CLR_SDIO_EXIST(chip); - - if (chip->use_hw_setting) { - retval = rtsx_read_register(chip, CHANGE_LINK_STATE, &val); - if (retval) - return retval; - chip->auto_delink_en = val & 0x80 ? 1 : 0; - } - - return STATUS_SUCCESS; -} - -static int rts5288_init(struct rtsx_chip *chip) -{ - int retval; - u8 val = 0, max_func; - u32 lval = 0; - - retval = rtsx_write_register(chip, CLK_SEL, 0x03, 0x03); - if (retval) - return retval; - retval = rtsx_read_register(chip, CLK_SEL, &val); - if (retval) - return retval; - chip->asic_code = val == 0 ? 1 : 0; - - chip->ic_version = 0; - chip->phy_debug_mode = 0; - - retval = rtsx_read_register(chip, PDINFO, &val); - if (retval) - return retval; - dev_dbg(rtsx_dev(chip), "PDINFO: 0x%x\n", val); - chip->aux_pwr_exist = val & AUX_PWR_DETECTED ? 1 : 0; - - retval = rtsx_read_register(chip, CARD_SHARE_MODE, &val); - if (retval) - return retval; - dev_dbg(rtsx_dev(chip), "CARD_SHARE_MODE: 0x%x\n", val); - chip->baro_pkg = val & 0x04 ? QFN : LQFP; - - retval = rtsx_read_register(chip, 0xFE5A, &val); - if (retval) - return retval; - chip->hw_bypass_sd = val & 0x10 ? 1 : 0; - - retval = rtsx_read_cfg_dw(chip, 0, 0x718, &lval); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - max_func = (u8)((lval >> 29) & 0x07); - dev_dbg(rtsx_dev(chip), "Max function number: %d\n", max_func); - if (max_func == 0x02) - SET_SDIO_EXIST(chip); - else - CLR_SDIO_EXIST(chip); - - if (chip->use_hw_setting) { - retval = rtsx_read_register(chip, CHANGE_LINK_STATE, &val); - if (retval) - return retval; - chip->auto_delink_en = val & 0x80 ? 1 : 0; - - if (CHECK_BARO_PKG(chip, LQFP)) - chip->lun_mode = SD_MS_1LUN; - else - chip->lun_mode = DEFAULT_SINGLE; - } - - return STATUS_SUCCESS; -} - -int rtsx_init_chip(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &chip->sd_card; - struct xd_info *xd_card = &chip->xd_card; - struct ms_info *ms_card = &chip->ms_card; - int retval; - unsigned int i; - - dev_dbg(rtsx_dev(chip), "Vendor ID: 0x%04x, Product ID: 0x%04x\n", - chip->vendor_id, chip->product_id); - - chip->ic_version = 0; - - memset(xd_card, 0, sizeof(struct xd_info)); - memset(sd_card, 0, sizeof(struct sd_info)); - memset(ms_card, 0, sizeof(struct ms_info)); - - chip->xd_reset_counter = 0; - chip->sd_reset_counter = 0; - chip->ms_reset_counter = 0; - - chip->xd_show_cnt = MAX_SHOW_CNT; - chip->sd_show_cnt = MAX_SHOW_CNT; - chip->ms_show_cnt = MAX_SHOW_CNT; - - chip->sd_io = 0; - chip->auto_delink_cnt = 0; - chip->auto_delink_allowed = 1; - rtsx_set_stat(chip, RTSX_STAT_INIT); - - chip->aspm_enabled = 0; - chip->chip_insert_with_sdio = 0; - chip->sdio_aspm = 0; - chip->sdio_idle = 0; - chip->sdio_counter = 0; - chip->cur_card = 0; - chip->phy_debug_mode = 0; - chip->sdio_func_exist = 0; - memset(chip->sdio_raw_data, 0, 12); - - for (i = 0; i < MAX_ALLOWED_LUN_CNT; i++) { - set_sense_type(chip, i, SENSE_TYPE_NO_SENSE); - chip->rw_fail_cnt[i] = 0; - } - - if (!valid_sd_speed_prior(chip->sd_speed_prior)) - chip->sd_speed_prior = 0x01040203; - - dev_dbg(rtsx_dev(chip), "sd_speed_prior = 0x%08x\n", - chip->sd_speed_prior); - - if (!valid_sd_current_prior(chip->sd_current_prior)) - chip->sd_current_prior = 0x00010203; - - dev_dbg(rtsx_dev(chip), "sd_current_prior = 0x%08x\n", - chip->sd_current_prior); - - if (chip->sd_ddr_tx_phase > 31 || chip->sd_ddr_tx_phase < 0) - chip->sd_ddr_tx_phase = 0; - - if (chip->mmc_ddr_tx_phase > 31 || chip->mmc_ddr_tx_phase < 0) - chip->mmc_ddr_tx_phase = 0; - - retval = rtsx_write_register(chip, FPDCTL, SSC_POWER_DOWN, 0); - if (retval) - return retval; - wait_timeout(200); - retval = rtsx_write_register(chip, CLK_DIV, 0x07, 0x07); - if (retval) - return retval; - dev_dbg(rtsx_dev(chip), "chip->use_hw_setting = %d\n", - chip->use_hw_setting); - - if (CHECK_PID(chip, 0x5208)) { - retval = rts5208_init(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - } else if (CHECK_PID(chip, 0x5288)) { - retval = rts5288_init(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - - if (chip->ss_en == 2) - chip->ss_en = 0; - - dev_dbg(rtsx_dev(chip), "chip->asic_code = %d\n", chip->asic_code); - dev_dbg(rtsx_dev(chip), "chip->ic_version = 0x%x\n", chip->ic_version); - dev_dbg(rtsx_dev(chip), "chip->phy_debug_mode = %d\n", - chip->phy_debug_mode); - dev_dbg(rtsx_dev(chip), "chip->aux_pwr_exist = %d\n", - chip->aux_pwr_exist); - dev_dbg(rtsx_dev(chip), "chip->sdio_func_exist = %d\n", - chip->sdio_func_exist); - dev_dbg(rtsx_dev(chip), "chip->hw_bypass_sd = %d\n", - chip->hw_bypass_sd); - dev_dbg(rtsx_dev(chip), "chip->aspm_l0s_l1_en = %d\n", - chip->aspm_l0s_l1_en); - dev_dbg(rtsx_dev(chip), "chip->lun_mode = %d\n", chip->lun_mode); - dev_dbg(rtsx_dev(chip), "chip->auto_delink_en = %d\n", - chip->auto_delink_en); - dev_dbg(rtsx_dev(chip), "chip->ss_en = %d\n", chip->ss_en); - dev_dbg(rtsx_dev(chip), "chip->baro_pkg = %d\n", chip->baro_pkg); - - if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) { - chip->card2lun[SD_CARD] = 0; - chip->card2lun[MS_CARD] = 1; - chip->card2lun[XD_CARD] = 0xFF; - chip->lun2card[0] = SD_CARD; - chip->lun2card[1] = MS_CARD; - chip->max_lun = 1; - SET_SDIO_IGNORED(chip); - } else if (CHECK_LUN_MODE(chip, SD_MS_1LUN)) { - chip->card2lun[SD_CARD] = 0; - chip->card2lun[MS_CARD] = 0; - chip->card2lun[XD_CARD] = 0xFF; - chip->lun2card[0] = SD_CARD | MS_CARD; - chip->max_lun = 0; - } else { - chip->card2lun[XD_CARD] = 0; - chip->card2lun[SD_CARD] = 0; - chip->card2lun[MS_CARD] = 0; - chip->lun2card[0] = XD_CARD | SD_CARD | MS_CARD; - chip->max_lun = 0; - } - - retval = rtsx_reset_chip(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} - -void rtsx_release_chip(struct rtsx_chip *chip) -{ - xd_free_l2p_tbl(chip); - ms_free_l2p_tbl(chip); - chip->card_exist = 0; - chip->card_ready = 0; -} - -#if !defined(LED_AUTO_BLINK) && defined(REGULAR_BLINK) -static inline void rtsx_blink_led(struct rtsx_chip *chip) -{ - if (chip->card_exist && chip->blink_led) { - if (chip->led_toggle_counter < LED_TOGGLE_INTERVAL) { - chip->led_toggle_counter++; - } else { - chip->led_toggle_counter = 0; - toggle_gpio(chip, LED_GPIO); - } - } -} -#endif - -static void rtsx_monitor_aspm_config(struct rtsx_chip *chip) -{ - bool reg_changed, maybe_support_aspm; - u32 tmp = 0; - u8 reg0 = 0, reg1 = 0; - - maybe_support_aspm = false; - reg_changed = false; - rtsx_read_config_byte(chip, LCTLR, ®0); - if (chip->aspm_level[0] != reg0) { - reg_changed = true; - chip->aspm_level[0] = reg0; - } - if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip)) { - rtsx_read_cfg_dw(chip, 1, 0xC0, &tmp); - reg1 = (u8)tmp; - if (chip->aspm_level[1] != reg1) { - reg_changed = true; - chip->aspm_level[1] = reg1; - } - - if ((reg0 & 0x03) && (reg1 & 0x03)) - maybe_support_aspm = true; - - } else { - if (reg0 & 0x03) - maybe_support_aspm = true; - } - - if (reg_changed) { - if (maybe_support_aspm) - chip->aspm_l0s_l1_en = 0x03; - - dev_dbg(rtsx_dev(chip), - "aspm_level[0] = 0x%02x, aspm_level[1] = 0x%02x\n", - chip->aspm_level[0], chip->aspm_level[1]); - - if (chip->aspm_l0s_l1_en) { - chip->aspm_enabled = 1; - } else { - chip->aspm_enabled = 0; - chip->sdio_aspm = 0; - } - rtsx_write_register(chip, ASPM_FORCE_CTL, 0xFF, - 0x30 | chip->aspm_level[0] | - (chip->aspm_level[1] << 2)); - } -} - -static void rtsx_manage_ocp(struct rtsx_chip *chip) -{ -#ifdef SUPPORT_OCP - if (!chip->ocp_int) - return; - - rtsx_read_register(chip, OCPSTAT, &chip->ocp_stat); - - if (chip->card_exist & SD_CARD) - sd_power_off_card3v3(chip); - else if (chip->card_exist & MS_CARD) - ms_power_off_card3v3(chip); - else if (chip->card_exist & XD_CARD) - xd_power_off_card3v3(chip); - - chip->ocp_int = 0; -#endif -} - -static void rtsx_manage_sd_lock(struct rtsx_chip *chip) -{ -#ifdef SUPPORT_SD_LOCK - struct sd_info *sd_card = &chip->sd_card; - u8 val; - - if (!sd_card->sd_erase_status) - return; - - if (chip->card_exist & SD_CARD) { - rtsx_read_register(chip, 0xFD30, &val); - if (val & 0x02) { - sd_card->sd_erase_status = SD_NOT_ERASE; - sd_card->sd_lock_notify = 1; - chip->need_reinit |= SD_CARD; - } - } else { - sd_card->sd_erase_status = SD_NOT_ERASE; - } -#endif -} - -static bool rtsx_is_ss_allowed(struct rtsx_chip *chip) -{ - u32 val; - - if (!chip->ss_en || CHECK_PID(chip, 0x5288)) - return false; - - if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip)) { - rtsx_read_cfg_dw(chip, 1, 0x04, &val); - if (val & 0x07) - return false; - } - - return true; -} - -static void rtsx_manage_ss(struct rtsx_chip *chip) -{ - if (!rtsx_is_ss_allowed(chip) || chip->sd_io) - return; - - if (rtsx_get_stat(chip) != RTSX_STAT_IDLE) { - chip->ss_counter = 0; - return; - } - - if (chip->ss_counter < (chip->ss_idle_period / POLLING_INTERVAL)) - chip->ss_counter++; - else - rtsx_exclusive_enter_ss(chip); -} - -static void rtsx_manage_aspm(struct rtsx_chip *chip) -{ - u8 data; - - if (!CHECK_PID(chip, 0x5208)) - return; - - rtsx_monitor_aspm_config(chip); - -#ifdef SUPPORT_SDIO_ASPM - if (!CHK_SDIO_EXIST(chip) || CHK_SDIO_IGNORED(chip) || - !chip->aspm_l0s_l1_en || !chip->dynamic_aspm) - return; - - if (chip->sd_io) { - dynamic_configure_sdio_aspm(chip); - return; - } - - if (chip->sdio_aspm) - return; - - dev_dbg(rtsx_dev(chip), "SDIO enter ASPM!\n"); - data = 0x30 | (chip->aspm_level[1] << 2); - rtsx_write_register(chip, ASPM_FORCE_CTL, 0xFC, data); - chip->sdio_aspm = 1; -#endif -} - -static void rtsx_manage_idle(struct rtsx_chip *chip) -{ - if (chip->idle_counter < IDLE_MAX_COUNT) { - chip->idle_counter++; - return; - } - - if (rtsx_get_stat(chip) == RTSX_STAT_IDLE) - return; - - dev_dbg(rtsx_dev(chip), "Idle state!\n"); - rtsx_set_stat(chip, RTSX_STAT_IDLE); - -#if !defined(LED_AUTO_BLINK) && defined(REGULAR_BLINK) - chip->led_toggle_counter = 0; -#endif - rtsx_force_power_on(chip, SSC_PDCTL); - - turn_off_led(chip, LED_GPIO); - - if (chip->auto_power_down && !chip->card_ready && !chip->sd_io) - rtsx_force_power_down(chip, SSC_PDCTL | OC_PDCTL); -} - -static void rtsx_manage_2lun_mode(struct rtsx_chip *chip) -{ -#ifdef SUPPORT_OCP - u8 sd_oc, ms_oc; - - sd_oc = chip->ocp_stat & (SD_OC_NOW | SD_OC_EVER); - ms_oc = chip->ocp_stat & (MS_OC_NOW | MS_OC_EVER); - - if (sd_oc || ms_oc) - dev_dbg(rtsx_dev(chip), "Over current, OCPSTAT is 0x%x\n", - chip->ocp_stat); - - if (sd_oc && (chip->card_exist & SD_CARD)) { - rtsx_write_register(chip, CARD_OE, SD_OUTPUT_EN, 0); - card_power_off(chip, SD_CARD); - chip->card_fail |= SD_CARD; - } - - if (ms_oc && (chip->card_exist & MS_CARD)) { - rtsx_write_register(chip, CARD_OE, MS_OUTPUT_EN, 0); - card_power_off(chip, MS_CARD); - chip->card_fail |= MS_CARD; - } -#endif -} - -static void rtsx_manage_1lun_mode(struct rtsx_chip *chip) -{ -#ifdef SUPPORT_OCP - if (!(chip->ocp_stat & (SD_OC_NOW | SD_OC_EVER))) - return; - - dev_dbg(rtsx_dev(chip), "Over current, OCPSTAT is 0x%x\n", - chip->ocp_stat); - - if (chip->card_exist & SD_CARD) { - rtsx_write_register(chip, CARD_OE, SD_OUTPUT_EN, 0); - chip->card_fail |= SD_CARD; - } else if (chip->card_exist & MS_CARD) { - rtsx_write_register(chip, CARD_OE, MS_OUTPUT_EN, 0); - chip->card_fail |= MS_CARD; - } else if (chip->card_exist & XD_CARD) { - rtsx_write_register(chip, CARD_OE, XD_OUTPUT_EN, 0); - chip->card_fail |= XD_CARD; - } - card_power_off(chip, SD_CARD); -#endif -} - -static void rtsx_delink_stage1(struct rtsx_chip *chip, int enter_L1, - int stage3_cnt) -{ - u8 val; - - rtsx_set_stat(chip, RTSX_STAT_DELINK); - - if (chip->asic_code && CHECK_PID(chip, 0x5208)) - rtsx_set_phy_reg_bit(chip, 0x1C, 2); - - if (chip->card_exist) - dev_dbg(rtsx_dev(chip), "False card inserted, do force delink\n"); - else - dev_dbg(rtsx_dev(chip), "No card inserted, do delink\n"); - - if (enter_L1) - rtsx_write_register(chip, HOST_SLEEP_STATE, 0x03, 1); - - if (chip->card_exist) - val = 0x02; - else - val = 0x0A; - - rtsx_write_register(chip, CHANGE_LINK_STATE, val, val); - - if (enter_L1) - rtsx_enter_L1(chip); - - if (chip->card_exist) - chip->auto_delink_cnt = stage3_cnt + 1; -} - -static void rtsx_delink_stage(struct rtsx_chip *chip) -{ - int delink_stage1_cnt, delink_stage2_cnt, delink_stage3_cnt; - int enter_L1; - - if (!chip->auto_delink_en || !chip->auto_delink_allowed || - chip->card_ready || chip->card_ejected || chip->sd_io) { - chip->auto_delink_cnt = 0; - return; - } - - enter_L1 = chip->auto_delink_in_L1 && - (chip->aspm_l0s_l1_en || chip->ss_en); - - delink_stage1_cnt = chip->delink_stage1_step; - delink_stage2_cnt = delink_stage1_cnt + chip->delink_stage2_step; - delink_stage3_cnt = delink_stage2_cnt + chip->delink_stage3_step; - - if (chip->auto_delink_cnt > delink_stage3_cnt) - return; - - if (chip->auto_delink_cnt == delink_stage1_cnt) - rtsx_delink_stage1(chip, enter_L1, delink_stage3_cnt); - - if (chip->auto_delink_cnt == delink_stage2_cnt) { - dev_dbg(rtsx_dev(chip), "Try to do force delink\n"); - - if (enter_L1) - rtsx_exit_L1(chip); - - if (chip->asic_code && CHECK_PID(chip, 0x5208)) - rtsx_set_phy_reg_bit(chip, 0x1C, 2); - - rtsx_write_register(chip, CHANGE_LINK_STATE, 0x0A, 0x0A); - } - - chip->auto_delink_cnt++; -} - -void rtsx_polling_func(struct rtsx_chip *chip) -{ - if (rtsx_chk_stat(chip, RTSX_STAT_SUSPEND)) - return; - - if (rtsx_chk_stat(chip, RTSX_STAT_DELINK)) - goto delink_stage; - - if (chip->polling_config) { - u8 val; - - rtsx_read_config_byte(chip, 0, &val); - } - - if (rtsx_chk_stat(chip, RTSX_STAT_SS)) - return; - - rtsx_manage_ocp(chip); - - rtsx_manage_sd_lock(chip); - - rtsx_init_cards(chip); - - rtsx_manage_ss(chip); - - rtsx_manage_aspm(chip); - - rtsx_manage_idle(chip); - - switch (rtsx_get_stat(chip)) { - case RTSX_STAT_RUN: -#if !defined(LED_AUTO_BLINK) && defined(REGULAR_BLINK) - rtsx_blink_led(chip); -#endif - do_remaining_work(chip); - break; - - case RTSX_STAT_IDLE: - if (chip->sd_io && !chip->sd_int) - try_to_switch_sdio_ctrl(chip); - - rtsx_enable_aspm(chip); - break; - - default: - break; - } - - if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) - rtsx_manage_2lun_mode(chip); - else - rtsx_manage_1lun_mode(chip); - -delink_stage: - rtsx_delink_stage(chip); -} - -/** - * rtsx_stop_cmd - stop command transfer and DMA transfer - * @chip: Realtek's card reader chip - * @card: flash card type - * - * Stop command transfer and DMA transfer. - * This function is called in error handler. - */ -void rtsx_stop_cmd(struct rtsx_chip *chip, int card) -{ - int i; - - for (i = 0; i <= 8; i++) { - int addr = RTSX_HCBAR + i * 4; - u32 reg; - - reg = rtsx_readl(chip, addr); - dev_dbg(rtsx_dev(chip), "BAR (0x%02x): 0x%08x\n", addr, reg); - } - rtsx_writel(chip, RTSX_HCBCTLR, STOP_CMD); - rtsx_writel(chip, RTSX_HDBCTLR, STOP_DMA); - - for (i = 0; i < 16; i++) { - u16 addr = 0xFE20 + (u16)i; - u8 val; - - rtsx_read_register(chip, addr, &val); - dev_dbg(rtsx_dev(chip), "0x%04X: 0x%02x\n", addr, val); - } - - rtsx_write_register(chip, DMACTL, 0x80, 0x80); - rtsx_write_register(chip, RBCTL, 0x80, 0x80); -} - -#define MAX_RW_REG_CNT 1024 - -int rtsx_write_register(struct rtsx_chip *chip, u16 addr, u8 mask, u8 data) -{ - int i; - u32 val = 3 << 30; - - val |= (u32)(addr & 0x3FFF) << 16; - val |= (u32)mask << 8; - val |= (u32)data; - - rtsx_writel(chip, RTSX_HAIMR, val); - - for (i = 0; i < MAX_RW_REG_CNT; i++) { - val = rtsx_readl(chip, RTSX_HAIMR); - if ((val & BIT(31)) == 0) { - if (data != (u8)val) - return STATUS_FAIL; - - return STATUS_SUCCESS; - } - } - - return STATUS_TIMEDOUT; -} - -int rtsx_read_register(struct rtsx_chip *chip, u16 addr, u8 *data) -{ - u32 val = 2 << 30; - int i; - - if (data) - *data = 0; - - val |= (u32)(addr & 0x3FFF) << 16; - - rtsx_writel(chip, RTSX_HAIMR, val); - - for (i = 0; i < MAX_RW_REG_CNT; i++) { - val = rtsx_readl(chip, RTSX_HAIMR); - if ((val & BIT(31)) == 0) - break; - } - - if (i >= MAX_RW_REG_CNT) - return STATUS_TIMEDOUT; - - if (data) - *data = (u8)(val & 0xFF); - - return STATUS_SUCCESS; -} - -int rtsx_write_cfg_dw(struct rtsx_chip *chip, u8 func_no, u16 addr, u32 mask, - u32 val) -{ - int retval; - u8 mode = 0, tmp; - int i; - - for (i = 0; i < 4; i++) { - if (mask & 0xFF) { - retval = rtsx_write_register(chip, CFGDATA0 + i, - 0xFF, - (u8)(val & mask & 0xFF)); - if (retval) - return retval; - mode |= (1 << i); - } - mask >>= 8; - val >>= 8; - } - - if (mode) { - retval = rtsx_write_register(chip, CFGADDR0, 0xFF, (u8)addr); - if (retval) - return retval; - retval = rtsx_write_register(chip, CFGADDR1, 0xFF, - (u8)(addr >> 8)); - if (retval) - return retval; - - retval = rtsx_write_register(chip, CFGRWCTL, 0xFF, - 0x80 | mode | - ((func_no & 0x03) << 4)); - if (retval) - return retval; - - for (i = 0; i < MAX_RW_REG_CNT; i++) { - retval = rtsx_read_register(chip, CFGRWCTL, &tmp); - if (retval) - return retval; - if ((tmp & 0x80) == 0) - break; - } - } - - return STATUS_SUCCESS; -} - -int rtsx_read_cfg_dw(struct rtsx_chip *chip, u8 func_no, u16 addr, u32 *val) -{ - int retval; - int i; - u8 tmp; - u32 data = 0; - - retval = rtsx_write_register(chip, CFGADDR0, 0xFF, (u8)addr); - if (retval) - return retval; - retval = rtsx_write_register(chip, CFGADDR1, 0xFF, (u8)(addr >> 8)); - if (retval) - return retval; - retval = rtsx_write_register(chip, CFGRWCTL, 0xFF, - 0x80 | ((func_no & 0x03) << 4)); - if (retval) - return retval; - - for (i = 0; i < MAX_RW_REG_CNT; i++) { - retval = rtsx_read_register(chip, CFGRWCTL, &tmp); - if (retval) - return retval; - if ((tmp & 0x80) == 0) - break; - } - - for (i = 0; i < 4; i++) { - retval = rtsx_read_register(chip, CFGDATA0 + i, &tmp); - if (retval) - return retval; - data |= (u32)tmp << (i * 8); - } - - if (val) - *val = data; - - return STATUS_SUCCESS; -} - -int rtsx_write_cfg_seq(struct rtsx_chip *chip, u8 func, u16 addr, u8 *buf, - int len) -{ - u32 *data, *mask; - u16 offset = addr % 4; - u16 aligned_addr = addr - offset; - int dw_len, i, j; - int retval; - size_t size; - - if (!buf) - return STATUS_NOMEM; - - if ((len + offset) % 4) - dw_len = (len + offset) / 4 + 1; - else - dw_len = (len + offset) / 4; - - dev_dbg(rtsx_dev(chip), "dw_len = %d\n", dw_len); - - size = array_size(dw_len, 4); - data = vzalloc(size); - if (!data) - return STATUS_NOMEM; - - mask = vzalloc(size); - if (!mask) { - vfree(data); - return STATUS_NOMEM; - } - - j = 0; - for (i = 0; i < len; i++) { - mask[j] |= 0xFF << (offset * 8); - data[j] |= buf[i] << (offset * 8); - if (++offset == 4) { - j++; - offset = 0; - } - } - - print_hex_dump_bytes(KBUILD_MODNAME ": ", DUMP_PREFIX_NONE, mask, size); - print_hex_dump_bytes(KBUILD_MODNAME ": ", DUMP_PREFIX_NONE, data, size); - - for (i = 0; i < dw_len; i++) { - retval = rtsx_write_cfg_dw(chip, func, aligned_addr + i * 4, - mask[i], data[i]); - if (retval != STATUS_SUCCESS) { - vfree(data); - vfree(mask); - return STATUS_FAIL; - } - } - - vfree(data); - vfree(mask); - - return STATUS_SUCCESS; -} - -int rtsx_read_cfg_seq(struct rtsx_chip *chip, u8 func, u16 addr, u8 *buf, - int len) -{ - u32 *data; - u16 offset = addr % 4; - u16 aligned_addr = addr - offset; - int dw_len, i, j; - int retval; - - if ((len + offset) % 4) - dw_len = (len + offset) / 4 + 1; - else - dw_len = (len + offset) / 4; - - dev_dbg(rtsx_dev(chip), "dw_len = %d\n", dw_len); - - data = vmalloc(array_size(dw_len, 4)); - if (!data) - return STATUS_NOMEM; - - for (i = 0; i < dw_len; i++) { - retval = rtsx_read_cfg_dw(chip, func, aligned_addr + i * 4, - data + i); - if (retval != STATUS_SUCCESS) { - vfree(data); - return STATUS_FAIL; - } - } - - if (buf) { - j = 0; - - for (i = 0; i < len; i++) { - buf[i] = (u8)(data[j] >> (offset * 8)); - if (++offset == 4) { - j++; - offset = 0; - } - } - } - - vfree(data); - - return STATUS_SUCCESS; -} - -int rtsx_write_phy_register(struct rtsx_chip *chip, u8 addr, u16 val) -{ - int retval; - bool finished = false; - int i; - u8 tmp; - - retval = rtsx_write_register(chip, PHYDATA0, 0xFF, (u8)val); - if (retval) - return retval; - retval = rtsx_write_register(chip, PHYDATA1, 0xFF, (u8)(val >> 8)); - if (retval) - return retval; - retval = rtsx_write_register(chip, PHYADDR, 0xFF, addr); - if (retval) - return retval; - retval = rtsx_write_register(chip, PHYRWCTL, 0xFF, 0x81); - if (retval) - return retval; - - for (i = 0; i < 100000; i++) { - retval = rtsx_read_register(chip, PHYRWCTL, &tmp); - if (retval) - return retval; - if (!(tmp & 0x80)) { - finished = true; - break; - } - } - - if (!finished) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} - -int rtsx_read_phy_register(struct rtsx_chip *chip, u8 addr, u16 *val) -{ - int retval; - bool finished = false; - int i; - u16 data = 0; - u8 tmp; - - retval = rtsx_write_register(chip, PHYADDR, 0xFF, addr); - if (retval) - return retval; - retval = rtsx_write_register(chip, PHYRWCTL, 0xFF, 0x80); - if (retval) - return retval; - - for (i = 0; i < 100000; i++) { - retval = rtsx_read_register(chip, PHYRWCTL, &tmp); - if (retval) - return retval; - if (!(tmp & 0x80)) { - finished = true; - break; - } - } - - if (!finished) - return STATUS_FAIL; - - retval = rtsx_read_register(chip, PHYDATA0, &tmp); - if (retval) - return retval; - data = tmp; - retval = rtsx_read_register(chip, PHYDATA1, &tmp); - if (retval) - return retval; - data |= (u16)tmp << 8; - - if (val) - *val = data; - - return STATUS_SUCCESS; -} - -int rtsx_read_efuse(struct rtsx_chip *chip, u8 addr, u8 *val) -{ - int retval; - int i; - u8 data = 0; - - retval = rtsx_write_register(chip, EFUSE_CTRL, 0xFF, 0x80 | addr); - if (retval) - return retval; - - for (i = 0; i < 100; i++) { - retval = rtsx_read_register(chip, EFUSE_CTRL, &data); - if (retval) - return retval; - if (!(data & 0x80)) - break; - udelay(1); - } - - if (data & 0x80) - return STATUS_TIMEDOUT; - - retval = rtsx_read_register(chip, EFUSE_DATA, &data); - if (retval) - return retval; - if (val) - *val = data; - - return STATUS_SUCCESS; -} - -int rtsx_write_efuse(struct rtsx_chip *chip, u8 addr, u8 val) -{ - int retval; - int i, j; - u8 data = 0, tmp = 0xFF; - - for (i = 0; i < 8; i++) { - if (val & (u8)(1 << i)) - continue; - - tmp &= (~(u8)(1 << i)); - dev_dbg(rtsx_dev(chip), "Write 0x%x to 0x%x\n", tmp, addr); - - retval = rtsx_write_register(chip, EFUSE_DATA, 0xFF, tmp); - if (retval) - return retval; - retval = rtsx_write_register(chip, EFUSE_CTRL, 0xFF, - 0xA0 | addr); - if (retval) - return retval; - - for (j = 0; j < 100; j++) { - retval = rtsx_read_register(chip, EFUSE_CTRL, &data); - if (retval) - return retval; - if (!(data & 0x80)) - break; - wait_timeout(3); - } - - if (data & 0x80) - return STATUS_TIMEDOUT; - - wait_timeout(5); - } - - return STATUS_SUCCESS; -} - -int rtsx_clr_phy_reg_bit(struct rtsx_chip *chip, u8 reg, u8 bit) -{ - int retval; - u16 value; - - retval = rtsx_read_phy_register(chip, reg, &value); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (value & (1 << bit)) { - value &= ~(1 << bit); - retval = rtsx_write_phy_register(chip, reg, value); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -int rtsx_set_phy_reg_bit(struct rtsx_chip *chip, u8 reg, u8 bit) -{ - int retval; - u16 value; - - retval = rtsx_read_phy_register(chip, reg, &value); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if ((value & (1 << bit)) == 0) { - value |= (1 << bit); - retval = rtsx_write_phy_register(chip, reg, value); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -static void rtsx_handle_pm_dstate(struct rtsx_chip *chip, u8 dstate) -{ - u32 ultmp; - - dev_dbg(rtsx_dev(chip), "%04x set pm_dstate to %d\n", - chip->product_id, dstate); - - if (CHK_SDIO_EXIST(chip)) { - u8 func_no; - - if (CHECK_PID(chip, 0x5288)) - func_no = 2; - else - func_no = 1; - - rtsx_read_cfg_dw(chip, func_no, 0x84, &ultmp); - dev_dbg(rtsx_dev(chip), "pm_dstate of function %d: 0x%x\n", - (int)func_no, ultmp); - rtsx_write_cfg_dw(chip, func_no, 0x84, 0xFF, dstate); - } - - rtsx_write_config_byte(chip, 0x44, dstate); - rtsx_write_config_byte(chip, 0x45, 0); -} - -void rtsx_enter_L1(struct rtsx_chip *chip) -{ - rtsx_handle_pm_dstate(chip, 2); -} - -void rtsx_exit_L1(struct rtsx_chip *chip) -{ - rtsx_write_config_byte(chip, 0x44, 0); - rtsx_write_config_byte(chip, 0x45, 0); -} - -void rtsx_enter_ss(struct rtsx_chip *chip) -{ - dev_dbg(rtsx_dev(chip), "Enter Selective Suspend State!\n"); - - rtsx_write_register(chip, IRQSTAT0, LINK_RDY_INT, LINK_RDY_INT); - - if (chip->power_down_in_ss) { - rtsx_power_off_card(chip); - rtsx_force_power_down(chip, SSC_PDCTL | OC_PDCTL); - } - - if (CHK_SDIO_EXIST(chip)) - rtsx_write_cfg_dw(chip, CHECK_PID(chip, 0x5288) ? 2 : 1, - 0xC0, 0xFF00, 0x0100); - - if (chip->auto_delink_en) { - rtsx_write_register(chip, HOST_SLEEP_STATE, 0x01, 0x01); - } else { - if (!chip->phy_debug_mode) { - u32 tmp; - - tmp = rtsx_readl(chip, RTSX_BIER); - tmp |= CARD_INT; - rtsx_writel(chip, RTSX_BIER, tmp); - } - - rtsx_write_register(chip, CHANGE_LINK_STATE, 0x02, 0); - } - - rtsx_enter_L1(chip); - - RTSX_CLR_DELINK(chip); - rtsx_set_stat(chip, RTSX_STAT_SS); -} - -void rtsx_exit_ss(struct rtsx_chip *chip) -{ - dev_dbg(rtsx_dev(chip), "Exit Selective Suspend State!\n"); - - rtsx_exit_L1(chip); - - if (chip->power_down_in_ss) { - rtsx_force_power_on(chip, SSC_PDCTL | OC_PDCTL); - udelay(1000); - } - - if (RTSX_TST_DELINK(chip)) { - chip->need_reinit = SD_CARD | MS_CARD | XD_CARD; - rtsx_reinit_cards(chip, 1); - RTSX_CLR_DELINK(chip); - } else if (chip->power_down_in_ss) { - chip->need_reinit = SD_CARD | MS_CARD | XD_CARD; - rtsx_reinit_cards(chip, 0); - } -} - -int rtsx_pre_handle_interrupt(struct rtsx_chip *chip) -{ - u32 status, int_enable; - bool exit_ss = false; -#ifdef SUPPORT_OCP - u32 ocp_int = 0; - - ocp_int = OC_INT; -#endif - - if (chip->ss_en) { - chip->ss_counter = 0; - if (rtsx_get_stat(chip) == RTSX_STAT_SS) { - exit_ss = true; - rtsx_exit_L1(chip); - rtsx_set_stat(chip, RTSX_STAT_RUN); - } - } - - int_enable = rtsx_readl(chip, RTSX_BIER); - chip->int_reg = rtsx_readl(chip, RTSX_BIPR); - - if (((chip->int_reg & int_enable) == 0) || - chip->int_reg == 0xFFFFFFFF) - return STATUS_FAIL; - - status = chip->int_reg &= (int_enable | 0x7FFFFF); - - if (status & CARD_INT) { - chip->auto_delink_cnt = 0; - - if (status & SD_INT) { - if (status & SD_EXIST) { - set_bit(SD_NR, &chip->need_reset); - } else { - set_bit(SD_NR, &chip->need_release); - chip->sd_reset_counter = 0; - chip->sd_show_cnt = 0; - clear_bit(SD_NR, &chip->need_reset); - } - } else { - /* - * If multi-luns, it's possible that - * when plugging/unplugging one card - * there is another card which still - * exists in the slot. In this case, - * all existed cards should be reset. - */ - if (exit_ss && (status & SD_EXIST)) - set_bit(SD_NR, &chip->need_reinit); - } - if (!CHECK_PID(chip, 0x5288) || CHECK_BARO_PKG(chip, QFN)) { - if (status & XD_INT) { - if (status & XD_EXIST) { - set_bit(XD_NR, &chip->need_reset); - } else { - set_bit(XD_NR, &chip->need_release); - chip->xd_reset_counter = 0; - chip->xd_show_cnt = 0; - clear_bit(XD_NR, &chip->need_reset); - } - } else { - if (exit_ss && (status & XD_EXIST)) - set_bit(XD_NR, &chip->need_reinit); - } - } - if (status & MS_INT) { - if (status & MS_EXIST) { - set_bit(MS_NR, &chip->need_reset); - } else { - set_bit(MS_NR, &chip->need_release); - chip->ms_reset_counter = 0; - chip->ms_show_cnt = 0; - clear_bit(MS_NR, &chip->need_reset); - } - } else { - if (exit_ss && (status & MS_EXIST)) - set_bit(MS_NR, &chip->need_reinit); - } - } - -#ifdef SUPPORT_OCP - chip->ocp_int = ocp_int & status; -#endif - - if (chip->sd_io && (chip->int_reg & DATA_DONE_INT)) - chip->int_reg &= ~(u32)DATA_DONE_INT; - - return STATUS_SUCCESS; -} - -void rtsx_do_before_power_down(struct rtsx_chip *chip, int pm_stat) -{ - int retval; - - dev_dbg(rtsx_dev(chip), "%s, pm_stat = %d\n", __func__, pm_stat); - - rtsx_set_stat(chip, RTSX_STAT_SUSPEND); - - retval = rtsx_force_power_on(chip, SSC_PDCTL); - if (retval != STATUS_SUCCESS) - return; - - rtsx_release_cards(chip); - rtsx_disable_bus_int(chip); - turn_off_led(chip, LED_GPIO); - -#ifdef HW_AUTO_SWITCH_SD_BUS - if (chip->sd_io) { - chip->sdio_in_charge = 1; - if (CHECK_PID(chip, 0x5208)) { - rtsx_write_register(chip, TLPTISTAT, 0x08, 0x08); - /* Enable sdio_bus_auto_switch */ - rtsx_write_register(chip, 0xFE70, 0x80, 0x80); - } else if (CHECK_PID(chip, 0x5288)) { - rtsx_write_register(chip, TLPTISTAT, 0x08, 0x08); - /* Enable sdio_bus_auto_switch */ - rtsx_write_register(chip, 0xFE5A, 0x08, 0x08); - } - } -#endif - - if (CHECK_PID(chip, 0x5208) && chip->ic_version >= IC_VER_D) { - /* u_force_clkreq_0 */ - rtsx_write_register(chip, PETXCFG, 0x08, 0x08); - } - - if (pm_stat == PM_S1) { - dev_dbg(rtsx_dev(chip), "Host enter S1\n"); - rtsx_write_register(chip, HOST_SLEEP_STATE, 0x03, - HOST_ENTER_S1); - } else if (pm_stat == PM_S3) { - if (chip->s3_pwr_off_delay > 0) - wait_timeout(chip->s3_pwr_off_delay); - - dev_dbg(rtsx_dev(chip), "Host enter S3\n"); - rtsx_write_register(chip, HOST_SLEEP_STATE, 0x03, - HOST_ENTER_S3); - } - - if (chip->do_delink_before_power_down && chip->auto_delink_en) - rtsx_write_register(chip, CHANGE_LINK_STATE, 0x02, 2); - - rtsx_force_power_down(chip, SSC_PDCTL | OC_PDCTL); - - chip->cur_clk = 0; - chip->cur_card = 0; - chip->card_exist = 0; -} - -void rtsx_enable_aspm(struct rtsx_chip *chip) -{ - if (chip->aspm_l0s_l1_en && chip->dynamic_aspm && !chip->aspm_enabled) { - dev_dbg(rtsx_dev(chip), "Try to enable ASPM\n"); - chip->aspm_enabled = 1; - - if (chip->asic_code && CHECK_PID(chip, 0x5208)) - rtsx_write_phy_register(chip, 0x07, 0); - if (CHECK_PID(chip, 0x5208)) { - rtsx_write_register(chip, ASPM_FORCE_CTL, 0xF3, - 0x30 | chip->aspm_level[0]); - } else { - rtsx_write_config_byte(chip, LCTLR, - chip->aspm_l0s_l1_en); - } - - if (CHK_SDIO_EXIST(chip)) { - u16 val = chip->aspm_l0s_l1_en | 0x0100; - - rtsx_write_cfg_dw(chip, CHECK_PID(chip, 0x5288) ? 2 : 1, - 0xC0, 0xFFF, val); - } - } -} - -void rtsx_disable_aspm(struct rtsx_chip *chip) -{ - if (CHECK_PID(chip, 0x5208)) - rtsx_monitor_aspm_config(chip); - - if (chip->aspm_l0s_l1_en && chip->dynamic_aspm && chip->aspm_enabled) { - dev_dbg(rtsx_dev(chip), "Try to disable ASPM\n"); - chip->aspm_enabled = 0; - - if (chip->asic_code && CHECK_PID(chip, 0x5208)) - rtsx_write_phy_register(chip, 0x07, 0x0129); - if (CHECK_PID(chip, 0x5208)) - rtsx_write_register(chip, ASPM_FORCE_CTL, - 0xF3, 0x30); - else - rtsx_write_config_byte(chip, LCTLR, 0x00); - - wait_timeout(1); - } -} - -int rtsx_read_ppbuf(struct rtsx_chip *chip, u8 *buf, int buf_len) -{ - int retval; - int i, j; - u16 reg_addr; - u8 *ptr; - - if (!buf) - return STATUS_ERROR; - - ptr = buf; - reg_addr = PPBUF_BASE2; - for (i = 0; i < buf_len / 256; i++) { - rtsx_init_cmd(chip); - - for (j = 0; j < 256; j++) - rtsx_add_cmd(chip, READ_REG_CMD, reg_addr++, 0, 0); - - retval = rtsx_send_cmd(chip, 0, 250); - if (retval < 0) - return STATUS_FAIL; - - memcpy(ptr, rtsx_get_cmd_data(chip), 256); - ptr += 256; - } - - if (buf_len % 256) { - rtsx_init_cmd(chip); - - for (j = 0; j < buf_len % 256; j++) - rtsx_add_cmd(chip, READ_REG_CMD, reg_addr++, 0, 0); - - retval = rtsx_send_cmd(chip, 0, 250); - if (retval < 0) - return STATUS_FAIL; - } - - memcpy(ptr, rtsx_get_cmd_data(chip), buf_len % 256); - - return STATUS_SUCCESS; -} - -int rtsx_write_ppbuf(struct rtsx_chip *chip, u8 *buf, int buf_len) -{ - int retval; - int i, j; - u16 reg_addr; - u8 *ptr; - - if (!buf) - return STATUS_ERROR; - - ptr = buf; - reg_addr = PPBUF_BASE2; - for (i = 0; i < buf_len / 256; i++) { - rtsx_init_cmd(chip); - - for (j = 0; j < 256; j++) { - rtsx_add_cmd(chip, WRITE_REG_CMD, reg_addr++, 0xFF, - *ptr); - ptr++; - } - - retval = rtsx_send_cmd(chip, 0, 250); - if (retval < 0) - return STATUS_FAIL; - } - - if (buf_len % 256) { - rtsx_init_cmd(chip); - - for (j = 0; j < buf_len % 256; j++) { - rtsx_add_cmd(chip, WRITE_REG_CMD, reg_addr++, 0xFF, - *ptr); - ptr++; - } - - retval = rtsx_send_cmd(chip, 0, 250); - if (retval < 0) - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -int rtsx_check_chip_exist(struct rtsx_chip *chip) -{ - if (rtsx_readl(chip, 0) == 0xFFFFFFFF) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} - -int rtsx_force_power_on(struct rtsx_chip *chip, u8 ctl) -{ - int retval; - u8 mask = 0; - - if (ctl & SSC_PDCTL) - mask |= SSC_POWER_DOWN; - -#ifdef SUPPORT_OCP - if (ctl & OC_PDCTL) { - mask |= SD_OC_POWER_DOWN; - if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) - mask |= MS_OC_POWER_DOWN; - } -#endif - - if (mask) { - retval = rtsx_write_register(chip, FPDCTL, mask, 0); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (CHECK_PID(chip, 0x5288)) - wait_timeout(200); - } - - return STATUS_SUCCESS; -} - -int rtsx_force_power_down(struct rtsx_chip *chip, u8 ctl) -{ - int retval; - u8 mask = 0, val = 0; - - if (ctl & SSC_PDCTL) - mask |= SSC_POWER_DOWN; - -#ifdef SUPPORT_OCP - if (ctl & OC_PDCTL) { - mask |= SD_OC_POWER_DOWN; - if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) - mask |= MS_OC_POWER_DOWN; - } -#endif - - if (mask) { - val = mask; - retval = rtsx_write_register(chip, FPDCTL, mask, val); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} diff --git a/drivers/staging/rts5208/rtsx_chip.h b/drivers/staging/rts5208/rtsx_chip.h deleted file mode 100644 index bac65784d4a1..000000000000 --- a/drivers/staging/rts5208/rtsx_chip.h +++ /dev/null @@ -1,987 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Driver for Realtek PCI-Express card reader - * - * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. - * - * Author: - * Wei WANG (wei_wang@xxxxxxxxxxxxxx) - * Micky Ching (micky_ching@xxxxxxxxxxxxxx) - */ - -#ifndef __REALTEK_RTSX_CHIP_H -#define __REALTEK_RTSX_CHIP_H - -#include "rtsx.h" - -#define SUPPORT_CPRM -#define SUPPORT_OCP -#define SUPPORT_SDIO_ASPM -#define SUPPORT_MAGIC_GATE -#define SUPPORT_MSXC -#define SUPPORT_SD_LOCK -/* Hardware switch bus_ctl and cd_ctl automatically */ -#define HW_AUTO_SWITCH_SD_BUS -/* Enable hardware interrupt write clear */ -#define HW_INT_WRITE_CLR -/* #define LED_AUTO_BLINK */ -/* #define DISABLE_CARD_INT */ - -#ifdef SUPPORT_MAGIC_GATE - /* Using NORMAL_WRITE instead of AUTO_WRITE to set ICV */ - #define MG_SET_ICV_SLOW - /* HW may miss ERR/CMDNK signal when sampling INT status. */ - #define MS_SAMPLE_INT_ERR - /* - * HW DO NOT support Wait_INT function - * during READ_BYTES transfer mode - */ - #define READ_BYTES_WAIT_INT -#endif - -#ifdef SUPPORT_MSXC -#define XC_POWERCLASS -#define SUPPORT_PCGL_1P18 -#endif - -#ifndef LED_AUTO_BLINK -#define REGULAR_BLINK -#endif - -#define LED_BLINK_SPEED 5 -#define LED_TOGGLE_INTERVAL 6 -#define GPIO_TOGGLE_THRESHOLD 1024 -#define LED_GPIO 0 - -#define POLLING_INTERVAL 30 - -#define TRACE_ITEM_CNT 64 - -#ifndef STATUS_SUCCESS -#define STATUS_SUCCESS 0 -#endif -#ifndef STATUS_FAIL -#define STATUS_FAIL 1 -#endif -#ifndef STATUS_TIMEDOUT -#define STATUS_TIMEDOUT 2 -#endif -#ifndef STATUS_NOMEM -#define STATUS_NOMEM 3 -#endif -#ifndef STATUS_READ_FAIL -#define STATUS_READ_FAIL 4 -#endif -#ifndef STATUS_WRITE_FAIL -#define STATUS_WRITE_FAIL 5 -#endif -#ifndef STATUS_ERROR -#define STATUS_ERROR 10 -#endif - -#define PM_S1 1 -#define PM_S3 3 - -/* - * Transport return codes - */ - -#define TRANSPORT_GOOD 0 /* Transport good, command good */ -#define TRANSPORT_FAILED 1 /* Transport good, command failed */ -#define TRANSPORT_NO_SENSE 2 /* Command failed, no auto-sense */ -#define TRANSPORT_ERROR 3 /* Transport bad (i.e. device dead) */ - -/* - * Start-Stop-Unit - */ -#define STOP_MEDIUM 0x00 /* access disable */ -#define MAKE_MEDIUM_READY 0x01 /* access enable */ -#define UNLOAD_MEDIUM 0x02 /* unload */ -#define LOAD_MEDIUM 0x03 /* load */ - -/* - * STANDARD_INQUIRY - */ -#define QULIFIRE 0x00 -#define AENC_FNC 0x00 -#define TRML_IOP 0x00 -#define REL_ADR 0x00 -#define WBUS_32 0x00 -#define WBUS_16 0x00 -#define SYNC 0x00 -#define LINKED 0x00 -#define CMD_QUE 0x00 -#define SFT_RE 0x00 - -#define VEN_ID_LEN 8 /* Vendor ID Length */ -#define PRDCT_ID_LEN 16 /* Product ID Length */ -#define PRDCT_REV_LEN 4 /* Product LOT Length */ - -/* Dynamic flag definitions: used in set_bit() etc. */ -/* 0x00040000 transfer is active */ -#define RTSX_FLIDX_TRANS_ACTIVE 18 -/* 0x00100000 abort is in progress */ -#define RTSX_FLIDX_ABORTING 20 -/* 0x00200000 disconnect in progress */ -#define RTSX_FLIDX_DISCONNECTING 21 - -#define ABORTING_OR_DISCONNECTING ((1UL << US_FLIDX_ABORTING) | \ - (1UL << US_FLIDX_DISCONNECTING)) - -/* 0x00400000 device reset in progress */ -#define RTSX_FLIDX_RESETTING 22 -/* 0x00800000 SCSI midlayer timed out */ -#define RTSX_FLIDX_TIMED_OUT 23 -#define DRCT_ACCESS_DEV 0x00 /* Direct Access Device */ -#define RMB_DISC 0x80 /* The Device is Removable */ -#define ANSI_SCSI2 0x02 /* Based on ANSI-SCSI2 */ - -#define SCSI 0x00 /* Interface ID */ - -#define WRITE_PROTECTED_MEDIA 0x07 - -/*---- sense key ----*/ -#define ILI 0x20 /* ILI bit is on */ - -#define NO_SENSE 0x00 /* not exist sense key */ -#define RECOVER_ERR 0x01 /* Target/Logical unit is recoverd */ -#define NOT_READY 0x02 /* Logical unit is not ready */ -#define MEDIA_ERR 0x03 /* medium/data error */ -#define HARDWARE_ERR 0x04 /* hardware error */ -#define ILGAL_REQ 0x05 /* CDB/parameter/identify msg error */ -#define UNIT_ATTENTION 0x06 /* unit attention condition occur */ -#define DAT_PRTCT 0x07 /* read/write is desable */ -#define BLNC_CHK 0x08 /* find blank/DOF in read */ - /* write to unblank area */ -#define CPY_ABRT 0x0a /* Copy/Compare/Copy&Verify illegal */ -#define ABRT_CMD 0x0b /* Target make the command in error */ -#define EQUAL 0x0c /* Search Data end with Equal */ -#define VLM_OVRFLW 0x0d /* Some data are left in buffer */ -#define MISCMP 0x0e /* find inequality */ - -#define READ_ERR -1 -#define WRITE_ERR -2 - -#define FIRST_RESET 0x01 -#define USED_EXIST 0x02 - -/* - * SENSE_DATA - */ -/*---- valid ----*/ -#define SENSE_VALID 0x80 /* Sense data is valid as SCSI2 */ -#define SENSE_INVALID 0x00 /* Sense data is invalid as SCSI2 */ - -/*---- error code ----*/ -#define CUR_ERR 0x70 /* current error */ -#define DEF_ERR 0x71 /* specific command error */ - -/*---- sense key Information ----*/ -#define SNSKEYINFO_LEN 3 /* length of sense key information */ - -#define SKSV 0x80 -#define CDB_ILLEGAL 0x40 -#define DAT_ILLEGAL 0x00 -#define BPV 0x08 -#define BIT_ILLEGAL0 0 /* bit0 is illegal */ -#define BIT_ILLEGAL1 1 /* bit1 is illegal */ -#define BIT_ILLEGAL2 2 /* bit2 is illegal */ -#define BIT_ILLEGAL3 3 /* bit3 is illegal */ -#define BIT_ILLEGAL4 4 /* bit4 is illegal */ -#define BIT_ILLEGAL5 5 /* bit5 is illegal */ -#define BIT_ILLEGAL6 6 /* bit6 is illegal */ -#define BIT_ILLEGAL7 7 /* bit7 is illegal */ - -/*---- ASC ----*/ -#define ASC_NO_INFO 0x00 -#define ASC_MISCMP 0x1d -#define ASC_INVLD_CDB 0x24 -#define ASC_INVLD_PARA 0x26 -#define ASC_LU_NOT_READY 0x04 -#define ASC_WRITE_ERR 0x0c -#define ASC_READ_ERR 0x11 -#define ASC_LOAD_EJCT_ERR 0x53 -#define ASC_MEDIA_NOT_PRESENT 0x3A -#define ASC_MEDIA_CHANGED 0x28 -#define ASC_MEDIA_IN_PROCESS 0x04 -#define ASC_WRITE_PROTECT 0x27 -#define ASC_LUN_NOT_SUPPORTED 0x25 - -/*---- ASQC ----*/ -#define ASCQ_NO_INFO 0x00 -#define ASCQ_MEDIA_IN_PROCESS 0x01 -#define ASCQ_MISCMP 0x00 -#define ASCQ_INVLD_CDB 0x00 -#define ASCQ_INVLD_PARA 0x02 -#define ASCQ_LU_NOT_READY 0x02 -#define ASCQ_WRITE_ERR 0x02 -#define ASCQ_READ_ERR 0x00 -#define ASCQ_LOAD_EJCT_ERR 0x00 -#define ASCQ_WRITE_PROTECT 0x00 - -struct sense_data_t { - unsigned char err_code; /* error code */ - /* bit7 : valid */ - /* (1 : SCSI2) */ - /* (0 : Vendor * specific) */ - /* bit6-0 : error * code */ - /* (0x70 : current * error) */ - /* (0x71 : specific command error) */ - unsigned char seg_no; /* segment No. */ - unsigned char sense_key; /* byte5 : ILI */ - /* bit3-0 : sense key */ - unsigned char info[4]; /* information */ - unsigned char ad_sense_len; /* additional sense data length */ - unsigned char cmd_info[4]; /* command specific information */ - unsigned char asc; /* ASC */ - unsigned char ascq; /* ASCQ */ - unsigned char rfu; /* FRU */ - unsigned char sns_key_info[3];/* sense key specific information */ -}; - -/* PCI Operation Register Address */ -#define RTSX_HCBAR 0x00 -#define RTSX_HCBCTLR 0x04 -#define RTSX_HDBAR 0x08 -#define RTSX_HDBCTLR 0x0C -#define RTSX_HAIMR 0x10 -#define RTSX_BIPR 0x14 -#define RTSX_BIER 0x18 - -/* Host command buffer control register */ -#define STOP_CMD (0x01 << 28) - -/* Host data buffer control register */ -#define SDMA_MODE 0x00 -#define ADMA_MODE (0x02 << 26) -#define STOP_DMA (0x01 << 28) -#define TRIG_DMA (0x01 << 31) - -/* Bus interrupt pending register */ -#define CMD_DONE_INT BIT(31) -#define DATA_DONE_INT BIT(30) -#define TRANS_OK_INT BIT(29) -#define TRANS_FAIL_INT BIT(28) -#define XD_INT BIT(27) -#define MS_INT BIT(26) -#define SD_INT BIT(25) -#define GPIO0_INT BIT(24) -#define OC_INT BIT(23) -#define SD_WRITE_PROTECT BIT(19) -#define XD_EXIST BIT(18) -#define MS_EXIST BIT(17) -#define SD_EXIST BIT(16) -#define DELINK_INT GPIO0_INT -#define MS_OC_INT BIT(23) -#define SD_OC_INT BIT(22) - -#define CARD_INT (XD_INT | MS_INT | SD_INT) -#define NEED_COMPLETE_INT (DATA_DONE_INT | TRANS_OK_INT | TRANS_FAIL_INT) -#define RTSX_INT (CMD_DONE_INT | NEED_COMPLETE_INT | CARD_INT | \ - GPIO0_INT | OC_INT) - -#define CARD_EXIST (XD_EXIST | MS_EXIST | SD_EXIST) - -/* Bus interrupt enable register */ -#define CMD_DONE_INT_EN BIT(31) -#define DATA_DONE_INT_EN BIT(30) -#define TRANS_OK_INT_EN BIT(29) -#define TRANS_FAIL_INT_EN BIT(28) -#define XD_INT_EN BIT(27) -#define MS_INT_EN BIT(26) -#define SD_INT_EN BIT(25) -#define GPIO0_INT_EN BIT(24) -#define OC_INT_EN BIT(23) -#define DELINK_INT_EN GPIO0_INT_EN -#define MS_OC_INT_EN BIT(23) -#define SD_OC_INT_EN BIT(22) - -#define READ_REG_CMD 0 -#define WRITE_REG_CMD 1 -#define CHECK_REG_CMD 2 - -#define HOST_TO_DEVICE 0 -#define DEVICE_TO_HOST 1 - -#define RTSX_RESV_BUF_LEN 4096 -#define HOST_CMDS_BUF_LEN 1024 -#define HOST_SG_TBL_BUF_LEN (RTSX_RESV_BUF_LEN - HOST_CMDS_BUF_LEN) - -#define SD_NR 2 -#define MS_NR 3 -#define XD_NR 4 -#define SPI_NR 7 -#define SD_CARD BIT(SD_NR) -#define MS_CARD BIT(MS_NR) -#define XD_CARD BIT(XD_NR) -#define SPI_CARD BIT(SPI_NR) - -#define MAX_ALLOWED_LUN_CNT 8 - -#define XD_FREE_TABLE_CNT 1200 -#define MS_FREE_TABLE_CNT 512 - -/* Bit Operation */ -#define SET_BIT(data, idx) ((data) |= 1 << (idx)) -#define CLR_BIT(data, idx) ((data) &= ~(1 << (idx))) -#define CHK_BIT(data, idx) ((data) & (1 << (idx))) - -/* SG descriptor */ -#define RTSX_SG_INT 0x04 -#define RTSX_SG_END 0x02 -#define RTSX_SG_VALID 0x01 - -#define RTSX_SG_NO_OP 0x00 -#define RTSX_SG_TRANS_DATA (0x02 << 4) -#define RTSX_SG_LINK_DESC (0x03 << 4) - -struct rtsx_chip; - -typedef int (*card_rw_func)(struct scsi_cmnd *srb, struct rtsx_chip *chip, - u32 sec_addr, u16 sec_cnt); - -/* Supported Clock */ -enum card_clock {CLK_20 = 1, CLK_30, CLK_40, CLK_50, CLK_60, - CLK_80, CLK_100, CLK_120, CLK_150, CLK_200}; - -enum RTSX_STAT {RTSX_STAT_INIT, RTSX_STAT_IDLE, RTSX_STAT_RUN, RTSX_STAT_SS, - RTSX_STAT_DELINK, RTSX_STAT_SUSPEND, - RTSX_STAT_ABORT, RTSX_STAT_DISCONNECT}; -enum IC_VER {IC_VER_AB, IC_VER_C = 2, IC_VER_D = 3}; - -#define MAX_RESET_CNT 3 - -/* For MS Card */ -#define MAX_DEFECTIVE_BLOCK 10 - -struct zone_entry { - u16 *l2p_table; - u16 *free_table; - u16 defect_list[MAX_DEFECTIVE_BLOCK]; /* For MS card only */ - int set_index; - int get_index; - int unused_blk_cnt; - int disable_count; - /* To indicate whether the L2P table of this zone has been built. */ - int build_flag; -}; - -#define TYPE_SD 0x0000 -#define TYPE_MMC 0x0001 - -/* TYPE_SD */ -#define SD_HS 0x0100 -#define SD_SDR50 0x0200 -#define SD_DDR50 0x0400 -#define SD_SDR104 0x0800 -#define SD_HCXC 0x1000 - -/* TYPE_MMC */ -#define MMC_26M 0x0100 -#define MMC_52M 0x0200 -#define MMC_4BIT 0x0400 -#define MMC_8BIT 0x0800 -#define MMC_SECTOR_MODE 0x1000 -#define MMC_DDR52 0x2000 - -/* SD card */ -#define CHK_SD(sd_card) (((sd_card)->sd_type & 0xFF) == TYPE_SD) -#define CHK_SD_HS(sd_card) (CHK_SD(sd_card) && \ - ((sd_card)->sd_type & SD_HS)) -#define CHK_SD_SDR50(sd_card) (CHK_SD(sd_card) && \ - ((sd_card)->sd_type & SD_SDR50)) -#define CHK_SD_DDR50(sd_card) (CHK_SD(sd_card) && \ - ((sd_card)->sd_type & SD_DDR50)) -#define CHK_SD_SDR104(sd_card) (CHK_SD(sd_card) && \ - ((sd_card)->sd_type & SD_SDR104)) -#define CHK_SD_HCXC(sd_card) (CHK_SD(sd_card) && \ - ((sd_card)->sd_type & SD_HCXC)) -#define CHK_SD_HC(sd_card) (CHK_SD_HCXC(sd_card) && \ - ((sd_card)->capacity <= 0x4000000)) -#define CHK_SD_XC(sd_card) (CHK_SD_HCXC(sd_card) && \ - ((sd_card)->capacity > 0x4000000)) -#define CHK_SD30_SPEED(sd_card) (CHK_SD_SDR50(sd_card) || \ - CHK_SD_DDR50(sd_card) || \ - CHK_SD_SDR104(sd_card)) - -#define SET_SD(sd_card) ((sd_card)->sd_type = TYPE_SD) -#define SET_SD_HS(sd_card) ((sd_card)->sd_type |= SD_HS) -#define SET_SD_SDR50(sd_card) ((sd_card)->sd_type |= SD_SDR50) -#define SET_SD_DDR50(sd_card) ((sd_card)->sd_type |= SD_DDR50) -#define SET_SD_SDR104(sd_card) ((sd_card)->sd_type |= SD_SDR104) -#define SET_SD_HCXC(sd_card) ((sd_card)->sd_type |= SD_HCXC) - -#define CLR_SD_HS(sd_card) ((sd_card)->sd_type &= ~SD_HS) -#define CLR_SD_SDR50(sd_card) ((sd_card)->sd_type &= ~SD_SDR50) -#define CLR_SD_DDR50(sd_card) ((sd_card)->sd_type &= ~SD_DDR50) -#define CLR_SD_SDR104(sd_card) ((sd_card)->sd_type &= ~SD_SDR104) -#define CLR_SD_HCXC(sd_card) ((sd_card)->sd_type &= ~SD_HCXC) - -/* MMC card */ -#define CHK_MMC(sd_card) (((sd_card)->sd_type & 0xFF) == \ - TYPE_MMC) -#define CHK_MMC_26M(sd_card) (CHK_MMC(sd_card) && \ - ((sd_card)->sd_type & MMC_26M)) -#define CHK_MMC_52M(sd_card) (CHK_MMC(sd_card) && \ - ((sd_card)->sd_type & MMC_52M)) -#define CHK_MMC_4BIT(sd_card) (CHK_MMC(sd_card) && \ - ((sd_card)->sd_type & MMC_4BIT)) -#define CHK_MMC_8BIT(sd_card) (CHK_MMC(sd_card) && \ - ((sd_card)->sd_type & MMC_8BIT)) -#define CHK_MMC_SECTOR_MODE(sd_card) (CHK_MMC(sd_card) && \ - ((sd_card)->sd_type & MMC_SECTOR_MODE)) -#define CHK_MMC_DDR52(sd_card) (CHK_MMC(sd_card) && \ - ((sd_card)->sd_type & MMC_DDR52)) - -#define SET_MMC(sd_card) ((sd_card)->sd_type = TYPE_MMC) -#define SET_MMC_26M(sd_card) ((sd_card)->sd_type |= MMC_26M) -#define SET_MMC_52M(sd_card) ((sd_card)->sd_type |= MMC_52M) -#define SET_MMC_4BIT(sd_card) ((sd_card)->sd_type |= MMC_4BIT) -#define SET_MMC_8BIT(sd_card) ((sd_card)->sd_type |= MMC_8BIT) -#define SET_MMC_SECTOR_MODE(sd_card) ((sd_card)->sd_type |= MMC_SECTOR_MODE) -#define SET_MMC_DDR52(sd_card) ((sd_card)->sd_type |= MMC_DDR52) - -#define CLR_MMC_26M(sd_card) ((sd_card)->sd_type &= ~MMC_26M) -#define CLR_MMC_52M(sd_card) ((sd_card)->sd_type &= ~MMC_52M) -#define CLR_MMC_4BIT(sd_card) ((sd_card)->sd_type &= ~MMC_4BIT) -#define CLR_MMC_8BIT(sd_card) ((sd_card)->sd_type &= ~MMC_8BIT) -#define CLR_MMC_SECTOR_MODE(sd_card) ((sd_card)->sd_type &= ~MMC_SECTOR_MODE) -#define CLR_MMC_DDR52(sd_card) ((sd_card)->sd_type &= ~MMC_DDR52) - -#define CHK_MMC_HS(sd_card) (CHK_MMC_52M(sd_card) && \ - CHK_MMC_26M(sd_card)) -#define CLR_MMC_HS(sd_card) \ -do { \ - CLR_MMC_DDR52(sd_card); \ - CLR_MMC_52M(sd_card); \ - CLR_MMC_26M(sd_card); \ -} while (0) - -#define SD_SUPPORT_CLASS_TEN 0x01 -#define SD_SUPPORT_1V8 0x02 - -#define SD_SET_CLASS_TEN(sd_card) ((sd_card)->sd_setting |= \ - SD_SUPPORT_CLASS_TEN) -#define SD_CHK_CLASS_TEN(sd_card) ((sd_card)->sd_setting & \ - SD_SUPPORT_CLASS_TEN) -#define SD_CLR_CLASS_TEN(sd_card) ((sd_card)->sd_setting &= \ - ~SD_SUPPORT_CLASS_TEN) -#define SD_SET_1V8(sd_card) ((sd_card)->sd_setting |= \ - SD_SUPPORT_1V8) -#define SD_CHK_1V8(sd_card) ((sd_card)->sd_setting & \ - SD_SUPPORT_1V8) -#define SD_CLR_1V8(sd_card) ((sd_card)->sd_setting &= \ - ~SD_SUPPORT_1V8) - -struct sd_info { - u16 sd_type; - u8 err_code; - u8 sd_data_buf_ready; - u32 sd_addr; - u32 capacity; - - u8 raw_csd[16]; - u8 raw_scr[8]; - - /* Sequential RW */ - int seq_mode; - enum dma_data_direction pre_dir; - u32 pre_sec_addr; - u16 pre_sec_cnt; - - int cleanup_counter; - - int sd_clock; - - int mmc_dont_switch_bus; - -#ifdef SUPPORT_CPRM - int sd_pass_thru_en; - int pre_cmd_err; - u8 last_rsp_type; - u8 rsp[17]; -#endif - - u8 func_group1_mask; - u8 func_group2_mask; - u8 func_group3_mask; - u8 func_group4_mask; - - u8 sd_switch_fail; - u8 sd_read_phase; - -#ifdef SUPPORT_SD_LOCK - u8 sd_lock_status; - u8 sd_erase_status; - u8 sd_lock_notify; -#endif - int need_retune; -}; - -struct xd_delay_write_tag { - u32 old_phyblock; - u32 new_phyblock; - u32 logblock; - u8 pageoff; - u8 delay_write_flag; -}; - -struct xd_info { - u8 maker_code; - u8 device_code; - u8 block_shift; - u8 page_off; - u8 addr_cycle; - u16 cis_block; - u8 multi_flag; - u8 err_code; - u32 capacity; - - struct zone_entry *zone; - int zone_cnt; - - struct xd_delay_write_tag delay_write; - int cleanup_counter; - - int xd_clock; -}; - -#define MODE_512_SEQ 0x01 -#define MODE_2K_SEQ 0x02 - -#define TYPE_MS 0x0000 -#define TYPE_MSPRO 0x0001 - -#define MS_4BIT 0x0100 -#define MS_8BIT 0x0200 -#define MS_HG 0x0400 -#define MS_XC 0x0800 - -#define HG8BIT (MS_HG | MS_8BIT) - -#define CHK_MSPRO(ms_card) (((ms_card)->ms_type & 0xFF) == TYPE_MSPRO) -#define CHK_HG8BIT(ms_card) (CHK_MSPRO(ms_card) && \ - (((ms_card)->ms_type & HG8BIT) == HG8BIT)) -#define CHK_MSXC(ms_card) (CHK_MSPRO(ms_card) && \ - ((ms_card)->ms_type & MS_XC)) -#define CHK_MSHG(ms_card) (CHK_MSPRO(ms_card) && \ - ((ms_card)->ms_type & MS_HG)) - -#define CHK_MS8BIT(ms_card) (((ms_card)->ms_type & MS_8BIT)) -#define CHK_MS4BIT(ms_card) (((ms_card)->ms_type & MS_4BIT)) - -struct ms_delay_write_tag { - u16 old_phyblock; - u16 new_phyblock; - u16 logblock; - u8 pageoff; - u8 delay_write_flag; -}; - -struct ms_info { - u16 ms_type; - u8 block_shift; - u8 page_off; - u16 total_block; - u16 boot_block; - u32 capacity; - - u8 check_ms_flow; - u8 switch_8bit_fail; - u8 err_code; - - struct zone_entry *segment; - int segment_cnt; - - int pro_under_formatting; - int format_status; - u16 progress; - u8 raw_sys_info[96]; -#ifdef SUPPORT_PCGL_1P18 - u8 raw_model_name[48]; -#endif - - u8 multi_flag; - - /* Sequential RW */ - u8 seq_mode; - enum dma_data_direction pre_dir; - u32 pre_sec_addr; - u16 pre_sec_cnt; - u32 total_sec_cnt; - - struct ms_delay_write_tag delay_write; - - int cleanup_counter; - - int ms_clock; - -#ifdef SUPPORT_MAGIC_GATE - u8 magic_gate_id[16]; - u8 mg_entry_num; - int mg_auth; /* flag to indicate authentication process */ -#endif -}; - -struct spi_info { - u8 use_clk; - u8 write_en; - u16 clk_div; - u8 err_code; - - int spi_clock; -}; - -/************/ -/* LUN mode */ -/************/ -/* Single LUN, support xD/SD/MS */ -#define DEFAULT_SINGLE 0 -/* 2 LUN mode, support SD/MS */ -#define SD_MS_2LUN 1 -/* Single LUN, but only support SD/MS, for Barossa LQFP */ -#define SD_MS_1LUN 2 - -#define LAST_LUN_MODE 2 - -/* Barossa package */ -#define QFN 0 -#define LQFP 1 - -/******************/ -/* sd_ctl bit map */ -/******************/ -/* SD push point control, bit 0, 1 */ -#define SD_PUSH_POINT_CTL_MASK 0x03 -#define SD_PUSH_POINT_DELAY 0x01 -#define SD_PUSH_POINT_AUTO 0x02 -/* SD sample point control, bit 2, 3 */ -#define SD_SAMPLE_POINT_CTL_MASK 0x0C -#define SD_SAMPLE_POINT_DELAY 0x04 -#define SD_SAMPLE_POINT_AUTO 0x08 -/* SD DDR Tx phase set by user, bit 4 */ -#define SD_DDR_TX_PHASE_SET_BY_USER 0x10 -/* MMC DDR Tx phase set by user, bit 5 */ -#define MMC_DDR_TX_PHASE_SET_BY_USER 0x20 -/* Support MMC DDR mode, bit 6 */ -#define SUPPORT_MMC_DDR_MODE 0x40 -/* Reset MMC at first */ -#define RESET_MMC_FIRST 0x80 - -#define SEQ_START_CRITERIA 0x20 - -/* MS Power Class En */ -#define POWER_CLASS_2_EN 0x02 -#define POWER_CLASS_1_EN 0x01 - -#define MAX_SHOW_CNT 10 -#define MAX_RESET_CNT 3 - -#define SDIO_EXIST 0x01 -#define SDIO_IGNORED 0x02 - -#define CHK_SDIO_EXIST(chip) ((chip)->sdio_func_exist & SDIO_EXIST) -#define SET_SDIO_EXIST(chip) ((chip)->sdio_func_exist |= SDIO_EXIST) -#define CLR_SDIO_EXIST(chip) ((chip)->sdio_func_exist &= ~SDIO_EXIST) - -#define CHK_SDIO_IGNORED(chip) ((chip)->sdio_func_exist & SDIO_IGNORED) -#define SET_SDIO_IGNORED(chip) ((chip)->sdio_func_exist |= \ - SDIO_IGNORED) -#define CLR_SDIO_IGNORED(chip) ((chip)->sdio_func_exist &= \ - ~SDIO_IGNORED) - -struct rtsx_chip { - struct rtsx_dev *rtsx; - - u32 int_reg; /* Bus interrupt pending register */ - char max_lun; - void *context; - - void *host_cmds_ptr; /* host commands buffer pointer */ - dma_addr_t host_cmds_addr; - int ci; /* Command Index */ - - void *host_sg_tbl_ptr; /* SG descriptor table */ - dma_addr_t host_sg_tbl_addr; - int sgi; /* SG entry index */ - - struct scsi_cmnd *srb; /* current srb */ - struct sense_data_t sense_buffer[MAX_ALLOWED_LUN_CNT]; - - int cur_clk; /* current card clock */ - - /* Current accessed card */ - int cur_card; - - unsigned long need_release; /* need release bit map */ - unsigned long need_reset; /* need reset bit map */ - /* - * Flag to indicate that this card is just resumed from SS state, - * and need released before being resetted - */ - unsigned long need_reinit; - - int rw_need_retry; - -#ifdef SUPPORT_OCP - u32 ocp_int; - u8 ocp_stat; -#endif - - u8 card_exist; /* card exist bit map (physical exist) */ - u8 card_ready; /* card ready bit map (reset successfully) */ - u8 card_fail; /* card reset fail bit map */ - u8 card_ejected; /* card ejected bit map */ - u8 card_wp; /* card write protected bit map */ - - u8 lun_mc; /* - * flag to indicate whether to answer - * MediaChange - */ - -#ifndef LED_AUTO_BLINK - int led_toggle_counter; -#endif - - int sd_reset_counter; - int xd_reset_counter; - int ms_reset_counter; - - /* card bus width */ - u8 card_bus_width[MAX_ALLOWED_LUN_CNT]; - /* card capacity */ - u32 capacity[MAX_ALLOWED_LUN_CNT]; - /* read/write card function pointer */ - card_rw_func rw_card[MAX_ALLOWED_LUN_CNT]; - /* read/write capacity, used for GPIO Toggle */ - u32 rw_cap[MAX_ALLOWED_LUN_CNT]; - /* card to lun mapping table */ - u8 card2lun[32]; - /* lun to card mapping table */ - u8 lun2card[MAX_ALLOWED_LUN_CNT]; - - int rw_fail_cnt[MAX_ALLOWED_LUN_CNT]; - - int sd_show_cnt; - int xd_show_cnt; - int ms_show_cnt; - - /* card information */ - struct sd_info sd_card; - struct xd_info xd_card; - struct ms_info ms_card; - - struct spi_info spi; - - int auto_delink_cnt; - int auto_delink_allowed; - - int aspm_enabled; - - int sdio_aspm; - int sdio_idle; - int sdio_counter; - u8 sdio_raw_data[12]; - - u8 sd_io; - u8 sd_int; - - u8 rtsx_flag; - - int ss_counter; - int idle_counter; - enum RTSX_STAT rtsx_stat; - - u16 vendor_id; - u16 product_id; - u8 ic_version; - - int driver_first_load; - -#ifdef HW_AUTO_SWITCH_SD_BUS - int sdio_in_charge; -#endif - - u8 aspm_level[2]; - - int chip_insert_with_sdio; - - /* Options */ - - int adma_mode; - - int auto_delink_en; - int ss_en; - u8 lun_mode; - u8 aspm_l0s_l1_en; - - int power_down_in_ss; - - int sdr104_en; - int ddr50_en; - int sdr50_en; - - int baro_pkg; - - int asic_code; - int phy_debug_mode; - int hw_bypass_sd; - int sdio_func_exist; - int aux_pwr_exist; - u8 ms_power_class_en; - - int mspro_formatter_enable; - - int remote_wakeup_en; - - int ignore_sd; - int use_hw_setting; - - int ss_idle_period; - - int dynamic_aspm; - - int fpga_sd_sdr104_clk; - int fpga_sd_ddr50_clk; - int fpga_sd_sdr50_clk; - int fpga_sd_hs_clk; - int fpga_mmc_52m_clk; - int fpga_ms_hg_clk; - int fpga_ms_4bit_clk; - int fpga_ms_1bit_clk; - - int asic_sd_sdr104_clk; - int asic_sd_ddr50_clk; - int asic_sd_sdr50_clk; - int asic_sd_hs_clk; - int asic_mmc_52m_clk; - int asic_ms_hg_clk; - int asic_ms_4bit_clk; - int asic_ms_1bit_clk; - - u8 ssc_depth_sd_sdr104; - u8 ssc_depth_sd_ddr50; - u8 ssc_depth_sd_sdr50; - u8 ssc_depth_sd_hs; - u8 ssc_depth_mmc_52m; - u8 ssc_depth_ms_hg; - u8 ssc_depth_ms_4bit; - u8 ssc_depth_low_speed; - - u8 card_drive_sel; - u8 sd30_drive_sel_1v8; - u8 sd30_drive_sel_3v3; - - u8 sd_400mA_ocp_thd; - u8 sd_800mA_ocp_thd; - u8 ms_ocp_thd; - - int ssc_en; - int msi_en; - - int xd_timeout; - int sd_timeout; - int ms_timeout; - int mspro_timeout; - - int auto_power_down; - - int sd_ddr_tx_phase; - int mmc_ddr_tx_phase; - int sd_default_tx_phase; - int sd_default_rx_phase; - - int pmos_pwr_on_interval; - int sd_voltage_switch_delay; - int s3_pwr_off_delay; - - int force_clkreq_0; - int ft2_fast_mode; - - int do_delink_before_power_down; - int polling_config; - int sdio_retry_cnt; - - int delink_stage1_step; - int delink_stage2_step; - int delink_stage3_step; - - int auto_delink_in_L1; - int hp_watch_bios_hotplug; - int support_ms_8bit; - - u8 blink_led; - u8 phy_voltage; - u8 max_payload; - - u32 sd_speed_prior; - u32 sd_current_prior; - u32 sd_ctl; -}; - -static inline struct device *rtsx_dev(const struct rtsx_chip *chip) -{ - return &chip->rtsx->pci->dev; -} - -#define rtsx_set_stat(chip, stat) \ -do { \ - if ((stat) != RTSX_STAT_IDLE) { \ - (chip)->idle_counter = 0; \ - } \ - (chip)->rtsx_stat = (enum RTSX_STAT)(stat); \ -} while (0) -#define rtsx_get_stat(chip) ((chip)->rtsx_stat) -#define rtsx_chk_stat(chip, stat) ((chip)->rtsx_stat == (stat)) - -#define RTSX_SET_DELINK(chip) ((chip)->rtsx_flag |= 0x01) -#define RTSX_CLR_DELINK(chip) ((chip)->rtsx_flag &= 0xFE) -#define RTSX_TST_DELINK(chip) ((chip)->rtsx_flag & 0x01) - -#define CHECK_PID(chip, pid) ((chip)->product_id == (pid)) -#define CHECK_BARO_PKG(chip, pkg) ((chip)->baro_pkg == (pkg)) -#define CHECK_LUN_MODE(chip, mode) ((chip)->lun_mode == (mode)) - -/* Power down control */ -#define SSC_PDCTL 0x01 -#define OC_PDCTL 0x02 - -int rtsx_force_power_on(struct rtsx_chip *chip, u8 ctl); -int rtsx_force_power_down(struct rtsx_chip *chip, u8 ctl); - -void rtsx_enable_card_int(struct rtsx_chip *chip); -void rtsx_enable_bus_int(struct rtsx_chip *chip); -void rtsx_disable_bus_int(struct rtsx_chip *chip); -int rtsx_reset_chip(struct rtsx_chip *chip); -int rtsx_init_chip(struct rtsx_chip *chip); -void rtsx_release_chip(struct rtsx_chip *chip); -void rtsx_polling_func(struct rtsx_chip *chip); -void rtsx_stop_cmd(struct rtsx_chip *chip, int card); -int rtsx_write_register(struct rtsx_chip *chip, u16 addr, u8 mask, u8 data); -int rtsx_read_register(struct rtsx_chip *chip, u16 addr, u8 *data); -int rtsx_write_cfg_dw(struct rtsx_chip *chip, - u8 func_no, u16 addr, u32 mask, u32 val); -int rtsx_read_cfg_dw(struct rtsx_chip *chip, u8 func_no, u16 addr, u32 *val); -int rtsx_write_cfg_seq(struct rtsx_chip *chip, - u8 func, u16 addr, u8 *buf, int len); -int rtsx_read_cfg_seq(struct rtsx_chip *chip, - u8 func, u16 addr, u8 *buf, int len); -int rtsx_write_phy_register(struct rtsx_chip *chip, u8 addr, u16 val); -int rtsx_read_phy_register(struct rtsx_chip *chip, u8 addr, u16 *val); -int rtsx_read_efuse(struct rtsx_chip *chip, u8 addr, u8 *val); -int rtsx_write_efuse(struct rtsx_chip *chip, u8 addr, u8 val); -int rtsx_clr_phy_reg_bit(struct rtsx_chip *chip, u8 reg, u8 bit); -int rtsx_set_phy_reg_bit(struct rtsx_chip *chip, u8 reg, u8 bit); -void rtsx_enter_ss(struct rtsx_chip *chip); -void rtsx_exit_ss(struct rtsx_chip *chip); -int rtsx_pre_handle_interrupt(struct rtsx_chip *chip); -void rtsx_enter_L1(struct rtsx_chip *chip); -void rtsx_exit_L1(struct rtsx_chip *chip); -void rtsx_do_before_power_down(struct rtsx_chip *chip, int pm_stat); -void rtsx_enable_aspm(struct rtsx_chip *chip); -void rtsx_disable_aspm(struct rtsx_chip *chip); -int rtsx_read_ppbuf(struct rtsx_chip *chip, u8 *buf, int buf_len); -int rtsx_write_ppbuf(struct rtsx_chip *chip, u8 *buf, int buf_len); -int rtsx_check_chip_exist(struct rtsx_chip *chip); - -#endif /* __REALTEK_RTSX_CHIP_H */ diff --git a/drivers/staging/rts5208/rtsx_scsi.c b/drivers/staging/rts5208/rtsx_scsi.c deleted file mode 100644 index c27cffb9ad8f..000000000000 --- a/drivers/staging/rts5208/rtsx_scsi.c +++ /dev/null @@ -1,3279 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Driver for Realtek PCI-Express card reader - * - * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. - * - * Author: - * Wei WANG (wei_wang@xxxxxxxxxxxxxx) - * Micky Ching (micky_ching@xxxxxxxxxxxxxx) - */ - -#include <linux/blkdev.h> -#include <linux/kthread.h> -#include <linux/sched.h> -#include <linux/vmalloc.h> - -#include "rtsx.h" -#include "sd.h" -#include "ms.h" -#include "spi.h" - -void scsi_show_command(struct rtsx_chip *chip) -{ - struct scsi_cmnd *srb = chip->srb; - char *what = NULL; - bool unknown_cmd = false; - int len; - - switch (srb->cmnd[0]) { - case TEST_UNIT_READY: - what = "TEST_UNIT_READY"; - break; - case REZERO_UNIT: - what = "REZERO_UNIT"; - break; - case REQUEST_SENSE: - what = "REQUEST_SENSE"; - break; - case FORMAT_UNIT: - what = "FORMAT_UNIT"; - break; - case READ_BLOCK_LIMITS: - what = "READ_BLOCK_LIMITS"; - break; - case REASSIGN_BLOCKS: - what = "REASSIGN_BLOCKS"; - break; - case READ_6: - what = "READ_6"; - break; - case WRITE_6: - what = "WRITE_6"; - break; - case SEEK_6: - what = "SEEK_6"; - break; - case READ_REVERSE: - what = "READ_REVERSE"; - break; - case WRITE_FILEMARKS: - what = "WRITE_FILEMARKS"; - break; - case SPACE: - what = "SPACE"; - break; - case INQUIRY: - what = "INQUIRY"; - break; - case RECOVER_BUFFERED_DATA: - what = "RECOVER_BUFFERED_DATA"; - break; - case MODE_SELECT: - what = "MODE_SELECT"; - break; - case RESERVE: - what = "RESERVE"; - break; - case RELEASE: - what = "RELEASE"; - break; - case COPY: - what = "COPY"; - break; - case ERASE: - what = "ERASE"; - break; - case MODE_SENSE: - what = "MODE_SENSE"; - break; - case START_STOP: - what = "START_STOP"; - break; - case RECEIVE_DIAGNOSTIC: - what = "RECEIVE_DIAGNOSTIC"; - break; - case SEND_DIAGNOSTIC: - what = "SEND_DIAGNOSTIC"; - break; - case ALLOW_MEDIUM_REMOVAL: - what = "ALLOW_MEDIUM_REMOVAL"; - break; - case SET_WINDOW: - what = "SET_WINDOW"; - break; - case READ_CAPACITY: - what = "READ_CAPACITY"; - break; - case READ_10: - what = "READ_10"; - break; - case WRITE_10: - what = "WRITE_10"; - break; - case SEEK_10: - what = "SEEK_10"; - break; - case WRITE_VERIFY: - what = "WRITE_VERIFY"; - break; - case VERIFY: - what = "VERIFY"; - break; - case SEARCH_HIGH: - what = "SEARCH_HIGH"; - break; - case SEARCH_EQUAL: - what = "SEARCH_EQUAL"; - break; - case SEARCH_LOW: - what = "SEARCH_LOW"; - break; - case SET_LIMITS: - what = "SET_LIMITS"; - break; - case READ_POSITION: - what = "READ_POSITION"; - break; - case SYNCHRONIZE_CACHE: - what = "SYNCHRONIZE_CACHE"; - break; - case LOCK_UNLOCK_CACHE: - what = "LOCK_UNLOCK_CACHE"; - break; - case READ_DEFECT_DATA: - what = "READ_DEFECT_DATA"; - break; - case MEDIUM_SCAN: - what = "MEDIUM_SCAN"; - break; - case COMPARE: - what = "COMPARE"; - break; - case COPY_VERIFY: - what = "COPY_VERIFY"; - break; - case WRITE_BUFFER: - what = "WRITE_BUFFER"; - break; - case READ_BUFFER: - what = "READ_BUFFER"; - break; - case UPDATE_BLOCK: - what = "UPDATE_BLOCK"; - break; - case READ_LONG: - what = "READ_LONG"; - break; - case WRITE_LONG: - what = "WRITE_LONG"; - break; - case CHANGE_DEFINITION: - what = "CHANGE_DEFINITION"; - break; - case WRITE_SAME: - what = "WRITE_SAME"; - break; - case GPCMD_READ_SUBCHANNEL: - what = "READ SUBCHANNEL"; - break; - case READ_TOC: - what = "READ_TOC"; - break; - case GPCMD_READ_HEADER: - what = "READ HEADER"; - break; - case GPCMD_PLAY_AUDIO_10: - what = "PLAY AUDIO (10)"; - break; - case GPCMD_PLAY_AUDIO_MSF: - what = "PLAY AUDIO MSF"; - break; - case GPCMD_GET_EVENT_STATUS_NOTIFICATION: - what = "GET EVENT/STATUS NOTIFICATION"; - break; - case GPCMD_PAUSE_RESUME: - what = "PAUSE/RESUME"; - break; - case LOG_SELECT: - what = "LOG_SELECT"; - break; - case LOG_SENSE: - what = "LOG_SENSE"; - break; - case GPCMD_STOP_PLAY_SCAN: - what = "STOP PLAY/SCAN"; - break; - case GPCMD_READ_DISC_INFO: - what = "READ DISC INFORMATION"; - break; - case GPCMD_READ_TRACK_RZONE_INFO: - what = "READ TRACK INFORMATION"; - break; - case GPCMD_RESERVE_RZONE_TRACK: - what = "RESERVE TRACK"; - break; - case GPCMD_SEND_OPC: - what = "SEND OPC"; - break; - case MODE_SELECT_10: - what = "MODE_SELECT_10"; - break; - case GPCMD_REPAIR_RZONE_TRACK: - what = "REPAIR TRACK"; - break; - case 0x59: - what = "READ MASTER CUE"; - break; - case MODE_SENSE_10: - what = "MODE_SENSE_10"; - break; - case GPCMD_CLOSE_TRACK: - what = "CLOSE TRACK/SESSION"; - break; - case 0x5C: - what = "READ BUFFER CAPACITY"; - break; - case 0x5D: - what = "SEND CUE SHEET"; - break; - case GPCMD_BLANK: - what = "BLANK"; - break; - case REPORT_LUNS: - what = "REPORT LUNS"; - break; - case MOVE_MEDIUM: - what = "MOVE_MEDIUM or PLAY AUDIO (12)"; - break; - case READ_12: - what = "READ_12"; - break; - case WRITE_12: - what = "WRITE_12"; - break; - case WRITE_VERIFY_12: - what = "WRITE_VERIFY_12"; - break; - case SEARCH_HIGH_12: - what = "SEARCH_HIGH_12"; - break; - case SEARCH_EQUAL_12: - what = "SEARCH_EQUAL_12"; - break; - case SEARCH_LOW_12: - what = "SEARCH_LOW_12"; - break; - case SEND_VOLUME_TAG: - what = "SEND_VOLUME_TAG"; - break; - case READ_ELEMENT_STATUS: - what = "READ_ELEMENT_STATUS"; - break; - case GPCMD_READ_CD_MSF: - what = "READ CD MSF"; - break; - case GPCMD_SCAN: - what = "SCAN"; - break; - case GPCMD_SET_SPEED: - what = "SET CD SPEED"; - break; - case GPCMD_MECHANISM_STATUS: - what = "MECHANISM STATUS"; - break; - case GPCMD_READ_CD: - what = "READ CD"; - break; - case 0xE1: - what = "WRITE CONTINUE"; - break; - case WRITE_LONG_2: - what = "WRITE_LONG_2"; - break; - case VENDOR_CMND: - what = "Realtek's vendor command"; - break; - default: - what = "(unknown command)"; - unknown_cmd = true; - break; - } - - if (srb->cmnd[0] != TEST_UNIT_READY) - dev_dbg(rtsx_dev(chip), "Command %s (%d bytes)\n", - what, srb->cmd_len); - - if (unknown_cmd) { - len = min_t(unsigned short, srb->cmd_len, 16); - dev_dbg(rtsx_dev(chip), "%*ph\n", len, srb->cmnd); - } -} - -void set_sense_type(struct rtsx_chip *chip, unsigned int lun, int sense_type) -{ - switch (sense_type) { - case SENSE_TYPE_MEDIA_CHANGE: - set_sense_data(chip, lun, CUR_ERR, 0x06, 0, 0x28, 0, 0, 0); - break; - - case SENSE_TYPE_MEDIA_NOT_PRESENT: - set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x3A, 0, 0, 0); - break; - - case SENSE_TYPE_MEDIA_LBA_OVER_RANGE: - set_sense_data(chip, lun, CUR_ERR, 0x05, 0, 0x21, 0, 0, 0); - break; - - case SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT: - set_sense_data(chip, lun, CUR_ERR, 0x05, 0, 0x25, 0, 0, 0); - break; - - case SENSE_TYPE_MEDIA_WRITE_PROTECT: - set_sense_data(chip, lun, CUR_ERR, 0x07, 0, 0x27, 0, 0, 0); - break; - - case SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR: - set_sense_data(chip, lun, CUR_ERR, 0x03, 0, 0x11, 0, 0, 0); - break; - - case SENSE_TYPE_MEDIA_WRITE_ERR: - set_sense_data(chip, lun, CUR_ERR, 0x03, 0, 0x0C, 0x02, 0, 0); - break; - - case SENSE_TYPE_MEDIA_INVALID_CMD_FIELD: - set_sense_data(chip, lun, CUR_ERR, ILGAL_REQ, 0, - ASC_INVLD_CDB, ASCQ_INVLD_CDB, CDB_ILLEGAL, 1); - break; - - case SENSE_TYPE_FORMAT_IN_PROGRESS: - set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x04, 0x04, 0, 0); - break; - - case SENSE_TYPE_FORMAT_CMD_FAILED: - set_sense_data(chip, lun, CUR_ERR, 0x03, 0, 0x31, 0x01, 0, 0); - break; - -#ifdef SUPPORT_MAGIC_GATE - case SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB: - set_sense_data(chip, lun, CUR_ERR, 0x05, 0, 0x6F, 0x02, 0, 0); - break; - - case SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN: - set_sense_data(chip, lun, CUR_ERR, 0x05, 0, 0x6F, 0x00, 0, 0); - break; - - case SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM: - set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x30, 0x00, 0, 0); - break; - - case SENSE_TYPE_MG_WRITE_ERR: - set_sense_data(chip, lun, CUR_ERR, 0x03, 0, 0x0C, 0x00, 0, 0); - break; -#endif - -#ifdef SUPPORT_SD_LOCK - case SENSE_TYPE_MEDIA_READ_FORBIDDEN: - set_sense_data(chip, lun, CUR_ERR, 0x07, 0, 0x11, 0x13, 0, 0); - break; -#endif - - case SENSE_TYPE_NO_SENSE: - default: - set_sense_data(chip, lun, CUR_ERR, 0, 0, 0, 0, 0, 0); - break; - } -} - -void set_sense_data(struct rtsx_chip *chip, unsigned int lun, u8 err_code, - u8 sense_key, u32 info, u8 asc, u8 ascq, u8 sns_key_info0, - u16 sns_key_info1) -{ - struct sense_data_t *sense = &chip->sense_buffer[lun]; - - sense->err_code = err_code; - sense->sense_key = sense_key; - sense->info[0] = (u8)(info >> 24); - sense->info[1] = (u8)(info >> 16); - sense->info[2] = (u8)(info >> 8); - sense->info[3] = (u8)info; - - sense->ad_sense_len = sizeof(struct sense_data_t) - 8; - sense->asc = asc; - sense->ascq = ascq; - if (sns_key_info0 != 0) { - sense->sns_key_info[0] = SKSV | sns_key_info0; - sense->sns_key_info[1] = (sns_key_info1 & 0xf0) >> 4; - sense->sns_key_info[2] = sns_key_info1 & 0x0f; - } -} - -static int test_unit_ready(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - unsigned int lun = SCSI_LUN(srb); - - if (!check_card_ready(chip, lun)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - return TRANSPORT_FAILED; - } - - if (!(CHK_BIT(chip->lun_mc, lun))) { - SET_BIT(chip->lun_mc, lun); - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); - return TRANSPORT_FAILED; - } - -#ifdef SUPPORT_SD_LOCK - if (get_lun_card(chip, SCSI_LUN(srb)) == SD_CARD) { - struct sd_info *sd_card = &chip->sd_card; - - if (sd_card->sd_lock_notify) { - sd_card->sd_lock_notify = 0; - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); - return TRANSPORT_FAILED; - } else if (sd_card->sd_lock_status & SD_LOCKED) { - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_READ_FORBIDDEN); - return TRANSPORT_FAILED; - } - } -#endif - - return TRANSPORT_GOOD; -} - -static unsigned char formatter_inquiry_str[20] = { - 'M', 'E', 'M', 'O', 'R', 'Y', 'S', 'T', 'I', 'C', 'K', -#ifdef SUPPORT_MAGIC_GATE - '-', 'M', 'G', /* Byte[47:49] */ -#else - 0x20, 0x20, 0x20, /* Byte[47:49] */ -#endif - -#ifdef SUPPORT_MAGIC_GATE - 0x0B, /* Byte[50]: MG, MS, MSPro, MSXC */ -#else - 0x09, /* Byte[50]: MS, MSPro, MSXC */ -#endif - 0x00, /* Byte[51]: Category Specific Commands */ - 0x00, /* Byte[52]: Access Control and feature */ - 0x20, 0x20, 0x20, /* Byte[53:55] */ -}; - -static int inquiry(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - unsigned int lun = SCSI_LUN(srb); - char *inquiry_default = (char *)"Generic-xD/SD/M.S. 1.00"; - char *inquiry_sdms = (char *)"Generic-SD/MemoryStick 1.00"; - char *inquiry_sd = (char *)"Generic-SD/MMC 1.00"; - char *inquiry_ms = (char *)"Generic-MemoryStick 1.00"; - char *inquiry_string; - unsigned char sendbytes; - unsigned char *buf; - u8 card = get_lun_card(chip, lun); - bool pro_formatter_flag = false; - unsigned char inquiry_buf[] = { - QULIFIRE | DRCT_ACCESS_DEV, - RMB_DISC | 0x0D, - 0x00, - 0x01, - 0x1f, - 0x02, - 0, - REL_ADR | WBUS_32 | WBUS_16 | SYNC | LINKED | CMD_QUE | SFT_RE, - }; - - if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) { - if (chip->lun2card[lun] == SD_CARD) - inquiry_string = inquiry_sd; - else - inquiry_string = inquiry_ms; - - } else if (CHECK_LUN_MODE(chip, SD_MS_1LUN)) { - inquiry_string = inquiry_sdms; - } else { - inquiry_string = inquiry_default; - } - - buf = vmalloc(scsi_bufflen(srb)); - if (!buf) - return TRANSPORT_ERROR; - -#ifdef SUPPORT_MAGIC_GATE - if (chip->mspro_formatter_enable && - (chip->lun2card[lun] & MS_CARD)) -#else - if (chip->mspro_formatter_enable) -#endif - if (!card || card == MS_CARD) - pro_formatter_flag = true; - - if (pro_formatter_flag) { - if (scsi_bufflen(srb) < 56) - sendbytes = (unsigned char)(scsi_bufflen(srb)); - else - sendbytes = 56; - - } else { - if (scsi_bufflen(srb) < 36) - sendbytes = (unsigned char)(scsi_bufflen(srb)); - else - sendbytes = 36; - } - - if (sendbytes > 8) { - memcpy(buf, inquiry_buf, 8); - memcpy(buf + 8, inquiry_string, min(sendbytes, 36) - 8); - if (pro_formatter_flag) { - /* Additional Length */ - buf[4] = 0x33; - } - } else { - memcpy(buf, inquiry_buf, sendbytes); - } - - if (pro_formatter_flag) { - if (sendbytes > 36) - memcpy(buf + 36, formatter_inquiry_str, sendbytes - 36); - } - - scsi_set_resid(srb, 0); - - rtsx_stor_set_xfer_buf(buf, scsi_bufflen(srb), srb); - vfree(buf); - - return TRANSPORT_GOOD; -} - -static int start_stop_unit(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - unsigned int lun = SCSI_LUN(srb); - - scsi_set_resid(srb, scsi_bufflen(srb)); - - if (srb->cmnd[1] == 1) - return TRANSPORT_GOOD; - - switch (srb->cmnd[0x4]) { - case STOP_MEDIUM: - /* Media disabled */ - return TRANSPORT_GOOD; - - case UNLOAD_MEDIUM: - /* Media shall be unload */ - if (check_card_ready(chip, lun)) - eject_card(chip, lun); - return TRANSPORT_GOOD; - - case MAKE_MEDIUM_READY: - case LOAD_MEDIUM: - if (check_card_ready(chip, lun)) - return TRANSPORT_GOOD; - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - return TRANSPORT_FAILED; - - break; - } - - return TRANSPORT_ERROR; -} - -static int allow_medium_removal(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - int prevent; - - prevent = srb->cmnd[4] & 0x1; - - scsi_set_resid(srb, 0); - - if (prevent) { - set_sense_type(chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - - return TRANSPORT_GOOD; -} - -static int request_sense(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - struct sense_data_t *sense; - unsigned int lun = SCSI_LUN(srb); - struct ms_info *ms_card = &chip->ms_card; - unsigned char *tmp, *buf; - - sense = &chip->sense_buffer[lun]; - - if ((get_lun_card(chip, lun) == MS_CARD) && - ms_card->pro_under_formatting) { - if (ms_card->format_status == FORMAT_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE); - ms_card->pro_under_formatting = 0; - ms_card->progress = 0; - } else if (ms_card->format_status == FORMAT_IN_PROGRESS) { - /* Logical Unit Not Ready Format in Progress */ - set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x04, 0x04, - 0, (u16)(ms_card->progress)); - } else { - /* Format Command Failed */ - set_sense_type(chip, lun, SENSE_TYPE_FORMAT_CMD_FAILED); - ms_card->pro_under_formatting = 0; - ms_card->progress = 0; - } - - rtsx_set_stat(chip, RTSX_STAT_RUN); - } - - buf = vmalloc(scsi_bufflen(srb)); - if (!buf) - return TRANSPORT_ERROR; - - tmp = (unsigned char *)sense; - memcpy(buf, tmp, scsi_bufflen(srb)); - - rtsx_stor_set_xfer_buf(buf, scsi_bufflen(srb), srb); - vfree(buf); - - scsi_set_resid(srb, 0); - /* Reset Sense Data */ - set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE); - return TRANSPORT_GOOD; -} - -static void ms_mode_sense(struct rtsx_chip *chip, u8 cmd, - int lun, u8 *buf, int buf_len) -{ - struct ms_info *ms_card = &chip->ms_card; - int sys_info_offset; - int data_size = buf_len; - bool support_format = false; - int i = 0; - - if (cmd == MODE_SENSE) { - sys_info_offset = 8; - if (data_size > 0x68) - data_size = 0x68; - - buf[i++] = 0x67; /* Mode Data Length */ - } else { - sys_info_offset = 12; - if (data_size > 0x6C) - data_size = 0x6C; - - buf[i++] = 0x00; /* Mode Data Length (MSB) */ - buf[i++] = 0x6A; /* Mode Data Length (LSB) */ - } - - /* Medium Type Code */ - if (check_card_ready(chip, lun)) { - if (CHK_MSXC(ms_card)) { - support_format = true; - buf[i++] = 0x40; - } else if (CHK_MSPRO(ms_card)) { - support_format = true; - buf[i++] = 0x20; - } else { - buf[i++] = 0x10; - } - - /* WP */ - if (check_card_wp(chip, lun)) - buf[i++] = 0x80; - else - buf[i++] = 0x00; - - } else { - buf[i++] = 0x00; /* MediaType */ - buf[i++] = 0x00; /* WP */ - } - - buf[i++] = 0x00; /* Reserved */ - - if (cmd == MODE_SENSE_10) { - buf[i++] = 0x00; /* Reserved */ - buf[i++] = 0x00; /* Block descriptor length(MSB) */ - buf[i++] = 0x00; /* Block descriptor length(LSB) */ - - /* The Following Data is the content of "Page 0x20" */ - if (data_size >= 9) - buf[i++] = 0x20; /* Page Code */ - if (data_size >= 10) - buf[i++] = 0x62; /* Page Length */ - if (data_size >= 11) - buf[i++] = 0x00; /* No Access Control */ - if (data_size >= 12) { - if (support_format) - buf[i++] = 0xC0; /* SF, SGM */ - else - buf[i++] = 0x00; - } - } else { - /* The Following Data is the content of "Page 0x20" */ - if (data_size >= 5) - buf[i++] = 0x20; /* Page Code */ - if (data_size >= 6) - buf[i++] = 0x62; /* Page Length */ - if (data_size >= 7) - buf[i++] = 0x00; /* No Access Control */ - if (data_size >= 8) { - if (support_format) - buf[i++] = 0xC0; /* SF, SGM */ - else - buf[i++] = 0x00; - } - } - - if (data_size > sys_info_offset) { - /* 96 Bytes Attribute Data */ - int len = data_size - sys_info_offset; - - len = (len < 96) ? len : 96; - - memcpy(buf + sys_info_offset, ms_card->raw_sys_info, len); - } -} - -static int mode_sense(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - unsigned int lun = SCSI_LUN(srb); - unsigned int data_size; - int status; - bool pro_formatter_flag; - unsigned char page_code, *buf; - u8 card = get_lun_card(chip, lun); - -#ifndef SUPPORT_MAGIC_GATE - if (!check_card_ready(chip, lun)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - scsi_set_resid(srb, scsi_bufflen(srb)); - return TRANSPORT_FAILED; - } -#endif - - pro_formatter_flag = false; - data_size = 8; -#ifdef SUPPORT_MAGIC_GATE - if ((chip->lun2card[lun] & MS_CARD)) { - if (!card || card == MS_CARD) { - data_size = 108; - if (chip->mspro_formatter_enable) - pro_formatter_flag = true; - } - } -#else - if (card == MS_CARD) { - if (chip->mspro_formatter_enable) { - pro_formatter_flag = true; - data_size = 108; - } - } -#endif - - buf = kmalloc(data_size, GFP_KERNEL); - if (!buf) - return TRANSPORT_ERROR; - - page_code = srb->cmnd[2] & 0x3f; - - if (page_code == 0x3F || page_code == 0x1C || - page_code == 0x00 || - (pro_formatter_flag && page_code == 0x20)) { - if (srb->cmnd[0] == MODE_SENSE) { - if (page_code == 0x3F || page_code == 0x20) { - ms_mode_sense(chip, srb->cmnd[0], - lun, buf, data_size); - } else { - data_size = 4; - buf[0] = 0x03; - buf[1] = 0x00; - if (check_card_wp(chip, lun)) - buf[2] = 0x80; - else - buf[2] = 0x00; - - buf[3] = 0x00; - } - } else { - if (page_code == 0x3F || page_code == 0x20) { - ms_mode_sense(chip, srb->cmnd[0], - lun, buf, data_size); - } else { - data_size = 8; - buf[0] = 0x00; - buf[1] = 0x06; - buf[2] = 0x00; - if (check_card_wp(chip, lun)) - buf[3] = 0x80; - else - buf[3] = 0x00; - buf[4] = 0x00; - buf[5] = 0x00; - buf[6] = 0x00; - buf[7] = 0x00; - } - } - status = TRANSPORT_GOOD; - } else { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - scsi_set_resid(srb, scsi_bufflen(srb)); - status = TRANSPORT_FAILED; - } - - if (status == TRANSPORT_GOOD) { - unsigned int len = min_t(unsigned int, scsi_bufflen(srb), - data_size); - rtsx_stor_set_xfer_buf(buf, len, srb); - scsi_set_resid(srb, scsi_bufflen(srb) - len); - } - kfree(buf); - - return status; -} - -static int read_write(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ -#ifdef SUPPORT_SD_LOCK - struct sd_info *sd_card = &chip->sd_card; -#endif - unsigned int lun = SCSI_LUN(srb); - int retval; - u32 start_sec; - u16 sec_cnt; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - if (!check_card_ready(chip, lun) || (get_card_size(chip, lun) == 0)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - return TRANSPORT_FAILED; - } - - if (!(CHK_BIT(chip->lun_mc, lun))) { - SET_BIT(chip->lun_mc, lun); - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); - return TRANSPORT_FAILED; - } - -#ifdef SUPPORT_SD_LOCK - if (sd_card->sd_erase_status) { - /* Accessing to any card is forbidden - * until the erase procedure of SD is completed - */ - dev_dbg(rtsx_dev(chip), "SD card being erased!\n"); - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_READ_FORBIDDEN); - return TRANSPORT_FAILED; - } - - if (get_lun_card(chip, lun) == SD_CARD) { - if (sd_card->sd_lock_status & SD_LOCKED) { - dev_dbg(rtsx_dev(chip), "SD card locked!\n"); - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_READ_FORBIDDEN); - return TRANSPORT_FAILED; - } - } -#endif - - if (srb->cmnd[0] == READ_10 || srb->cmnd[0] == WRITE_10) { - start_sec = ((u32)srb->cmnd[2] << 24) | - ((u32)srb->cmnd[3] << 16) | - ((u32)srb->cmnd[4] << 8) | ((u32)srb->cmnd[5]); - sec_cnt = ((u16)(srb->cmnd[7]) << 8) | srb->cmnd[8]; - } else if ((srb->cmnd[0] == READ_6) || (srb->cmnd[0] == WRITE_6)) { - start_sec = ((u32)(srb->cmnd[1] & 0x1F) << 16) | - ((u32)srb->cmnd[2] << 8) | ((u32)srb->cmnd[3]); - sec_cnt = srb->cmnd[4]; - if (sec_cnt == 0) - sec_cnt = 256; - } else if ((srb->cmnd[0] == VENDOR_CMND) && - (srb->cmnd[1] == SCSI_APP_CMD) && - ((srb->cmnd[2] == PP_READ10) || (srb->cmnd[2] == PP_WRITE10))) { - start_sec = ((u32)srb->cmnd[4] << 24) | - ((u32)srb->cmnd[5] << 16) | - ((u32)srb->cmnd[6] << 8) | ((u32)srb->cmnd[7]); - sec_cnt = ((u16)(srb->cmnd[9]) << 8) | srb->cmnd[10]; - } else { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - - /* In some test, we will receive a start_sec like 0xFFFFFFFF. - * In this situation, start_sec + sec_cnt will overflow, so we - * need to judge start_sec at first - */ - if (start_sec > get_card_size(chip, lun) || - ((start_sec + sec_cnt) > get_card_size(chip, lun))) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LBA_OVER_RANGE); - return TRANSPORT_FAILED; - } - - if (sec_cnt == 0) { - scsi_set_resid(srb, 0); - return TRANSPORT_GOOD; - } - - if (chip->rw_fail_cnt[lun] == 3) { - dev_dbg(rtsx_dev(chip), "read/write fail three times in succession\n"); - if (srb->sc_data_direction == DMA_FROM_DEVICE) - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - else - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); - - return TRANSPORT_FAILED; - } - - if (srb->sc_data_direction == DMA_TO_DEVICE) { - if (check_card_wp(chip, lun)) { - dev_dbg(rtsx_dev(chip), "Write protected card!\n"); - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_WRITE_PROTECT); - return TRANSPORT_FAILED; - } - } - - retval = card_rw(srb, chip, start_sec, sec_cnt); - if (retval != STATUS_SUCCESS) { - if (chip->need_release & chip->lun2card[lun]) { - chip->rw_fail_cnt[lun] = 0; - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - } else { - chip->rw_fail_cnt[lun]++; - if (srb->sc_data_direction == DMA_FROM_DEVICE) - set_sense_type - (chip, lun, - SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - else - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_WRITE_ERR); - } - retval = TRANSPORT_FAILED; - goto exit; - } else { - chip->rw_fail_cnt[lun] = 0; - retval = TRANSPORT_GOOD; - } - - scsi_set_resid(srb, 0); - -exit: - return retval; -} - -static int read_format_capacity(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - unsigned char *buf; - unsigned int lun = SCSI_LUN(srb); - unsigned int buf_len; - u8 card = get_lun_card(chip, lun); - u32 card_size; - int desc_cnt; - int i = 0; - - if (!check_card_ready(chip, lun)) { - if (!chip->mspro_formatter_enable) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - return TRANSPORT_FAILED; - } - } - - buf_len = (scsi_bufflen(srb) > 12) ? 0x14 : 12; - - buf = kmalloc(buf_len, GFP_KERNEL); - if (!buf) - return TRANSPORT_ERROR; - - buf[i++] = 0; - buf[i++] = 0; - buf[i++] = 0; - - /* Capacity List Length */ - if (buf_len > 12 && chip->mspro_formatter_enable && - (chip->lun2card[lun] & MS_CARD) && - (!card || card == MS_CARD)) { - buf[i++] = 0x10; - desc_cnt = 2; - } else { - buf[i++] = 0x08; - desc_cnt = 1; - } - - while (desc_cnt) { - if (check_card_ready(chip, lun)) { - card_size = get_card_size(chip, lun); - buf[i++] = (unsigned char)(card_size >> 24); - buf[i++] = (unsigned char)(card_size >> 16); - buf[i++] = (unsigned char)(card_size >> 8); - buf[i++] = (unsigned char)card_size; - - if (desc_cnt == 2) - buf[i++] = 2; - else - buf[i++] = 0; - } else { - buf[i++] = 0xFF; - buf[i++] = 0xFF; - buf[i++] = 0xFF; - buf[i++] = 0xFF; - - if (desc_cnt == 2) - buf[i++] = 3; - else - buf[i++] = 0; - } - - buf[i++] = 0x00; - buf[i++] = 0x02; - buf[i++] = 0x00; - - desc_cnt--; - } - - buf_len = min_t(unsigned int, scsi_bufflen(srb), buf_len); - rtsx_stor_set_xfer_buf(buf, buf_len, srb); - kfree(buf); - - scsi_set_resid(srb, scsi_bufflen(srb) - buf_len); - - return TRANSPORT_GOOD; -} - -static int read_capacity(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - unsigned char *buf; - unsigned int lun = SCSI_LUN(srb); - u32 card_size; - - if (!check_card_ready(chip, lun)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - return TRANSPORT_FAILED; - } - - if (!(CHK_BIT(chip->lun_mc, lun))) { - SET_BIT(chip->lun_mc, lun); - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); - return TRANSPORT_FAILED; - } - - buf = kmalloc(8, GFP_KERNEL); - if (!buf) - return TRANSPORT_ERROR; - - card_size = get_card_size(chip, lun); - buf[0] = (unsigned char)((card_size - 1) >> 24); - buf[1] = (unsigned char)((card_size - 1) >> 16); - buf[2] = (unsigned char)((card_size - 1) >> 8); - buf[3] = (unsigned char)(card_size - 1); - - buf[4] = 0x00; - buf[5] = 0x00; - buf[6] = 0x02; - buf[7] = 0x00; - - rtsx_stor_set_xfer_buf(buf, scsi_bufflen(srb), srb); - kfree(buf); - - scsi_set_resid(srb, 0); - - return TRANSPORT_GOOD; -} - -static int read_eeprom(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - unsigned short len, i; - int retval; - u8 *buf; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - len = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5]; - - buf = vmalloc(len); - if (!buf) - return TRANSPORT_ERROR; - - retval = rtsx_force_power_on(chip, SSC_PDCTL); - if (retval != STATUS_SUCCESS) { - vfree(buf); - set_sense_type(chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - return TRANSPORT_FAILED; - } - - for (i = 0; i < len; i++) { - retval = spi_read_eeprom(chip, i, buf + i); - if (retval != STATUS_SUCCESS) { - vfree(buf); - set_sense_type(chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - return TRANSPORT_FAILED; - } - } - - len = (unsigned short)min_t(unsigned int, scsi_bufflen(srb), len); - rtsx_stor_set_xfer_buf(buf, len, srb); - scsi_set_resid(srb, scsi_bufflen(srb) - len); - - vfree(buf); - - return TRANSPORT_GOOD; -} - -static int write_eeprom(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - unsigned short len, i; - int retval; - u8 *buf; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - len = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5]; - - retval = rtsx_force_power_on(chip, SSC_PDCTL); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); - return TRANSPORT_FAILED; - } - - if (len == 511) { - retval = spi_erase_eeprom_chip(chip); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_WRITE_ERR); - return TRANSPORT_FAILED; - } - } else { - len = (unsigned short)min_t(unsigned int, scsi_bufflen(srb), - len); - buf = vmalloc(len); - if (!buf) - return TRANSPORT_ERROR; - - rtsx_stor_get_xfer_buf(buf, len, srb); - scsi_set_resid(srb, scsi_bufflen(srb) - len); - - for (i = 0; i < len; i++) { - retval = spi_write_eeprom(chip, i, buf[i]); - if (retval != STATUS_SUCCESS) { - vfree(buf); - set_sense_type(chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_WRITE_ERR); - return TRANSPORT_FAILED; - } - } - - vfree(buf); - } - - return TRANSPORT_GOOD; -} - -static int read_mem(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - unsigned short addr, len, i; - int retval; - u8 *buf; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - addr = ((u16)srb->cmnd[2] << 8) | srb->cmnd[3]; - len = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5]; - - if (addr < 0xFC00) { - set_sense_type(chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - - buf = vmalloc(len); - if (!buf) - return TRANSPORT_ERROR; - - retval = rtsx_force_power_on(chip, SSC_PDCTL); - if (retval != STATUS_SUCCESS) { - vfree(buf); - set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); - return TRANSPORT_FAILED; - } - - for (i = 0; i < len; i++) { - retval = rtsx_read_register(chip, addr + i, buf + i); - if (retval != STATUS_SUCCESS) { - vfree(buf); - set_sense_type(chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - return TRANSPORT_FAILED; - } - } - - len = (unsigned short)min_t(unsigned int, scsi_bufflen(srb), len); - rtsx_stor_set_xfer_buf(buf, len, srb); - scsi_set_resid(srb, scsi_bufflen(srb) - len); - - vfree(buf); - - return TRANSPORT_GOOD; -} - -static int write_mem(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - unsigned short addr, len, i; - int retval; - u8 *buf; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - addr = ((u16)srb->cmnd[2] << 8) | srb->cmnd[3]; - len = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5]; - - if (addr < 0xFC00) { - set_sense_type(chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - - len = (unsigned short)min_t(unsigned int, scsi_bufflen(srb), len); - buf = vmalloc(len); - if (!buf) - return TRANSPORT_ERROR; - - rtsx_stor_get_xfer_buf(buf, len, srb); - scsi_set_resid(srb, scsi_bufflen(srb) - len); - - retval = rtsx_force_power_on(chip, SSC_PDCTL); - if (retval != STATUS_SUCCESS) { - vfree(buf); - set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); - return TRANSPORT_FAILED; - } - - for (i = 0; i < len; i++) { - retval = rtsx_write_register(chip, addr + i, 0xFF, buf[i]); - if (retval != STATUS_SUCCESS) { - vfree(buf); - set_sense_type(chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_WRITE_ERR); - return TRANSPORT_FAILED; - } - } - - vfree(buf); - - return TRANSPORT_GOOD; -} - -static int get_sd_csd(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &chip->sd_card; - unsigned int lun = SCSI_LUN(srb); - - if (!check_card_ready(chip, lun)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - return TRANSPORT_FAILED; - } - - if (get_lun_card(chip, lun) != SD_CARD) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - return TRANSPORT_FAILED; - } - - scsi_set_resid(srb, 0); - rtsx_stor_set_xfer_buf(sd_card->raw_csd, scsi_bufflen(srb), srb); - - return TRANSPORT_GOOD; -} - -static int toggle_gpio_cmd(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - u8 gpio = srb->cmnd[2]; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - if (gpio > 3) - gpio = 1; - toggle_gpio(chip, gpio); - - return TRANSPORT_GOOD; -} - -static int read_host_reg(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - u8 addr, buf[4]; - u32 val; - unsigned int len; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - addr = srb->cmnd[4]; - - val = rtsx_readl(chip, addr); - dev_dbg(rtsx_dev(chip), "Host register (0x%x): 0x%x\n", addr, val); - - buf[0] = (u8)(val >> 24); - buf[1] = (u8)(val >> 16); - buf[2] = (u8)(val >> 8); - buf[3] = (u8)val; - - len = min_t(unsigned int, scsi_bufflen(srb), 4); - rtsx_stor_set_xfer_buf(buf, len, srb); - scsi_set_resid(srb, scsi_bufflen(srb) - len); - - return TRANSPORT_GOOD; -} - -static int write_host_reg(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - u8 addr, buf[4]; - u32 val; - unsigned int len; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - addr = srb->cmnd[4]; - - len = min_t(unsigned int, scsi_bufflen(srb), 4); - rtsx_stor_get_xfer_buf(buf, len, srb); - scsi_set_resid(srb, scsi_bufflen(srb) - len); - - val = ((u32)buf[0] << 24) | ((u32)buf[1] << 16) | ((u32)buf[2] - << 8) | buf[3]; - - rtsx_writel(chip, addr, val); - - return TRANSPORT_GOOD; -} - -static int set_variable(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - unsigned int lun = SCSI_LUN(srb); - - if (srb->cmnd[3] == 1) { - /* Variable Clock */ - struct xd_info *xd_card = &chip->xd_card; - struct sd_info *sd_card = &chip->sd_card; - struct ms_info *ms_card = &chip->ms_card; - - switch (srb->cmnd[4]) { - case XD_CARD: - xd_card->xd_clock = srb->cmnd[5]; - break; - - case SD_CARD: - sd_card->sd_clock = srb->cmnd[5]; - break; - - case MS_CARD: - ms_card->ms_clock = srb->cmnd[5]; - break; - - default: - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - } else if (srb->cmnd[3] == 2) { - if (srb->cmnd[4]) { - chip->blink_led = 1; - } else { - int retval; - - chip->blink_led = 0; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && - (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - retval = rtsx_force_power_on(chip, SSC_PDCTL); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_WRITE_ERR); - return TRANSPORT_FAILED; - } - - turn_off_led(chip, LED_GPIO); - } - } else { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - - return TRANSPORT_GOOD; -} - -static int get_variable(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - unsigned int lun = SCSI_LUN(srb); - - if (srb->cmnd[3] == 1) { - struct xd_info *xd_card = &chip->xd_card; - struct sd_info *sd_card = &chip->sd_card; - struct ms_info *ms_card = &chip->ms_card; - u8 tmp; - - switch (srb->cmnd[4]) { - case XD_CARD: - tmp = (u8)(xd_card->xd_clock); - break; - - case SD_CARD: - tmp = (u8)(sd_card->sd_clock); - break; - - case MS_CARD: - tmp = (u8)(ms_card->ms_clock); - break; - - default: - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - - rtsx_stor_set_xfer_buf(&tmp, 1, srb); - } else if (srb->cmnd[3] == 2) { - u8 tmp = chip->blink_led; - - rtsx_stor_set_xfer_buf(&tmp, 1, srb); - } else { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - - return TRANSPORT_GOOD; -} - -static int dma_access_ring_buffer(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - int retval; - unsigned int lun = SCSI_LUN(srb); - u16 len; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - len = ((u16)(srb->cmnd[4]) << 8) | srb->cmnd[5]; - len = min_t(u16, len, scsi_bufflen(srb)); - - if (srb->sc_data_direction == DMA_FROM_DEVICE) - dev_dbg(rtsx_dev(chip), "Read from device\n"); - else - dev_dbg(rtsx_dev(chip), "Write to device\n"); - - retval = rtsx_transfer_data(chip, 0, scsi_sglist(srb), len, - scsi_sg_count(srb), srb->sc_data_direction, - 1000); - if (retval < 0) { - if (srb->sc_data_direction == DMA_FROM_DEVICE) - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - else - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_WRITE_ERR); - - return TRANSPORT_FAILED; - } - scsi_set_resid(srb, 0); - - return TRANSPORT_GOOD; -} - -static int get_dev_status(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &chip->sd_card; - struct ms_info *ms_card = &chip->ms_card; - int buf_len; - unsigned int lun = SCSI_LUN(srb); - u8 card = get_lun_card(chip, lun); - u8 status[32]; -#ifdef SUPPORT_OCP - u8 oc_now_mask = 0, oc_ever_mask = 0; -#endif - - memset(status, 0, 32); - - status[0] = (u8)(chip->product_id); - status[1] = chip->ic_version; - - if (chip->auto_delink_en) - status[2] = 0x10; - else - status[2] = 0x00; - - status[3] = 20; - status[4] = 10; - status[5] = 05; - status[6] = 21; - - if (chip->card_wp) - status[7] = 0x20; - else - status[7] = 0x00; - -#ifdef SUPPORT_OCP - status[8] = 0; - if (CHECK_LUN_MODE(chip, SD_MS_2LUN) && - chip->lun2card[lun] == MS_CARD) { - oc_now_mask = MS_OC_NOW; - oc_ever_mask = MS_OC_EVER; - } else { - oc_now_mask = SD_OC_NOW; - oc_ever_mask = SD_OC_EVER; - } - - if (chip->ocp_stat & oc_now_mask) - status[8] |= 0x02; - - if (chip->ocp_stat & oc_ever_mask) - status[8] |= 0x01; -#endif - - if (card == SD_CARD) { - if (CHK_SD(sd_card)) { - if (CHK_SD_HCXC(sd_card)) { - if (sd_card->capacity > 0x4000000) - status[0x0E] = 0x02; - else - status[0x0E] = 0x01; - } else { - status[0x0E] = 0x00; - } - - if (CHK_SD_SDR104(sd_card)) - status[0x0F] = 0x03; - else if (CHK_SD_DDR50(sd_card)) - status[0x0F] = 0x04; - else if (CHK_SD_SDR50(sd_card)) - status[0x0F] = 0x02; - else if (CHK_SD_HS(sd_card)) - status[0x0F] = 0x01; - else - status[0x0F] = 0x00; - } else { - if (CHK_MMC_SECTOR_MODE(sd_card)) - status[0x0E] = 0x01; - else - status[0x0E] = 0x00; - - if (CHK_MMC_DDR52(sd_card)) - status[0x0F] = 0x03; - else if (CHK_MMC_52M(sd_card)) - status[0x0F] = 0x02; - else if (CHK_MMC_26M(sd_card)) - status[0x0F] = 0x01; - else - status[0x0F] = 0x00; - } - } else if (card == MS_CARD) { - if (CHK_MSPRO(ms_card)) { - if (CHK_MSXC(ms_card)) - status[0x0E] = 0x01; - else - status[0x0E] = 0x00; - - if (CHK_HG8BIT(ms_card)) - status[0x0F] = 0x01; - else - status[0x0F] = 0x00; - } - } - -#ifdef SUPPORT_SD_LOCK - if (card == SD_CARD) { - status[0x17] = 0x80; - if (sd_card->sd_erase_status) - status[0x17] |= 0x01; - if (sd_card->sd_lock_status & SD_LOCKED) { - status[0x17] |= 0x02; - status[0x07] |= 0x40; - } - if (sd_card->sd_lock_status & SD_PWD_EXIST) - status[0x17] |= 0x04; - } else { - status[0x17] = 0x00; - } - - dev_dbg(rtsx_dev(chip), "status[0x17] = 0x%x\n", status[0x17]); -#endif - - status[0x18] = 0x8A; - status[0x1A] = 0x28; -#ifdef SUPPORT_SD_LOCK - status[0x1F] = 0x01; -#endif - - buf_len = min_t(unsigned int, scsi_bufflen(srb), sizeof(status)); - rtsx_stor_set_xfer_buf(status, buf_len, srb); - scsi_set_resid(srb, scsi_bufflen(srb) - buf_len); - - return TRANSPORT_GOOD; -} - -static int set_chip_mode(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - int phy_debug_mode; - int retval; - u16 reg; - - if (!CHECK_PID(chip, 0x5208)) { - set_sense_type(chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - - phy_debug_mode = (int)(srb->cmnd[3]); - - if (phy_debug_mode) { - chip->phy_debug_mode = 1; - retval = rtsx_write_register(chip, CDRESUMECTL, 0x77, 0); - if (retval != STATUS_SUCCESS) - return TRANSPORT_FAILED; - - rtsx_disable_bus_int(chip); - - retval = rtsx_read_phy_register(chip, 0x1C, ®); - if (retval != STATUS_SUCCESS) - return TRANSPORT_FAILED; - - reg |= 0x0001; - retval = rtsx_write_phy_register(chip, 0x1C, reg); - if (retval != STATUS_SUCCESS) - return TRANSPORT_FAILED; - } else { - chip->phy_debug_mode = 0; - retval = rtsx_write_register(chip, CDRESUMECTL, 0x77, 0x77); - if (retval != STATUS_SUCCESS) - return TRANSPORT_FAILED; - - rtsx_enable_bus_int(chip); - - retval = rtsx_read_phy_register(chip, 0x1C, ®); - if (retval != STATUS_SUCCESS) - return TRANSPORT_FAILED; - - reg &= 0xFFFE; - retval = rtsx_write_phy_register(chip, 0x1C, reg); - if (retval != STATUS_SUCCESS) - return TRANSPORT_FAILED; - } - - return TRANSPORT_GOOD; -} - -static int rw_mem_cmd_buf(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - int retval = STATUS_SUCCESS; - unsigned int lun = SCSI_LUN(srb); - u8 cmd_type, mask, value, idx; - u16 addr; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - switch (srb->cmnd[3]) { - case INIT_BATCHCMD: - rtsx_init_cmd(chip); - break; - - case ADD_BATCHCMD: - cmd_type = srb->cmnd[4]; - if (cmd_type > 2) { - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - addr = (srb->cmnd[5] << 8) | srb->cmnd[6]; - mask = srb->cmnd[7]; - value = srb->cmnd[8]; - rtsx_add_cmd(chip, cmd_type, addr, mask, value); - break; - - case SEND_BATCHCMD: - retval = rtsx_send_cmd(chip, 0, 1000); - break; - - case GET_BATCHRSP: - idx = srb->cmnd[4]; - value = *(rtsx_get_cmd_data(chip) + idx); - if (scsi_bufflen(srb) < 1) { - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - rtsx_stor_set_xfer_buf(&value, 1, srb); - scsi_set_resid(srb, 0); - break; - - default: - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); - return TRANSPORT_FAILED; - } - - return TRANSPORT_GOOD; -} - -static int suit_cmd(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - switch (srb->cmnd[3]) { - case INIT_BATCHCMD: - case ADD_BATCHCMD: - case SEND_BATCHCMD: - case GET_BATCHRSP: - return rw_mem_cmd_buf(srb, chip); - default: - return TRANSPORT_ERROR; - } -} - -static int read_phy_register(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - unsigned short addr, len, i; - int retval; - u8 *buf; - u16 val; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - addr = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5]; - len = ((u16)srb->cmnd[6] << 8) | srb->cmnd[7]; - - if (len % 2) - len -= len % 2; - - if (len) { - buf = vmalloc(len); - if (!buf) - return TRANSPORT_ERROR; - - retval = rtsx_force_power_on(chip, SSC_PDCTL); - if (retval != STATUS_SUCCESS) { - vfree(buf); - set_sense_type(chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - return TRANSPORT_FAILED; - } - - for (i = 0; i < len / 2; i++) { - retval = rtsx_read_phy_register(chip, addr + i, &val); - if (retval != STATUS_SUCCESS) { - vfree(buf); - set_sense_type - (chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - return TRANSPORT_FAILED; - } - - buf[2 * i] = (u8)(val >> 8); - buf[2 * i + 1] = (u8)val; - } - - len = (unsigned short)min_t(unsigned int, scsi_bufflen(srb), - len); - rtsx_stor_set_xfer_buf(buf, len, srb); - scsi_set_resid(srb, scsi_bufflen(srb) - len); - - vfree(buf); - } - - return TRANSPORT_GOOD; -} - -static int write_phy_register(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - unsigned short addr, len, i; - int retval; - u8 *buf; - u16 val; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - addr = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5]; - len = ((u16)srb->cmnd[6] << 8) | srb->cmnd[7]; - - if (len % 2) - len -= len % 2; - - if (len) { - len = (unsigned short)min_t(unsigned int, scsi_bufflen(srb), - len); - - buf = vmalloc(len); - if (!buf) - return TRANSPORT_ERROR; - - rtsx_stor_get_xfer_buf(buf, len, srb); - scsi_set_resid(srb, scsi_bufflen(srb) - len); - - retval = rtsx_force_power_on(chip, SSC_PDCTL); - if (retval != STATUS_SUCCESS) { - vfree(buf); - set_sense_type(chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_WRITE_ERR); - return TRANSPORT_FAILED; - } - - for (i = 0; i < len / 2; i++) { - val = ((u16)buf[2 * i] << 8) | buf[2 * i + 1]; - retval = rtsx_write_phy_register(chip, addr + i, val); - if (retval != STATUS_SUCCESS) { - vfree(buf); - set_sense_type(chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_WRITE_ERR); - return TRANSPORT_FAILED; - } - } - - vfree(buf); - } - - return TRANSPORT_GOOD; -} - -static int erase_eeprom2(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - unsigned short addr; - int retval; - u8 mode; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - retval = rtsx_force_power_on(chip, SSC_PDCTL); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); - return TRANSPORT_FAILED; - } - - mode = srb->cmnd[3]; - addr = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5]; - - if (mode == 0) { - retval = spi_erase_eeprom_chip(chip); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_WRITE_ERR); - return TRANSPORT_FAILED; - } - } else if (mode == 1) { - retval = spi_erase_eeprom_byte(chip, addr); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_WRITE_ERR); - return TRANSPORT_FAILED; - } - } else { - set_sense_type(chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - - return TRANSPORT_GOOD; -} - -static int read_eeprom2(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - unsigned short addr, len, i; - int retval; - u8 *buf; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - addr = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5]; - len = ((u16)srb->cmnd[6] << 8) | srb->cmnd[7]; - - buf = vmalloc(len); - if (!buf) - return TRANSPORT_ERROR; - - retval = rtsx_force_power_on(chip, SSC_PDCTL); - if (retval != STATUS_SUCCESS) { - vfree(buf); - set_sense_type(chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - return TRANSPORT_FAILED; - } - - for (i = 0; i < len; i++) { - retval = spi_read_eeprom(chip, addr + i, buf + i); - if (retval != STATUS_SUCCESS) { - vfree(buf); - set_sense_type(chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - return TRANSPORT_FAILED; - } - } - - len = (unsigned short)min_t(unsigned int, scsi_bufflen(srb), len); - rtsx_stor_set_xfer_buf(buf, len, srb); - scsi_set_resid(srb, scsi_bufflen(srb) - len); - - vfree(buf); - - return TRANSPORT_GOOD; -} - -static int write_eeprom2(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - unsigned short addr, len, i; - int retval; - u8 *buf; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - addr = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5]; - len = ((u16)srb->cmnd[6] << 8) | srb->cmnd[7]; - - len = (unsigned short)min_t(unsigned int, scsi_bufflen(srb), len); - buf = vmalloc(len); - if (!buf) - return TRANSPORT_ERROR; - - rtsx_stor_get_xfer_buf(buf, len, srb); - scsi_set_resid(srb, scsi_bufflen(srb) - len); - - retval = rtsx_force_power_on(chip, SSC_PDCTL); - if (retval != STATUS_SUCCESS) { - vfree(buf); - set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); - return TRANSPORT_FAILED; - } - - for (i = 0; i < len; i++) { - retval = spi_write_eeprom(chip, addr + i, buf[i]); - if (retval != STATUS_SUCCESS) { - vfree(buf); - set_sense_type(chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_WRITE_ERR); - return TRANSPORT_FAILED; - } - } - - vfree(buf); - - return TRANSPORT_GOOD; -} - -static int read_efuse(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - int retval; - u8 addr, len, i; - u8 *buf; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - addr = srb->cmnd[4]; - len = srb->cmnd[5]; - - buf = vmalloc(len); - if (!buf) - return TRANSPORT_ERROR; - - retval = rtsx_force_power_on(chip, SSC_PDCTL); - if (retval != STATUS_SUCCESS) { - vfree(buf); - set_sense_type(chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - return TRANSPORT_FAILED; - } - - for (i = 0; i < len; i++) { - retval = rtsx_read_efuse(chip, addr + i, buf + i); - if (retval != STATUS_SUCCESS) { - vfree(buf); - set_sense_type(chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - return TRANSPORT_FAILED; - } - } - - len = (u8)min_t(unsigned int, scsi_bufflen(srb), len); - rtsx_stor_set_xfer_buf(buf, len, srb); - scsi_set_resid(srb, scsi_bufflen(srb) - len); - - vfree(buf); - - return TRANSPORT_GOOD; -} - -static int write_efuse(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - int retval, result = TRANSPORT_GOOD; - u16 val; - u8 addr, len, i; - u8 *buf; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - addr = srb->cmnd[4]; - len = srb->cmnd[5]; - - len = (u8)min_t(unsigned int, scsi_bufflen(srb), len); - buf = vmalloc(len); - if (!buf) - return TRANSPORT_ERROR; - - rtsx_stor_get_xfer_buf(buf, len, srb); - scsi_set_resid(srb, scsi_bufflen(srb) - len); - - retval = rtsx_force_power_on(chip, SSC_PDCTL); - if (retval != STATUS_SUCCESS) { - vfree(buf); - return TRANSPORT_ERROR; - } - - if (chip->asic_code) { - retval = rtsx_read_phy_register(chip, 0x08, &val); - if (retval != STATUS_SUCCESS) { - vfree(buf); - return TRANSPORT_ERROR; - } - - retval = rtsx_write_register(chip, PWR_GATE_CTRL, - LDO3318_PWR_MASK, LDO_OFF); - if (retval != STATUS_SUCCESS) { - vfree(buf); - return TRANSPORT_ERROR; - } - - wait_timeout(600); - - retval = rtsx_write_phy_register(chip, 0x08, - 0x4C00 | chip->phy_voltage); - if (retval != STATUS_SUCCESS) { - vfree(buf); - return TRANSPORT_ERROR; - } - - retval = rtsx_write_register(chip, PWR_GATE_CTRL, - LDO3318_PWR_MASK, LDO_ON); - if (retval != STATUS_SUCCESS) { - vfree(buf); - return TRANSPORT_ERROR; - } - - wait_timeout(600); - } - - retval = card_power_on(chip, SPI_CARD); - if (retval != STATUS_SUCCESS) { - vfree(buf); - return TRANSPORT_ERROR; - } - - wait_timeout(50); - - for (i = 0; i < len; i++) { - retval = rtsx_write_efuse(chip, addr + i, buf[i]); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_WRITE_ERR); - result = TRANSPORT_FAILED; - goto exit; - } - } - -exit: - vfree(buf); - - retval = card_power_off(chip, SPI_CARD); - if (retval != STATUS_SUCCESS) - return TRANSPORT_ERROR; - - if (chip->asic_code) { - retval = rtsx_write_register(chip, PWR_GATE_CTRL, - LDO3318_PWR_MASK, LDO_OFF); - if (retval != STATUS_SUCCESS) - return TRANSPORT_ERROR; - - wait_timeout(600); - - retval = rtsx_write_phy_register(chip, 0x08, val); - if (retval != STATUS_SUCCESS) - return TRANSPORT_ERROR; - - retval = rtsx_write_register(chip, PWR_GATE_CTRL, - LDO3318_PWR_MASK, LDO_ON); - if (retval != STATUS_SUCCESS) - return TRANSPORT_ERROR; - } - - return result; -} - -static int read_cfg_byte(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - int retval; - bool func_max; - u8 func; - u16 addr, len; - u8 *buf; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - func = srb->cmnd[3]; - addr = ((u16)(srb->cmnd[4]) << 8) | srb->cmnd[5]; - len = ((u16)(srb->cmnd[6]) << 8) | srb->cmnd[7]; - - dev_dbg(rtsx_dev(chip), "%s: func = %d, addr = 0x%x, len = %d\n", - __func__, func, addr, len); - - if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip)) - func_max = true; - else - func_max = false; - - if (func > func_max) { - set_sense_type(chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - - buf = vmalloc(len); - if (!buf) - return TRANSPORT_ERROR; - - retval = rtsx_read_cfg_seq(chip, func, addr, buf, len); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - vfree(buf); - return TRANSPORT_FAILED; - } - - len = (u16)min_t(unsigned int, scsi_bufflen(srb), len); - rtsx_stor_set_xfer_buf(buf, len, srb); - scsi_set_resid(srb, scsi_bufflen(srb) - len); - - vfree(buf); - - return TRANSPORT_GOOD; -} - -static int write_cfg_byte(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - int retval; - bool func_max; - u8 func; - u16 addr, len; - u8 *buf; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - func = srb->cmnd[3]; - addr = ((u16)(srb->cmnd[4]) << 8) | srb->cmnd[5]; - len = ((u16)(srb->cmnd[6]) << 8) | srb->cmnd[7]; - - dev_dbg(rtsx_dev(chip), "%s: func = %d, addr = 0x%x\n", - __func__, func, addr); - - if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip)) - func_max = true; - else - func_max = false; - - if (func > func_max) { - set_sense_type(chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - - len = (unsigned short)min_t(unsigned int, scsi_bufflen(srb), len); - buf = vmalloc(len); - if (!buf) - return TRANSPORT_ERROR; - - rtsx_stor_get_xfer_buf(buf, len, srb); - scsi_set_resid(srb, scsi_bufflen(srb) - len); - - retval = rtsx_write_cfg_seq(chip, func, addr, buf, len); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); - vfree(buf); - return TRANSPORT_FAILED; - } - - vfree(buf); - - return TRANSPORT_GOOD; -} - -static int app_cmd(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - int result; - - switch (srb->cmnd[2]) { - case PP_READ10: - case PP_WRITE10: - result = read_write(srb, chip); - break; - - case READ_HOST_REG: - result = read_host_reg(srb, chip); - break; - - case WRITE_HOST_REG: - result = write_host_reg(srb, chip); - break; - - case GET_VAR: - result = get_variable(srb, chip); - break; - - case SET_VAR: - result = set_variable(srb, chip); - break; - - case DMA_READ: - case DMA_WRITE: - result = dma_access_ring_buffer(srb, chip); - break; - - case READ_PHY: - result = read_phy_register(srb, chip); - break; - - case WRITE_PHY: - result = write_phy_register(srb, chip); - break; - - case ERASE_EEPROM2: - result = erase_eeprom2(srb, chip); - break; - - case READ_EEPROM2: - result = read_eeprom2(srb, chip); - break; - - case WRITE_EEPROM2: - result = write_eeprom2(srb, chip); - break; - - case READ_EFUSE: - result = read_efuse(srb, chip); - break; - - case WRITE_EFUSE: - result = write_efuse(srb, chip); - break; - - case READ_CFG: - result = read_cfg_byte(srb, chip); - break; - - case WRITE_CFG: - result = write_cfg_byte(srb, chip); - break; - - case SET_CHIP_MODE: - result = set_chip_mode(srb, chip); - break; - - case SUIT_CMD: - result = suit_cmd(srb, chip); - break; - - case GET_DEV_STATUS: - result = get_dev_status(srb, chip); - break; - - default: - set_sense_type(chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - - return result; -} - -static int read_status(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - u8 rtsx_status[16]; - int buf_len; - unsigned int lun = SCSI_LUN(srb); - - rtsx_status[0] = (u8)(chip->vendor_id >> 8); - rtsx_status[1] = (u8)(chip->vendor_id); - - rtsx_status[2] = (u8)(chip->product_id >> 8); - rtsx_status[3] = (u8)(chip->product_id); - - rtsx_status[4] = (u8)lun; - - if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) { - if (chip->lun2card[lun] == SD_CARD) - rtsx_status[5] = 2; - else - rtsx_status[5] = 3; - } else { - if (chip->card_exist) { - if (chip->card_exist & XD_CARD) - rtsx_status[5] = 4; - else if (chip->card_exist & SD_CARD) - rtsx_status[5] = 2; - else if (chip->card_exist & MS_CARD) - rtsx_status[5] = 3; - else - rtsx_status[5] = 7; - } else { - rtsx_status[5] = 7; - } - } - - if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) - rtsx_status[6] = 2; - else - rtsx_status[6] = 1; - - rtsx_status[7] = (u8)(chip->product_id); - rtsx_status[8] = chip->ic_version; - - if (check_card_exist(chip, lun)) - rtsx_status[9] = 1; - else - rtsx_status[9] = 0; - - if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) - rtsx_status[10] = 0; - else - rtsx_status[10] = 1; - - if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) { - if (chip->lun2card[lun] == SD_CARD) - rtsx_status[11] = SD_CARD; - else - rtsx_status[11] = MS_CARD; - } else { - rtsx_status[11] = XD_CARD | SD_CARD | MS_CARD; - } - - if (check_card_ready(chip, lun)) - rtsx_status[12] = 1; - else - rtsx_status[12] = 0; - - if (get_lun_card(chip, lun) == XD_CARD) { - rtsx_status[13] = 0x40; - } else if (get_lun_card(chip, lun) == SD_CARD) { - struct sd_info *sd_card = &chip->sd_card; - - rtsx_status[13] = 0x20; - if (CHK_SD(sd_card)) { - if (CHK_SD_HCXC(sd_card)) - rtsx_status[13] |= 0x04; - if (CHK_SD_HS(sd_card)) - rtsx_status[13] |= 0x02; - } else { - rtsx_status[13] |= 0x08; - if (CHK_MMC_52M(sd_card)) - rtsx_status[13] |= 0x02; - if (CHK_MMC_SECTOR_MODE(sd_card)) - rtsx_status[13] |= 0x04; - } - } else if (get_lun_card(chip, lun) == MS_CARD) { - struct ms_info *ms_card = &chip->ms_card; - - if (CHK_MSPRO(ms_card)) { - rtsx_status[13] = 0x38; - if (CHK_HG8BIT(ms_card)) - rtsx_status[13] |= 0x04; -#ifdef SUPPORT_MSXC - if (CHK_MSXC(ms_card)) - rtsx_status[13] |= 0x01; -#endif - } else { - rtsx_status[13] = 0x30; - } - } else { - if (CHECK_LUN_MODE(chip, DEFAULT_SINGLE)) { -#ifdef SUPPORT_SDIO - if (chip->sd_io && chip->sd_int) - rtsx_status[13] = 0x60; - else - rtsx_status[13] = 0x70; -#else - rtsx_status[13] = 0x70; -#endif - } else { - if (chip->lun2card[lun] == SD_CARD) - rtsx_status[13] = 0x20; - else - rtsx_status[13] = 0x30; - } - } - - rtsx_status[14] = 0x78; - if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip)) - rtsx_status[15] = 0x83; - else - rtsx_status[15] = 0x82; - - buf_len = min_t(unsigned int, scsi_bufflen(srb), sizeof(rtsx_status)); - rtsx_stor_set_xfer_buf(rtsx_status, buf_len, srb); - scsi_set_resid(srb, scsi_bufflen(srb) - buf_len); - - return TRANSPORT_GOOD; -} - -static int get_card_bus_width(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - unsigned int lun = SCSI_LUN(srb); - u8 card, bus_width; - - if (!check_card_ready(chip, lun)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - return TRANSPORT_FAILED; - } - - card = get_lun_card(chip, lun); - if (card == SD_CARD || card == MS_CARD) { - bus_width = chip->card_bus_width[lun]; - } else { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - return TRANSPORT_FAILED; - } - - scsi_set_resid(srb, 0); - rtsx_stor_set_xfer_buf(&bus_width, scsi_bufflen(srb), srb); - - return TRANSPORT_GOOD; -} - -static int spi_vendor_cmd(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - int result; - unsigned int lun = SCSI_LUN(srb); - u8 gpio_dir; - - if (CHECK_PID(chip, 0x5208) || CHECK_PID(chip, 0x5288)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - rtsx_force_power_on(chip, SSC_PDCTL); - - rtsx_read_register(chip, CARD_GPIO_DIR, &gpio_dir); - rtsx_write_register(chip, CARD_GPIO_DIR, 0x07, gpio_dir & 0x06); - - switch (srb->cmnd[2]) { - case SCSI_SPI_GETSTATUS: - result = spi_get_status(srb, chip); - break; - - case SCSI_SPI_SETPARAMETER: - result = spi_set_parameter(srb, chip); - break; - - case SCSI_SPI_READFALSHID: - result = spi_read_flash_id(srb, chip); - break; - - case SCSI_SPI_READFLASH: - result = spi_read_flash(srb, chip); - break; - - case SCSI_SPI_WRITEFLASH: - result = spi_write_flash(srb, chip); - break; - - case SCSI_SPI_WRITEFLASHSTATUS: - result = spi_write_flash_status(srb, chip); - break; - - case SCSI_SPI_ERASEFLASH: - result = spi_erase_flash(srb, chip); - break; - - default: - rtsx_write_register(chip, CARD_GPIO_DIR, 0x07, gpio_dir); - - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - - rtsx_write_register(chip, CARD_GPIO_DIR, 0x07, gpio_dir); - - if (result != STATUS_SUCCESS) - return TRANSPORT_FAILED; - - return TRANSPORT_GOOD; -} - -static int vendor_cmnd(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - int result; - - switch (srb->cmnd[1]) { - case READ_STATUS: - result = read_status(srb, chip); - break; - - case READ_MEM: - result = read_mem(srb, chip); - break; - - case WRITE_MEM: - result = write_mem(srb, chip); - break; - - case READ_EEPROM: - result = read_eeprom(srb, chip); - break; - - case WRITE_EEPROM: - result = write_eeprom(srb, chip); - break; - - case TOGGLE_GPIO: - result = toggle_gpio_cmd(srb, chip); - break; - - case GET_SD_CSD: - result = get_sd_csd(srb, chip); - break; - - case GET_BUS_WIDTH: - result = get_card_bus_width(srb, chip); - break; - - case SCSI_APP_CMD: - result = app_cmd(srb, chip); - break; - - case SPI_VENDOR_COMMAND: - result = spi_vendor_cmd(srb, chip); - break; - - default: - set_sense_type(chip, SCSI_LUN(srb), - SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - - return result; -} - -#if !defined(LED_AUTO_BLINK) && !defined(REGULAR_BLINK) -void led_shine(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - unsigned int lun = SCSI_LUN(srb); - u16 sec_cnt; - - if (srb->cmnd[0] == READ_10 || srb->cmnd[0] == WRITE_10) { - sec_cnt = ((u16)(srb->cmnd[7]) << 8) | srb->cmnd[8]; - } else if ((srb->cmnd[0] == READ_6) || (srb->cmnd[0] == WRITE_6)) { - sec_cnt = srb->cmnd[4]; - if (sec_cnt == 0) - sec_cnt = 256; - } else { - return; - } - - if (chip->rw_cap[lun] >= GPIO_TOGGLE_THRESHOLD) { - toggle_gpio(chip, LED_GPIO); - chip->rw_cap[lun] = 0; - } else { - chip->rw_cap[lun] += sec_cnt; - } -} -#endif - -static int ms_format_cmnd(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &chip->ms_card; - unsigned int lun = SCSI_LUN(srb); - bool quick_format; - int retval; - - if (get_lun_card(chip, lun) != MS_CARD) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT); - return TRANSPORT_FAILED; - } - - if (srb->cmnd[3] != 0x4D || srb->cmnd[4] != 0x47 || - srb->cmnd[5] != 0x66 || srb->cmnd[6] != 0x6D || - srb->cmnd[7] != 0x74) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - - if (!check_card_ready(chip, lun) || - (get_card_size(chip, lun) == 0)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - return TRANSPORT_FAILED; - } - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - if (srb->cmnd[8] & 0x01) - quick_format = false; - else - quick_format = true; - - if (!(chip->card_ready & MS_CARD)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - return TRANSPORT_FAILED; - } - - if (chip->card_wp & MS_CARD) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_PROTECT); - return TRANSPORT_FAILED; - } - - if (!CHK_MSPRO(ms_card)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT); - return TRANSPORT_FAILED; - } - - retval = mspro_format(srb, chip, MS_SHORT_DATA_LEN, quick_format); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_FORMAT_CMD_FAILED); - return TRANSPORT_FAILED; - } - - scsi_set_resid(srb, 0); - return TRANSPORT_GOOD; -} - -#ifdef SUPPORT_PCGL_1P18 -static int get_ms_information(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &chip->ms_card; - unsigned int lun = SCSI_LUN(srb); - u8 dev_info_id, data_len; - u8 *buf; - unsigned int buf_len; - int i; - - if (!check_card_ready(chip, lun)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - return TRANSPORT_FAILED; - } - if (get_lun_card(chip, lun) != MS_CARD) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT); - return TRANSPORT_FAILED; - } - - if (srb->cmnd[2] != 0xB0 || srb->cmnd[4] != 0x4D || - srb->cmnd[5] != 0x53 || srb->cmnd[6] != 0x49 || - srb->cmnd[7] != 0x44) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - - dev_info_id = srb->cmnd[3]; - if ((CHK_MSXC(ms_card) && dev_info_id == 0x10) || - (!CHK_MSXC(ms_card) && dev_info_id == 0x13) || - !CHK_MSPRO(ms_card)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - - if (dev_info_id == 0x15) { - buf_len = 0x3C; - data_len = 0x3A; - } else { - buf_len = 0x6C; - data_len = 0x6A; - } - - buf = kmalloc(buf_len, GFP_KERNEL); - if (!buf) - return TRANSPORT_ERROR; - - i = 0; - /* GET Memory Stick Media Information Response Header */ - buf[i++] = 0x00; /* Data length MSB */ - buf[i++] = data_len; /* Data length LSB */ - /* Device Information Type Code */ - if (CHK_MSXC(ms_card)) - buf[i++] = 0x03; - else - buf[i++] = 0x02; - - /* SGM bit */ - buf[i++] = 0x01; - /* Reserved */ - buf[i++] = 0x00; - buf[i++] = 0x00; - buf[i++] = 0x00; - /* Number of Device Information */ - buf[i++] = 0x01; - - /* Device Information Body */ - - /* Device Information ID Number */ - buf[i++] = dev_info_id; - /* Device Information Length */ - if (dev_info_id == 0x15) - data_len = 0x31; - else - data_len = 0x61; - - buf[i++] = 0x00; /* Data length MSB */ - buf[i++] = data_len; /* Data length LSB */ - /* Valid Bit */ - buf[i++] = 0x80; - if (dev_info_id == 0x10 || dev_info_id == 0x13) { - /* System Information */ - memcpy(buf + i, ms_card->raw_sys_info, 96); - } else { - /* Model Name */ - memcpy(buf + i, ms_card->raw_model_name, 48); - } - - rtsx_stor_set_xfer_buf(buf, buf_len, srb); - scsi_set_resid(srb, scsi_bufflen(srb) - buf_len); - - kfree(buf); - return STATUS_SUCCESS; -} -#endif - -static int ms_sp_cmnd(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - int retval = TRANSPORT_ERROR; - - if (srb->cmnd[2] == MS_FORMAT) - retval = ms_format_cmnd(srb, chip); -#ifdef SUPPORT_PCGL_1P18 - else if (srb->cmnd[2] == GET_MS_INFORMATION) - retval = get_ms_information(srb, chip); -#endif - - return retval; -} - -#ifdef SUPPORT_CPRM -static int sd_extension_cmnd(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - unsigned int lun = SCSI_LUN(srb); - int result; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - sd_cleanup_work(chip); - - if (!check_card_ready(chip, lun)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - return TRANSPORT_FAILED; - } - if (get_lun_card(chip, lun) != SD_CARD) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT); - return TRANSPORT_FAILED; - } - - switch (srb->cmnd[0]) { - case SD_PASS_THRU_MODE: - result = sd_pass_thru_mode(srb, chip); - break; - - case SD_EXECUTE_NO_DATA: - result = sd_execute_no_data(srb, chip); - break; - - case SD_EXECUTE_READ: - result = sd_execute_read_data(srb, chip); - break; - - case SD_EXECUTE_WRITE: - result = sd_execute_write_data(srb, chip); - break; - - case SD_GET_RSP: - result = sd_get_cmd_rsp(srb, chip); - break; - - case SD_HW_RST: - result = sd_hw_rst(srb, chip); - break; - - default: - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - - return result; -} -#endif - -#ifdef SUPPORT_MAGIC_GATE -static int mg_report_key(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &chip->ms_card; - unsigned int lun = SCSI_LUN(srb); - int retval; - u8 key_format; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - ms_cleanup_work(chip); - - if (!check_card_ready(chip, lun)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - return TRANSPORT_FAILED; - } - if (get_lun_card(chip, lun) != MS_CARD) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT); - return TRANSPORT_FAILED; - } - - if (srb->cmnd[7] != KC_MG_R_PRO) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - - if (!CHK_MSPRO(ms_card)) { - set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); - return TRANSPORT_FAILED; - } - - key_format = srb->cmnd[10] & 0x3F; - dev_dbg(rtsx_dev(chip), "key_format = 0x%x\n", key_format); - - switch (key_format) { - case KF_GET_LOC_EKB: - if ((scsi_bufflen(srb) == 0x41C) && - srb->cmnd[8] == 0x04 && - srb->cmnd[9] == 0x1C) { - retval = mg_get_local_EKB(srb, chip); - if (retval != STATUS_SUCCESS) - return TRANSPORT_FAILED; - - } else { - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - break; - - case KF_RSP_CHG: - if ((scsi_bufflen(srb) == 0x24) && - srb->cmnd[8] == 0x00 && - srb->cmnd[9] == 0x24) { - retval = mg_get_rsp_chg(srb, chip); - if (retval != STATUS_SUCCESS) - return TRANSPORT_FAILED; - - } else { - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - break; - - case KF_GET_ICV: - ms_card->mg_entry_num = srb->cmnd[5]; - if ((scsi_bufflen(srb) == 0x404) && - srb->cmnd[8] == 0x04 && - srb->cmnd[9] == 0x04 && - srb->cmnd[2] == 0x00 && - srb->cmnd[3] == 0x00 && - srb->cmnd[4] == 0x00 && - srb->cmnd[5] < 32) { - retval = mg_get_ICV(srb, chip); - if (retval != STATUS_SUCCESS) - return TRANSPORT_FAILED; - - } else { - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - break; - - default: - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - - scsi_set_resid(srb, 0); - return TRANSPORT_GOOD; -} - -static int mg_send_key(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &chip->ms_card; - unsigned int lun = SCSI_LUN(srb); - int retval; - u8 key_format; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - ms_cleanup_work(chip); - - if (!check_card_ready(chip, lun)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - return TRANSPORT_FAILED; - } - if (check_card_wp(chip, lun)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_PROTECT); - return TRANSPORT_FAILED; - } - if (get_lun_card(chip, lun) != MS_CARD) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT); - return TRANSPORT_FAILED; - } - - if (srb->cmnd[7] != KC_MG_R_PRO) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - - if (!CHK_MSPRO(ms_card)) { - set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); - return TRANSPORT_FAILED; - } - - key_format = srb->cmnd[10] & 0x3F; - dev_dbg(rtsx_dev(chip), "key_format = 0x%x\n", key_format); - - switch (key_format) { - case KF_SET_LEAF_ID: - if ((scsi_bufflen(srb) == 0x0C) && - srb->cmnd[8] == 0x00 && - srb->cmnd[9] == 0x0C) { - retval = mg_set_leaf_id(srb, chip); - if (retval != STATUS_SUCCESS) - return TRANSPORT_FAILED; - - } else { - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - break; - - case KF_CHG_HOST: - if ((scsi_bufflen(srb) == 0x0C) && - srb->cmnd[8] == 0x00 && - srb->cmnd[9] == 0x0C) { - retval = mg_chg(srb, chip); - if (retval != STATUS_SUCCESS) - return TRANSPORT_FAILED; - - } else { - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - break; - - case KF_RSP_HOST: - if ((scsi_bufflen(srb) == 0x0C) && - srb->cmnd[8] == 0x00 && - srb->cmnd[9] == 0x0C) { - retval = mg_rsp(srb, chip); - if (retval != STATUS_SUCCESS) - return TRANSPORT_FAILED; - - } else { - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - break; - - case KF_SET_ICV: - ms_card->mg_entry_num = srb->cmnd[5]; - if ((scsi_bufflen(srb) == 0x404) && - srb->cmnd[8] == 0x04 && - srb->cmnd[9] == 0x04 && - srb->cmnd[2] == 0x00 && - srb->cmnd[3] == 0x00 && - srb->cmnd[4] == 0x00 && - srb->cmnd[5] < 32) { - retval = mg_set_ICV(srb, chip); - if (retval != STATUS_SUCCESS) - return TRANSPORT_FAILED; - - } else { - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - break; - - default: - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - - scsi_set_resid(srb, 0); - return TRANSPORT_GOOD; -} -#endif - -int rtsx_scsi_handler(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ -#ifdef SUPPORT_SD_LOCK - struct sd_info *sd_card = &chip->sd_card; -#endif - struct ms_info *ms_card = &chip->ms_card; - unsigned int lun = SCSI_LUN(srb); - int result; - -#ifdef SUPPORT_SD_LOCK - if (sd_card->sd_erase_status) { - /* Block all SCSI command except for - * REQUEST_SENSE and rs_ppstatus - */ - if (!(srb->cmnd[0] == VENDOR_CMND && - srb->cmnd[1] == SCSI_APP_CMD && - srb->cmnd[2] == GET_DEV_STATUS) && - srb->cmnd[0] != REQUEST_SENSE) { - /* Logical Unit Not Ready Format in Progress */ - set_sense_data(chip, lun, CUR_ERR, - 0x02, 0, 0x04, 0x04, 0, 0); - return TRANSPORT_FAILED; - } - } -#endif - - if ((get_lun_card(chip, lun) == MS_CARD) && - ms_card->format_status == FORMAT_IN_PROGRESS) { - if (srb->cmnd[0] != REQUEST_SENSE && - srb->cmnd[0] != INQUIRY) { - /* Logical Unit Not Ready Format in Progress */ - set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x04, 0x04, - 0, (u16)(ms_card->progress)); - return TRANSPORT_FAILED; - } - } - - switch (srb->cmnd[0]) { - case READ_10: - case WRITE_10: - case READ_6: - case WRITE_6: - result = read_write(srb, chip); -#if !defined(LED_AUTO_BLINK) && !defined(REGULAR_BLINK) - led_shine(srb, chip); -#endif - break; - - case TEST_UNIT_READY: - result = test_unit_ready(srb, chip); - break; - - case INQUIRY: - result = inquiry(srb, chip); - break; - - case READ_CAPACITY: - result = read_capacity(srb, chip); - break; - - case START_STOP: - result = start_stop_unit(srb, chip); - break; - - case ALLOW_MEDIUM_REMOVAL: - result = allow_medium_removal(srb, chip); - break; - - case REQUEST_SENSE: - result = request_sense(srb, chip); - break; - - case MODE_SENSE: - case MODE_SENSE_10: - result = mode_sense(srb, chip); - break; - - case 0x23: - result = read_format_capacity(srb, chip); - break; - - case VENDOR_CMND: - result = vendor_cmnd(srb, chip); - break; - - case MS_SP_CMND: - result = ms_sp_cmnd(srb, chip); - break; - -#ifdef SUPPORT_CPRM - case SD_PASS_THRU_MODE: - case SD_EXECUTE_NO_DATA: - case SD_EXECUTE_READ: - case SD_EXECUTE_WRITE: - case SD_GET_RSP: - case SD_HW_RST: - result = sd_extension_cmnd(srb, chip); - break; -#endif - -#ifdef SUPPORT_MAGIC_GATE - case CMD_MSPRO_MG_RKEY: - result = mg_report_key(srb, chip); - break; - - case CMD_MSPRO_MG_SKEY: - result = mg_send_key(srb, chip); - break; -#endif - - case FORMAT_UNIT: - case MODE_SELECT: - case VERIFY: - result = TRANSPORT_GOOD; - break; - - default: - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - result = TRANSPORT_FAILED; - } - - return result; -} diff --git a/drivers/staging/rts5208/rtsx_scsi.h b/drivers/staging/rts5208/rtsx_scsi.h deleted file mode 100644 index df6138c97aaa..000000000000 --- a/drivers/staging/rts5208/rtsx_scsi.h +++ /dev/null @@ -1,131 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Driver for Realtek PCI-Express card reader - * - * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. - * - * Author: - * Wei WANG (wei_wang@xxxxxxxxxxxxxx) - * Micky Ching (micky_ching@xxxxxxxxxxxxxx) - */ - -#ifndef __REALTEK_RTSX_SCSI_H -#define __REALTEK_RTSX_SCSI_H - -#include "rtsx.h" -#include "rtsx_chip.h" - -#define MS_SP_CMND 0xFA -#define MS_FORMAT 0xA0 -#define GET_MS_INFORMATION 0xB0 - -#define VENDOR_CMND 0xF0 - -#define READ_STATUS 0x09 - -#define READ_EEPROM 0x04 -#define WRITE_EEPROM 0x05 -#define READ_MEM 0x0D -#define WRITE_MEM 0x0E -#define GET_BUS_WIDTH 0x13 -#define GET_SD_CSD 0x14 -#define TOGGLE_GPIO 0x15 -#define TRACE_MSG 0x18 - -#define SCSI_APP_CMD 0x10 - -#define PP_READ10 0x1A -#define PP_WRITE10 0x0A -#define READ_HOST_REG 0x1D -#define WRITE_HOST_REG 0x0D -#define SET_VAR 0x05 -#define GET_VAR 0x15 -#define DMA_READ 0x16 -#define DMA_WRITE 0x06 -#define GET_DEV_STATUS 0x10 -#define SET_CHIP_MODE 0x27 -#define SUIT_CMD 0xE0 -#define WRITE_PHY 0x07 -#define READ_PHY 0x17 -#define WRITE_EEPROM2 0x03 -#define READ_EEPROM2 0x13 -#define ERASE_EEPROM2 0x23 -#define WRITE_EFUSE 0x04 -#define READ_EFUSE 0x14 -#define WRITE_CFG 0x0E -#define READ_CFG 0x1E - -#define SPI_VENDOR_COMMAND 0x1C - -#define SCSI_SPI_GETSTATUS 0x00 -#define SCSI_SPI_SETPARAMETER 0x01 -#define SCSI_SPI_READFALSHID 0x02 -#define SCSI_SPI_READFLASH 0x03 -#define SCSI_SPI_WRITEFLASH 0x04 -#define SCSI_SPI_WRITEFLASHSTATUS 0x05 -#define SCSI_SPI_ERASEFLASH 0x06 - -#define INIT_BATCHCMD 0x41 -#define ADD_BATCHCMD 0x42 -#define SEND_BATCHCMD 0x43 -#define GET_BATCHRSP 0x44 - -#define CHIP_NORMALMODE 0x00 -#define CHIP_DEBUGMODE 0x01 - -/* SD Pass Through Command Extension */ -#define SD_PASS_THRU_MODE 0xD0 -#define SD_EXECUTE_NO_DATA 0xD1 -#define SD_EXECUTE_READ 0xD2 -#define SD_EXECUTE_WRITE 0xD3 -#define SD_GET_RSP 0xD4 -#define SD_HW_RST 0xD6 - -#ifdef SUPPORT_MAGIC_GATE -#define CMD_MSPRO_MG_RKEY 0xA4 /* Report Key Command */ -#define CMD_MSPRO_MG_SKEY 0xA3 /* Send Key Command */ - -/* CBWCB field: key class */ -#define KC_MG_R_PRO 0xBE /* MG-R PRO*/ - -/* CBWCB field: key format */ -#define KF_SET_LEAF_ID 0x31 /* Set Leaf ID */ -#define KF_GET_LOC_EKB 0x32 /* Get Local EKB */ -#define KF_CHG_HOST 0x33 /* Challenge (host) */ -#define KF_RSP_CHG 0x34 /* Response and Challenge (device) */ -#define KF_RSP_HOST 0x35 /* Response (host) */ -#define KF_GET_ICV 0x36 /* Get ICV */ -#define KF_SET_ICV 0x37 /* SSet ICV */ -#endif - -/* Sense type */ -#define SENSE_TYPE_NO_SENSE 0 -#define SENSE_TYPE_MEDIA_CHANGE 1 -#define SENSE_TYPE_MEDIA_NOT_PRESENT 2 -#define SENSE_TYPE_MEDIA_LBA_OVER_RANGE 3 -#define SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT 4 -#define SENSE_TYPE_MEDIA_WRITE_PROTECT 5 -#define SENSE_TYPE_MEDIA_INVALID_CMD_FIELD 6 -#define SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR 7 -#define SENSE_TYPE_MEDIA_WRITE_ERR 8 -#define SENSE_TYPE_FORMAT_IN_PROGRESS 9 -#define SENSE_TYPE_FORMAT_CMD_FAILED 10 -#ifdef SUPPORT_MAGIC_GATE -#define SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB 0x0b -#define SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN 0x0c -#define SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM 0x0d -#define SENSE_TYPE_MG_WRITE_ERR 0x0e -#endif -#ifdef SUPPORT_SD_LOCK -/* FOR Locked SD card*/ -#define SENSE_TYPE_MEDIA_READ_FORBIDDEN 0x10 -#endif - -void scsi_show_command(struct rtsx_chip *chip); -void set_sense_type(struct rtsx_chip *chip, unsigned int lun, int sense_type); -void set_sense_data(struct rtsx_chip *chip, unsigned int lun, u8 err_code, - u8 sense_key, u32 info, u8 asc, u8 ascq, - u8 sns_key_info0, u16 sns_key_info1); -int rtsx_scsi_handler(struct scsi_cmnd *srb, struct rtsx_chip *chip); - -#endif /* __REALTEK_RTSX_SCSI_H */ diff --git a/drivers/staging/rts5208/rtsx_sys.h b/drivers/staging/rts5208/rtsx_sys.h deleted file mode 100644 index 77094809c814..000000000000 --- a/drivers/staging/rts5208/rtsx_sys.h +++ /dev/null @@ -1,36 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Driver for Realtek PCI-Express card reader - * - * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. - * - * Author: - * Wei WANG (wei_wang@xxxxxxxxxxxxxx) - * Micky Ching (micky_ching@xxxxxxxxxxxxxx) - */ - -#ifndef __RTSX_SYS_H -#define __RTSX_SYS_H - -#include "rtsx.h" -#include "rtsx_chip.h" -#include "rtsx_card.h" - -static inline void rtsx_exclusive_enter_ss(struct rtsx_chip *chip) -{ - struct rtsx_dev *dev = chip->rtsx; - - spin_lock(&dev->reg_lock); - rtsx_enter_ss(chip); - spin_unlock(&dev->reg_lock); -} - -static inline void rtsx_reset_detected_cards(struct rtsx_chip *chip, int flag) -{ - rtsx_reset_cards(chip); -} - -#define RTSX_MSG_IN_INT(x) - -#endif /* __RTSX_SYS_H */ - diff --git a/drivers/staging/rts5208/rtsx_transport.c b/drivers/staging/rts5208/rtsx_transport.c deleted file mode 100644 index d5ad49de4c56..000000000000 --- a/drivers/staging/rts5208/rtsx_transport.c +++ /dev/null @@ -1,768 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Driver for Realtek PCI-Express card reader - * - * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. - * - * Author: - * Wei WANG (wei_wang@xxxxxxxxxxxxxx) - * Micky Ching (micky_ching@xxxxxxxxxxxxxx) - */ - -#include <linux/blkdev.h> -#include <linux/kthread.h> -#include <linux/sched.h> - -#include "rtsx.h" - -/*********************************************************************** - * Scatter-gather transfer buffer access routines - ***********************************************************************/ - -/* - * Copy a buffer of length buflen to/from the srb's transfer buffer. - * (Note: for scatter-gather transfers (srb->use_sg > 0), srb->request_buffer - * points to a list of s-g entries and we ignore srb->request_bufflen. - * For non-scatter-gather transfers, srb->request_buffer points to the - * transfer buffer itself and srb->request_bufflen is the buffer's length.) - * Update the *index and *offset variables so that the next copy will - * pick up from where this one left off. - */ - -unsigned int rtsx_stor_access_xfer_buf(unsigned char *buffer, - unsigned int buflen, - struct scsi_cmnd *srb, - unsigned int *index, - unsigned int *offset, - enum xfer_buf_dir dir) -{ - unsigned int cnt; - - /* If not using scatter-gather, just transfer the data directly. */ - if (scsi_sg_count(srb) == 0) { - unsigned char *sgbuffer; - - if (*offset >= scsi_bufflen(srb)) - return 0; - cnt = min(buflen, scsi_bufflen(srb) - *offset); - - sgbuffer = (unsigned char *)scsi_sglist(srb) + *offset; - - if (dir == TO_XFER_BUF) - memcpy(sgbuffer, buffer, cnt); - else - memcpy(buffer, sgbuffer, cnt); - *offset += cnt; - - /* - * Using scatter-gather. We have to go through the list one entry - * at a time. Each s-g entry contains some number of pages which - * have to be copied one at a time. - */ - } else { - struct scatterlist *sg = - (struct scatterlist *)scsi_sglist(srb) - + *index; - - /* - * This loop handles a single s-g list entry, which may - * include multiple pages. Find the initial page structure - * and the starting offset within the page, and update - * the *offset and *index values for the next loop. - */ - cnt = 0; - while (cnt < buflen && *index < scsi_sg_count(srb)) { - struct page *page = sg_page(sg) + - ((sg->offset + *offset) >> PAGE_SHIFT); - unsigned int poff = (sg->offset + *offset) & - (PAGE_SIZE - 1); - unsigned int sglen = sg->length - *offset; - - if (sglen > buflen - cnt) { - /* Transfer ends within this s-g entry */ - sglen = buflen - cnt; - *offset += sglen; - } else { - /* Transfer continues to next s-g entry */ - *offset = 0; - ++*index; - ++sg; - } - - while (sglen > 0) { - unsigned int plen = min(sglen, (unsigned int) - PAGE_SIZE - poff); - - if (dir == TO_XFER_BUF) - memcpy_to_page(page, poff, buffer + cnt, plen); - else - memcpy_from_page(buffer + cnt, page, poff, plen); - - /* Start at the beginning of the next page */ - poff = 0; - ++page; - cnt += plen; - sglen -= plen; - } - } - } - - /* Return the amount actually transferred */ - return cnt; -} - -/* - * Store the contents of buffer into srb's transfer buffer and set the - * SCSI residue. - */ -void rtsx_stor_set_xfer_buf(unsigned char *buffer, - unsigned int buflen, struct scsi_cmnd *srb) -{ - unsigned int index = 0, offset = 0; - - rtsx_stor_access_xfer_buf(buffer, buflen, srb, &index, &offset, - TO_XFER_BUF); - if (buflen < scsi_bufflen(srb)) - scsi_set_resid(srb, scsi_bufflen(srb) - buflen); -} - -void rtsx_stor_get_xfer_buf(unsigned char *buffer, - unsigned int buflen, struct scsi_cmnd *srb) -{ - unsigned int index = 0, offset = 0; - - rtsx_stor_access_xfer_buf(buffer, buflen, srb, &index, &offset, - FROM_XFER_BUF); - if (buflen < scsi_bufflen(srb)) - scsi_set_resid(srb, scsi_bufflen(srb) - buflen); -} - -/*********************************************************************** - * Transport routines - ***********************************************************************/ - -/* - * Invoke the transport and basic error-handling/recovery methods - * - * This is used to send the message to the device and receive the response. - */ -void rtsx_invoke_transport(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - int result; - - result = rtsx_scsi_handler(srb, chip); - - /* - * if the command gets aborted by the higher layers, we need to - * short-circuit all other processing. - */ - if (rtsx_chk_stat(chip, RTSX_STAT_ABORT)) { - dev_dbg(rtsx_dev(chip), "-- command was aborted\n"); - srb->result = DID_ABORT << 16; - goto handle_errors; - } - - /* if there is a transport error, reset and don't auto-sense */ - if (result == TRANSPORT_ERROR) { - dev_dbg(rtsx_dev(chip), "-- transport indicates error, resetting\n"); - srb->result = DID_ERROR << 16; - goto handle_errors; - } - - srb->result = SAM_STAT_GOOD; - - /* - * If we have a failure, we're going to do a REQUEST_SENSE - * automatically. Note that we differentiate between a command - * "failure" and an "error" in the transport mechanism. - */ - if (result == TRANSPORT_FAILED) { - /* set the result so the higher layers expect this data */ - srb->result = SAM_STAT_CHECK_CONDITION; - memcpy(srb->sense_buffer, - (unsigned char *)&chip->sense_buffer[SCSI_LUN(srb)], - sizeof(struct sense_data_t)); - } - - return; - -handle_errors: - return; -} - -void rtsx_add_cmd(struct rtsx_chip *chip, - u8 cmd_type, u16 reg_addr, u8 mask, u8 data) -{ - __le32 *cb = (__le32 *)(chip->host_cmds_ptr); - u32 val = 0; - - val |= (u32)(cmd_type & 0x03) << 30; - val |= (u32)(reg_addr & 0x3FFF) << 16; - val |= (u32)mask << 8; - val |= (u32)data; - - spin_lock_irq(&chip->rtsx->reg_lock); - if (chip->ci < (HOST_CMDS_BUF_LEN / 4)) - cb[(chip->ci)++] = cpu_to_le32(val); - - spin_unlock_irq(&chip->rtsx->reg_lock); -} - -void rtsx_send_cmd_no_wait(struct rtsx_chip *chip) -{ - u32 val = BIT(31); - - rtsx_writel(chip, RTSX_HCBAR, chip->host_cmds_addr); - - val |= (u32)(chip->ci * 4) & 0x00FFFFFF; - /* Hardware Auto Response */ - val |= 0x40000000; - rtsx_writel(chip, RTSX_HCBCTLR, val); -} - -int rtsx_send_cmd(struct rtsx_chip *chip, u8 card, int timeout) -{ - struct rtsx_dev *rtsx = chip->rtsx; - struct completion trans_done; - u32 val = BIT(31); - long timeleft; - int err = 0; - - if (card == SD_CARD) - rtsx->check_card_cd = SD_EXIST; - else if (card == MS_CARD) - rtsx->check_card_cd = MS_EXIST; - else if (card == XD_CARD) - rtsx->check_card_cd = XD_EXIST; - else - rtsx->check_card_cd = 0; - - spin_lock_irq(&rtsx->reg_lock); - - /* set up data structures for the wakeup system */ - rtsx->done = &trans_done; - rtsx->trans_result = TRANS_NOT_READY; - init_completion(&trans_done); - rtsx->trans_state = STATE_TRANS_CMD; - - rtsx_writel(chip, RTSX_HCBAR, chip->host_cmds_addr); - - val |= (u32)(chip->ci * 4) & 0x00FFFFFF; - /* Hardware Auto Response */ - val |= 0x40000000; - rtsx_writel(chip, RTSX_HCBCTLR, val); - - spin_unlock_irq(&rtsx->reg_lock); - - /* Wait for TRANS_OK_INT */ - timeleft = wait_for_completion_interruptible_timeout(&trans_done, - msecs_to_jiffies(timeout)); - if (timeleft <= 0) { - dev_dbg(rtsx_dev(chip), "chip->int_reg = 0x%x\n", - chip->int_reg); - err = -ETIMEDOUT; - goto finish_send_cmd; - } - - spin_lock_irq(&rtsx->reg_lock); - if (rtsx->trans_result == TRANS_RESULT_FAIL) - err = -EIO; - else if (rtsx->trans_result == TRANS_RESULT_OK) - err = 0; - - spin_unlock_irq(&rtsx->reg_lock); - -finish_send_cmd: - rtsx->done = NULL; - rtsx->trans_state = STATE_TRANS_NONE; - - if (err < 0) - rtsx_stop_cmd(chip, card); - - return err; -} - -static inline void rtsx_add_sg_tbl(struct rtsx_chip *chip, - u32 addr, u32 len, u8 option) -{ - __le64 *sgb = (__le64 *)(chip->host_sg_tbl_ptr); - u64 val = 0; - u32 temp_len = 0; - u8 temp_opt = 0; - - do { - if (len > 0x80000) { - temp_len = 0x80000; - temp_opt = option & (~RTSX_SG_END); - } else { - temp_len = len; - temp_opt = option; - } - val = ((u64)addr << 32) | ((u64)temp_len << 12) | temp_opt; - - if (chip->sgi < (HOST_SG_TBL_BUF_LEN / 8)) - sgb[(chip->sgi)++] = cpu_to_le64(val); - - len -= temp_len; - addr += temp_len; - } while (len); -} - -static int rtsx_transfer_sglist_adma_partial(struct rtsx_chip *chip, u8 card, - struct scatterlist *sg, int num_sg, - unsigned int *index, - unsigned int *offset, int size, - enum dma_data_direction dma_dir, - int timeout) -{ - struct rtsx_dev *rtsx = chip->rtsx; - struct completion trans_done; - u8 dir; - int sg_cnt, i, resid; - int err = 0; - long timeleft; - struct scatterlist *sg_ptr; - u32 val = TRIG_DMA; - - if (!sg || num_sg <= 0 || !offset || !index) - return -EIO; - - if (dma_dir == DMA_TO_DEVICE) - dir = HOST_TO_DEVICE; - else if (dma_dir == DMA_FROM_DEVICE) - dir = DEVICE_TO_HOST; - else - return -ENXIO; - - if (card == SD_CARD) - rtsx->check_card_cd = SD_EXIST; - else if (card == MS_CARD) - rtsx->check_card_cd = MS_EXIST; - else if (card == XD_CARD) - rtsx->check_card_cd = XD_EXIST; - else - rtsx->check_card_cd = 0; - - spin_lock_irq(&rtsx->reg_lock); - - /* set up data structures for the wakeup system */ - rtsx->done = &trans_done; - - rtsx->trans_state = STATE_TRANS_SG; - rtsx->trans_result = TRANS_NOT_READY; - - spin_unlock_irq(&rtsx->reg_lock); - - sg_cnt = dma_map_sg(&rtsx->pci->dev, sg, num_sg, dma_dir); - - resid = size; - sg_ptr = sg; - chip->sgi = 0; - /* - * Usually the next entry will be @sg@ + 1, but if this sg element - * is part of a chained scatterlist, it could jump to the start of - * a new scatterlist array. So here we use sg_next to move to - * the proper sg. - */ - for (i = 0; i < *index; i++) - sg_ptr = sg_next(sg_ptr); - for (i = *index; i < sg_cnt; i++) { - dma_addr_t addr; - unsigned int len; - u8 option; - - addr = sg_dma_address(sg_ptr); - len = sg_dma_len(sg_ptr); - - dev_dbg(rtsx_dev(chip), "DMA addr: 0x%x, Len: 0x%x\n", - (unsigned int)addr, len); - dev_dbg(rtsx_dev(chip), "*index = %d, *offset = %d\n", - *index, *offset); - - addr += *offset; - - if ((len - *offset) > resid) { - *offset += resid; - len = resid; - resid = 0; - } else { - resid -= (len - *offset); - len -= *offset; - *offset = 0; - *index = *index + 1; - } - option = RTSX_SG_VALID | RTSX_SG_TRANS_DATA; - if ((i == sg_cnt - 1) || !resid) - option |= RTSX_SG_END; - - rtsx_add_sg_tbl(chip, (u32)addr, (u32)len, option); - - if (!resid) - break; - - sg_ptr = sg_next(sg_ptr); - } - - dev_dbg(rtsx_dev(chip), "SG table count = %d\n", chip->sgi); - - val |= (u32)(dir & 0x01) << 29; - val |= ADMA_MODE; - - spin_lock_irq(&rtsx->reg_lock); - - init_completion(&trans_done); - - rtsx_writel(chip, RTSX_HDBAR, chip->host_sg_tbl_addr); - rtsx_writel(chip, RTSX_HDBCTLR, val); - - spin_unlock_irq(&rtsx->reg_lock); - - timeleft = wait_for_completion_interruptible_timeout(&trans_done, - msecs_to_jiffies(timeout)); - if (timeleft <= 0) { - dev_dbg(rtsx_dev(chip), "Timeout (%s %d)\n", - __func__, __LINE__); - dev_dbg(rtsx_dev(chip), "chip->int_reg = 0x%x\n", - chip->int_reg); - err = -ETIMEDOUT; - goto out; - } - - spin_lock_irq(&rtsx->reg_lock); - if (rtsx->trans_result == TRANS_RESULT_FAIL) { - err = -EIO; - spin_unlock_irq(&rtsx->reg_lock); - goto out; - } - spin_unlock_irq(&rtsx->reg_lock); - - /* Wait for TRANS_OK_INT */ - spin_lock_irq(&rtsx->reg_lock); - if (rtsx->trans_result == TRANS_NOT_READY) { - init_completion(&trans_done); - spin_unlock_irq(&rtsx->reg_lock); - timeleft = wait_for_completion_interruptible_timeout(&trans_done, - msecs_to_jiffies(timeout)); - if (timeleft <= 0) { - dev_dbg(rtsx_dev(chip), "Timeout (%s %d)\n", - __func__, __LINE__); - dev_dbg(rtsx_dev(chip), "chip->int_reg = 0x%x\n", - chip->int_reg); - err = -ETIMEDOUT; - goto out; - } - } else { - spin_unlock_irq(&rtsx->reg_lock); - } - - spin_lock_irq(&rtsx->reg_lock); - if (rtsx->trans_result == TRANS_RESULT_FAIL) - err = -EIO; - else if (rtsx->trans_result == TRANS_RESULT_OK) - err = 0; - - spin_unlock_irq(&rtsx->reg_lock); - -out: - rtsx->done = NULL; - rtsx->trans_state = STATE_TRANS_NONE; - dma_unmap_sg(&rtsx->pci->dev, sg, num_sg, dma_dir); - - if (err < 0) - rtsx_stop_cmd(chip, card); - - return err; -} - -static int rtsx_transfer_sglist_adma(struct rtsx_chip *chip, u8 card, - struct scatterlist *sg, int num_sg, - enum dma_data_direction dma_dir, - int timeout) -{ - struct rtsx_dev *rtsx = chip->rtsx; - struct completion trans_done; - u8 dir; - int buf_cnt, i; - int err = 0; - long timeleft; - struct scatterlist *sg_ptr; - - if (!sg || num_sg <= 0) - return -EIO; - - if (dma_dir == DMA_TO_DEVICE) - dir = HOST_TO_DEVICE; - else if (dma_dir == DMA_FROM_DEVICE) - dir = DEVICE_TO_HOST; - else - return -ENXIO; - - if (card == SD_CARD) - rtsx->check_card_cd = SD_EXIST; - else if (card == MS_CARD) - rtsx->check_card_cd = MS_EXIST; - else if (card == XD_CARD) - rtsx->check_card_cd = XD_EXIST; - else - rtsx->check_card_cd = 0; - - spin_lock_irq(&rtsx->reg_lock); - - /* set up data structures for the wakeup system */ - rtsx->done = &trans_done; - - rtsx->trans_state = STATE_TRANS_SG; - rtsx->trans_result = TRANS_NOT_READY; - - spin_unlock_irq(&rtsx->reg_lock); - - buf_cnt = dma_map_sg(&rtsx->pci->dev, sg, num_sg, dma_dir); - - sg_ptr = sg; - - for (i = 0; i <= buf_cnt / (HOST_SG_TBL_BUF_LEN / 8); i++) { - u32 val = TRIG_DMA; - int sg_cnt, j; - - if (i == buf_cnt / (HOST_SG_TBL_BUF_LEN / 8)) - sg_cnt = buf_cnt % (HOST_SG_TBL_BUF_LEN / 8); - else - sg_cnt = HOST_SG_TBL_BUF_LEN / 8; - - chip->sgi = 0; - for (j = 0; j < sg_cnt; j++) { - dma_addr_t addr = sg_dma_address(sg_ptr); - unsigned int len = sg_dma_len(sg_ptr); - u8 option; - - dev_dbg(rtsx_dev(chip), "DMA addr: 0x%x, Len: 0x%x\n", - (unsigned int)addr, len); - - option = RTSX_SG_VALID | RTSX_SG_TRANS_DATA; - if (j == (sg_cnt - 1)) - option |= RTSX_SG_END; - - rtsx_add_sg_tbl(chip, (u32)addr, (u32)len, option); - - sg_ptr = sg_next(sg_ptr); - } - - dev_dbg(rtsx_dev(chip), "SG table count = %d\n", chip->sgi); - - val |= (u32)(dir & 0x01) << 29; - val |= ADMA_MODE; - - spin_lock_irq(&rtsx->reg_lock); - - init_completion(&trans_done); - - rtsx_writel(chip, RTSX_HDBAR, chip->host_sg_tbl_addr); - rtsx_writel(chip, RTSX_HDBCTLR, val); - - spin_unlock_irq(&rtsx->reg_lock); - - timeleft = wait_for_completion_interruptible_timeout(&trans_done, - msecs_to_jiffies(timeout)); - if (timeleft <= 0) { - dev_dbg(rtsx_dev(chip), "Timeout (%s %d)\n", - __func__, __LINE__); - dev_dbg(rtsx_dev(chip), "chip->int_reg = 0x%x\n", - chip->int_reg); - err = -ETIMEDOUT; - goto out; - } - - spin_lock_irq(&rtsx->reg_lock); - if (rtsx->trans_result == TRANS_RESULT_FAIL) { - err = -EIO; - spin_unlock_irq(&rtsx->reg_lock); - goto out; - } - spin_unlock_irq(&rtsx->reg_lock); - - sg_ptr += sg_cnt; - } - - /* Wait for TRANS_OK_INT */ - spin_lock_irq(&rtsx->reg_lock); - if (rtsx->trans_result == TRANS_NOT_READY) { - init_completion(&trans_done); - spin_unlock_irq(&rtsx->reg_lock); - timeleft = wait_for_completion_interruptible_timeout(&trans_done, - msecs_to_jiffies(timeout)); - if (timeleft <= 0) { - dev_dbg(rtsx_dev(chip), "Timeout (%s %d)\n", - __func__, __LINE__); - dev_dbg(rtsx_dev(chip), "chip->int_reg = 0x%x\n", - chip->int_reg); - err = -ETIMEDOUT; - goto out; - } - } else { - spin_unlock_irq(&rtsx->reg_lock); - } - - spin_lock_irq(&rtsx->reg_lock); - if (rtsx->trans_result == TRANS_RESULT_FAIL) - err = -EIO; - else if (rtsx->trans_result == TRANS_RESULT_OK) - err = 0; - - spin_unlock_irq(&rtsx->reg_lock); - -out: - rtsx->done = NULL; - rtsx->trans_state = STATE_TRANS_NONE; - dma_unmap_sg(&rtsx->pci->dev, sg, num_sg, dma_dir); - - if (err < 0) - rtsx_stop_cmd(chip, card); - - return err; -} - -static int rtsx_transfer_buf(struct rtsx_chip *chip, u8 card, void *buf, - size_t len, enum dma_data_direction dma_dir, - int timeout) -{ - struct rtsx_dev *rtsx = chip->rtsx; - struct completion trans_done; - dma_addr_t addr; - u8 dir; - int err = 0; - u32 val = BIT(31); - long timeleft; - - if (!buf || len <= 0) - return -EIO; - - if (dma_dir == DMA_TO_DEVICE) - dir = HOST_TO_DEVICE; - else if (dma_dir == DMA_FROM_DEVICE) - dir = DEVICE_TO_HOST; - else - return -ENXIO; - - addr = dma_map_single(&rtsx->pci->dev, buf, len, dma_dir); - if (dma_mapping_error(&rtsx->pci->dev, addr)) - return -ENOMEM; - - if (card == SD_CARD) - rtsx->check_card_cd = SD_EXIST; - else if (card == MS_CARD) - rtsx->check_card_cd = MS_EXIST; - else if (card == XD_CARD) - rtsx->check_card_cd = XD_EXIST; - else - rtsx->check_card_cd = 0; - - val |= (u32)(dir & 0x01) << 29; - val |= (u32)(len & 0x00FFFFFF); - - spin_lock_irq(&rtsx->reg_lock); - - /* set up data structures for the wakeup system */ - rtsx->done = &trans_done; - - init_completion(&trans_done); - - rtsx->trans_state = STATE_TRANS_BUF; - rtsx->trans_result = TRANS_NOT_READY; - - rtsx_writel(chip, RTSX_HDBAR, addr); - rtsx_writel(chip, RTSX_HDBCTLR, val); - - spin_unlock_irq(&rtsx->reg_lock); - - /* Wait for TRANS_OK_INT */ - timeleft = wait_for_completion_interruptible_timeout(&trans_done, - msecs_to_jiffies(timeout)); - if (timeleft <= 0) { - dev_dbg(rtsx_dev(chip), "Timeout (%s %d)\n", - __func__, __LINE__); - dev_dbg(rtsx_dev(chip), "chip->int_reg = 0x%x\n", - chip->int_reg); - err = -ETIMEDOUT; - goto out; - } - - spin_lock_irq(&rtsx->reg_lock); - if (rtsx->trans_result == TRANS_RESULT_FAIL) - err = -EIO; - else if (rtsx->trans_result == TRANS_RESULT_OK) - err = 0; - - spin_unlock_irq(&rtsx->reg_lock); - -out: - rtsx->done = NULL; - rtsx->trans_state = STATE_TRANS_NONE; - dma_unmap_single(&rtsx->pci->dev, addr, len, dma_dir); - - if (err < 0) - rtsx_stop_cmd(chip, card); - - return err; -} - -int rtsx_transfer_data_partial(struct rtsx_chip *chip, u8 card, - void *buf, size_t len, int use_sg, - unsigned int *index, unsigned int *offset, - enum dma_data_direction dma_dir, int timeout) -{ - int err = 0; - - /* don't transfer data during abort processing */ - if (rtsx_chk_stat(chip, RTSX_STAT_ABORT)) - return -EIO; - - if (use_sg) { - struct scatterlist *sg = buf; - - err = rtsx_transfer_sglist_adma_partial(chip, card, sg, use_sg, - index, offset, (int)len, - dma_dir, timeout); - } else { - err = rtsx_transfer_buf(chip, card, - buf, len, dma_dir, timeout); - } - if (err < 0) { - if (RTSX_TST_DELINK(chip)) { - RTSX_CLR_DELINK(chip); - chip->need_reinit = SD_CARD | MS_CARD | XD_CARD; - rtsx_reinit_cards(chip, 1); - } - } - - return err; -} - -int rtsx_transfer_data(struct rtsx_chip *chip, u8 card, void *buf, size_t len, - int use_sg, enum dma_data_direction dma_dir, int timeout) -{ - int err = 0; - - dev_dbg(rtsx_dev(chip), "use_sg = %d\n", use_sg); - - /* don't transfer data during abort processing */ - if (rtsx_chk_stat(chip, RTSX_STAT_ABORT)) - return -EIO; - - if (use_sg) { - err = rtsx_transfer_sglist_adma(chip, card, buf, - use_sg, dma_dir, timeout); - } else { - err = rtsx_transfer_buf(chip, card, buf, len, dma_dir, timeout); - } - - if (err < 0) { - if (RTSX_TST_DELINK(chip)) { - RTSX_CLR_DELINK(chip); - chip->need_reinit = SD_CARD | MS_CARD | XD_CARD; - rtsx_reinit_cards(chip, 1); - } - } - - return err; -} - diff --git a/drivers/staging/rts5208/rtsx_transport.h b/drivers/staging/rts5208/rtsx_transport.h deleted file mode 100644 index 097efed24b79..000000000000 --- a/drivers/staging/rts5208/rtsx_transport.h +++ /dev/null @@ -1,57 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Driver for Realtek PCI-Express card reader - * - * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. - * - * Author: - * Wei WANG (wei_wang@xxxxxxxxxxxxxx) - * Micky Ching (micky_ching@xxxxxxxxxxxxxx) - */ - -#ifndef __REALTEK_RTSX_TRANSPORT_H -#define __REALTEK_RTSX_TRANSPORT_H - -#include "rtsx.h" -#include "rtsx_chip.h" - -#define WAIT_TIME 2000 - -unsigned int rtsx_stor_access_xfer_buf(unsigned char *buffer, - unsigned int buflen, - struct scsi_cmnd *srb, - unsigned int *index, - unsigned int *offset, - enum xfer_buf_dir dir); -void rtsx_stor_set_xfer_buf(unsigned char *buffer, unsigned int buflen, - struct scsi_cmnd *srb); -void rtsx_stor_get_xfer_buf(unsigned char *buffer, unsigned int buflen, - struct scsi_cmnd *srb); -void rtsx_invoke_transport(struct scsi_cmnd *srb, struct rtsx_chip *chip); - -#define rtsx_init_cmd(chip) ((chip)->ci = 0) - -void rtsx_add_cmd(struct rtsx_chip *chip, u8 cmd_type, u16 reg_addr, u8 mask, - u8 data); -void rtsx_send_cmd_no_wait(struct rtsx_chip *chip); -int rtsx_send_cmd(struct rtsx_chip *chip, u8 card, int timeout); - -static inline u8 *rtsx_get_cmd_data(struct rtsx_chip *chip) -{ -#ifdef CMD_USING_SG - return (u8 *)(chip->host_sg_tbl_ptr); -#else - return (u8 *)(chip->host_cmds_ptr); -#endif -} - -int rtsx_transfer_data(struct rtsx_chip *chip, u8 card, void *buf, size_t len, - int use_sg, enum dma_data_direction dma_dir, - int timeout); - -int rtsx_transfer_data_partial(struct rtsx_chip *chip, u8 card, void *buf, - size_t len, int use_sg, unsigned int *index, - unsigned int *offset, - enum dma_data_direction dma_dir, int timeout); - -#endif /* __REALTEK_RTSX_TRANSPORT_H */ diff --git a/drivers/staging/rts5208/sd.c b/drivers/staging/rts5208/sd.c deleted file mode 100644 index 74c4f476b3a4..000000000000 --- a/drivers/staging/rts5208/sd.c +++ /dev/null @@ -1,4717 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Driver for Realtek PCI-Express card reader - * - * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. - * - * Author: - * Wei WANG (wei_wang@xxxxxxxxxxxxxx) - * Micky Ching (micky_ching@xxxxxxxxxxxxxx) - */ - -#include <linux/blkdev.h> -#include <linux/kthread.h> -#include <linux/sched.h> - -#include "rtsx.h" -#include "sd.h" - -#define SD_MAX_RETRY_COUNT 3 - -static u16 REG_SD_CFG1; -static u16 REG_SD_CFG2; -static u16 REG_SD_CFG3; -static u16 REG_SD_STAT1; -static u16 REG_SD_STAT2; -static u16 REG_SD_BUS_STAT; -static u16 REG_SD_PAD_CTL; -static u16 REG_SD_SAMPLE_POINT_CTL; -static u16 REG_SD_PUSH_POINT_CTL; -static u16 REG_SD_CMD0; -static u16 REG_SD_CMD1; -static u16 REG_SD_CMD2; -static u16 REG_SD_CMD3; -static u16 REG_SD_CMD4; -static u16 REG_SD_CMD5; -static u16 REG_SD_BYTE_CNT_L; -static u16 REG_SD_BYTE_CNT_H; -static u16 REG_SD_BLOCK_CNT_L; -static u16 REG_SD_BLOCK_CNT_H; -static u16 REG_SD_TRANSFER; -static u16 REG_SD_VPCLK0_CTL; -static u16 REG_SD_VPCLK1_CTL; -static u16 REG_SD_DCMPS0_CTL; -static u16 REG_SD_DCMPS1_CTL; - -static inline void sd_set_err_code(struct rtsx_chip *chip, u8 err_code) -{ - struct sd_info *sd_card = &chip->sd_card; - - sd_card->err_code |= err_code; -} - -static inline void sd_clr_err_code(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &chip->sd_card; - - sd_card->err_code = 0; -} - -static inline int sd_check_err_code(struct rtsx_chip *chip, u8 err_code) -{ - struct sd_info *sd_card = &chip->sd_card; - - return sd_card->err_code & err_code; -} - -static void sd_init_reg_addr(struct rtsx_chip *chip) -{ - REG_SD_CFG1 = 0xFD31; - REG_SD_CFG2 = 0xFD33; - REG_SD_CFG3 = 0xFD3E; - REG_SD_STAT1 = 0xFD30; - REG_SD_STAT2 = 0; - REG_SD_BUS_STAT = 0; - REG_SD_PAD_CTL = 0; - REG_SD_SAMPLE_POINT_CTL = 0; - REG_SD_PUSH_POINT_CTL = 0; - REG_SD_CMD0 = 0xFD34; - REG_SD_CMD1 = 0xFD35; - REG_SD_CMD2 = 0xFD36; - REG_SD_CMD3 = 0xFD37; - REG_SD_CMD4 = 0xFD38; - REG_SD_CMD5 = 0xFD5A; - REG_SD_BYTE_CNT_L = 0xFD39; - REG_SD_BYTE_CNT_H = 0xFD3A; - REG_SD_BLOCK_CNT_L = 0xFD3B; - REG_SD_BLOCK_CNT_H = 0xFD3C; - REG_SD_TRANSFER = 0xFD32; - REG_SD_VPCLK0_CTL = 0; - REG_SD_VPCLK1_CTL = 0; - REG_SD_DCMPS0_CTL = 0; - REG_SD_DCMPS1_CTL = 0; -} - -static int sd_check_data0_status(struct rtsx_chip *chip) -{ - int retval; - u8 stat; - - retval = rtsx_read_register(chip, REG_SD_STAT1, &stat); - if (retval) - return retval; - - if (!(stat & SD_DAT0_STATUS)) { - sd_set_err_code(chip, SD_BUSY); - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -static int sd_send_cmd_get_rsp(struct rtsx_chip *chip, u8 cmd_idx, - u32 arg, u8 rsp_type, u8 *rsp, int rsp_len) -{ - struct sd_info *sd_card = &chip->sd_card; - int retval; - int timeout = 100; - u16 reg_addr; - u8 *ptr; - int stat_idx = 0; - int rty_cnt = 0; - - sd_clr_err_code(chip); - - dev_dbg(rtsx_dev(chip), "SD/MMC CMD %d, arg = 0x%08x\n", cmd_idx, arg); - - if (rsp_type == SD_RSP_TYPE_R1b) - timeout = 3000; - -RTY_SEND_CMD: - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD0, 0xFF, 0x40 | cmd_idx); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD1, 0xFF, (u8)(arg >> 24)); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD2, 0xFF, (u8)(arg >> 16)); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD3, 0xFF, (u8)(arg >> 8)); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD4, 0xFF, (u8)arg); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF, rsp_type); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, - 0x01, PINGPONG_BUFFER); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, - 0xFF, SD_TM_CMD_RSP | SD_TRANSFER_START); - rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, - SD_TRANSFER_END | SD_STAT_IDLE, SD_TRANSFER_END | - SD_STAT_IDLE); - - if (rsp_type == SD_RSP_TYPE_R2) { - for (reg_addr = PPBUF_BASE2; reg_addr < PPBUF_BASE2 + 16; - reg_addr++) - rtsx_add_cmd(chip, READ_REG_CMD, reg_addr, 0, 0); - - stat_idx = 16; - } else if (rsp_type != SD_RSP_TYPE_R0) { - for (reg_addr = REG_SD_CMD0; reg_addr <= REG_SD_CMD4; - reg_addr++) - rtsx_add_cmd(chip, READ_REG_CMD, reg_addr, 0, 0); - - stat_idx = 5; - } - - rtsx_add_cmd(chip, READ_REG_CMD, REG_SD_STAT1, 0, 0); - - retval = rtsx_send_cmd(chip, SD_CARD, timeout); - if (retval < 0) { - u8 val; - - rtsx_read_register(chip, REG_SD_STAT1, &val); - dev_dbg(rtsx_dev(chip), "SD_STAT1: 0x%x\n", val); - - rtsx_read_register(chip, REG_SD_CFG3, &val); - dev_dbg(rtsx_dev(chip), "SD_CFG3: 0x%x\n", val); - - if (retval == -ETIMEDOUT) { - if (rsp_type & SD_WAIT_BUSY_END) { - retval = sd_check_data0_status(chip); - if (retval != STATUS_SUCCESS) { - rtsx_clear_sd_error(chip); - return retval; - } - } else { - sd_set_err_code(chip, SD_TO_ERR); - } - retval = STATUS_TIMEDOUT; - } else { - retval = STATUS_FAIL; - } - rtsx_clear_sd_error(chip); - - return retval; - } - - if (rsp_type == SD_RSP_TYPE_R0) - return STATUS_SUCCESS; - - ptr = rtsx_get_cmd_data(chip) + 1; - - if ((ptr[0] & 0xC0) != 0) { - sd_set_err_code(chip, SD_STS_ERR); - return STATUS_FAIL; - } - - if (!(rsp_type & SD_NO_CHECK_CRC7)) { - if (ptr[stat_idx] & SD_CRC7_ERR) { - if (cmd_idx == WRITE_MULTIPLE_BLOCK) { - sd_set_err_code(chip, SD_CRC_ERR); - return STATUS_FAIL; - } - if (rty_cnt < SD_MAX_RETRY_COUNT) { - wait_timeout(20); - rty_cnt++; - goto RTY_SEND_CMD; - } else { - sd_set_err_code(chip, SD_CRC_ERR); - return STATUS_FAIL; - } - } - } - - if (rsp_type == SD_RSP_TYPE_R1 || rsp_type == SD_RSP_TYPE_R1b) { - if (cmd_idx != SEND_RELATIVE_ADDR && - cmd_idx != SEND_IF_COND) { - if (cmd_idx != STOP_TRANSMISSION) { - if (ptr[1] & 0x80) - return STATUS_FAIL; - } -#ifdef SUPPORT_SD_LOCK - if (ptr[1] & 0x7D) { -#else - if (ptr[1] & 0x7F) { -#endif - dev_dbg(rtsx_dev(chip), "ptr[1]: 0x%02x\n", - ptr[1]); - return STATUS_FAIL; - } - if (ptr[2] & 0xFF) { - dev_dbg(rtsx_dev(chip), "ptr[2]: 0x%02x\n", - ptr[2]); - return STATUS_FAIL; - } - if (ptr[3] & 0x80) { - dev_dbg(rtsx_dev(chip), "ptr[3]: 0x%02x\n", - ptr[3]); - return STATUS_FAIL; - } - if (ptr[3] & 0x01) - sd_card->sd_data_buf_ready = 1; - else - sd_card->sd_data_buf_ready = 0; - } - } - - if (rsp && rsp_len) - memcpy(rsp, ptr, rsp_len); - - return STATUS_SUCCESS; -} - -static int sd_read_data(struct rtsx_chip *chip, - u8 trans_mode, u8 *cmd, int cmd_len, u16 byte_cnt, - u16 blk_cnt, u8 bus_width, u8 *buf, int buf_len, - int timeout) -{ - struct sd_info *sd_card = &chip->sd_card; - int retval; - int i; - - sd_clr_err_code(chip); - - if (!buf) - buf_len = 0; - - if (buf_len > 512) - return STATUS_FAIL; - - rtsx_init_cmd(chip); - - if (cmd_len) { - dev_dbg(rtsx_dev(chip), "SD/MMC CMD %d\n", cmd[0] - 0x40); - for (i = 0; i < (min(cmd_len, 6)); i++) - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD0 + i, - 0xFF, cmd[i]); - } - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_L, 0xFF, - (u8)byte_cnt); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_H, 0xFF, - (u8)(byte_cnt >> 8)); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_L, 0xFF, - (u8)blk_cnt); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_H, 0xFF, - (u8)(blk_cnt >> 8)); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG1, 0x03, bus_width); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF, - SD_CALCULATE_CRC7 | SD_CHECK_CRC16 | SD_NO_WAIT_BUSY_END | - SD_CHECK_CRC7 | SD_RSP_LEN_6); - if (trans_mode != SD_TM_AUTO_TUNING) - rtsx_add_cmd(chip, WRITE_REG_CMD, - CARD_DATA_SOURCE, 0x01, PINGPONG_BUFFER); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF, - trans_mode | SD_TRANSFER_START); - rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, SD_TRANSFER_END, - SD_TRANSFER_END); - - retval = rtsx_send_cmd(chip, SD_CARD, timeout); - if (retval < 0) { - if (retval == -ETIMEDOUT) { - sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, - SD_RSP_TYPE_R1, NULL, 0); - } - - return STATUS_FAIL; - } - - if (buf && buf_len) { - retval = rtsx_read_ppbuf(chip, buf, buf_len); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -static int sd_write_data(struct rtsx_chip *chip, u8 trans_mode, - u8 *cmd, int cmd_len, u16 byte_cnt, u16 blk_cnt, - u8 bus_width, u8 *buf, int buf_len, int timeout) -{ - struct sd_info *sd_card = &chip->sd_card; - int retval; - int i; - - sd_clr_err_code(chip); - - if (!buf) - buf_len = 0; - - if (buf_len > 512) { - /* This function can't write data more than one page */ - return STATUS_FAIL; - } - - if (buf && buf_len) { - retval = rtsx_write_ppbuf(chip, buf, buf_len); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - - rtsx_init_cmd(chip); - - if (cmd_len) { - dev_dbg(rtsx_dev(chip), "SD/MMC CMD %d\n", cmd[0] - 0x40); - for (i = 0; i < (min(cmd_len, 6)); i++) { - rtsx_add_cmd(chip, WRITE_REG_CMD, - REG_SD_CMD0 + i, 0xFF, cmd[i]); - } - } - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_L, 0xFF, - (u8)byte_cnt); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_H, 0xFF, - (u8)(byte_cnt >> 8)); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_L, 0xFF, - (u8)blk_cnt); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_H, 0xFF, - (u8)(blk_cnt >> 8)); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG1, 0x03, bus_width); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF, - SD_CALCULATE_CRC7 | SD_CHECK_CRC16 | SD_NO_WAIT_BUSY_END | - SD_CHECK_CRC7 | SD_RSP_LEN_6); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF, - trans_mode | SD_TRANSFER_START); - rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, SD_TRANSFER_END, - SD_TRANSFER_END); - - retval = rtsx_send_cmd(chip, SD_CARD, timeout); - if (retval < 0) { - if (retval == -ETIMEDOUT) { - sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, - SD_RSP_TYPE_R1, NULL, 0); - } - - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -static int sd_check_csd(struct rtsx_chip *chip, char check_wp) -{ - struct sd_info *sd_card = &chip->sd_card; - int retval; - int i; - u8 csd_ver, trans_speed; - u8 rsp[16]; - - for (i = 0; i < 6; i++) { - if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) { - sd_set_err_code(chip, SD_NO_CARD); - return STATUS_FAIL; - } - - retval = sd_send_cmd_get_rsp(chip, SEND_CSD, sd_card->sd_addr, - SD_RSP_TYPE_R2, rsp, 16); - if (retval == STATUS_SUCCESS) - break; - } - - if (i == 6) - return STATUS_FAIL; - - memcpy(sd_card->raw_csd, rsp + 1, 15); - - dev_dbg(rtsx_dev(chip), "CSD Response:\n"); - dev_dbg(rtsx_dev(chip), "%*ph\n", 16, sd_card->raw_csd); - - csd_ver = (rsp[1] & 0xc0) >> 6; - dev_dbg(rtsx_dev(chip), "csd_ver = %d\n", csd_ver); - - trans_speed = rsp[4]; - if ((trans_speed & 0x07) == 0x02) { - if ((trans_speed & 0xf8) >= 0x30) { - if (chip->asic_code) - sd_card->sd_clock = 47; - else - sd_card->sd_clock = CLK_50; - - } else if ((trans_speed & 0xf8) == 0x28) { - if (chip->asic_code) - sd_card->sd_clock = 39; - else - sd_card->sd_clock = CLK_40; - - } else if ((trans_speed & 0xf8) == 0x20) { - if (chip->asic_code) - sd_card->sd_clock = 29; - else - sd_card->sd_clock = CLK_30; - - } else if ((trans_speed & 0xf8) >= 0x10) { - if (chip->asic_code) - sd_card->sd_clock = 23; - else - sd_card->sd_clock = CLK_20; - - } else if ((trans_speed & 0x08) >= 0x08) { - if (chip->asic_code) - sd_card->sd_clock = 19; - else - sd_card->sd_clock = CLK_20; - } else { - return STATUS_FAIL; - } - } else { - return STATUS_FAIL; - } - - if (CHK_MMC_SECTOR_MODE(sd_card)) { - sd_card->capacity = 0; - } else { - if ((!CHK_SD_HCXC(sd_card)) || csd_ver == 0) { - u8 blk_size, c_size_mult; - u16 c_size; - - blk_size = rsp[6] & 0x0F; - c_size = ((u16)(rsp[7] & 0x03) << 10) - + ((u16)rsp[8] << 2) - + ((u16)(rsp[9] & 0xC0) >> 6); - c_size_mult = (u8)((rsp[10] & 0x03) << 1); - c_size_mult += (rsp[11] & 0x80) >> 7; - sd_card->capacity = (((u32)(c_size + 1)) * - (1 << (c_size_mult + 2))) - << (blk_size - 9); - } else { - u32 total_sector = 0; - - total_sector = (((u32)rsp[8] & 0x3f) << 16) | - ((u32)rsp[9] << 8) | (u32)rsp[10]; - sd_card->capacity = (total_sector + 1) << 10; - } - } - - if (check_wp) { - if (rsp[15] & 0x30) - chip->card_wp |= SD_CARD; - - dev_dbg(rtsx_dev(chip), "CSD WP Status: 0x%x\n", rsp[15]); - } - - return STATUS_SUCCESS; -} - -static int sd_set_sample_push_timing(struct rtsx_chip *chip) -{ - int retval; - struct sd_info *sd_card = &chip->sd_card; - u8 val = 0; - - if ((chip->sd_ctl & SD_PUSH_POINT_CTL_MASK) == SD_PUSH_POINT_DELAY) - val |= 0x10; - - if ((chip->sd_ctl & SD_SAMPLE_POINT_CTL_MASK) == SD_SAMPLE_POINT_AUTO) { - if (chip->asic_code) { - if (CHK_SD_HS(sd_card) || CHK_MMC_52M(sd_card)) { - if (val & 0x10) - val |= 0x04; - else - val |= 0x08; - } - } else { - if (val & 0x10) - val |= 0x04; - else - val |= 0x08; - } - } else if ((chip->sd_ctl & SD_SAMPLE_POINT_CTL_MASK) == - SD_SAMPLE_POINT_DELAY) { - if (val & 0x10) - val |= 0x04; - else - val |= 0x08; - } - - retval = rtsx_write_register(chip, REG_SD_CFG1, 0x1C, val); - if (retval) - return retval; - - return STATUS_SUCCESS; -} - -static void sd_choose_proper_clock(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &chip->sd_card; - - if (CHK_SD_SDR104(sd_card)) { - if (chip->asic_code) - sd_card->sd_clock = chip->asic_sd_sdr104_clk; - else - sd_card->sd_clock = chip->fpga_sd_sdr104_clk; - - } else if (CHK_SD_DDR50(sd_card)) { - if (chip->asic_code) - sd_card->sd_clock = chip->asic_sd_ddr50_clk; - else - sd_card->sd_clock = chip->fpga_sd_ddr50_clk; - - } else if (CHK_SD_SDR50(sd_card)) { - if (chip->asic_code) - sd_card->sd_clock = chip->asic_sd_sdr50_clk; - else - sd_card->sd_clock = chip->fpga_sd_sdr50_clk; - - } else if (CHK_SD_HS(sd_card)) { - if (chip->asic_code) - sd_card->sd_clock = chip->asic_sd_hs_clk; - else - sd_card->sd_clock = chip->fpga_sd_hs_clk; - - } else if (CHK_MMC_52M(sd_card) || CHK_MMC_DDR52(sd_card)) { - if (chip->asic_code) - sd_card->sd_clock = chip->asic_mmc_52m_clk; - else - sd_card->sd_clock = chip->fpga_mmc_52m_clk; - - } else if (CHK_MMC_26M(sd_card)) { - if (chip->asic_code) - sd_card->sd_clock = 48; - else - sd_card->sd_clock = CLK_50; - } -} - -static int sd_set_clock_divider(struct rtsx_chip *chip, u8 clk_div) -{ - int retval; - u8 mask = 0, val = 0; - - mask = 0x60; - if (clk_div == SD_CLK_DIVIDE_0) - val = 0x00; - else if (clk_div == SD_CLK_DIVIDE_128) - val = 0x40; - else if (clk_div == SD_CLK_DIVIDE_256) - val = 0x20; - - retval = rtsx_write_register(chip, REG_SD_CFG1, mask, val); - if (retval) - return retval; - - return STATUS_SUCCESS; -} - -static int sd_set_init_para(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &chip->sd_card; - int retval; - - retval = sd_set_sample_push_timing(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - sd_choose_proper_clock(chip); - - retval = switch_clock(chip, sd_card->sd_clock); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} - -int sd_select_card(struct rtsx_chip *chip, int select) -{ - struct sd_info *sd_card = &chip->sd_card; - int retval; - u8 cmd_idx, cmd_type; - u32 addr; - - if (select) { - cmd_idx = SELECT_CARD; - cmd_type = SD_RSP_TYPE_R1; - addr = sd_card->sd_addr; - } else { - cmd_idx = DESELECT_CARD; - cmd_type = SD_RSP_TYPE_R0; - addr = 0; - } - - retval = sd_send_cmd_get_rsp(chip, cmd_idx, addr, cmd_type, NULL, 0); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} - -#ifdef SUPPORT_SD_LOCK -static int sd_update_lock_status(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &chip->sd_card; - int retval; - u8 rsp[5]; - - retval = sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, - SD_RSP_TYPE_R1, rsp, 5); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (rsp[1] & 0x02) - sd_card->sd_lock_status |= SD_LOCKED; - else - sd_card->sd_lock_status &= ~SD_LOCKED; - - dev_dbg(rtsx_dev(chip), "sd_card->sd_lock_status = 0x%x\n", - sd_card->sd_lock_status); - - if (rsp[1] & 0x01) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} -#endif - -static int sd_wait_state_data_ready(struct rtsx_chip *chip, u8 state, - u8 data_ready, int polling_cnt) -{ - struct sd_info *sd_card = &chip->sd_card; - int retval, i; - u8 rsp[5]; - - for (i = 0; i < polling_cnt; i++) { - retval = sd_send_cmd_get_rsp(chip, SEND_STATUS, - sd_card->sd_addr, SD_RSP_TYPE_R1, - rsp, 5); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (((rsp[3] & 0x1E) == state) && - ((rsp[3] & 0x01) == data_ready)) - return STATUS_SUCCESS; - } - - return STATUS_FAIL; -} - -static int sd_change_bank_voltage(struct rtsx_chip *chip, u8 voltage) -{ - int retval; - - if (voltage == SD_IO_3V3) { - if (chip->asic_code) { - retval = rtsx_write_phy_register(chip, 0x08, - 0x4FC0 | - chip->phy_voltage); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } else { - retval = rtsx_write_register(chip, SD_PAD_CTL, - SD_IO_USING_1V8, 0); - if (retval) - return retval; - } - } else if (voltage == SD_IO_1V8) { - if (chip->asic_code) { - retval = rtsx_write_phy_register(chip, 0x08, - 0x4C40 | - chip->phy_voltage); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } else { - retval = rtsx_write_register(chip, SD_PAD_CTL, - SD_IO_USING_1V8, - SD_IO_USING_1V8); - if (retval) - return retval; - } - } else { - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -static int sd_voltage_switch(struct rtsx_chip *chip) -{ - int retval; - u8 stat; - - retval = rtsx_write_register(chip, SD_BUS_STAT, - SD_CLK_TOGGLE_EN | SD_CLK_FORCE_STOP, - SD_CLK_TOGGLE_EN); - if (retval) - return retval; - - retval = sd_send_cmd_get_rsp(chip, VOLTAGE_SWITCH, 0, SD_RSP_TYPE_R1, - NULL, 0); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - udelay(chip->sd_voltage_switch_delay); - - retval = rtsx_read_register(chip, SD_BUS_STAT, &stat); - if (retval) - return retval; - if (stat & (SD_CMD_STATUS | SD_DAT3_STATUS | SD_DAT2_STATUS | - SD_DAT1_STATUS | SD_DAT0_STATUS)) { - return STATUS_FAIL; - } - - retval = rtsx_write_register(chip, SD_BUS_STAT, 0xFF, - SD_CLK_FORCE_STOP); - if (retval) - return retval; - retval = sd_change_bank_voltage(chip, SD_IO_1V8); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - wait_timeout(50); - - retval = rtsx_write_register(chip, SD_BUS_STAT, 0xFF, - SD_CLK_TOGGLE_EN); - if (retval) - return retval; - wait_timeout(10); - - retval = rtsx_read_register(chip, SD_BUS_STAT, &stat); - if (retval) - return retval; - if ((stat & (SD_CMD_STATUS | SD_DAT3_STATUS | SD_DAT2_STATUS | - SD_DAT1_STATUS | SD_DAT0_STATUS)) != - (SD_CMD_STATUS | SD_DAT3_STATUS | SD_DAT2_STATUS | - SD_DAT1_STATUS | SD_DAT0_STATUS)) { - dev_dbg(rtsx_dev(chip), "SD_BUS_STAT: 0x%x\n", stat); - rtsx_write_register(chip, SD_BUS_STAT, SD_CLK_TOGGLE_EN | - SD_CLK_FORCE_STOP, 0); - rtsx_write_register(chip, CARD_CLK_EN, 0xFF, 0); - return STATUS_FAIL; - } - - retval = rtsx_write_register(chip, SD_BUS_STAT, - SD_CLK_TOGGLE_EN | SD_CLK_FORCE_STOP, 0); - if (retval) - return retval; - - return STATUS_SUCCESS; -} - -static int sd_reset_dcm(struct rtsx_chip *chip, u8 tune_dir) -{ - int retval; - - if (tune_dir == TUNE_RX) { - retval = rtsx_write_register(chip, DCM_DRP_CTL, 0xFF, - DCM_RESET | DCM_RX); - if (retval) - return retval; - retval = rtsx_write_register(chip, DCM_DRP_CTL, 0xFF, DCM_RX); - if (retval) - return retval; - } else { - retval = rtsx_write_register(chip, DCM_DRP_CTL, 0xFF, - DCM_RESET | DCM_TX); - if (retval) - return retval; - retval = rtsx_write_register(chip, DCM_DRP_CTL, 0xFF, DCM_TX); - if (retval) - return retval; - } - - return STATUS_SUCCESS; -} - -static int sd_change_phase(struct rtsx_chip *chip, u8 sample_point, u8 tune_dir) -{ - struct sd_info *sd_card = &chip->sd_card; - u16 SD_VP_CTL, SD_DCMPS_CTL; - u8 val; - int retval; - bool ddr_rx = false; - - dev_dbg(rtsx_dev(chip), "%s (sample_point = %d, tune_dir = %d)\n", - __func__, sample_point, tune_dir); - - if (tune_dir == TUNE_RX) { - SD_VP_CTL = SD_VPRX_CTL; - SD_DCMPS_CTL = SD_DCMPS_RX_CTL; - if (CHK_SD_DDR50(sd_card)) - ddr_rx = true; - } else { - SD_VP_CTL = SD_VPTX_CTL; - SD_DCMPS_CTL = SD_DCMPS_TX_CTL; - } - - if (chip->asic_code) { - retval = rtsx_write_register(chip, CLK_CTL, CHANGE_CLK, - CHANGE_CLK); - if (retval) - return retval; - retval = rtsx_write_register(chip, SD_VP_CTL, 0x1F, - sample_point); - if (retval) - return retval; - retval = rtsx_write_register(chip, SD_VPCLK0_CTL, - PHASE_NOT_RESET, 0); - if (retval) - return retval; - retval = rtsx_write_register(chip, SD_VPCLK0_CTL, - PHASE_NOT_RESET, PHASE_NOT_RESET); - if (retval) - return retval; - retval = rtsx_write_register(chip, CLK_CTL, CHANGE_CLK, 0); - if (retval) - return retval; - } else { - rtsx_read_register(chip, SD_VP_CTL, &val); - dev_dbg(rtsx_dev(chip), "SD_VP_CTL: 0x%x\n", val); - rtsx_read_register(chip, SD_DCMPS_CTL, &val); - dev_dbg(rtsx_dev(chip), "SD_DCMPS_CTL: 0x%x\n", val); - - if (ddr_rx) { - retval = rtsx_write_register(chip, SD_VP_CTL, - PHASE_CHANGE, - PHASE_CHANGE); - if (retval) - return retval; - udelay(50); - retval = rtsx_write_register(chip, SD_VP_CTL, 0xFF, - PHASE_CHANGE | - PHASE_NOT_RESET | - sample_point); - if (retval) - return retval; - } else { - retval = rtsx_write_register(chip, CLK_CTL, - CHANGE_CLK, CHANGE_CLK); - if (retval) - return retval; - udelay(50); - retval = rtsx_write_register(chip, SD_VP_CTL, 0xFF, - PHASE_NOT_RESET | - sample_point); - if (retval) - return retval; - } - udelay(100); - - rtsx_init_cmd(chip); - rtsx_add_cmd(chip, WRITE_REG_CMD, SD_DCMPS_CTL, DCMPS_CHANGE, - DCMPS_CHANGE); - rtsx_add_cmd(chip, CHECK_REG_CMD, SD_DCMPS_CTL, - DCMPS_CHANGE_DONE, DCMPS_CHANGE_DONE); - retval = rtsx_send_cmd(chip, SD_CARD, 100); - if (retval != STATUS_SUCCESS) - goto fail; - - val = *rtsx_get_cmd_data(chip); - if (val & DCMPS_ERROR) - goto fail; - - if ((val & DCMPS_CURRENT_PHASE) != sample_point) - goto fail; - - retval = rtsx_write_register(chip, SD_DCMPS_CTL, - DCMPS_CHANGE, 0); - if (retval) - return retval; - if (ddr_rx) { - retval = rtsx_write_register(chip, SD_VP_CTL, - PHASE_CHANGE, 0); - if (retval) - return retval; - } else { - retval = rtsx_write_register(chip, CLK_CTL, - CHANGE_CLK, 0); - if (retval) - return retval; - } - - udelay(50); - } - - retval = rtsx_write_register(chip, SD_CFG1, SD_ASYNC_FIFO_NOT_RST, 0); - if (retval) - return retval; - - return STATUS_SUCCESS; - -fail: - rtsx_read_register(chip, SD_VP_CTL, &val); - dev_dbg(rtsx_dev(chip), "SD_VP_CTL: 0x%x\n", val); - rtsx_read_register(chip, SD_DCMPS_CTL, &val); - dev_dbg(rtsx_dev(chip), "SD_DCMPS_CTL: 0x%x\n", val); - - rtsx_write_register(chip, SD_DCMPS_CTL, DCMPS_CHANGE, 0); - rtsx_write_register(chip, SD_VP_CTL, PHASE_CHANGE, 0); - mdelay(10); - sd_reset_dcm(chip, tune_dir); - return STATUS_FAIL; -} - -static int sd_check_spec(struct rtsx_chip *chip, u8 bus_width) -{ - struct sd_info *sd_card = &chip->sd_card; - int retval; - u8 cmd[5], buf[8]; - - retval = sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr, - SD_RSP_TYPE_R1, NULL, 0); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - cmd[0] = 0x40 | SEND_SCR; - cmd[1] = 0; - cmd[2] = 0; - cmd[3] = 0; - cmd[4] = 0; - - retval = sd_read_data(chip, SD_TM_NORMAL_READ, cmd, 5, 8, 1, bus_width, - buf, 8, 250); - if (retval != STATUS_SUCCESS) { - rtsx_clear_sd_error(chip); - return STATUS_FAIL; - } - - memcpy(sd_card->raw_scr, buf, 8); - - if ((buf[0] & 0x0F) == 0) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} - -static int sd_query_switch_result(struct rtsx_chip *chip, u8 func_group, - u8 func_to_switch, u8 *buf, int buf_len) -{ - u8 support_mask = 0, query_switch = 0, switch_busy = 0; - int support_offset = 0, query_switch_offset = 0, check_busy_offset = 0; - - if (func_group == SD_FUNC_GROUP_1) { - support_offset = FUNCTION_GROUP1_SUPPORT_OFFSET; - query_switch_offset = FUNCTION_GROUP1_QUERY_SWITCH_OFFSET; - check_busy_offset = FUNCTION_GROUP1_CHECK_BUSY_OFFSET; - - switch (func_to_switch) { - case HS_SUPPORT: - support_mask = HS_SUPPORT_MASK; - query_switch = HS_QUERY_SWITCH_OK; - switch_busy = HS_SWITCH_BUSY; - break; - - case SDR50_SUPPORT: - support_mask = SDR50_SUPPORT_MASK; - query_switch = SDR50_QUERY_SWITCH_OK; - switch_busy = SDR50_SWITCH_BUSY; - break; - - case SDR104_SUPPORT: - support_mask = SDR104_SUPPORT_MASK; - query_switch = SDR104_QUERY_SWITCH_OK; - switch_busy = SDR104_SWITCH_BUSY; - break; - - case DDR50_SUPPORT: - support_mask = DDR50_SUPPORT_MASK; - query_switch = DDR50_QUERY_SWITCH_OK; - switch_busy = DDR50_SWITCH_BUSY; - break; - - default: - return STATUS_FAIL; - } - } else if (func_group == SD_FUNC_GROUP_3) { - support_offset = FUNCTION_GROUP3_SUPPORT_OFFSET; - query_switch_offset = FUNCTION_GROUP3_QUERY_SWITCH_OFFSET; - check_busy_offset = FUNCTION_GROUP3_CHECK_BUSY_OFFSET; - - switch (func_to_switch) { - case DRIVING_TYPE_A: - support_mask = DRIVING_TYPE_A_MASK; - query_switch = TYPE_A_QUERY_SWITCH_OK; - switch_busy = TYPE_A_SWITCH_BUSY; - break; - - case DRIVING_TYPE_C: - support_mask = DRIVING_TYPE_C_MASK; - query_switch = TYPE_C_QUERY_SWITCH_OK; - switch_busy = TYPE_C_SWITCH_BUSY; - break; - - case DRIVING_TYPE_D: - support_mask = DRIVING_TYPE_D_MASK; - query_switch = TYPE_D_QUERY_SWITCH_OK; - switch_busy = TYPE_D_SWITCH_BUSY; - break; - - default: - return STATUS_FAIL; - } - } else if (func_group == SD_FUNC_GROUP_4) { - support_offset = FUNCTION_GROUP4_SUPPORT_OFFSET; - query_switch_offset = FUNCTION_GROUP4_QUERY_SWITCH_OFFSET; - check_busy_offset = FUNCTION_GROUP4_CHECK_BUSY_OFFSET; - - switch (func_to_switch) { - case CURRENT_LIMIT_400: - support_mask = CURRENT_LIMIT_400_MASK; - query_switch = CURRENT_LIMIT_400_QUERY_SWITCH_OK; - switch_busy = CURRENT_LIMIT_400_SWITCH_BUSY; - break; - - case CURRENT_LIMIT_600: - support_mask = CURRENT_LIMIT_600_MASK; - query_switch = CURRENT_LIMIT_600_QUERY_SWITCH_OK; - switch_busy = CURRENT_LIMIT_600_SWITCH_BUSY; - break; - - case CURRENT_LIMIT_800: - support_mask = CURRENT_LIMIT_800_MASK; - query_switch = CURRENT_LIMIT_800_QUERY_SWITCH_OK; - switch_busy = CURRENT_LIMIT_800_SWITCH_BUSY; - break; - - default: - return STATUS_FAIL; - } - } else { - return STATUS_FAIL; - } - - if (func_group == SD_FUNC_GROUP_1) { - if (!(buf[support_offset] & support_mask) || - ((buf[query_switch_offset] & 0x0F) != query_switch)) { - return STATUS_FAIL; - } - } - - /* Check 'Busy Status' */ - if (buf[DATA_STRUCTURE_VER_OFFSET] == 0x01 && - ((buf[check_busy_offset] & switch_busy) == switch_busy)) { - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -static int sd_check_switch_mode(struct rtsx_chip *chip, u8 mode, u8 func_group, - u8 func_to_switch, u8 bus_width) -{ - struct sd_info *sd_card = &chip->sd_card; - int retval; - u8 cmd[5], buf[64]; - - dev_dbg(rtsx_dev(chip), "%s (mode = %d, func_group = %d, func_to_switch = %d)\n", - __func__, mode, func_group, func_to_switch); - - cmd[0] = 0x40 | SWITCH; - cmd[1] = mode; - - if (func_group == SD_FUNC_GROUP_1) { - cmd[2] = 0xFF; - cmd[3] = 0xFF; - cmd[4] = 0xF0 + func_to_switch; - } else if (func_group == SD_FUNC_GROUP_3) { - cmd[2] = 0xFF; - cmd[3] = 0xF0 + func_to_switch; - cmd[4] = 0xFF; - } else if (func_group == SD_FUNC_GROUP_4) { - cmd[2] = 0xFF; - cmd[3] = 0x0F + (func_to_switch << 4); - cmd[4] = 0xFF; - } else { - cmd[1] = SD_CHECK_MODE; - cmd[2] = 0xFF; - cmd[3] = 0xFF; - cmd[4] = 0xFF; - } - - retval = sd_read_data(chip, SD_TM_NORMAL_READ, cmd, 5, 64, 1, bus_width, - buf, 64, 250); - if (retval != STATUS_SUCCESS) { - rtsx_clear_sd_error(chip); - return STATUS_FAIL; - } - - dev_dbg(rtsx_dev(chip), "%*ph\n", 64, buf); - - if (func_group == NO_ARGUMENT) { - sd_card->func_group1_mask = buf[0x0D]; - sd_card->func_group2_mask = buf[0x0B]; - sd_card->func_group3_mask = buf[0x09]; - sd_card->func_group4_mask = buf[0x07]; - - dev_dbg(rtsx_dev(chip), "func_group1_mask = 0x%02x\n", - buf[0x0D]); - dev_dbg(rtsx_dev(chip), "func_group2_mask = 0x%02x\n", - buf[0x0B]); - dev_dbg(rtsx_dev(chip), "func_group3_mask = 0x%02x\n", - buf[0x09]); - dev_dbg(rtsx_dev(chip), "func_group4_mask = 0x%02x\n", - buf[0x07]); - } else { - /* Maximum current consumption, check whether current is - * acceptable; bit[511:496] = 0x0000 means some error happened. - */ - u16 cc = ((u16)buf[0] << 8) | buf[1]; - - dev_dbg(rtsx_dev(chip), "Maximum current consumption: %dmA\n", - cc); - if (cc == 0 || cc > 800) - return STATUS_FAIL; - - retval = sd_query_switch_result(chip, func_group, - func_to_switch, buf, 64); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (cc > 400 || func_to_switch > CURRENT_LIMIT_400) { - retval = rtsx_write_register(chip, OCPPARA2, - SD_OCP_THD_MASK, - chip->sd_800mA_ocp_thd); - if (retval) - return retval; - retval = rtsx_write_register(chip, CARD_PWR_CTL, - PMOS_STRG_MASK, - PMOS_STRG_800mA); - if (retval) - return retval; - } - } - - return STATUS_SUCCESS; -} - -static u8 downgrade_switch_mode(u8 func_group, u8 func_to_switch) -{ - if (func_group == SD_FUNC_GROUP_1) { - if (func_to_switch > HS_SUPPORT) - func_to_switch--; - - } else if (func_group == SD_FUNC_GROUP_4) { - if (func_to_switch > CURRENT_LIMIT_200) - func_to_switch--; - } - - return func_to_switch; -} - -static int sd_check_switch(struct rtsx_chip *chip, - u8 func_group, u8 func_to_switch, u8 bus_width) -{ - int retval; - int i; - bool switch_good = false; - - for (i = 0; i < 3; i++) { - if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) { - sd_set_err_code(chip, SD_NO_CARD); - return STATUS_FAIL; - } - - retval = sd_check_switch_mode(chip, SD_CHECK_MODE, func_group, - func_to_switch, bus_width); - if (retval == STATUS_SUCCESS) { - u8 stat; - - retval = sd_check_switch_mode(chip, SD_SWITCH_MODE, - func_group, - func_to_switch, - bus_width); - if (retval == STATUS_SUCCESS) { - switch_good = true; - break; - } - - retval = rtsx_read_register(chip, SD_STAT1, &stat); - if (retval) - return retval; - if (stat & SD_CRC16_ERR) { - dev_dbg(rtsx_dev(chip), "SD CRC16 error when switching mode\n"); - return STATUS_FAIL; - } - } - - func_to_switch = downgrade_switch_mode(func_group, - func_to_switch); - - wait_timeout(20); - } - - if (!switch_good) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} - -static int sd_switch_function(struct rtsx_chip *chip, u8 bus_width) -{ - struct sd_info *sd_card = &chip->sd_card; - int retval; - int i; - u8 func_to_switch = 0; - - /* Get supported functions */ - retval = sd_check_switch_mode(chip, SD_CHECK_MODE, NO_ARGUMENT, - NO_ARGUMENT, bus_width); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - sd_card->func_group1_mask &= ~(sd_card->sd_switch_fail); - - /* Function Group 1: Access Mode */ - for (i = 0; i < 4; i++) { - switch ((u8)(chip->sd_speed_prior >> (i * 8))) { - case SDR104_SUPPORT: - if ((sd_card->func_group1_mask & SDR104_SUPPORT_MASK) && - chip->sdr104_en) { - func_to_switch = SDR104_SUPPORT; - } - break; - - case DDR50_SUPPORT: - if ((sd_card->func_group1_mask & DDR50_SUPPORT_MASK) && - chip->ddr50_en) { - func_to_switch = DDR50_SUPPORT; - } - break; - - case SDR50_SUPPORT: - if ((sd_card->func_group1_mask & SDR50_SUPPORT_MASK) && - chip->sdr50_en) { - func_to_switch = SDR50_SUPPORT; - } - break; - - case HS_SUPPORT: - if (sd_card->func_group1_mask & HS_SUPPORT_MASK) - func_to_switch = HS_SUPPORT; - - break; - - default: - continue; - } - - if (func_to_switch) - break; - } - dev_dbg(rtsx_dev(chip), "SD_FUNC_GROUP_1: func_to_switch = 0x%02x", - func_to_switch); - -#ifdef SUPPORT_SD_LOCK - if ((sd_card->sd_lock_status & SD_SDR_RST) && - func_to_switch == DDR50_SUPPORT && - (sd_card->func_group1_mask & SDR50_SUPPORT_MASK)) { - func_to_switch = SDR50_SUPPORT; - dev_dbg(rtsx_dev(chip), "Using SDR50 instead of DDR50 for SD Lock\n"); - } -#endif - - if (func_to_switch) { - retval = sd_check_switch(chip, SD_FUNC_GROUP_1, func_to_switch, - bus_width); - if (retval != STATUS_SUCCESS) { - if (func_to_switch == SDR104_SUPPORT) { - sd_card->sd_switch_fail = SDR104_SUPPORT_MASK; - } else if (func_to_switch == DDR50_SUPPORT) { - sd_card->sd_switch_fail = SDR104_SUPPORT_MASK | - DDR50_SUPPORT_MASK; - } else if (func_to_switch == SDR50_SUPPORT) { - sd_card->sd_switch_fail = SDR104_SUPPORT_MASK | - DDR50_SUPPORT_MASK | SDR50_SUPPORT_MASK; - } - return STATUS_FAIL; - } - - if (func_to_switch == SDR104_SUPPORT) - SET_SD_SDR104(sd_card); - else if (func_to_switch == DDR50_SUPPORT) - SET_SD_DDR50(sd_card); - else if (func_to_switch == SDR50_SUPPORT) - SET_SD_SDR50(sd_card); - else - SET_SD_HS(sd_card); - } - - if (CHK_SD_DDR50(sd_card)) { - retval = rtsx_write_register(chip, SD_PUSH_POINT_CTL, 0x06, - 0x04); - if (retval) - return retval; - retval = sd_set_sample_push_timing(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - - if (!func_to_switch || func_to_switch == HS_SUPPORT) { - /* Do not try to switch current limit if the card doesn't - * support UHS mode or we don't want it to support UHS mode - */ - return STATUS_SUCCESS; - } - - /* Function Group 4: Current Limit */ - func_to_switch = 0xFF; - - for (i = 0; i < 4; i++) { - switch ((u8)(chip->sd_current_prior >> (i * 8))) { - case CURRENT_LIMIT_800: - if (sd_card->func_group4_mask & CURRENT_LIMIT_800_MASK) - func_to_switch = CURRENT_LIMIT_800; - - break; - - case CURRENT_LIMIT_600: - if (sd_card->func_group4_mask & CURRENT_LIMIT_600_MASK) - func_to_switch = CURRENT_LIMIT_600; - - break; - - case CURRENT_LIMIT_400: - if (sd_card->func_group4_mask & CURRENT_LIMIT_400_MASK) - func_to_switch = CURRENT_LIMIT_400; - - break; - - case CURRENT_LIMIT_200: - if (sd_card->func_group4_mask & CURRENT_LIMIT_200_MASK) - func_to_switch = CURRENT_LIMIT_200; - - break; - - default: - continue; - } - - if (func_to_switch != 0xFF) - break; - } - - dev_dbg(rtsx_dev(chip), "SD_FUNC_GROUP_4: func_to_switch = 0x%02x", - func_to_switch); - - if (func_to_switch <= CURRENT_LIMIT_800) { - retval = sd_check_switch(chip, SD_FUNC_GROUP_4, func_to_switch, - bus_width); - if (retval != STATUS_SUCCESS) { - if (sd_check_err_code(chip, SD_NO_CARD)) - return STATUS_FAIL; - } - dev_dbg(rtsx_dev(chip), "Switch current limit finished! (%d)\n", - retval); - } - - if (CHK_SD_DDR50(sd_card)) { - retval = rtsx_write_register(chip, SD_PUSH_POINT_CTL, 0x06, 0); - if (retval) - return retval; - } - - return STATUS_SUCCESS; -} - -static int sd_wait_data_idle(struct rtsx_chip *chip) -{ - int retval = STATUS_TIMEDOUT; - int i; - u8 val = 0; - - for (i = 0; i < 100; i++) { - retval = rtsx_read_register(chip, SD_DATA_STATE, &val); - if (retval) - return retval; - if (val & SD_DATA_IDLE) { - retval = STATUS_SUCCESS; - break; - } - udelay(100); - } - dev_dbg(rtsx_dev(chip), "SD_DATA_STATE: 0x%02x\n", val); - - return retval; -} - -static int sd_sdr_tuning_rx_cmd(struct rtsx_chip *chip, u8 sample_point) -{ - int retval; - u8 cmd[5]; - - retval = sd_change_phase(chip, sample_point, TUNE_RX); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - cmd[0] = 0x40 | SEND_TUNING_PATTERN; - cmd[1] = 0; - cmd[2] = 0; - cmd[3] = 0; - cmd[4] = 0; - - retval = sd_read_data(chip, SD_TM_AUTO_TUNING, cmd, 5, 0x40, 1, - SD_BUS_WIDTH_4, NULL, 0, 100); - if (retval != STATUS_SUCCESS) { - (void)sd_wait_data_idle(chip); - - rtsx_clear_sd_error(chip); - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -static int sd_ddr_tuning_rx_cmd(struct rtsx_chip *chip, u8 sample_point) -{ - struct sd_info *sd_card = &chip->sd_card; - int retval; - u8 cmd[5]; - - retval = sd_change_phase(chip, sample_point, TUNE_RX); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - dev_dbg(rtsx_dev(chip), "sd ddr tuning rx\n"); - - retval = sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr, - SD_RSP_TYPE_R1, NULL, 0); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - cmd[0] = 0x40 | SD_STATUS; - cmd[1] = 0; - cmd[2] = 0; - cmd[3] = 0; - cmd[4] = 0; - - retval = sd_read_data(chip, SD_TM_NORMAL_READ, cmd, 5, 64, 1, - SD_BUS_WIDTH_4, NULL, 0, 100); - if (retval != STATUS_SUCCESS) { - (void)sd_wait_data_idle(chip); - - rtsx_clear_sd_error(chip); - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -static int mmc_ddr_tuning_rx_cmd(struct rtsx_chip *chip, u8 sample_point) -{ - struct sd_info *sd_card = &chip->sd_card; - int retval; - u8 cmd[5], bus_width; - - if (CHK_MMC_8BIT(sd_card)) - bus_width = SD_BUS_WIDTH_8; - else if (CHK_MMC_4BIT(sd_card)) - bus_width = SD_BUS_WIDTH_4; - else - bus_width = SD_BUS_WIDTH_1; - - retval = sd_change_phase(chip, sample_point, TUNE_RX); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - dev_dbg(rtsx_dev(chip), "mmc ddr tuning rx\n"); - - cmd[0] = 0x40 | SEND_EXT_CSD; - cmd[1] = 0; - cmd[2] = 0; - cmd[3] = 0; - cmd[4] = 0; - - retval = sd_read_data(chip, SD_TM_NORMAL_READ, cmd, 5, 0x200, 1, - bus_width, NULL, 0, 100); - if (retval != STATUS_SUCCESS) { - (void)sd_wait_data_idle(chip); - - rtsx_clear_sd_error(chip); - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -static int sd_sdr_tuning_tx_cmd(struct rtsx_chip *chip, u8 sample_point) -{ - struct sd_info *sd_card = &chip->sd_card; - int retval; - - retval = sd_change_phase(chip, sample_point, TUNE_TX); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = rtsx_write_register(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, - SD_RSP_80CLK_TIMEOUT_EN); - if (retval) - return retval; - - retval = sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, - SD_RSP_TYPE_R1, NULL, 0); - if (retval != STATUS_SUCCESS) { - if (sd_check_err_code(chip, SD_RSP_TIMEOUT)) { - rtsx_write_register(chip, SD_CFG3, - SD_RSP_80CLK_TIMEOUT_EN, 0); - return STATUS_FAIL; - } - } - - retval = rtsx_write_register(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, - 0); - if (retval) - return retval; - - return STATUS_SUCCESS; -} - -static int sd_ddr_tuning_tx_cmd(struct rtsx_chip *chip, u8 sample_point) -{ - struct sd_info *sd_card = &chip->sd_card; - int retval; - u8 cmd[5], bus_width; - - retval = sd_change_phase(chip, sample_point, TUNE_TX); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (CHK_SD(sd_card)) { - bus_width = SD_BUS_WIDTH_4; - } else { - if (CHK_MMC_8BIT(sd_card)) - bus_width = SD_BUS_WIDTH_8; - else if (CHK_MMC_4BIT(sd_card)) - bus_width = SD_BUS_WIDTH_4; - else - bus_width = SD_BUS_WIDTH_1; - } - - retval = sd_wait_state_data_ready(chip, 0x08, 1, 1000); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = rtsx_write_register(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, - SD_RSP_80CLK_TIMEOUT_EN); - if (retval) - return retval; - - cmd[0] = 0x40 | PROGRAM_CSD; - cmd[1] = 0; - cmd[2] = 0; - cmd[3] = 0; - cmd[4] = 0; - - retval = sd_write_data(chip, SD_TM_AUTO_WRITE_2, cmd, 5, 16, 1, - bus_width, sd_card->raw_csd, 16, 100); - if (retval != STATUS_SUCCESS) { - rtsx_clear_sd_error(chip); - rtsx_write_register(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, 0); - return STATUS_FAIL; - } - - retval = rtsx_write_register(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, - 0); - if (retval) - return retval; - - sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, SD_RSP_TYPE_R1, - NULL, 0); - - return STATUS_SUCCESS; -} - -static u8 sd_search_final_phase(struct rtsx_chip *chip, u32 phase_map, - u8 tune_dir) -{ - struct sd_info *sd_card = &chip->sd_card; - struct timing_phase_path path[MAX_PHASE + 1]; - int i, j, cont_path_cnt; - bool new_block; - int max_len, final_path_idx; - u8 final_phase = 0xFF; - - if (phase_map == 0xFFFFFFFF) { - if (tune_dir == TUNE_RX) - final_phase = (u8)chip->sd_default_rx_phase; - else - final_phase = (u8)chip->sd_default_tx_phase; - - goto search_finish; - } - - cont_path_cnt = 0; - new_block = true; - j = 0; - for (i = 0; i < MAX_PHASE + 1; i++) { - if (phase_map & (1 << i)) { - if (new_block) { - new_block = false; - j = cont_path_cnt++; - path[j].start = i; - path[j].end = i; - } else { - path[j].end = i; - } - } else { - new_block = true; - if (cont_path_cnt) { - int idx = cont_path_cnt - 1; - - path[idx].len = path[idx].end - - path[idx].start + 1; - path[idx].mid = path[idx].start + - path[idx].len / 2; - } - } - } - - if (cont_path_cnt == 0) { - dev_dbg(rtsx_dev(chip), "No continuous phase path\n"); - goto search_finish; - } else { - int idx = cont_path_cnt - 1; - - path[idx].len = path[idx].end - path[idx].start + 1; - path[idx].mid = path[idx].start + path[idx].len / 2; - } - - if (path[0].start == 0 && - path[cont_path_cnt - 1].end == MAX_PHASE) { - path[0].start = path[cont_path_cnt - 1].start - MAX_PHASE - 1; - path[0].len += path[cont_path_cnt - 1].len; - path[0].mid = path[0].start + path[0].len / 2; - if (path[0].mid < 0) - path[0].mid += MAX_PHASE + 1; - - cont_path_cnt--; - } - - max_len = 0; - final_phase = 0; - final_path_idx = 0; - for (i = 0; i < cont_path_cnt; i++) { - if (path[i].len > max_len) { - max_len = path[i].len; - final_phase = (u8)path[i].mid; - final_path_idx = i; - } - - dev_dbg(rtsx_dev(chip), "path[%d].start = %d\n", - i, path[i].start); - dev_dbg(rtsx_dev(chip), "path[%d].end = %d\n", i, path[i].end); - dev_dbg(rtsx_dev(chip), "path[%d].len = %d\n", i, path[i].len); - dev_dbg(rtsx_dev(chip), "path[%d].mid = %d\n", i, path[i].mid); - dev_dbg(rtsx_dev(chip), "\n"); - } - - if (tune_dir == TUNE_TX) { - if (CHK_SD_SDR104(sd_card)) { - if (max_len > 15) { - int temp_mid = (max_len - 16) / 2; - int temp_final_phase = - path[final_path_idx].end - - (max_len - (6 + temp_mid)); - - if (temp_final_phase < 0) - final_phase = (u8)(temp_final_phase + - MAX_PHASE + 1); - else - final_phase = (u8)temp_final_phase; - } - } else if (CHK_SD_SDR50(sd_card)) { - if (max_len > 12) { - int temp_mid = (max_len - 13) / 2; - int temp_final_phase = - path[final_path_idx].end - - (max_len - (3 + temp_mid)); - - if (temp_final_phase < 0) - final_phase = (u8)(temp_final_phase + - MAX_PHASE + 1); - else - final_phase = (u8)temp_final_phase; - } - } - } - -search_finish: - dev_dbg(rtsx_dev(chip), "Final chosen phase: %d\n", final_phase); - return final_phase; -} - -static int sd_tuning_rx(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &chip->sd_card; - int retval; - int i, j; - u32 raw_phase_map[3], phase_map; - u8 final_phase; - int (*tuning_cmd)(struct rtsx_chip *chip, u8 sample_point); - - if (CHK_SD(sd_card)) { - if (CHK_SD_DDR50(sd_card)) - tuning_cmd = sd_ddr_tuning_rx_cmd; - else - tuning_cmd = sd_sdr_tuning_rx_cmd; - - } else { - if (CHK_MMC_DDR52(sd_card)) - tuning_cmd = mmc_ddr_tuning_rx_cmd; - else - return STATUS_FAIL; - } - - for (i = 0; i < 3; i++) { - raw_phase_map[i] = 0; - for (j = MAX_PHASE; j >= 0; j--) { - if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) { - sd_set_err_code(chip, SD_NO_CARD); - return STATUS_FAIL; - } - - retval = tuning_cmd(chip, (u8)j); - if (retval == STATUS_SUCCESS) - raw_phase_map[i] |= 1 << j; - } - } - - phase_map = raw_phase_map[0] & raw_phase_map[1] & raw_phase_map[2]; - for (i = 0; i < 3; i++) - dev_dbg(rtsx_dev(chip), "RX raw_phase_map[%d] = 0x%08x\n", - i, raw_phase_map[i]); - - dev_dbg(rtsx_dev(chip), "RX phase_map = 0x%08x\n", phase_map); - - final_phase = sd_search_final_phase(chip, phase_map, TUNE_RX); - if (final_phase == 0xFF) - return STATUS_FAIL; - - retval = sd_change_phase(chip, final_phase, TUNE_RX); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} - -static int sd_ddr_pre_tuning_tx(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &chip->sd_card; - int retval; - int i; - u32 phase_map; - u8 final_phase; - - retval = rtsx_write_register(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, - SD_RSP_80CLK_TIMEOUT_EN); - if (retval) - return retval; - - phase_map = 0; - for (i = MAX_PHASE; i >= 0; i--) { - if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) { - sd_set_err_code(chip, SD_NO_CARD); - rtsx_write_register(chip, SD_CFG3, - SD_RSP_80CLK_TIMEOUT_EN, 0); - return STATUS_FAIL; - } - - retval = sd_change_phase(chip, (u8)i, TUNE_TX); - if (retval != STATUS_SUCCESS) - continue; - - retval = sd_send_cmd_get_rsp(chip, SEND_STATUS, - sd_card->sd_addr, SD_RSP_TYPE_R1, - NULL, 0); - if (retval == STATUS_SUCCESS || - !sd_check_err_code(chip, SD_RSP_TIMEOUT)) - phase_map |= 1 << i; - } - - retval = rtsx_write_register(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, - 0); - if (retval) - return retval; - - dev_dbg(rtsx_dev(chip), "DDR TX pre tune phase_map = 0x%08x\n", - phase_map); - - final_phase = sd_search_final_phase(chip, phase_map, TUNE_TX); - if (final_phase == 0xFF) - return STATUS_FAIL; - - retval = sd_change_phase(chip, final_phase, TUNE_TX); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - dev_dbg(rtsx_dev(chip), "DDR TX pre tune phase: %d\n", - (int)final_phase); - - return STATUS_SUCCESS; -} - -static int sd_tuning_tx(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &chip->sd_card; - int retval; - int i, j; - u32 raw_phase_map[3], phase_map; - u8 final_phase; - int (*tuning_cmd)(struct rtsx_chip *chip, u8 sample_point); - - if (CHK_SD(sd_card)) { - if (CHK_SD_DDR50(sd_card)) - tuning_cmd = sd_ddr_tuning_tx_cmd; - else - tuning_cmd = sd_sdr_tuning_tx_cmd; - - } else { - if (CHK_MMC_DDR52(sd_card)) - tuning_cmd = sd_ddr_tuning_tx_cmd; - else - return STATUS_FAIL; - } - - for (i = 0; i < 3; i++) { - raw_phase_map[i] = 0; - for (j = MAX_PHASE; j >= 0; j--) { - if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) { - sd_set_err_code(chip, SD_NO_CARD); - rtsx_write_register(chip, SD_CFG3, - SD_RSP_80CLK_TIMEOUT_EN, 0); - return STATUS_FAIL; - } - - retval = tuning_cmd(chip, (u8)j); - if (retval == STATUS_SUCCESS) - raw_phase_map[i] |= 1 << j; - } - } - - phase_map = raw_phase_map[0] & raw_phase_map[1] & raw_phase_map[2]; - for (i = 0; i < 3; i++) - dev_dbg(rtsx_dev(chip), "TX raw_phase_map[%d] = 0x%08x\n", - i, raw_phase_map[i]); - - dev_dbg(rtsx_dev(chip), "TX phase_map = 0x%08x\n", phase_map); - - final_phase = sd_search_final_phase(chip, phase_map, TUNE_TX); - if (final_phase == 0xFF) - return STATUS_FAIL; - - retval = sd_change_phase(chip, final_phase, TUNE_TX); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} - -static int sd_sdr_tuning(struct rtsx_chip *chip) -{ - int retval; - - retval = sd_tuning_tx(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = sd_tuning_rx(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} - -static int sd_ddr_tuning(struct rtsx_chip *chip) -{ - int retval; - - if (!(chip->sd_ctl & SD_DDR_TX_PHASE_SET_BY_USER)) { - retval = sd_ddr_pre_tuning_tx(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } else { - retval = sd_change_phase(chip, (u8)chip->sd_ddr_tx_phase, - TUNE_TX); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - - retval = sd_tuning_rx(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (!(chip->sd_ctl & SD_DDR_TX_PHASE_SET_BY_USER)) { - retval = sd_tuning_tx(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -static int mmc_ddr_tuning(struct rtsx_chip *chip) -{ - int retval; - - if (!(chip->sd_ctl & MMC_DDR_TX_PHASE_SET_BY_USER)) { - retval = sd_ddr_pre_tuning_tx(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } else { - retval = sd_change_phase(chip, (u8)chip->mmc_ddr_tx_phase, - TUNE_TX); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - - retval = sd_tuning_rx(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (!(chip->sd_ctl & MMC_DDR_TX_PHASE_SET_BY_USER)) { - retval = sd_tuning_tx(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -int sd_switch_clock(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &chip->sd_card; - int retval; - int re_tuning = 0; - - retval = select_card(chip, SD_CARD); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = switch_clock(chip, sd_card->sd_clock); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (re_tuning) { - if (CHK_SD(sd_card)) { - if (CHK_SD_DDR50(sd_card)) - retval = sd_ddr_tuning(chip); - else - retval = sd_sdr_tuning(chip); - } else { - if (CHK_MMC_DDR52(sd_card)) - retval = mmc_ddr_tuning(chip); - } - - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -static int sd_prepare_reset(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &chip->sd_card; - int retval; - - if (chip->asic_code) - sd_card->sd_clock = 29; - else - sd_card->sd_clock = CLK_30; - - sd_card->sd_type = 0; - sd_card->seq_mode = 0; - sd_card->sd_data_buf_ready = 0; - sd_card->capacity = 0; - -#ifdef SUPPORT_SD_LOCK - sd_card->sd_lock_status = 0; - sd_card->sd_erase_status = 0; -#endif - - chip->capacity[chip->card2lun[SD_CARD]] = 0; - chip->sd_io = 0; - - retval = sd_set_init_para(chip); - if (retval != STATUS_SUCCESS) - return retval; - - retval = rtsx_write_register(chip, REG_SD_CFG1, 0xFF, 0x40); - if (retval) - return retval; - - retval = rtsx_write_register(chip, CARD_STOP, SD_STOP | SD_CLR_ERR, - SD_STOP | SD_CLR_ERR); - if (retval) - return retval; - - retval = select_card(chip, SD_CARD); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} - -static int sd_pull_ctl_disable(struct rtsx_chip *chip) -{ - int retval; - - if (CHECK_PID(chip, 0x5208)) { - retval = rtsx_write_register(chip, CARD_PULL_CTL1, 0xFF, - XD_D3_PD | SD_D7_PD | SD_CLK_PD | - SD_D5_PD); - if (retval) - return retval; - retval = rtsx_write_register(chip, CARD_PULL_CTL2, 0xFF, - SD_D6_PD | SD_D0_PD | SD_D1_PD | - XD_D5_PD); - if (retval) - return retval; - retval = rtsx_write_register(chip, CARD_PULL_CTL3, 0xFF, - SD_D4_PD | XD_CE_PD | XD_CLE_PD | - XD_CD_PU); - if (retval) - return retval; - retval = rtsx_write_register(chip, CARD_PULL_CTL4, 0xFF, - XD_RDY_PD | SD_D3_PD | SD_D2_PD | - XD_ALE_PD); - if (retval) - return retval; - retval = rtsx_write_register(chip, CARD_PULL_CTL5, 0xFF, - MS_INS_PU | SD_WP_PD | SD_CD_PU | - SD_CMD_PD); - if (retval) - return retval; - retval = rtsx_write_register(chip, CARD_PULL_CTL6, 0xFF, - MS_D5_PD | MS_D4_PD); - if (retval) - return retval; - } else if (CHECK_PID(chip, 0x5288)) { - if (CHECK_BARO_PKG(chip, QFN)) { - retval = rtsx_write_register(chip, CARD_PULL_CTL1, - 0xFF, 0x55); - if (retval) - return retval; - retval = rtsx_write_register(chip, CARD_PULL_CTL2, - 0xFF, 0x55); - if (retval) - return retval; - retval = rtsx_write_register(chip, CARD_PULL_CTL3, - 0xFF, 0x4B); - if (retval) - return retval; - retval = rtsx_write_register(chip, CARD_PULL_CTL4, - 0xFF, 0x69); - if (retval) - return retval; - } - } - - return STATUS_SUCCESS; -} - -int sd_pull_ctl_enable(struct rtsx_chip *chip) -{ - int retval; - - rtsx_init_cmd(chip); - - if (CHECK_PID(chip, 0x5208)) { - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, - XD_D3_PD | SD_DAT7_PU | SD_CLK_NP | SD_D5_PU); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, - SD_D6_PU | SD_D0_PU | SD_D1_PU | XD_D5_PD); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, - SD_D4_PU | XD_CE_PD | XD_CLE_PD | XD_CD_PU); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, - XD_RDY_PD | SD_D3_PU | SD_D2_PU | XD_ALE_PD); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF, - MS_INS_PU | SD_WP_PU | SD_CD_PU | SD_CMD_PU); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, - MS_D5_PD | MS_D4_PD); - } else if (CHECK_PID(chip, 0x5288)) { - if (CHECK_BARO_PKG(chip, QFN)) { - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, - 0xA8); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, - 0x5A); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, - 0x95); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, - 0xAA); - } - } - - retval = rtsx_send_cmd(chip, SD_CARD, 100); - if (retval < 0) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} - -static int sd_init_power(struct rtsx_chip *chip) -{ - int retval; - - retval = sd_power_off_card3v3(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (!chip->ft2_fast_mode) - wait_timeout(250); - - retval = enable_card_clock(chip, SD_CARD); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (chip->asic_code) { - retval = sd_pull_ctl_enable(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } else { - retval = rtsx_write_register(chip, FPGA_PULL_CTL, - FPGA_SD_PULL_CTL_BIT | 0x20, 0); - if (retval) - return retval; - } - - if (!chip->ft2_fast_mode) { - retval = card_power_on(chip, SD_CARD); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - wait_timeout(260); - -#ifdef SUPPORT_OCP - if (chip->ocp_stat & (SD_OC_NOW | SD_OC_EVER)) { - dev_dbg(rtsx_dev(chip), "Over current, OCPSTAT is 0x%x\n", - chip->ocp_stat); - return STATUS_FAIL; - } -#endif - } - - retval = rtsx_write_register(chip, CARD_OE, SD_OUTPUT_EN, - SD_OUTPUT_EN); - if (retval) - return retval; - - return STATUS_SUCCESS; -} - -static int sd_dummy_clock(struct rtsx_chip *chip) -{ - int retval; - - retval = rtsx_write_register(chip, REG_SD_CFG3, 0x01, 0x01); - if (retval) - return retval; - wait_timeout(5); - retval = rtsx_write_register(chip, REG_SD_CFG3, 0x01, 0); - if (retval) - return retval; - - return STATUS_SUCCESS; -} - -static int sd_read_lba0(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &chip->sd_card; - int retval; - u8 cmd[5], bus_width; - - cmd[0] = 0x40 | READ_SINGLE_BLOCK; - cmd[1] = 0; - cmd[2] = 0; - cmd[3] = 0; - cmd[4] = 0; - - if (CHK_SD(sd_card)) { - bus_width = SD_BUS_WIDTH_4; - } else { - if (CHK_MMC_8BIT(sd_card)) - bus_width = SD_BUS_WIDTH_8; - else if (CHK_MMC_4BIT(sd_card)) - bus_width = SD_BUS_WIDTH_4; - else - bus_width = SD_BUS_WIDTH_1; - } - - retval = sd_read_data(chip, SD_TM_NORMAL_READ, cmd, 5, 512, 1, - bus_width, NULL, 0, 100); - if (retval != STATUS_SUCCESS) { - rtsx_clear_sd_error(chip); - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -static int sd_check_wp_state(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &chip->sd_card; - int retval; - u32 val; - u16 sd_card_type; - u8 cmd[5], buf[64]; - - retval = sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr, - SD_RSP_TYPE_R1, NULL, 0); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - cmd[0] = 0x40 | SD_STATUS; - cmd[1] = 0; - cmd[2] = 0; - cmd[3] = 0; - cmd[4] = 0; - - retval = sd_read_data(chip, SD_TM_NORMAL_READ, cmd, 5, 64, 1, - SD_BUS_WIDTH_4, buf, 64, 250); - if (retval != STATUS_SUCCESS) { - rtsx_clear_sd_error(chip); - - sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, - SD_RSP_TYPE_R1, NULL, 0); - return STATUS_FAIL; - } - - dev_dbg(rtsx_dev(chip), "ACMD13:\n"); - dev_dbg(rtsx_dev(chip), "%*ph\n", 64, buf); - - sd_card_type = ((u16)buf[2] << 8) | buf[3]; - dev_dbg(rtsx_dev(chip), "sd_card_type = 0x%04x\n", sd_card_type); - if (sd_card_type == 0x0001 || sd_card_type == 0x0002) { - /* ROM card or OTP */ - chip->card_wp |= SD_CARD; - } - - /* Check SD Machanical Write-Protect Switch */ - val = rtsx_readl(chip, RTSX_BIPR); - if (val & SD_WRITE_PROTECT) - chip->card_wp |= SD_CARD; - - return STATUS_SUCCESS; -} - -static int reset_sd(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &chip->sd_card; - bool hi_cap_flow = false; - int retval, i = 0, j = 0, k = 0; - bool sd_dont_switch = false; - bool support_1v8 = false; - bool try_sdio = true; - u8 rsp[16]; - u8 switch_bus_width; - u32 voltage = 0; - bool sd20_mode = false; - - SET_SD(sd_card); - -switch_fail: - - i = 0; - j = 0; - k = 0; - hi_cap_flow = false; - -#ifdef SUPPORT_SD_LOCK - if (sd_card->sd_lock_status & SD_UNLOCK_POW_ON) - goto SD_UNLOCK_ENTRY; -#endif - - retval = sd_prepare_reset(chip); - if (retval != STATUS_SUCCESS) - goto status_fail; - - retval = sd_dummy_clock(chip); - if (retval != STATUS_SUCCESS) - goto status_fail; - - if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip) && try_sdio) { - int rty_cnt = 0; - - for (; rty_cnt < chip->sdio_retry_cnt; rty_cnt++) { - if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) { - sd_set_err_code(chip, SD_NO_CARD); - goto status_fail; - } - - retval = sd_send_cmd_get_rsp(chip, IO_SEND_OP_COND, 0, - SD_RSP_TYPE_R4, rsp, 5); - if (retval == STATUS_SUCCESS) { - int func_num = (rsp[1] >> 4) & 0x07; - - if (func_num) { - dev_dbg(rtsx_dev(chip), "SD_IO card (Function number: %d)!\n", - func_num); - chip->sd_io = 1; - goto status_fail; - } - - break; - } - - sd_init_power(chip); - - sd_dummy_clock(chip); - } - - dev_dbg(rtsx_dev(chip), "Normal card!\n"); - } - - /* Start Initialization Process of SD Card */ -RTY_SD_RST: - retval = sd_send_cmd_get_rsp(chip, GO_IDLE_STATE, 0, SD_RSP_TYPE_R0, - NULL, 0); - if (retval != STATUS_SUCCESS) - goto status_fail; - - wait_timeout(20); - - retval = sd_send_cmd_get_rsp(chip, SEND_IF_COND, 0x000001AA, - SD_RSP_TYPE_R7, rsp, 5); - if (retval == STATUS_SUCCESS) { - if (rsp[4] == 0xAA && ((rsp[3] & 0x0f) == 0x01)) { - hi_cap_flow = true; - voltage = SUPPORT_VOLTAGE | 0x40000000; - } - } - - if (!hi_cap_flow) { - voltage = SUPPORT_VOLTAGE; - - retval = sd_send_cmd_get_rsp(chip, GO_IDLE_STATE, 0, - SD_RSP_TYPE_R0, NULL, 0); - if (retval != STATUS_SUCCESS) - goto status_fail; - - wait_timeout(20); - } - - do { - retval = sd_send_cmd_get_rsp(chip, APP_CMD, 0, SD_RSP_TYPE_R1, - NULL, 0); - if (retval != STATUS_SUCCESS) { - if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) { - sd_set_err_code(chip, SD_NO_CARD); - goto status_fail; - } - - j++; - if (j < 3) - goto RTY_SD_RST; - else - goto status_fail; - } - - retval = sd_send_cmd_get_rsp(chip, SD_APP_OP_COND, voltage, - SD_RSP_TYPE_R3, rsp, 5); - if (retval != STATUS_SUCCESS) { - k++; - if (k < 3) - goto RTY_SD_RST; - else - goto status_fail; - } - - i++; - wait_timeout(20); - } while (!(rsp[1] & 0x80) && (i < 255)); - - if (i == 255) - goto status_fail; - - if (hi_cap_flow) { - if (rsp[1] & 0x40) - SET_SD_HCXC(sd_card); - else - CLR_SD_HCXC(sd_card); - - support_1v8 = false; - } else { - CLR_SD_HCXC(sd_card); - support_1v8 = false; - } - dev_dbg(rtsx_dev(chip), "support_1v8 = %d\n", support_1v8); - - if (support_1v8) { - retval = sd_voltage_switch(chip); - if (retval != STATUS_SUCCESS) - goto status_fail; - } - - retval = sd_send_cmd_get_rsp(chip, ALL_SEND_CID, 0, SD_RSP_TYPE_R2, - NULL, 0); - if (retval != STATUS_SUCCESS) - goto status_fail; - - for (i = 0; i < 3; i++) { - retval = sd_send_cmd_get_rsp(chip, SEND_RELATIVE_ADDR, 0, - SD_RSP_TYPE_R6, rsp, 5); - if (retval != STATUS_SUCCESS) - goto status_fail; - - sd_card->sd_addr = (u32)rsp[1] << 24; - sd_card->sd_addr += (u32)rsp[2] << 16; - - if (sd_card->sd_addr) - break; - } - - retval = sd_check_csd(chip, 1); - if (retval != STATUS_SUCCESS) - goto status_fail; - - retval = sd_select_card(chip, 1); - if (retval != STATUS_SUCCESS) - goto status_fail; - -#ifdef SUPPORT_SD_LOCK -SD_UNLOCK_ENTRY: - retval = sd_update_lock_status(chip); - if (retval != STATUS_SUCCESS) - goto status_fail; - - if (sd_card->sd_lock_status & SD_LOCKED) { - sd_card->sd_lock_status |= (SD_LOCK_1BIT_MODE | SD_PWD_EXIST); - return STATUS_SUCCESS; - } else if (!(sd_card->sd_lock_status & SD_UNLOCK_POW_ON)) { - sd_card->sd_lock_status &= ~SD_PWD_EXIST; - } -#endif - - retval = sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr, - SD_RSP_TYPE_R1, NULL, 0); - if (retval != STATUS_SUCCESS) - goto status_fail; - - retval = sd_send_cmd_get_rsp(chip, SET_CLR_CARD_DETECT, 0, - SD_RSP_TYPE_R1, NULL, 0); - if (retval != STATUS_SUCCESS) - goto status_fail; - - if (support_1v8) { - retval = sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr, - SD_RSP_TYPE_R1, NULL, 0); - if (retval != STATUS_SUCCESS) - goto status_fail; - - retval = sd_send_cmd_get_rsp(chip, SET_BUS_WIDTH, 2, - SD_RSP_TYPE_R1, NULL, 0); - if (retval != STATUS_SUCCESS) - goto status_fail; - - switch_bus_width = SD_BUS_WIDTH_4; - } else { - switch_bus_width = SD_BUS_WIDTH_1; - } - - retval = sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, 0x200, SD_RSP_TYPE_R1, - NULL, 0); - if (retval != STATUS_SUCCESS) - goto status_fail; - - retval = sd_set_clock_divider(chip, SD_CLK_DIVIDE_0); - if (retval != STATUS_SUCCESS) - goto status_fail; - - if (!(sd_card->raw_csd[4] & 0x40)) - sd_dont_switch = true; - - if (!sd_dont_switch) { - if (sd20_mode) { - /* Set sd_switch_fail here, because we needn't - * switch to UHS mode - */ - sd_card->sd_switch_fail = SDR104_SUPPORT_MASK | - DDR50_SUPPORT_MASK | SDR50_SUPPORT_MASK; - } - - /* Check the card whether follow SD1.1 spec or higher */ - retval = sd_check_spec(chip, switch_bus_width); - if (retval == STATUS_SUCCESS) { - retval = sd_switch_function(chip, switch_bus_width); - if (retval != STATUS_SUCCESS) { - sd_init_power(chip); - sd_dont_switch = true; - try_sdio = false; - - goto switch_fail; - } - } else { - if (support_1v8) { - sd_init_power(chip); - sd_dont_switch = true; - try_sdio = false; - - goto switch_fail; - } - } - } - - if (!support_1v8) { - retval = sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr, - SD_RSP_TYPE_R1, NULL, 0); - if (retval != STATUS_SUCCESS) - goto status_fail; - - retval = sd_send_cmd_get_rsp(chip, SET_BUS_WIDTH, 2, - SD_RSP_TYPE_R1, NULL, 0); - if (retval != STATUS_SUCCESS) - goto status_fail; - } - -#ifdef SUPPORT_SD_LOCK - sd_card->sd_lock_status &= ~SD_LOCK_1BIT_MODE; -#endif - - if (!sd20_mode && CHK_SD30_SPEED(sd_card)) { - int read_lba0 = 1; - - retval = rtsx_write_register(chip, SD30_DRIVE_SEL, 0x07, - chip->sd30_drive_sel_1v8); - if (retval) - return retval; - - retval = sd_set_init_para(chip); - if (retval != STATUS_SUCCESS) - goto status_fail; - - if (CHK_SD_DDR50(sd_card)) - retval = sd_ddr_tuning(chip); - else - retval = sd_sdr_tuning(chip); - - if (retval != STATUS_SUCCESS) { - retval = sd_init_power(chip); - if (retval != STATUS_SUCCESS) - goto status_fail; - - try_sdio = false; - sd20_mode = true; - goto switch_fail; - } - - sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, - SD_RSP_TYPE_R1, NULL, 0); - - if (CHK_SD_DDR50(sd_card)) { - retval = sd_wait_state_data_ready(chip, 0x08, 1, 1000); - if (retval != STATUS_SUCCESS) - read_lba0 = 0; - } - - if (read_lba0) { - retval = sd_read_lba0(chip); - if (retval != STATUS_SUCCESS) { - retval = sd_init_power(chip); - if (retval != STATUS_SUCCESS) - goto status_fail; - - try_sdio = false; - sd20_mode = true; - goto switch_fail; - } - } - } - - retval = sd_check_wp_state(chip); - if (retval != STATUS_SUCCESS) - goto status_fail; - - chip->card_bus_width[chip->card2lun[SD_CARD]] = 4; - -#ifdef SUPPORT_SD_LOCK - if (sd_card->sd_lock_status & SD_UNLOCK_POW_ON) { - retval = rtsx_write_register(chip, REG_SD_BLOCK_CNT_H, 0xFF, - 0x02); - if (retval) - return retval; - retval = rtsx_write_register(chip, REG_SD_BLOCK_CNT_L, 0xFF, - 0x00); - if (retval) - return retval; - } -#endif - - return STATUS_SUCCESS; - -status_fail: - return STATUS_FAIL; -} - -static int mmc_test_switch_bus(struct rtsx_chip *chip, u8 width) -{ - struct sd_info *sd_card = &chip->sd_card; - int retval; - u8 buf[8] = {0}, bus_width, *ptr; - u16 byte_cnt; - int len; - - retval = sd_send_cmd_get_rsp(chip, BUSTEST_W, 0, SD_RSP_TYPE_R1, NULL, - 0); - if (retval != STATUS_SUCCESS) - return SWITCH_FAIL; - - if (width == MMC_8BIT_BUS) { - buf[0] = 0x55; - buf[1] = 0xAA; - len = 8; - byte_cnt = 8; - bus_width = SD_BUS_WIDTH_8; - } else { - buf[0] = 0x5A; - len = 4; - byte_cnt = 4; - bus_width = SD_BUS_WIDTH_4; - } - - retval = rtsx_write_register(chip, REG_SD_CFG3, 0x02, 0x02); - if (retval != STATUS_SUCCESS) - return SWITCH_ERR; - - retval = sd_write_data(chip, SD_TM_AUTO_WRITE_3, NULL, 0, byte_cnt, 1, - bus_width, buf, len, 100); - if (retval != STATUS_SUCCESS) { - rtsx_clear_sd_error(chip); - rtsx_write_register(chip, REG_SD_CFG3, 0x02, 0); - return SWITCH_ERR; - } - - retval = rtsx_write_register(chip, REG_SD_CFG3, 0x02, 0); - if (retval != STATUS_SUCCESS) - return SWITCH_ERR; - - dev_dbg(rtsx_dev(chip), "SD/MMC CMD %d\n", BUSTEST_R); - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD0, 0xFF, 0x40 | BUSTEST_R); - - if (width == MMC_8BIT_BUS) - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_L, - 0xFF, 0x08); - else - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_L, - 0xFF, 0x04); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_L, 0xFF, 1); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_H, 0xFF, 0); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF, SD_CALCULATE_CRC7 | - SD_NO_CHECK_CRC16 | SD_NO_WAIT_BUSY_END | - SD_CHECK_CRC7 | SD_RSP_LEN_6); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, - PINGPONG_BUFFER); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF, - SD_TM_NORMAL_READ | SD_TRANSFER_START); - rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, SD_TRANSFER_END, - SD_TRANSFER_END); - - rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2, 0, 0); - if (width == MMC_8BIT_BUS) - rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + 1, 0, 0); - - retval = rtsx_send_cmd(chip, SD_CARD, 100); - if (retval < 0) { - rtsx_clear_sd_error(chip); - return SWITCH_ERR; - } - - ptr = rtsx_get_cmd_data(chip) + 1; - - if (width == MMC_8BIT_BUS) { - dev_dbg(rtsx_dev(chip), "BUSTEST_R [8bits]: 0x%02x 0x%02x\n", - ptr[0], ptr[1]); - if (ptr[0] == 0xAA && ptr[1] == 0x55) { - u8 rsp[5]; - u32 arg; - - if (CHK_MMC_DDR52(sd_card)) - arg = 0x03B70600; - else - arg = 0x03B70200; - - retval = sd_send_cmd_get_rsp(chip, SWITCH, arg, - SD_RSP_TYPE_R1b, rsp, 5); - if (retval == STATUS_SUCCESS && - !(rsp[4] & MMC_SWITCH_ERR)) - return SWITCH_SUCCESS; - } - } else { - dev_dbg(rtsx_dev(chip), "BUSTEST_R [4bits]: 0x%02x\n", ptr[0]); - if (ptr[0] == 0xA5) { - u8 rsp[5]; - u32 arg; - - if (CHK_MMC_DDR52(sd_card)) - arg = 0x03B70500; - else - arg = 0x03B70100; - - retval = sd_send_cmd_get_rsp(chip, SWITCH, arg, - SD_RSP_TYPE_R1b, rsp, 5); - if (retval == STATUS_SUCCESS && - !(rsp[4] & MMC_SWITCH_ERR)) - return SWITCH_SUCCESS; - } - } - - return SWITCH_FAIL; -} - -static int mmc_switch_timing_bus(struct rtsx_chip *chip, bool switch_ddr) -{ - struct sd_info *sd_card = &chip->sd_card; - int retval; - u8 *ptr, card_type, card_type_mask = 0; - - CLR_MMC_HS(sd_card); - - dev_dbg(rtsx_dev(chip), "SD/MMC CMD %d\n", SEND_EXT_CSD); - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD0, 0xFF, - 0x40 | SEND_EXT_CSD); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD1, 0xFF, 0); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD2, 0xFF, 0); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD3, 0xFF, 0); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD4, 0xFF, 0); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_L, 0xFF, 0); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_H, 0xFF, 2); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_L, 0xFF, 1); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_H, 0xFF, 0); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF, - SD_CALCULATE_CRC7 | SD_CHECK_CRC16 | SD_NO_WAIT_BUSY_END | - SD_CHECK_CRC7 | SD_RSP_LEN_6); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, - PINGPONG_BUFFER); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF, - SD_TM_NORMAL_READ | SD_TRANSFER_START); - rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, SD_TRANSFER_END, - SD_TRANSFER_END); - - rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + 196, 0xFF, 0); - rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + 212, 0xFF, 0); - rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + 213, 0xFF, 0); - rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + 214, 0xFF, 0); - rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + 215, 0xFF, 0); - - retval = rtsx_send_cmd(chip, SD_CARD, 1000); - if (retval < 0) { - if (retval == -ETIMEDOUT) { - rtsx_clear_sd_error(chip); - sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, - SD_RSP_TYPE_R1, NULL, 0); - } - return STATUS_FAIL; - } - - ptr = rtsx_get_cmd_data(chip); - if (ptr[0] & SD_TRANSFER_ERR) { - sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, - SD_RSP_TYPE_R1, NULL, 0); - return STATUS_FAIL; - } - - if (CHK_MMC_SECTOR_MODE(sd_card)) { - sd_card->capacity = ((u32)ptr[5] << 24) | ((u32)ptr[4] << 16) | - ((u32)ptr[3] << 8) | ((u32)ptr[2]); - } - - card_type_mask = 0x03; - card_type = ptr[1] & card_type_mask; - if (card_type) { - u8 rsp[5]; - - if (card_type & 0x04) { - if (switch_ddr) - SET_MMC_DDR52(sd_card); - else - SET_MMC_52M(sd_card); - } else if (card_type & 0x02) { - SET_MMC_52M(sd_card); - } else { - SET_MMC_26M(sd_card); - } - - retval = sd_send_cmd_get_rsp(chip, SWITCH, 0x03B90100, - SD_RSP_TYPE_R1b, rsp, 5); - if (retval != STATUS_SUCCESS || (rsp[4] & MMC_SWITCH_ERR)) - CLR_MMC_HS(sd_card); - } - - sd_choose_proper_clock(chip); - retval = switch_clock(chip, sd_card->sd_clock); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - /* Test Bus Procedure */ - retval = mmc_test_switch_bus(chip, MMC_8BIT_BUS); - if (retval == SWITCH_SUCCESS) { - SET_MMC_8BIT(sd_card); - chip->card_bus_width[chip->card2lun[SD_CARD]] = 8; -#ifdef SUPPORT_SD_LOCK - sd_card->sd_lock_status &= ~SD_LOCK_1BIT_MODE; -#endif - } else if (retval == SWITCH_FAIL) { - retval = mmc_test_switch_bus(chip, MMC_4BIT_BUS); - if (retval == SWITCH_SUCCESS) { - SET_MMC_4BIT(sd_card); - chip->card_bus_width[chip->card2lun[SD_CARD]] = 4; -#ifdef SUPPORT_SD_LOCK - sd_card->sd_lock_status &= ~SD_LOCK_1BIT_MODE; -#endif - } else if (retval == SWITCH_FAIL) { - CLR_MMC_8BIT(sd_card); - CLR_MMC_4BIT(sd_card); - } else { - return STATUS_FAIL; - } - } else { - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -static int reset_mmc(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &chip->sd_card; - int retval, i = 0, j = 0, k = 0; - bool switch_ddr = true; - u8 rsp[16]; - u8 spec_ver = 0; - u32 temp; - -#ifdef SUPPORT_SD_LOCK - if (sd_card->sd_lock_status & SD_UNLOCK_POW_ON) - goto MMC_UNLOCK_ENTRY; -#endif - -switch_fail: - retval = sd_prepare_reset(chip); - if (retval != STATUS_SUCCESS) - return retval; - - SET_MMC(sd_card); - -RTY_MMC_RST: - retval = sd_send_cmd_get_rsp(chip, GO_IDLE_STATE, 0, SD_RSP_TYPE_R0, - NULL, 0); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - do { - if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) { - sd_set_err_code(chip, SD_NO_CARD); - return STATUS_FAIL; - } - - retval = sd_send_cmd_get_rsp(chip, SEND_OP_COND, - (SUPPORT_VOLTAGE | 0x40000000), - SD_RSP_TYPE_R3, rsp, 5); - if (retval != STATUS_SUCCESS) { - if (sd_check_err_code(chip, SD_BUSY) || - sd_check_err_code(chip, SD_TO_ERR)) { - k++; - if (k < 20) { - sd_clr_err_code(chip); - goto RTY_MMC_RST; - } else { - return STATUS_FAIL; - } - } else { - j++; - if (j < 100) { - sd_clr_err_code(chip); - goto RTY_MMC_RST; - } else { - return STATUS_FAIL; - } - } - } - - wait_timeout(20); - i++; - } while (!(rsp[1] & 0x80) && (i < 255)); - - if (i == 255) - return STATUS_FAIL; - - if ((rsp[1] & 0x60) == 0x40) - SET_MMC_SECTOR_MODE(sd_card); - else - CLR_MMC_SECTOR_MODE(sd_card); - - retval = sd_send_cmd_get_rsp(chip, ALL_SEND_CID, 0, SD_RSP_TYPE_R2, - NULL, 0); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - sd_card->sd_addr = 0x00100000; - retval = sd_send_cmd_get_rsp(chip, SET_RELATIVE_ADDR, sd_card->sd_addr, - SD_RSP_TYPE_R6, rsp, 5); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = sd_check_csd(chip, 1); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - spec_ver = (sd_card->raw_csd[0] & 0x3C) >> 2; - - retval = sd_select_card(chip, 1); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, 0x200, SD_RSP_TYPE_R1, - NULL, 0); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - -#ifdef SUPPORT_SD_LOCK -MMC_UNLOCK_ENTRY: - retval = sd_update_lock_status(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; -#endif - - retval = sd_set_clock_divider(chip, SD_CLK_DIVIDE_0); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - chip->card_bus_width[chip->card2lun[SD_CARD]] = 1; - - if (!sd_card->mmc_dont_switch_bus) { - if (spec_ver == 4) { - /* MMC 4.x Cards */ - retval = mmc_switch_timing_bus(chip, switch_ddr); - if (retval != STATUS_SUCCESS) { - retval = sd_init_power(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - sd_card->mmc_dont_switch_bus = 1; - goto switch_fail; - } - } - - if (CHK_MMC_SECTOR_MODE(sd_card) && sd_card->capacity == 0) - return STATUS_FAIL; - - if (switch_ddr && CHK_MMC_DDR52(sd_card)) { - retval = sd_set_init_para(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = mmc_ddr_tuning(chip); - if (retval != STATUS_SUCCESS) { - retval = sd_init_power(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - switch_ddr = false; - goto switch_fail; - } - - retval = sd_wait_state_data_ready(chip, 0x08, 1, 1000); - if (retval == STATUS_SUCCESS) { - retval = sd_read_lba0(chip); - if (retval != STATUS_SUCCESS) { - retval = sd_init_power(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - switch_ddr = false; - goto switch_fail; - } - } - } - } - -#ifdef SUPPORT_SD_LOCK - if (sd_card->sd_lock_status & SD_UNLOCK_POW_ON) { - retval = rtsx_write_register(chip, REG_SD_BLOCK_CNT_H, 0xFF, - 0x02); - if (retval) - return retval; - retval = rtsx_write_register(chip, REG_SD_BLOCK_CNT_L, 0xFF, - 0x00); - if (retval) - return retval; - } -#endif - - temp = rtsx_readl(chip, RTSX_BIPR); - if (temp & SD_WRITE_PROTECT) - chip->card_wp |= SD_CARD; - - return STATUS_SUCCESS; -} - -int reset_sd_card(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &chip->sd_card; - int retval; - - sd_init_reg_addr(chip); - - memset(sd_card, 0, sizeof(struct sd_info)); - chip->capacity[chip->card2lun[SD_CARD]] = 0; - - retval = enable_card_clock(chip, SD_CARD); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (chip->ignore_sd && CHK_SDIO_EXIST(chip) && - !CHK_SDIO_IGNORED(chip)) { - if (chip->asic_code) { - retval = sd_pull_ctl_enable(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } else { - retval = rtsx_write_register(chip, FPGA_PULL_CTL, - FPGA_SD_PULL_CTL_BIT | - 0x20, 0); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - retval = card_share_mode(chip, SD_CARD); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - chip->sd_io = 1; - return STATUS_FAIL; - } - - retval = sd_init_power(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (chip->sd_ctl & RESET_MMC_FIRST) { - retval = reset_mmc(chip); - if (retval != STATUS_SUCCESS) { - if (sd_check_err_code(chip, SD_NO_CARD)) - return STATUS_FAIL; - - retval = reset_sd(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - } else { - retval = reset_sd(chip); - if (retval != STATUS_SUCCESS) { - if (sd_check_err_code(chip, SD_NO_CARD)) - return STATUS_FAIL; - - if (chip->sd_io) - return STATUS_FAIL; - retval = reset_mmc(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - } - - retval = sd_set_clock_divider(chip, SD_CLK_DIVIDE_0); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = rtsx_write_register(chip, REG_SD_BYTE_CNT_L, 0xFF, 0); - if (retval) - return retval; - retval = rtsx_write_register(chip, REG_SD_BYTE_CNT_H, 0xFF, 2); - if (retval) - return retval; - - chip->capacity[chip->card2lun[SD_CARD]] = sd_card->capacity; - - retval = sd_set_init_para(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - dev_dbg(rtsx_dev(chip), "sd_card->sd_type = 0x%x\n", sd_card->sd_type); - - return STATUS_SUCCESS; -} - -static int reset_mmc_only(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &chip->sd_card; - int retval; - - sd_card->sd_type = 0; - sd_card->seq_mode = 0; - sd_card->sd_data_buf_ready = 0; - sd_card->capacity = 0; - sd_card->sd_switch_fail = 0; - -#ifdef SUPPORT_SD_LOCK - sd_card->sd_lock_status = 0; - sd_card->sd_erase_status = 0; -#endif - - chip->capacity[chip->card2lun[SD_CARD]] = sd_card->capacity = 0; - - retval = enable_card_clock(chip, SD_CARD); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = sd_init_power(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = reset_mmc(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = sd_set_clock_divider(chip, SD_CLK_DIVIDE_0); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = rtsx_write_register(chip, REG_SD_BYTE_CNT_L, 0xFF, 0); - if (retval) - return retval; - retval = rtsx_write_register(chip, REG_SD_BYTE_CNT_H, 0xFF, 2); - if (retval) - return retval; - - chip->capacity[chip->card2lun[SD_CARD]] = sd_card->capacity; - - retval = sd_set_init_para(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - dev_dbg(rtsx_dev(chip), "In %s, sd_card->sd_type = 0x%x\n", - __func__, sd_card->sd_type); - - return STATUS_SUCCESS; -} - -#define WAIT_DATA_READY_RTY_CNT 255 - -static int wait_data_buf_ready(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &chip->sd_card; - int i, retval; - - for (i = 0; i < WAIT_DATA_READY_RTY_CNT; i++) { - if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) { - sd_set_err_code(chip, SD_NO_CARD); - return STATUS_FAIL; - } - - sd_card->sd_data_buf_ready = 0; - - retval = sd_send_cmd_get_rsp(chip, SEND_STATUS, - sd_card->sd_addr, SD_RSP_TYPE_R1, - NULL, 0); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (sd_card->sd_data_buf_ready) { - return sd_send_cmd_get_rsp(chip, SEND_STATUS, - sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0); - } - } - - sd_set_err_code(chip, SD_TO_ERR); - - return STATUS_FAIL; -} - -void sd_stop_seq_mode(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &chip->sd_card; - int retval; - - if (sd_card->seq_mode) { - retval = sd_switch_clock(chip); - if (retval != STATUS_SUCCESS) - return; - - retval = sd_send_cmd_get_rsp(chip, STOP_TRANSMISSION, 0, - SD_RSP_TYPE_R1b, NULL, 0); - if (retval != STATUS_SUCCESS) - sd_set_err_code(chip, SD_STS_ERR); - - retval = sd_wait_state_data_ready(chip, 0x08, 1, 1000); - if (retval != STATUS_SUCCESS) - sd_set_err_code(chip, SD_STS_ERR); - - sd_card->seq_mode = 0; - - rtsx_write_register(chip, RBCTL, RB_FLUSH, RB_FLUSH); - } -} - -static inline int sd_auto_tune_clock(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &chip->sd_card; - int retval; - - if (chip->asic_code) { - if (sd_card->sd_clock > 30) - sd_card->sd_clock -= 20; - } else { - switch (sd_card->sd_clock) { - case CLK_200: - sd_card->sd_clock = CLK_150; - break; - - case CLK_150: - sd_card->sd_clock = CLK_120; - break; - - case CLK_120: - sd_card->sd_clock = CLK_100; - break; - - case CLK_100: - sd_card->sd_clock = CLK_80; - break; - - case CLK_80: - sd_card->sd_clock = CLK_60; - break; - - case CLK_60: - sd_card->sd_clock = CLK_50; - break; - - default: - break; - } - } - - retval = sd_switch_clock(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} - -int sd_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 start_sector, - u16 sector_cnt) -{ - struct sd_info *sd_card = &chip->sd_card; - u32 data_addr; - u8 cfg2; - int retval; - - if (srb->sc_data_direction == DMA_FROM_DEVICE) { - dev_dbg(rtsx_dev(chip), "%s: Read %d %s from 0x%x\n", __func__, - sector_cnt, (sector_cnt > 1) ? "sectors" : "sector", - start_sector); - } else { - dev_dbg(rtsx_dev(chip), "%s: Write %d %s to 0x%x\n", __func__, - sector_cnt, (sector_cnt > 1) ? "sectors" : "sector", - start_sector); - } - - sd_card->cleanup_counter = 0; - - if (!(chip->card_ready & SD_CARD)) { - sd_card->seq_mode = 0; - - retval = reset_sd_card(chip); - if (retval == STATUS_SUCCESS) { - chip->card_ready |= SD_CARD; - chip->card_fail &= ~SD_CARD; - } else { - chip->card_ready &= ~SD_CARD; - chip->card_fail |= SD_CARD; - chip->capacity[chip->card2lun[SD_CARD]] = 0; - chip->rw_need_retry = 1; - return STATUS_FAIL; - } - } - - if (!CHK_SD_HCXC(sd_card) && !CHK_MMC_SECTOR_MODE(sd_card)) - data_addr = start_sector << 9; - else - data_addr = start_sector; - - sd_clr_err_code(chip); - - retval = sd_switch_clock(chip); - if (retval != STATUS_SUCCESS) { - sd_set_err_code(chip, SD_IO_ERR); - goto RW_FAIL; - } - - if (sd_card->seq_mode && - (sd_card->pre_dir != srb->sc_data_direction || - ((sd_card->pre_sec_addr + sd_card->pre_sec_cnt) != - start_sector))) { - if (sd_card->pre_sec_cnt < 0x80 && - sd_card->pre_dir == DMA_FROM_DEVICE && - !CHK_SD30_SPEED(sd_card) && - !CHK_SD_HS(sd_card) && - !CHK_MMC_HS(sd_card)) { - sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, - SD_RSP_TYPE_R1, NULL, 0); - } - - retval = sd_send_cmd_get_rsp(chip, STOP_TRANSMISSION, 0, - SD_RSP_TYPE_R1b, NULL, 0); - if (retval != STATUS_SUCCESS) { - chip->rw_need_retry = 1; - sd_set_err_code(chip, SD_STS_ERR); - goto RW_FAIL; - } - - sd_card->seq_mode = 0; - - retval = rtsx_write_register(chip, RBCTL, RB_FLUSH, RB_FLUSH); - if (retval != STATUS_SUCCESS) { - sd_set_err_code(chip, SD_IO_ERR); - goto RW_FAIL; - } - - if (sd_card->pre_sec_cnt < 0x80 && - !CHK_SD30_SPEED(sd_card) && - !CHK_SD_HS(sd_card) && - !CHK_MMC_HS(sd_card)) { - sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, - SD_RSP_TYPE_R1, NULL, 0); - } - } - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_L, 0xFF, 0x00); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_H, 0xFF, 0x02); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_L, 0xFF, - (u8)sector_cnt); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_H, 0xFF, - (u8)(sector_cnt >> 8)); - - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER); - - if (CHK_MMC_8BIT(sd_card)) - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG1, - 0x03, SD_BUS_WIDTH_8); - else if (CHK_MMC_4BIT(sd_card) || CHK_SD(sd_card)) - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG1, - 0x03, SD_BUS_WIDTH_4); - else - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG1, - 0x03, SD_BUS_WIDTH_1); - - if (sd_card->seq_mode) { - cfg2 = SD_NO_CALCULATE_CRC7 | SD_CHECK_CRC16 | - SD_NO_WAIT_BUSY_END | SD_NO_CHECK_CRC7 | - SD_RSP_LEN_0; - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF, cfg2); - - trans_dma_enable(srb->sc_data_direction, chip, sector_cnt * 512, - DMA_512); - - if (srb->sc_data_direction == DMA_FROM_DEVICE) { - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF, - SD_TM_AUTO_READ_3 | SD_TRANSFER_START); - } else { - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF, - SD_TM_AUTO_WRITE_3 | SD_TRANSFER_START); - } - - rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, - SD_TRANSFER_END, SD_TRANSFER_END); - - rtsx_send_cmd_no_wait(chip); - } else { - if (srb->sc_data_direction == DMA_FROM_DEVICE) { - dev_dbg(rtsx_dev(chip), "SD/MMC CMD %d\n", - READ_MULTIPLE_BLOCK); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD0, 0xFF, - 0x40 | READ_MULTIPLE_BLOCK); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD1, 0xFF, - (u8)(data_addr >> 24)); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD2, 0xFF, - (u8)(data_addr >> 16)); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD3, 0xFF, - (u8)(data_addr >> 8)); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD4, 0xFF, - (u8)data_addr); - - cfg2 = SD_CALCULATE_CRC7 | SD_CHECK_CRC16 | - SD_NO_WAIT_BUSY_END | SD_CHECK_CRC7 | - SD_RSP_LEN_6; - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF, - cfg2); - - trans_dma_enable(srb->sc_data_direction, chip, - sector_cnt * 512, DMA_512); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF, - SD_TM_AUTO_READ_2 | SD_TRANSFER_START); - rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, - SD_TRANSFER_END, SD_TRANSFER_END); - - rtsx_send_cmd_no_wait(chip); - } else { - retval = rtsx_send_cmd(chip, SD_CARD, 50); - if (retval < 0) { - rtsx_clear_sd_error(chip); - - chip->rw_need_retry = 1; - sd_set_err_code(chip, SD_TO_ERR); - goto RW_FAIL; - } - - retval = wait_data_buf_ready(chip); - if (retval != STATUS_SUCCESS) { - chip->rw_need_retry = 1; - sd_set_err_code(chip, SD_TO_ERR); - goto RW_FAIL; - } - - retval = sd_send_cmd_get_rsp(chip, WRITE_MULTIPLE_BLOCK, - data_addr, SD_RSP_TYPE_R1, - NULL, 0); - if (retval != STATUS_SUCCESS) { - chip->rw_need_retry = 1; - goto RW_FAIL; - } - - rtsx_init_cmd(chip); - - cfg2 = SD_NO_CALCULATE_CRC7 | SD_CHECK_CRC16 | - SD_NO_WAIT_BUSY_END | - SD_NO_CHECK_CRC7 | SD_RSP_LEN_0; - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF, - cfg2); - - trans_dma_enable(srb->sc_data_direction, chip, - sector_cnt * 512, DMA_512); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF, - SD_TM_AUTO_WRITE_3 | SD_TRANSFER_START); - rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, - SD_TRANSFER_END, SD_TRANSFER_END); - - rtsx_send_cmd_no_wait(chip); - } - - sd_card->seq_mode = 1; - } - - retval = rtsx_transfer_data(chip, SD_CARD, scsi_sglist(srb), - scsi_bufflen(srb), scsi_sg_count(srb), - srb->sc_data_direction, chip->sd_timeout); - if (retval < 0) { - u8 stat = 0; - int err; - - sd_card->seq_mode = 0; - - if (retval == -ETIMEDOUT) - err = STATUS_TIMEDOUT; - else - err = STATUS_FAIL; - - rtsx_read_register(chip, REG_SD_STAT1, &stat); - rtsx_clear_sd_error(chip); - if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) { - chip->rw_need_retry = 0; - dev_dbg(rtsx_dev(chip), "No card exist, exit %s\n", - __func__); - return STATUS_FAIL; - } - - chip->rw_need_retry = 1; - - retval = sd_send_cmd_get_rsp(chip, STOP_TRANSMISSION, 0, - SD_RSP_TYPE_R1b, NULL, 0); - if (retval != STATUS_SUCCESS) { - sd_set_err_code(chip, SD_STS_ERR); - goto RW_FAIL; - } - - if (stat & (SD_CRC7_ERR | SD_CRC16_ERR | SD_CRC_WRITE_ERR)) { - dev_dbg(rtsx_dev(chip), "SD CRC error, tune clock!\n"); - sd_set_err_code(chip, SD_CRC_ERR); - goto RW_FAIL; - } - - if (err == STATUS_TIMEDOUT) { - sd_set_err_code(chip, SD_TO_ERR); - goto RW_FAIL; - } - - return err; - } - - sd_card->pre_sec_addr = start_sector; - sd_card->pre_sec_cnt = sector_cnt; - sd_card->pre_dir = srb->sc_data_direction; - - return STATUS_SUCCESS; - -RW_FAIL: - sd_card->seq_mode = 0; - - if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) { - chip->rw_need_retry = 0; - dev_dbg(rtsx_dev(chip), "No card exist, exit %s\n", __func__); - return STATUS_FAIL; - } - - if (sd_check_err_code(chip, SD_CRC_ERR)) { - if (CHK_MMC_4BIT(sd_card) || CHK_MMC_8BIT(sd_card)) { - sd_card->mmc_dont_switch_bus = 1; - reset_mmc_only(chip); - sd_card->mmc_dont_switch_bus = 0; - } else { - sd_card->need_retune = 1; - sd_auto_tune_clock(chip); - } - } else if (sd_check_err_code(chip, SD_TO_ERR | SD_STS_ERR)) { - retval = reset_sd_card(chip); - if (retval != STATUS_SUCCESS) { - chip->card_ready &= ~SD_CARD; - chip->card_fail |= SD_CARD; - chip->capacity[chip->card2lun[SD_CARD]] = 0; - } - } - - return STATUS_FAIL; -} - -#ifdef SUPPORT_CPRM -int ext_sd_send_cmd_get_rsp(struct rtsx_chip *chip, u8 cmd_idx, u32 arg, - u8 rsp_type, u8 *rsp, int rsp_len, - bool special_check) -{ - int retval; - int timeout = 100; - u16 reg_addr; - u8 *ptr; - int stat_idx = 0; - int rty_cnt = 0; - - dev_dbg(rtsx_dev(chip), "EXT SD/MMC CMD %d\n", cmd_idx); - - if (rsp_type == SD_RSP_TYPE_R1b) - timeout = 3000; - -RTY_SEND_CMD: - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD0, 0xFF, 0x40 | cmd_idx); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD1, 0xFF, (u8)(arg >> 24)); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD2, 0xFF, (u8)(arg >> 16)); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD3, 0xFF, (u8)(arg >> 8)); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD4, 0xFF, (u8)arg); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF, rsp_type); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, - 0x01, PINGPONG_BUFFER); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, - 0xFF, SD_TM_CMD_RSP | SD_TRANSFER_START); - rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, SD_TRANSFER_END, - SD_TRANSFER_END); - - if (rsp_type == SD_RSP_TYPE_R2) { - for (reg_addr = PPBUF_BASE2; reg_addr < PPBUF_BASE2 + 16; - reg_addr++) - rtsx_add_cmd(chip, READ_REG_CMD, reg_addr, 0, 0); - - stat_idx = 17; - } else if (rsp_type != SD_RSP_TYPE_R0) { - for (reg_addr = REG_SD_CMD0; reg_addr <= REG_SD_CMD4; - reg_addr++) - rtsx_add_cmd(chip, READ_REG_CMD, reg_addr, 0, 0); - - stat_idx = 6; - } - rtsx_add_cmd(chip, READ_REG_CMD, REG_SD_CMD5, 0, 0); - - rtsx_add_cmd(chip, READ_REG_CMD, REG_SD_STAT1, 0, 0); - - retval = rtsx_send_cmd(chip, SD_CARD, timeout); - if (retval < 0) { - if (retval == -ETIMEDOUT) { - rtsx_clear_sd_error(chip); - - if (rsp_type & SD_WAIT_BUSY_END) { - retval = sd_check_data0_status(chip); - if (retval != STATUS_SUCCESS) - return retval; - } else { - sd_set_err_code(chip, SD_TO_ERR); - } - } - return STATUS_FAIL; - } - - if (rsp_type == SD_RSP_TYPE_R0) - return STATUS_SUCCESS; - - ptr = rtsx_get_cmd_data(chip) + 1; - - if ((ptr[0] & 0xC0) != 0) { - sd_set_err_code(chip, SD_STS_ERR); - return STATUS_FAIL; - } - - if (!(rsp_type & SD_NO_CHECK_CRC7)) { - if (ptr[stat_idx] & SD_CRC7_ERR) { - if (cmd_idx == WRITE_MULTIPLE_BLOCK) { - sd_set_err_code(chip, SD_CRC_ERR); - return STATUS_FAIL; - } - if (rty_cnt < SD_MAX_RETRY_COUNT) { - wait_timeout(20); - rty_cnt++; - goto RTY_SEND_CMD; - } else { - sd_set_err_code(chip, SD_CRC_ERR); - return STATUS_FAIL; - } - } - } - - if (cmd_idx == SELECT_CARD || cmd_idx == APP_CMD || - cmd_idx == SEND_STATUS || cmd_idx == STOP_TRANSMISSION) { - if (cmd_idx != STOP_TRANSMISSION && !special_check) { - if (ptr[1] & 0x80) - return STATUS_FAIL; - } -#ifdef SUPPORT_SD_LOCK - if (ptr[1] & 0x7D) { -#else - if (ptr[1] & 0x7F) { -#endif - return STATUS_FAIL; - } - if (ptr[2] & 0xF8) - return STATUS_FAIL; - - if (cmd_idx == SELECT_CARD) { - if (rsp_type == SD_RSP_TYPE_R2) { - if ((ptr[3] & 0x1E) != 0x04) - return STATUS_FAIL; - } - } - } - - if (rsp && rsp_len) - memcpy(rsp, ptr, rsp_len); - - return STATUS_SUCCESS; -} - -int ext_sd_get_rsp(struct rtsx_chip *chip, int len, u8 *rsp, u8 rsp_type) -{ - int retval, rsp_len; - u16 reg_addr; - - if (rsp_type == SD_RSP_TYPE_R0) - return STATUS_SUCCESS; - - rtsx_init_cmd(chip); - - if (rsp_type == SD_RSP_TYPE_R2) { - for (reg_addr = PPBUF_BASE2; reg_addr < PPBUF_BASE2 + 16; - reg_addr++) - rtsx_add_cmd(chip, READ_REG_CMD, reg_addr, 0xFF, 0); - - rsp_len = 17; - } else if (rsp_type != SD_RSP_TYPE_R0) { - for (reg_addr = REG_SD_CMD0; reg_addr <= REG_SD_CMD4; - reg_addr++) - rtsx_add_cmd(chip, READ_REG_CMD, reg_addr, 0xFF, 0); - - rsp_len = 6; - } - rtsx_add_cmd(chip, READ_REG_CMD, REG_SD_CMD5, 0xFF, 0); - - retval = rtsx_send_cmd(chip, SD_CARD, 100); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (rsp) { - int min_len = (rsp_len < len) ? rsp_len : len; - - memcpy(rsp, rtsx_get_cmd_data(chip), min_len); - - dev_dbg(rtsx_dev(chip), "min_len = %d\n", min_len); - dev_dbg(rtsx_dev(chip), "Response in cmd buf: 0x%x 0x%x 0x%x 0x%x\n", - rsp[0], rsp[1], rsp[2], rsp[3]); - } - - return STATUS_SUCCESS; -} - -int sd_pass_thru_mode(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &chip->sd_card; - unsigned int lun = SCSI_LUN(srb); - int len; - u8 buf[18] = { - 0x00, - 0x00, - 0x00, - 0x0E, - 0x00, - 0x00, - 0x00, - 0x00, - 0x53, - 0x44, - 0x20, - 0x43, - 0x61, - 0x72, - 0x64, - 0x00, - 0x00, - 0x00, - }; - - sd_card->pre_cmd_err = 0; - - if (!(CHK_BIT(chip->lun_mc, lun))) { - SET_BIT(chip->lun_mc, lun); - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); - return TRANSPORT_FAILED; - } - - if (srb->cmnd[2] != 0x53 || srb->cmnd[3] != 0x44 || - srb->cmnd[4] != 0x20 || srb->cmnd[5] != 0x43 || - srb->cmnd[6] != 0x61 || srb->cmnd[7] != 0x72 || - srb->cmnd[8] != 0x64) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - - switch (srb->cmnd[1] & 0x0F) { - case 0: - sd_card->sd_pass_thru_en = 0; - break; - - case 1: - sd_card->sd_pass_thru_en = 1; - break; - - default: - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - - buf[5] = (CHK_SD(sd_card) == 1) ? 0x01 : 0x02; - if (chip->card_wp & SD_CARD) - buf[5] |= 0x80; - - buf[6] = (u8)(sd_card->sd_addr >> 16); - buf[7] = (u8)(sd_card->sd_addr >> 24); - - buf[15] = chip->max_lun; - - len = min_t(int, 18, scsi_bufflen(srb)); - rtsx_stor_set_xfer_buf(buf, len, srb); - - return TRANSPORT_GOOD; -} - -static inline int get_rsp_type(struct scsi_cmnd *srb, u8 *rsp_type, - int *rsp_len) -{ - if (!rsp_type || !rsp_len) - return STATUS_FAIL; - - switch (srb->cmnd[10]) { - case 0x03: - *rsp_type = SD_RSP_TYPE_R0; - *rsp_len = 0; - break; - - case 0x04: - *rsp_type = SD_RSP_TYPE_R1; - *rsp_len = 6; - break; - - case 0x05: - *rsp_type = SD_RSP_TYPE_R1b; - *rsp_len = 6; - break; - - case 0x06: - *rsp_type = SD_RSP_TYPE_R2; - *rsp_len = 17; - break; - - case 0x07: - *rsp_type = SD_RSP_TYPE_R3; - *rsp_len = 6; - break; - - default: - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -int sd_execute_no_data(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &chip->sd_card; - unsigned int lun = SCSI_LUN(srb); - int retval, rsp_len; - u8 cmd_idx, rsp_type; - bool standby = false, acmd = false; - u32 arg; - - if (!sd_card->sd_pass_thru_en) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - - retval = sd_switch_clock(chip); - if (retval != STATUS_SUCCESS) - return TRANSPORT_FAILED; - - if (sd_card->pre_cmd_err) { - sd_card->pre_cmd_err = 0; - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); - return TRANSPORT_FAILED; - } - - cmd_idx = srb->cmnd[2] & 0x3F; - if (srb->cmnd[1] & 0x02) - standby = true; - - if (srb->cmnd[1] & 0x01) - acmd = true; - - arg = ((u32)srb->cmnd[3] << 24) | ((u32)srb->cmnd[4] << 16) | - ((u32)srb->cmnd[5] << 8) | srb->cmnd[6]; - - retval = get_rsp_type(srb, &rsp_type, &rsp_len); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - sd_card->last_rsp_type = rsp_type; - - retval = sd_switch_clock(chip); - if (retval != STATUS_SUCCESS) - return TRANSPORT_FAILED; - -#ifdef SUPPORT_SD_LOCK - if ((sd_card->sd_lock_status & SD_LOCK_1BIT_MODE) == 0) { - if (CHK_MMC_8BIT(sd_card)) { - retval = rtsx_write_register(chip, REG_SD_CFG1, 0x03, - SD_BUS_WIDTH_8); - if (retval != STATUS_SUCCESS) - return TRANSPORT_FAILED; - - } else if (CHK_SD(sd_card) || CHK_MMC_4BIT(sd_card)) { - retval = rtsx_write_register(chip, REG_SD_CFG1, 0x03, - SD_BUS_WIDTH_4); - if (retval != STATUS_SUCCESS) - return TRANSPORT_FAILED; - } - } -#else - retval = rtsx_write_register(chip, REG_SD_CFG1, 0x03, SD_BUS_WIDTH_4); - if (retval != STATUS_SUCCESS) - return TRANSPORT_FAILED; -#endif - - if (standby) { - retval = sd_select_card(chip, 0); - if (retval != STATUS_SUCCESS) - goto sd_execute_cmd_failed; - } - - if (acmd) { - retval = ext_sd_send_cmd_get_rsp(chip, APP_CMD, - sd_card->sd_addr, - SD_RSP_TYPE_R1, NULL, 0, - false); - if (retval != STATUS_SUCCESS) - goto sd_execute_cmd_failed; - } - - retval = ext_sd_send_cmd_get_rsp(chip, cmd_idx, arg, rsp_type, - sd_card->rsp, rsp_len, false); - if (retval != STATUS_SUCCESS) - goto sd_execute_cmd_failed; - - if (standby) { - retval = sd_select_card(chip, 1); - if (retval != STATUS_SUCCESS) - goto sd_execute_cmd_failed; - } - -#ifdef SUPPORT_SD_LOCK - retval = sd_update_lock_status(chip); - if (retval != STATUS_SUCCESS) - goto sd_execute_cmd_failed; -#endif - - scsi_set_resid(srb, 0); - return TRANSPORT_GOOD; - -sd_execute_cmd_failed: - sd_card->pre_cmd_err = 1; - set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE); - release_sd_card(chip); - do_reset_sd_card(chip); - if (!(chip->card_ready & SD_CARD)) - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - - return TRANSPORT_FAILED; -} - -int sd_execute_read_data(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &chip->sd_card; - unsigned int lun = SCSI_LUN(srb); - int retval, rsp_len, i; - bool read_err = false, cmd13_checkbit = false; - u8 cmd_idx, rsp_type, bus_width; - bool standby = false, send_cmd12 = false, acmd = false; - u32 data_len; - - if (!sd_card->sd_pass_thru_en) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - - if (sd_card->pre_cmd_err) { - sd_card->pre_cmd_err = 0; - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); - return TRANSPORT_FAILED; - } - - retval = sd_switch_clock(chip); - if (retval != STATUS_SUCCESS) - return TRANSPORT_FAILED; - - cmd_idx = srb->cmnd[2] & 0x3F; - if (srb->cmnd[1] & 0x04) - send_cmd12 = true; - - if (srb->cmnd[1] & 0x02) - standby = true; - - if (srb->cmnd[1] & 0x01) - acmd = true; - - data_len = ((u32)srb->cmnd[7] << 16) | ((u32)srb->cmnd[8] - << 8) | srb->cmnd[9]; - - retval = get_rsp_type(srb, &rsp_type, &rsp_len); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - sd_card->last_rsp_type = rsp_type; - - retval = sd_switch_clock(chip); - if (retval != STATUS_SUCCESS) - return TRANSPORT_FAILED; - -#ifdef SUPPORT_SD_LOCK - if ((sd_card->sd_lock_status & SD_LOCK_1BIT_MODE) == 0) { - if (CHK_MMC_8BIT(sd_card)) - bus_width = SD_BUS_WIDTH_8; - else if (CHK_SD(sd_card) || CHK_MMC_4BIT(sd_card)) - bus_width = SD_BUS_WIDTH_4; - else - bus_width = SD_BUS_WIDTH_1; - } else { - bus_width = SD_BUS_WIDTH_4; - } - dev_dbg(rtsx_dev(chip), "bus_width = %d\n", bus_width); -#else - bus_width = SD_BUS_WIDTH_4; -#endif - - if (data_len < 512) { - retval = ext_sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, data_len, - SD_RSP_TYPE_R1, NULL, 0, - false); - if (retval != STATUS_SUCCESS) - goto sd_execute_read_cmd_failed; - } - - if (standby) { - retval = sd_select_card(chip, 0); - if (retval != STATUS_SUCCESS) - goto sd_execute_read_cmd_failed; - } - - if (acmd) { - retval = ext_sd_send_cmd_get_rsp(chip, APP_CMD, - sd_card->sd_addr, - SD_RSP_TYPE_R1, NULL, 0, - false); - if (retval != STATUS_SUCCESS) - goto sd_execute_read_cmd_failed; - } - - if (data_len <= 512) { - int min_len; - u8 *buf; - u16 byte_cnt, blk_cnt; - u8 cmd[5]; - - byte_cnt = ((u16)(srb->cmnd[8] & 0x03) << 8) | srb->cmnd[9]; - blk_cnt = 1; - - cmd[0] = 0x40 | cmd_idx; - cmd[1] = srb->cmnd[3]; - cmd[2] = srb->cmnd[4]; - cmd[3] = srb->cmnd[5]; - cmd[4] = srb->cmnd[6]; - - buf = kmalloc(data_len, GFP_KERNEL); - if (!buf) - return TRANSPORT_ERROR; - - retval = sd_read_data(chip, SD_TM_NORMAL_READ, cmd, 5, byte_cnt, - blk_cnt, bus_width, buf, data_len, 2000); - if (retval != STATUS_SUCCESS) { - read_err = true; - kfree(buf); - rtsx_clear_sd_error(chip); - goto sd_execute_read_cmd_failed; - } - - min_len = min(data_len, scsi_bufflen(srb)); - rtsx_stor_set_xfer_buf(buf, min_len, srb); - - kfree(buf); - } else if (!(data_len & 0x1FF)) { - rtsx_init_cmd(chip); - - trans_dma_enable(DMA_FROM_DEVICE, chip, data_len, DMA_512); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_H, 0xFF, - 0x02); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_L, 0xFF, - 0x00); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_H, - 0xFF, (srb->cmnd[7] & 0xFE) >> 1); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_L, - 0xFF, (u8)((data_len & 0x0001FE00) >> 9)); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD0, 0xFF, - 0x40 | cmd_idx); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD1, 0xFF, - srb->cmnd[3]); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD2, 0xFF, - srb->cmnd[4]); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD3, 0xFF, - srb->cmnd[5]); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD4, 0xFF, - srb->cmnd[6]); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG1, 0x03, bus_width); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF, rsp_type); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, - 0xFF, SD_TM_AUTO_READ_2 | SD_TRANSFER_START); - rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, - SD_TRANSFER_END, SD_TRANSFER_END); - - rtsx_send_cmd_no_wait(chip); - - retval = rtsx_transfer_data(chip, SD_CARD, scsi_sglist(srb), - scsi_bufflen(srb), - scsi_sg_count(srb), - DMA_FROM_DEVICE, 10000); - if (retval < 0) { - read_err = true; - rtsx_clear_sd_error(chip); - goto sd_execute_read_cmd_failed; - } - - } else { - goto sd_execute_read_cmd_failed; - } - - retval = ext_sd_get_rsp(chip, rsp_len, sd_card->rsp, rsp_type); - if (retval != STATUS_SUCCESS) - goto sd_execute_read_cmd_failed; - - if (standby) { - retval = sd_select_card(chip, 1); - if (retval != STATUS_SUCCESS) - goto sd_execute_read_cmd_failed; - } - - if (send_cmd12) { - retval = ext_sd_send_cmd_get_rsp(chip, STOP_TRANSMISSION, 0, - SD_RSP_TYPE_R1b, NULL, 0, - false); - if (retval != STATUS_SUCCESS) - goto sd_execute_read_cmd_failed; - } - - if (data_len < 512) { - retval = ext_sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, 0x200, - SD_RSP_TYPE_R1, NULL, 0, - false); - if (retval != STATUS_SUCCESS) - goto sd_execute_read_cmd_failed; - - retval = rtsx_write_register(chip, SD_BYTE_CNT_H, 0xFF, 0x02); - if (retval != STATUS_SUCCESS) - goto sd_execute_read_cmd_failed; - - retval = rtsx_write_register(chip, SD_BYTE_CNT_L, 0xFF, 0x00); - if (retval != STATUS_SUCCESS) - goto sd_execute_read_cmd_failed; - } - - if ((srb->cmnd[1] & 0x02) || (srb->cmnd[1] & 0x04)) - cmd13_checkbit = true; - - for (i = 0; i < 3; i++) { - retval = ext_sd_send_cmd_get_rsp(chip, SEND_STATUS, - sd_card->sd_addr, - SD_RSP_TYPE_R1, NULL, 0, - cmd13_checkbit); - if (retval == STATUS_SUCCESS) - break; - } - if (retval != STATUS_SUCCESS) - goto sd_execute_read_cmd_failed; - - scsi_set_resid(srb, 0); - return TRANSPORT_GOOD; - -sd_execute_read_cmd_failed: - sd_card->pre_cmd_err = 1; - set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE); - if (read_err) - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - - release_sd_card(chip); - do_reset_sd_card(chip); - if (!(chip->card_ready & SD_CARD)) - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - - return TRANSPORT_FAILED; -} - -int sd_execute_write_data(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &chip->sd_card; - unsigned int lun = SCSI_LUN(srb); - int retval, rsp_len, i; - bool write_err = false, cmd13_checkbit = false; - u8 cmd_idx, rsp_type; - bool standby = false, send_cmd12 = false, acmd = false; - u32 data_len, arg; -#ifdef SUPPORT_SD_LOCK - int lock_cmd_fail = 0; - u8 sd_lock_state = 0; - u8 lock_cmd_type = 0; -#endif - - if (!sd_card->sd_pass_thru_en) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - - if (sd_card->pre_cmd_err) { - sd_card->pre_cmd_err = 0; - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); - return TRANSPORT_FAILED; - } - - retval = sd_switch_clock(chip); - if (retval != STATUS_SUCCESS) - return TRANSPORT_FAILED; - - cmd_idx = srb->cmnd[2] & 0x3F; - if (srb->cmnd[1] & 0x04) - send_cmd12 = true; - - if (srb->cmnd[1] & 0x02) - standby = true; - - if (srb->cmnd[1] & 0x01) - acmd = true; - - data_len = ((u32)srb->cmnd[7] << 16) | ((u32)srb->cmnd[8] - << 8) | srb->cmnd[9]; - arg = ((u32)srb->cmnd[3] << 24) | ((u32)srb->cmnd[4] << 16) | - ((u32)srb->cmnd[5] << 8) | srb->cmnd[6]; - -#ifdef SUPPORT_SD_LOCK - if (cmd_idx == LOCK_UNLOCK) { - sd_lock_state = sd_card->sd_lock_status; - sd_lock_state &= SD_LOCKED; - } -#endif - - retval = get_rsp_type(srb, &rsp_type, &rsp_len); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - sd_card->last_rsp_type = rsp_type; - - retval = sd_switch_clock(chip); - if (retval != STATUS_SUCCESS) - return TRANSPORT_FAILED; - -#ifdef SUPPORT_SD_LOCK - if ((sd_card->sd_lock_status & SD_LOCK_1BIT_MODE) == 0) { - if (CHK_MMC_8BIT(sd_card)) { - retval = rtsx_write_register(chip, REG_SD_CFG1, 0x03, - SD_BUS_WIDTH_8); - if (retval != STATUS_SUCCESS) - return TRANSPORT_FAILED; - - } else if (CHK_SD(sd_card) || CHK_MMC_4BIT(sd_card)) { - retval = rtsx_write_register(chip, REG_SD_CFG1, 0x03, - SD_BUS_WIDTH_4); - if (retval != STATUS_SUCCESS) - return TRANSPORT_FAILED; - } - } -#else - retval = rtsx_write_register(chip, REG_SD_CFG1, 0x03, SD_BUS_WIDTH_4); - if (retval != STATUS_SUCCESS) - return TRANSPORT_FAILED; -#endif - - if (data_len < 512) { - retval = ext_sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, data_len, - SD_RSP_TYPE_R1, NULL, 0, - false); - if (retval != STATUS_SUCCESS) - goto sd_execute_write_cmd_failed; - } - - if (standby) { - retval = sd_select_card(chip, 0); - if (retval != STATUS_SUCCESS) - goto sd_execute_write_cmd_failed; - } - - if (acmd) { - retval = ext_sd_send_cmd_get_rsp(chip, APP_CMD, - sd_card->sd_addr, - SD_RSP_TYPE_R1, NULL, 0, - false); - if (retval != STATUS_SUCCESS) - goto sd_execute_write_cmd_failed; - } - - retval = ext_sd_send_cmd_get_rsp(chip, cmd_idx, arg, rsp_type, - sd_card->rsp, rsp_len, false); - if (retval != STATUS_SUCCESS) - goto sd_execute_write_cmd_failed; - - if (data_len <= 512) { - u16 i; - u8 *buf; - - buf = kmalloc(data_len, GFP_KERNEL); - if (!buf) - return TRANSPORT_ERROR; - - rtsx_stor_get_xfer_buf(buf, data_len, srb); - -#ifdef SUPPORT_SD_LOCK - if (cmd_idx == LOCK_UNLOCK) - lock_cmd_type = buf[0] & 0x0F; -#endif - - if (data_len > 256) { - rtsx_init_cmd(chip); - for (i = 0; i < 256; i++) { - rtsx_add_cmd(chip, WRITE_REG_CMD, - PPBUF_BASE2 + i, 0xFF, buf[i]); - } - retval = rtsx_send_cmd(chip, 0, 250); - if (retval != STATUS_SUCCESS) { - kfree(buf); - goto sd_execute_write_cmd_failed; - } - - rtsx_init_cmd(chip); - for (i = 256; i < data_len; i++) { - rtsx_add_cmd(chip, WRITE_REG_CMD, - PPBUF_BASE2 + i, 0xFF, buf[i]); - } - retval = rtsx_send_cmd(chip, 0, 250); - if (retval != STATUS_SUCCESS) { - kfree(buf); - goto sd_execute_write_cmd_failed; - } - } else { - rtsx_init_cmd(chip); - for (i = 0; i < data_len; i++) { - rtsx_add_cmd(chip, WRITE_REG_CMD, - PPBUF_BASE2 + i, 0xFF, buf[i]); - } - retval = rtsx_send_cmd(chip, 0, 250); - if (retval != STATUS_SUCCESS) { - kfree(buf); - goto sd_execute_write_cmd_failed; - } - } - - kfree(buf); - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_H, 0xFF, - srb->cmnd[8] & 0x03); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_L, 0xFF, - srb->cmnd[9]); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_H, 0xFF, - 0x00); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_L, 0xFF, - 0x01); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, - PINGPONG_BUFFER); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF, - SD_TM_AUTO_WRITE_3 | SD_TRANSFER_START); - rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, - SD_TRANSFER_END, SD_TRANSFER_END); - - retval = rtsx_send_cmd(chip, SD_CARD, 250); - } else if (!(data_len & 0x1FF)) { - rtsx_init_cmd(chip); - - trans_dma_enable(DMA_TO_DEVICE, chip, data_len, DMA_512); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_H, 0xFF, - 0x02); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_L, 0xFF, - 0x00); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_H, - 0xFF, (srb->cmnd[7] & 0xFE) >> 1); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_L, - 0xFF, (u8)((data_len & 0x0001FE00) >> 9)); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF, - SD_TM_AUTO_WRITE_3 | SD_TRANSFER_START); - rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, - SD_TRANSFER_END, SD_TRANSFER_END); - - rtsx_send_cmd_no_wait(chip); - - retval = rtsx_transfer_data(chip, SD_CARD, scsi_sglist(srb), - scsi_bufflen(srb), - scsi_sg_count(srb), - DMA_TO_DEVICE, 10000); - - } else { - goto sd_execute_write_cmd_failed; - } - - if (retval < 0) { - write_err = true; - rtsx_clear_sd_error(chip); - goto sd_execute_write_cmd_failed; - } - -#ifdef SUPPORT_SD_LOCK - if (cmd_idx == LOCK_UNLOCK) { - if (lock_cmd_type == SD_ERASE) { - sd_card->sd_erase_status = SD_UNDER_ERASING; - scsi_set_resid(srb, 0); - return TRANSPORT_GOOD; - } - - rtsx_init_cmd(chip); - rtsx_add_cmd(chip, CHECK_REG_CMD, 0xFD30, 0x02, 0x02); - - retval = rtsx_send_cmd(chip, SD_CARD, 250); - if (retval < 0) { - write_err = true; - rtsx_clear_sd_error(chip); - goto sd_execute_write_cmd_failed; - } - - retval = sd_update_lock_status(chip); - if (retval != STATUS_SUCCESS) { - dev_dbg(rtsx_dev(chip), "Lock command fail!\n"); - lock_cmd_fail = 1; - } - } -#endif /* SUPPORT_SD_LOCK */ - - if (standby) { - retval = sd_select_card(chip, 1); - if (retval != STATUS_SUCCESS) - goto sd_execute_write_cmd_failed; - } - - if (send_cmd12) { - retval = ext_sd_send_cmd_get_rsp(chip, STOP_TRANSMISSION, 0, - SD_RSP_TYPE_R1b, NULL, 0, - false); - if (retval != STATUS_SUCCESS) - goto sd_execute_write_cmd_failed; - } - - if (data_len < 512) { - retval = ext_sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, 0x200, - SD_RSP_TYPE_R1, NULL, 0, - false); - if (retval != STATUS_SUCCESS) - goto sd_execute_write_cmd_failed; - - retval = rtsx_write_register(chip, SD_BYTE_CNT_H, 0xFF, 0x02); - if (retval != STATUS_SUCCESS) - goto sd_execute_write_cmd_failed; - - retval = rtsx_write_register(chip, SD_BYTE_CNT_L, 0xFF, 0x00); - if (retval != STATUS_SUCCESS) - goto sd_execute_write_cmd_failed; - } - - if ((srb->cmnd[1] & 0x02) || (srb->cmnd[1] & 0x04)) - cmd13_checkbit = true; - - for (i = 0; i < 3; i++) { - retval = ext_sd_send_cmd_get_rsp(chip, SEND_STATUS, - sd_card->sd_addr, - SD_RSP_TYPE_R1, NULL, 0, - cmd13_checkbit); - if (retval == STATUS_SUCCESS) - break; - } - if (retval != STATUS_SUCCESS) - goto sd_execute_write_cmd_failed; - -#ifdef SUPPORT_SD_LOCK - if (cmd_idx == LOCK_UNLOCK) { - if (!lock_cmd_fail) { - dev_dbg(rtsx_dev(chip), "lock_cmd_type = 0x%x\n", - lock_cmd_type); - if (lock_cmd_type & SD_CLR_PWD) - sd_card->sd_lock_status &= ~SD_PWD_EXIST; - - if (lock_cmd_type & SD_SET_PWD) - sd_card->sd_lock_status |= SD_PWD_EXIST; - } - - dev_dbg(rtsx_dev(chip), "sd_lock_state = 0x%x, sd_card->sd_lock_status = 0x%x\n", - sd_lock_state, sd_card->sd_lock_status); - if (sd_lock_state ^ (sd_card->sd_lock_status & SD_LOCKED)) { - sd_card->sd_lock_notify = 1; - if (sd_lock_state && - (sd_card->sd_lock_status & SD_LOCK_1BIT_MODE)) { - sd_card->sd_lock_status |= (SD_UNLOCK_POW_ON | SD_SDR_RST); - if (CHK_SD(sd_card)) { - retval = reset_sd(chip); - if (retval != STATUS_SUCCESS) { - sd_card->sd_lock_status &= - ~(SD_UNLOCK_POW_ON | SD_SDR_RST); - goto sd_execute_write_cmd_failed; - } - } - - sd_card->sd_lock_status &= ~(SD_UNLOCK_POW_ON | SD_SDR_RST); - } - } - } - - if (lock_cmd_fail) { - scsi_set_resid(srb, 0); - set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE); - return TRANSPORT_FAILED; - } -#endif /* SUPPORT_SD_LOCK */ - - scsi_set_resid(srb, 0); - return TRANSPORT_GOOD; - -sd_execute_write_cmd_failed: - sd_card->pre_cmd_err = 1; - set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE); - if (write_err) - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); - - release_sd_card(chip); - do_reset_sd_card(chip); - if (!(chip->card_ready & SD_CARD)) - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - - return TRANSPORT_FAILED; -} - -int sd_get_cmd_rsp(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &chip->sd_card; - unsigned int lun = SCSI_LUN(srb); - int count; - u16 data_len; - - if (!sd_card->sd_pass_thru_en) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - - if (sd_card->pre_cmd_err) { - sd_card->pre_cmd_err = 0; - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); - return TRANSPORT_FAILED; - } - - data_len = ((u16)srb->cmnd[7] << 8) | srb->cmnd[8]; - - if (sd_card->last_rsp_type == SD_RSP_TYPE_R0) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } else if (sd_card->last_rsp_type == SD_RSP_TYPE_R2) { - count = (data_len < 17) ? data_len : 17; - } else { - count = (data_len < 6) ? data_len : 6; - } - rtsx_stor_set_xfer_buf(sd_card->rsp, count, srb); - - dev_dbg(rtsx_dev(chip), "Response length: %d\n", data_len); - dev_dbg(rtsx_dev(chip), "Response: 0x%x 0x%x 0x%x 0x%x\n", - sd_card->rsp[0], sd_card->rsp[1], - sd_card->rsp[2], sd_card->rsp[3]); - - scsi_set_resid(srb, 0); - return TRANSPORT_GOOD; -} - -int sd_hw_rst(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &chip->sd_card; - unsigned int lun = SCSI_LUN(srb); - int retval; - - if (!sd_card->sd_pass_thru_en) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - - if (sd_card->pre_cmd_err) { - sd_card->pre_cmd_err = 0; - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); - return TRANSPORT_FAILED; - } - - if (srb->cmnd[2] != 0x53 || srb->cmnd[3] != 0x44 || - srb->cmnd[4] != 0x20 || srb->cmnd[5] != 0x43 || - srb->cmnd[6] != 0x61 || srb->cmnd[7] != 0x72 || - srb->cmnd[8] != 0x64) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - - switch (srb->cmnd[1] & 0x0F) { - case 0: -#ifdef SUPPORT_SD_LOCK - if (srb->cmnd[9] == 0x64) - sd_card->sd_lock_status |= SD_SDR_RST; -#endif - retval = reset_sd_card(chip); - if (retval != STATUS_SUCCESS) { -#ifdef SUPPORT_SD_LOCK - sd_card->sd_lock_status &= ~SD_SDR_RST; -#endif - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - sd_card->pre_cmd_err = 1; - return TRANSPORT_FAILED; - } -#ifdef SUPPORT_SD_LOCK - sd_card->sd_lock_status &= ~SD_SDR_RST; -#endif - break; - - case 1: - retval = reset_sd(chip); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - sd_card->pre_cmd_err = 1; - return TRANSPORT_FAILED; - } - break; - - default: - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - return TRANSPORT_FAILED; - } - - scsi_set_resid(srb, 0); - return TRANSPORT_GOOD; -} -#endif - -void sd_cleanup_work(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &chip->sd_card; - - if (sd_card->seq_mode) { - dev_dbg(rtsx_dev(chip), "SD: stop transmission\n"); - sd_stop_seq_mode(chip); - sd_card->cleanup_counter = 0; - } -} - -int sd_power_off_card3v3(struct rtsx_chip *chip) -{ - int retval; - - retval = disable_card_clock(chip, SD_CARD); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = rtsx_write_register(chip, CARD_OE, SD_OUTPUT_EN, 0); - if (retval) - return retval; - - if (!chip->ft2_fast_mode) { - retval = card_power_off(chip, SD_CARD); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - mdelay(50); - } - - if (chip->asic_code) { - retval = sd_pull_ctl_disable(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } else { - retval = rtsx_write_register(chip, FPGA_PULL_CTL, - FPGA_SD_PULL_CTL_BIT | 0x20, - FPGA_SD_PULL_CTL_BIT); - if (retval) - return retval; - } - - return STATUS_SUCCESS; -} - -int release_sd_card(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &chip->sd_card; - int retval; - - chip->card_ready &= ~SD_CARD; - chip->card_fail &= ~SD_CARD; - chip->card_wp &= ~SD_CARD; - - chip->sd_io = 0; - chip->sd_int = 0; - -#ifdef SUPPORT_SD_LOCK - sd_card->sd_lock_status = 0; - sd_card->sd_erase_status = 0; -#endif - - memset(sd_card->raw_csd, 0, 16); - memset(sd_card->raw_scr, 0, 8); - - retval = sd_power_off_card3v3(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} diff --git a/drivers/staging/rts5208/sd.h b/drivers/staging/rts5208/sd.h deleted file mode 100644 index f4ff62653b56..000000000000 --- a/drivers/staging/rts5208/sd.h +++ /dev/null @@ -1,289 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Driver for Realtek PCI-Express card reader - * - * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. - * - * Author: - * Wei WANG (wei_wang@xxxxxxxxxxxxxx) - * Micky Ching (micky_ching@xxxxxxxxxxxxxx) - */ - -#ifndef __REALTEK_RTSX_SD_H -#define __REALTEK_RTSX_SD_H - -#include "rtsx_chip.h" - -#define SUPPORT_VOLTAGE 0x003C0000 - -/* Error Code */ -#define SD_NO_ERROR 0x0 -#define SD_CRC_ERR 0x80 -#define SD_TO_ERR 0x40 -#define SD_NO_CARD 0x20 -#define SD_BUSY 0x10 -#define SD_STS_ERR 0x08 -#define SD_RSP_TIMEOUT 0x04 -#define SD_IO_ERR 0x02 - -/* Return code for MMC switch bus */ -#define SWITCH_SUCCESS 0 -#define SWITCH_ERR 1 -#define SWITCH_FAIL 2 - -/* MMC/SD Command Index */ -/* Basic command (class 0) */ -#define GO_IDLE_STATE 0 -#define SEND_OP_COND 1 -#define ALL_SEND_CID 2 -#define SET_RELATIVE_ADDR 3 -#define SEND_RELATIVE_ADDR 3 -#define SET_DSR 4 -#define IO_SEND_OP_COND 5 -#define SWITCH 6 -#define SELECT_CARD 7 -#define DESELECT_CARD 7 -/* CMD8 is "SEND_EXT_CSD" for MMC4.x Spec - * while is "SEND_IF_COND" for SD 2.0 - */ -#define SEND_EXT_CSD 8 -#define SEND_IF_COND 8 - -#define SEND_CSD 9 -#define SEND_CID 10 -#define VOLTAGE_SWITCH 11 -#define READ_DAT_UTIL_STOP 11 -#define STOP_TRANSMISSION 12 -#define SEND_STATUS 13 -#define GO_INACTIVE_STATE 15 - -#define SET_BLOCKLEN 16 -#define READ_SINGLE_BLOCK 17 -#define READ_MULTIPLE_BLOCK 18 -#define SEND_TUNING_PATTERN 19 - -#define BUSTEST_R 14 -#define BUSTEST_W 19 - -#define WRITE_BLOCK 24 -#define WRITE_MULTIPLE_BLOCK 25 -#define PROGRAM_CSD 27 - -#define ERASE_WR_BLK_START 32 -#define ERASE_WR_BLK_END 33 -#define ERASE_CMD 38 - -#define LOCK_UNLOCK 42 -#define IO_RW_DIRECT 52 - -#define APP_CMD 55 -#define GEN_CMD 56 - -#define SET_BUS_WIDTH 6 -#define SD_STATUS 13 -#define SEND_NUM_WR_BLOCKS 22 -#define SET_WR_BLK_ERASE_COUNT 23 -#define SD_APP_OP_COND 41 -#define SET_CLR_CARD_DETECT 42 -#define SEND_SCR 51 - -#define SD_READ_COMPLETE 0x00 -#define SD_READ_TO 0x01 -#define SD_READ_ADVENCE 0x02 - -#define SD_CHECK_MODE 0x00 -#define SD_SWITCH_MODE 0x80 -#define SD_FUNC_GROUP_1 0x01 -#define SD_FUNC_GROUP_2 0x02 -#define SD_FUNC_GROUP_3 0x03 -#define SD_FUNC_GROUP_4 0x04 -#define SD_CHECK_SPEC_V1_1 0xFF - -#define NO_ARGUMENT 0x00 -#define CHECK_PATTERN 0x000000AA -#define VOLTAGE_SUPPLY_RANGE 0x00000100 -#define SUPPORT_HIGH_AND_EXTENDED_CAPACITY 0x40000000 -#define SUPPORT_MAX_POWER_PERMANCE 0x10000000 -#define SUPPORT_1V8 0x01000000 - -#define SWITCH_NO_ERR 0x00 -#define CARD_NOT_EXIST 0x01 -#define SPEC_NOT_SUPPORT 0x02 -#define CHECK_MODE_ERR 0x03 -#define CHECK_NOT_READY 0x04 -#define SWITCH_CRC_ERR 0x05 -#define SWITCH_MODE_ERR 0x06 -#define SWITCH_PASS 0x07 - -#ifdef SUPPORT_SD_LOCK -#define SD_ERASE 0x08 -#define SD_LOCK 0x04 -#define SD_UNLOCK 0x00 -#define SD_CLR_PWD 0x02 -#define SD_SET_PWD 0x01 - -#define SD_PWD_LEN 0x10 - -#define SD_LOCKED 0x80 -#define SD_LOCK_1BIT_MODE 0x40 -#define SD_PWD_EXIST 0x20 -#define SD_UNLOCK_POW_ON 0x01 -#define SD_SDR_RST 0x02 - -#define SD_NOT_ERASE 0x00 -#define SD_UNDER_ERASING 0x01 -#define SD_COMPLETE_ERASE 0x02 - -#define SD_RW_FORBIDDEN 0x0F - -#endif - -#define HS_SUPPORT 0x01 -#define SDR50_SUPPORT 0x02 -#define SDR104_SUPPORT 0x03 -#define DDR50_SUPPORT 0x04 - -#define HS_SUPPORT_MASK 0x02 -#define SDR50_SUPPORT_MASK 0x04 -#define SDR104_SUPPORT_MASK 0x08 -#define DDR50_SUPPORT_MASK 0x10 - -#define HS_QUERY_SWITCH_OK 0x01 -#define SDR50_QUERY_SWITCH_OK 0x02 -#define SDR104_QUERY_SWITCH_OK 0x03 -#define DDR50_QUERY_SWITCH_OK 0x04 - -#define HS_SWITCH_BUSY 0x02 -#define SDR50_SWITCH_BUSY 0x04 -#define SDR104_SWITCH_BUSY 0x08 -#define DDR50_SWITCH_BUSY 0x10 - -#define FUNCTION_GROUP1_SUPPORT_OFFSET 0x0D -#define FUNCTION_GROUP1_QUERY_SWITCH_OFFSET 0x10 -#define FUNCTION_GROUP1_CHECK_BUSY_OFFSET 0x1D - -#define DRIVING_TYPE_A 0x01 -#define DRIVING_TYPE_B 0x00 -#define DRIVING_TYPE_C 0x02 -#define DRIVING_TYPE_D 0x03 - -#define DRIVING_TYPE_A_MASK 0x02 -#define DRIVING_TYPE_B_MASK 0x01 -#define DRIVING_TYPE_C_MASK 0x04 -#define DRIVING_TYPE_D_MASK 0x08 - -#define TYPE_A_QUERY_SWITCH_OK 0x01 -#define TYPE_B_QUERY_SWITCH_OK 0x00 -#define TYPE_C_QUERY_SWITCH_OK 0x02 -#define TYPE_D_QUERY_SWITCH_OK 0x03 - -#define TYPE_A_SWITCH_BUSY 0x02 -#define TYPE_B_SWITCH_BUSY 0x01 -#define TYPE_C_SWITCH_BUSY 0x04 -#define TYPE_D_SWITCH_BUSY 0x08 - -#define FUNCTION_GROUP3_SUPPORT_OFFSET 0x09 -#define FUNCTION_GROUP3_QUERY_SWITCH_OFFSET 0x0F -#define FUNCTION_GROUP3_CHECK_BUSY_OFFSET 0x19 - -#define CURRENT_LIMIT_200 0x00 -#define CURRENT_LIMIT_400 0x01 -#define CURRENT_LIMIT_600 0x02 -#define CURRENT_LIMIT_800 0x03 - -#define CURRENT_LIMIT_200_MASK 0x01 -#define CURRENT_LIMIT_400_MASK 0x02 -#define CURRENT_LIMIT_600_MASK 0x04 -#define CURRENT_LIMIT_800_MASK 0x08 - -#define CURRENT_LIMIT_200_QUERY_SWITCH_OK 0x00 -#define CURRENT_LIMIT_400_QUERY_SWITCH_OK 0x01 -#define CURRENT_LIMIT_600_QUERY_SWITCH_OK 0x02 -#define CURRENT_LIMIT_800_QUERY_SWITCH_OK 0x03 - -#define CURRENT_LIMIT_200_SWITCH_BUSY 0x01 -#define CURRENT_LIMIT_400_SWITCH_BUSY 0x02 -#define CURRENT_LIMIT_600_SWITCH_BUSY 0x04 -#define CURRENT_LIMIT_800_SWITCH_BUSY 0x08 - -#define FUNCTION_GROUP4_SUPPORT_OFFSET 0x07 -#define FUNCTION_GROUP4_QUERY_SWITCH_OFFSET 0x0F -#define FUNCTION_GROUP4_CHECK_BUSY_OFFSET 0x17 - -#define DATA_STRUCTURE_VER_OFFSET 0x11 - -#define MAX_PHASE 31 - -#define MMC_8BIT_BUS 0x0010 -#define MMC_4BIT_BUS 0x0020 - -#define MMC_SWITCH_ERR 0x80 - -#define SD_IO_3V3 0 -#define SD_IO_1V8 1 - -#define TUNE_TX 0x00 -#define TUNE_RX 0x01 - -#define CHANGE_TX 0x00 -#define CHANGE_RX 0x01 - -#define DCM_HIGH_FREQUENCY_MODE 0x00 -#define DCM_LOW_FREQUENCY_MODE 0x01 - -#define DCM_HIGH_FREQUENCY_MODE_SET 0x0C -#define DCM_LOW_FREQUENCY_MODE_SET 0x00 - -#define MULTIPLY_BY_1 0x00 -#define MULTIPLY_BY_2 0x01 -#define MULTIPLY_BY_3 0x02 -#define MULTIPLY_BY_4 0x03 -#define MULTIPLY_BY_5 0x04 -#define MULTIPLY_BY_6 0x05 -#define MULTIPLY_BY_7 0x06 -#define MULTIPLY_BY_8 0x07 -#define MULTIPLY_BY_9 0x08 -#define MULTIPLY_BY_10 0x09 - -#define DIVIDE_BY_2 0x01 -#define DIVIDE_BY_3 0x02 -#define DIVIDE_BY_4 0x03 -#define DIVIDE_BY_5 0x04 -#define DIVIDE_BY_6 0x05 -#define DIVIDE_BY_7 0x06 -#define DIVIDE_BY_8 0x07 -#define DIVIDE_BY_9 0x08 -#define DIVIDE_BY_10 0x09 - -struct timing_phase_path { - int start; - int end; - int mid; - int len; -}; - -int sd_select_card(struct rtsx_chip *chip, int select); -int sd_pull_ctl_enable(struct rtsx_chip *chip); -int reset_sd_card(struct rtsx_chip *chip); -int sd_switch_clock(struct rtsx_chip *chip); -void sd_stop_seq_mode(struct rtsx_chip *chip); -int sd_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, - u32 start_sector, u16 sector_cnt); -void sd_cleanup_work(struct rtsx_chip *chip); -int sd_power_off_card3v3(struct rtsx_chip *chip); -int release_sd_card(struct rtsx_chip *chip); -#ifdef SUPPORT_CPRM -int ext_sd_send_cmd_get_rsp(struct rtsx_chip *chip, u8 cmd_idx, - u32 arg, u8 rsp_type, u8 *rsp, int rsp_len, - bool special_check); -int ext_sd_get_rsp(struct rtsx_chip *chip, int len, u8 *rsp, u8 rsp_type); - -int sd_pass_thru_mode(struct scsi_cmnd *srb, struct rtsx_chip *chip); -int sd_execute_no_data(struct scsi_cmnd *srb, struct rtsx_chip *chip); -int sd_execute_read_data(struct scsi_cmnd *srb, struct rtsx_chip *chip); -int sd_execute_write_data(struct scsi_cmnd *srb, struct rtsx_chip *chip); -int sd_get_cmd_rsp(struct scsi_cmnd *srb, struct rtsx_chip *chip); -int sd_hw_rst(struct scsi_cmnd *srb, struct rtsx_chip *chip); -#endif - -#endif /* __REALTEK_RTSX_SD_H */ diff --git a/drivers/staging/rts5208/spi.c b/drivers/staging/rts5208/spi.c deleted file mode 100644 index e88fe1a998f8..000000000000 --- a/drivers/staging/rts5208/spi.c +++ /dev/null @@ -1,906 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Driver for Realtek PCI-Express card reader - * - * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. - * - * Author: - * Wei WANG (wei_wang@xxxxxxxxxxxxxx) - * Micky Ching (micky_ching@xxxxxxxxxxxxxx) - */ - -#include <linux/blkdev.h> -#include <linux/kthread.h> -#include <linux/sched.h> - -#include "rtsx.h" -#include "spi.h" - -static inline void spi_set_err_code(struct rtsx_chip *chip, u8 err_code) -{ - struct spi_info *spi = &chip->spi; - - spi->err_code = err_code; -} - -static int spi_init(struct rtsx_chip *chip) -{ - int retval; - - retval = rtsx_write_register(chip, SPI_CONTROL, 0xFF, - CS_POLARITY_LOW | DTO_MSB_FIRST - | SPI_MASTER | SPI_MODE0 | SPI_AUTO); - if (retval) - return retval; - retval = rtsx_write_register(chip, SPI_TCTL, EDO_TIMING_MASK, - SAMPLE_DELAY_HALF); - if (retval) - return retval; - - return STATUS_SUCCESS; -} - -static int spi_set_init_para(struct rtsx_chip *chip) -{ - struct spi_info *spi = &chip->spi; - int retval; - - retval = rtsx_write_register(chip, SPI_CLK_DIVIDER1, 0xFF, - (u8)(spi->clk_div >> 8)); - if (retval) - return retval; - retval = rtsx_write_register(chip, SPI_CLK_DIVIDER0, 0xFF, - (u8)(spi->clk_div)); - if (retval) - return retval; - - retval = switch_clock(chip, spi->spi_clock); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = select_card(chip, SPI_CARD); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = rtsx_write_register(chip, CARD_CLK_EN, SPI_CLK_EN, - SPI_CLK_EN); - if (retval) - return retval; - retval = rtsx_write_register(chip, CARD_OE, SPI_OUTPUT_EN, - SPI_OUTPUT_EN); - if (retval) - return retval; - - wait_timeout(10); - - retval = spi_init(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} - -static int sf_polling_status(struct rtsx_chip *chip, int msec) -{ - int retval; - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, SPI_RDSR); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, - SPI_TRANSFER0_START | SPI_POLLING_MODE0); - rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, - SPI_TRANSFER0_END); - - retval = rtsx_send_cmd(chip, 0, msec); - if (retval < 0) { - rtsx_clear_spi_error(chip); - spi_set_err_code(chip, SPI_BUSY_ERR); - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -static int sf_enable_write(struct rtsx_chip *chip, u8 ins) -{ - struct spi_info *spi = &chip->spi; - int retval; - - if (!spi->write_en) - return STATUS_SUCCESS; - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, ins); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, - SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_24); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, - SPI_TRANSFER0_START | SPI_C_MODE0); - rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, - SPI_TRANSFER0_END); - - retval = rtsx_send_cmd(chip, 0, 100); - if (retval < 0) { - rtsx_clear_spi_error(chip); - spi_set_err_code(chip, SPI_HW_ERR); - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -static int sf_disable_write(struct rtsx_chip *chip, u8 ins) -{ - struct spi_info *spi = &chip->spi; - int retval; - - if (!spi->write_en) - return STATUS_SUCCESS; - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, ins); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, - SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_24); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, - SPI_TRANSFER0_START | SPI_C_MODE0); - rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, - SPI_TRANSFER0_END); - - retval = rtsx_send_cmd(chip, 0, 100); - if (retval < 0) { - rtsx_clear_spi_error(chip); - spi_set_err_code(chip, SPI_HW_ERR); - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -static void sf_program(struct rtsx_chip *chip, u8 ins, u8 addr_mode, u32 addr, - u16 len) -{ - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, ins); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, - SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_24); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH0, 0xFF, (u8)len); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH1, 0xFF, (u8)(len >> 8)); - if (addr_mode) { - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, (u8)addr); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, - (u8)(addr >> 8)); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR2, 0xFF, - (u8)(addr >> 16)); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, - SPI_TRANSFER0_START | SPI_CADO_MODE0); - } else { - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, - SPI_TRANSFER0_START | SPI_CDO_MODE0); - } - rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, - SPI_TRANSFER0_END); -} - -static int sf_erase(struct rtsx_chip *chip, u8 ins, u8 addr_mode, u32 addr) -{ - int retval; - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, ins); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, - SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_24); - if (addr_mode) { - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, (u8)addr); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, - (u8)(addr >> 8)); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR2, 0xFF, - (u8)(addr >> 16)); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, - SPI_TRANSFER0_START | SPI_CA_MODE0); - } else { - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, - SPI_TRANSFER0_START | SPI_C_MODE0); - } - rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, - SPI_TRANSFER0_END); - - retval = rtsx_send_cmd(chip, 0, 100); - if (retval < 0) { - rtsx_clear_spi_error(chip); - spi_set_err_code(chip, SPI_HW_ERR); - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -static int spi_init_eeprom(struct rtsx_chip *chip) -{ - int retval; - int clk; - - if (chip->asic_code) - clk = 30; - else - clk = CLK_30; - - retval = rtsx_write_register(chip, SPI_CLK_DIVIDER1, 0xFF, 0x00); - if (retval) - return retval; - retval = rtsx_write_register(chip, SPI_CLK_DIVIDER0, 0xFF, 0x27); - if (retval) - return retval; - - retval = switch_clock(chip, clk); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = select_card(chip, SPI_CARD); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = rtsx_write_register(chip, CARD_CLK_EN, SPI_CLK_EN, - SPI_CLK_EN); - if (retval) - return retval; - retval = rtsx_write_register(chip, CARD_OE, SPI_OUTPUT_EN, - SPI_OUTPUT_EN); - if (retval) - return retval; - - wait_timeout(10); - - retval = rtsx_write_register(chip, SPI_CONTROL, 0xFF, - CS_POLARITY_HIGH | SPI_EEPROM_AUTO); - if (retval) - return retval; - retval = rtsx_write_register(chip, SPI_TCTL, EDO_TIMING_MASK, - SAMPLE_DELAY_HALF); - if (retval) - return retval; - - return STATUS_SUCCESS; -} - -static int spi_eeprom_program_enable(struct rtsx_chip *chip) -{ - int retval; - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, 0x86); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, 0x13); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, - SPI_TRANSFER0_START | SPI_CA_MODE0); - rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, - SPI_TRANSFER0_END); - - retval = rtsx_send_cmd(chip, 0, 100); - if (retval < 0) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} - -int spi_erase_eeprom_chip(struct rtsx_chip *chip) -{ - int retval; - - retval = spi_init_eeprom(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = spi_eeprom_program_enable(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_GPIO_DIR, 0x01, 0); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, 0x12); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, 0x84); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, - SPI_TRANSFER0_START | SPI_CA_MODE0); - rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, - SPI_TRANSFER0_END); - - retval = rtsx_send_cmd(chip, 0, 100); - if (retval < 0) - return STATUS_FAIL; - - retval = rtsx_write_register(chip, CARD_GPIO_DIR, 0x01, 0x01); - if (retval) - return retval; - - return STATUS_SUCCESS; -} - -int spi_erase_eeprom_byte(struct rtsx_chip *chip, u16 addr) -{ - int retval; - - retval = spi_init_eeprom(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = spi_eeprom_program_enable(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_GPIO_DIR, 0x01, 0); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, 0x07); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, (u8)addr); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, (u8)(addr >> 8)); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, 0x46); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, - SPI_TRANSFER0_START | SPI_CA_MODE0); - rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, - SPI_TRANSFER0_END); - - retval = rtsx_send_cmd(chip, 0, 100); - if (retval < 0) - return STATUS_FAIL; - - retval = rtsx_write_register(chip, CARD_GPIO_DIR, 0x01, 0x01); - if (retval) - return retval; - - return STATUS_SUCCESS; -} - -int spi_read_eeprom(struct rtsx_chip *chip, u16 addr, u8 *val) -{ - int retval; - u8 data; - - retval = spi_init_eeprom(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_GPIO_DIR, 0x01, 0); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, 0x06); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, (u8)addr); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, (u8)(addr >> 8)); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, 0x46); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH0, 0xFF, 1); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, - SPI_TRANSFER0_START | SPI_CADI_MODE0); - rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, - SPI_TRANSFER0_END); - - retval = rtsx_send_cmd(chip, 0, 100); - if (retval < 0) - return STATUS_FAIL; - - wait_timeout(5); - retval = rtsx_read_register(chip, SPI_DATA, &data); - if (retval) - return retval; - - if (val) - *val = data; - - retval = rtsx_write_register(chip, CARD_GPIO_DIR, 0x01, 0x01); - if (retval) - return retval; - - return STATUS_SUCCESS; -} - -int spi_write_eeprom(struct rtsx_chip *chip, u16 addr, u8 val) -{ - int retval; - - retval = spi_init_eeprom(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = spi_eeprom_program_enable(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_GPIO_DIR, 0x01, 0); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, 0x05); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, val); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, (u8)addr); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR2, 0xFF, (u8)(addr >> 8)); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, 0x4E); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, - SPI_TRANSFER0_START | SPI_CA_MODE0); - rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, - SPI_TRANSFER0_END); - - retval = rtsx_send_cmd(chip, 0, 100); - if (retval < 0) - return STATUS_FAIL; - - retval = rtsx_write_register(chip, CARD_GPIO_DIR, 0x01, 0x01); - if (retval) - return retval; - - return STATUS_SUCCESS; -} - -int spi_get_status(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - struct spi_info *spi = &chip->spi; - - dev_dbg(rtsx_dev(chip), "%s: err_code = 0x%x\n", __func__, - spi->err_code); - rtsx_stor_set_xfer_buf(&spi->err_code, - min_t(int, scsi_bufflen(srb), 1), srb); - scsi_set_resid(srb, scsi_bufflen(srb) - 1); - - return STATUS_SUCCESS; -} - -int spi_set_parameter(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - struct spi_info *spi = &chip->spi; - - spi_set_err_code(chip, SPI_NO_ERR); - - if (chip->asic_code) - spi->spi_clock = ((u16)(srb->cmnd[8]) << 8) | srb->cmnd[9]; - else - spi->spi_clock = srb->cmnd[3]; - - spi->clk_div = ((u16)(srb->cmnd[4]) << 8) | srb->cmnd[5]; - spi->write_en = srb->cmnd[6]; - - dev_dbg(rtsx_dev(chip), "spi_clock = %d, clk_div = %d, write_en = %d\n", - spi->spi_clock, spi->clk_div, spi->write_en); - - return STATUS_SUCCESS; -} - -int spi_read_flash_id(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - int retval; - u16 len; - u8 *buf; - - spi_set_err_code(chip, SPI_NO_ERR); - - len = ((u16)(srb->cmnd[7]) << 8) | srb->cmnd[8]; - if (len > 512) { - spi_set_err_code(chip, SPI_INVALID_COMMAND); - return STATUS_FAIL; - } - - retval = spi_set_init_para(chip); - if (retval != STATUS_SUCCESS) { - spi_set_err_code(chip, SPI_HW_ERR); - return STATUS_FAIL; - } - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, - PINGPONG_BUFFER); - - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, srb->cmnd[3]); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR2, 0xFF, srb->cmnd[4]); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, srb->cmnd[5]); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, srb->cmnd[6]); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, - SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_24); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH1, 0xFF, srb->cmnd[7]); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH0, 0xFF, srb->cmnd[8]); - - if (len == 0) { - if (srb->cmnd[9]) { - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, - 0xFF, SPI_TRANSFER0_START | SPI_CA_MODE0); - } else { - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, - 0xFF, SPI_TRANSFER0_START | SPI_C_MODE0); - } - } else { - if (srb->cmnd[9]) { - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, - SPI_TRANSFER0_START | SPI_CADI_MODE0); - } else { - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, - SPI_TRANSFER0_START | SPI_CDI_MODE0); - } - } - - rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, - SPI_TRANSFER0_END); - - retval = rtsx_send_cmd(chip, 0, 100); - if (retval < 0) { - rtsx_clear_spi_error(chip); - spi_set_err_code(chip, SPI_HW_ERR); - return STATUS_FAIL; - } - - if (len) { - buf = kmalloc(len, GFP_KERNEL); - if (!buf) - return STATUS_ERROR; - - retval = rtsx_read_ppbuf(chip, buf, len); - if (retval != STATUS_SUCCESS) { - spi_set_err_code(chip, SPI_READ_ERR); - kfree(buf); - return STATUS_FAIL; - } - - rtsx_stor_set_xfer_buf(buf, scsi_bufflen(srb), srb); - scsi_set_resid(srb, 0); - - kfree(buf); - } - - return STATUS_SUCCESS; -} - -int spi_read_flash(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - int retval; - unsigned int index = 0, offset = 0; - u8 ins, slow_read; - u32 addr; - u16 len; - u8 *buf; - - spi_set_err_code(chip, SPI_NO_ERR); - - ins = srb->cmnd[3]; - addr = ((u32)(srb->cmnd[4]) << 16) | ((u32)(srb->cmnd[5]) - << 8) | srb->cmnd[6]; - len = ((u16)(srb->cmnd[7]) << 8) | srb->cmnd[8]; - slow_read = srb->cmnd[9]; - - retval = spi_set_init_para(chip); - if (retval != STATUS_SUCCESS) { - spi_set_err_code(chip, SPI_HW_ERR); - return STATUS_FAIL; - } - - buf = kmalloc(SF_PAGE_LEN, GFP_KERNEL); - if (!buf) - return STATUS_ERROR; - - while (len) { - u16 pagelen = SF_PAGE_LEN - (u8)addr; - - if (pagelen > len) - pagelen = len; - - rtsx_init_cmd(chip); - - trans_dma_enable(DMA_FROM_DEVICE, chip, 256, DMA_256); - - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, ins); - - if (slow_read) { - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, - (u8)addr); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, - (u8)(addr >> 8)); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR2, 0xFF, - (u8)(addr >> 16)); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, - SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_24); - } else { - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, - (u8)addr); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR2, 0xFF, - (u8)(addr >> 8)); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR3, 0xFF, - (u8)(addr >> 16)); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, - SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_32); - } - - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH1, 0xFF, - (u8)(pagelen >> 8)); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH0, 0xFF, - (u8)pagelen); - - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, - SPI_TRANSFER0_START | SPI_CADI_MODE0); - rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, - SPI_TRANSFER0_END, SPI_TRANSFER0_END); - - rtsx_send_cmd_no_wait(chip); - - retval = rtsx_transfer_data(chip, 0, buf, pagelen, 0, - DMA_FROM_DEVICE, 10000); - if (retval < 0) { - kfree(buf); - rtsx_clear_spi_error(chip); - spi_set_err_code(chip, SPI_HW_ERR); - return STATUS_FAIL; - } - - rtsx_stor_access_xfer_buf(buf, pagelen, srb, &index, &offset, - TO_XFER_BUF); - - addr += pagelen; - len -= pagelen; - } - - scsi_set_resid(srb, 0); - kfree(buf); - - return STATUS_SUCCESS; -} - -int spi_write_flash(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - int retval; - u8 ins, program_mode; - u32 addr; - u16 len; - u8 *buf; - unsigned int index = 0, offset = 0; - - spi_set_err_code(chip, SPI_NO_ERR); - - ins = srb->cmnd[3]; - addr = ((u32)(srb->cmnd[4]) << 16) | ((u32)(srb->cmnd[5]) - << 8) | srb->cmnd[6]; - len = ((u16)(srb->cmnd[7]) << 8) | srb->cmnd[8]; - program_mode = srb->cmnd[9]; - - retval = spi_set_init_para(chip); - if (retval != STATUS_SUCCESS) { - spi_set_err_code(chip, SPI_HW_ERR); - return STATUS_FAIL; - } - - if (program_mode == BYTE_PROGRAM) { - buf = kmalloc(4, GFP_KERNEL); - if (!buf) - return STATUS_ERROR; - - while (len) { - retval = sf_enable_write(chip, SPI_WREN); - if (retval != STATUS_SUCCESS) { - kfree(buf); - return STATUS_FAIL; - } - - rtsx_stor_access_xfer_buf(buf, 1, srb, &index, &offset, - FROM_XFER_BUF); - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, - 0x01, PINGPONG_BUFFER); - rtsx_add_cmd(chip, WRITE_REG_CMD, PPBUF_BASE2, 0xFF, - buf[0]); - sf_program(chip, ins, 1, addr, 1); - - retval = rtsx_send_cmd(chip, 0, 100); - if (retval < 0) { - kfree(buf); - rtsx_clear_spi_error(chip); - spi_set_err_code(chip, SPI_HW_ERR); - return STATUS_FAIL; - } - - retval = sf_polling_status(chip, 100); - if (retval != STATUS_SUCCESS) { - kfree(buf); - return STATUS_FAIL; - } - - addr++; - len--; - } - - kfree(buf); - - } else if (program_mode == AAI_PROGRAM) { - int first_byte = 1; - - retval = sf_enable_write(chip, SPI_WREN); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - buf = kmalloc(4, GFP_KERNEL); - if (!buf) - return STATUS_ERROR; - - while (len) { - rtsx_stor_access_xfer_buf(buf, 1, srb, &index, &offset, - FROM_XFER_BUF); - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, - 0x01, PINGPONG_BUFFER); - rtsx_add_cmd(chip, WRITE_REG_CMD, PPBUF_BASE2, 0xFF, - buf[0]); - if (first_byte) { - sf_program(chip, ins, 1, addr, 1); - first_byte = 0; - } else { - sf_program(chip, ins, 0, 0, 1); - } - - retval = rtsx_send_cmd(chip, 0, 100); - if (retval < 0) { - kfree(buf); - rtsx_clear_spi_error(chip); - spi_set_err_code(chip, SPI_HW_ERR); - return STATUS_FAIL; - } - - retval = sf_polling_status(chip, 100); - if (retval != STATUS_SUCCESS) { - kfree(buf); - return STATUS_FAIL; - } - - len--; - } - - kfree(buf); - - retval = sf_disable_write(chip, SPI_WRDI); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = sf_polling_status(chip, 100); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } else if (program_mode == PAGE_PROGRAM) { - buf = kmalloc(SF_PAGE_LEN, GFP_KERNEL); - if (!buf) - return STATUS_NOMEM; - - while (len) { - u16 pagelen = SF_PAGE_LEN - (u8)addr; - - if (pagelen > len) - pagelen = len; - - retval = sf_enable_write(chip, SPI_WREN); - if (retval != STATUS_SUCCESS) { - kfree(buf); - return STATUS_FAIL; - } - - rtsx_init_cmd(chip); - - trans_dma_enable(DMA_TO_DEVICE, chip, 256, DMA_256); - sf_program(chip, ins, 1, addr, pagelen); - - rtsx_send_cmd_no_wait(chip); - - rtsx_stor_access_xfer_buf(buf, pagelen, srb, &index, - &offset, FROM_XFER_BUF); - - retval = rtsx_transfer_data(chip, 0, buf, pagelen, 0, - DMA_TO_DEVICE, 100); - if (retval < 0) { - kfree(buf); - rtsx_clear_spi_error(chip); - spi_set_err_code(chip, SPI_HW_ERR); - return STATUS_FAIL; - } - - retval = sf_polling_status(chip, 100); - if (retval != STATUS_SUCCESS) { - kfree(buf); - return STATUS_FAIL; - } - - addr += pagelen; - len -= pagelen; - } - - kfree(buf); - } else { - spi_set_err_code(chip, SPI_INVALID_COMMAND); - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -int spi_erase_flash(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - int retval; - u8 ins, erase_mode; - u32 addr; - - spi_set_err_code(chip, SPI_NO_ERR); - - ins = srb->cmnd[3]; - addr = ((u32)(srb->cmnd[4]) << 16) | ((u32)(srb->cmnd[5]) - << 8) | srb->cmnd[6]; - erase_mode = srb->cmnd[9]; - - retval = spi_set_init_para(chip); - if (retval != STATUS_SUCCESS) { - spi_set_err_code(chip, SPI_HW_ERR); - return STATUS_FAIL; - } - - if (erase_mode == PAGE_ERASE) { - retval = sf_enable_write(chip, SPI_WREN); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = sf_erase(chip, ins, 1, addr); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } else if (erase_mode == CHIP_ERASE) { - retval = sf_enable_write(chip, SPI_WREN); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = sf_erase(chip, ins, 0, 0); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } else { - spi_set_err_code(chip, SPI_INVALID_COMMAND); - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -int spi_write_flash_status(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - int retval; - u8 ins, status, ewsr; - - ins = srb->cmnd[3]; - status = srb->cmnd[4]; - ewsr = srb->cmnd[5]; - - retval = spi_set_init_para(chip); - if (retval != STATUS_SUCCESS) { - spi_set_err_code(chip, SPI_HW_ERR); - return STATUS_FAIL; - } - - retval = sf_enable_write(chip, ewsr); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, - PINGPONG_BUFFER); - - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, ins); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, - SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_24); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH1, 0xFF, 0); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH0, 0xFF, 1); - rtsx_add_cmd(chip, WRITE_REG_CMD, PPBUF_BASE2, 0xFF, status); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, - SPI_TRANSFER0_START | SPI_CDO_MODE0); - rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, - SPI_TRANSFER0_END); - - retval = rtsx_send_cmd(chip, 0, 100); - if (retval != STATUS_SUCCESS) { - rtsx_clear_spi_error(chip); - spi_set_err_code(chip, SPI_HW_ERR); - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} diff --git a/drivers/staging/rts5208/spi.h b/drivers/staging/rts5208/spi.h deleted file mode 100644 index dcf93c80b2d5..000000000000 --- a/drivers/staging/rts5208/spi.h +++ /dev/null @@ -1,52 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Driver for Realtek PCI-Express card reader - * - * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. - * - * Author: - * Wei WANG (wei_wang@xxxxxxxxxxxxxx) - * Micky Ching (micky_ching@xxxxxxxxxxxxxx) - */ - -#ifndef __REALTEK_RTSX_SPI_H -#define __REALTEK_RTSX_SPI_H - -/* SPI operation error */ -#define SPI_NO_ERR 0x00 -#define SPI_HW_ERR 0x01 -#define SPI_INVALID_COMMAND 0x02 -#define SPI_READ_ERR 0x03 -#define SPI_WRITE_ERR 0x04 -#define SPI_ERASE_ERR 0x05 -#define SPI_BUSY_ERR 0x06 - -/* Serial flash instruction */ -#define SPI_READ 0x03 -#define SPI_FAST_READ 0x0B -#define SPI_WREN 0x06 -#define SPI_WRDI 0x04 -#define SPI_RDSR 0x05 - -#define SF_PAGE_LEN 256 - -#define BYTE_PROGRAM 0 -#define AAI_PROGRAM 1 -#define PAGE_PROGRAM 2 - -#define PAGE_ERASE 0 -#define CHIP_ERASE 1 - -int spi_erase_eeprom_chip(struct rtsx_chip *chip); -int spi_erase_eeprom_byte(struct rtsx_chip *chip, u16 addr); -int spi_read_eeprom(struct rtsx_chip *chip, u16 addr, u8 *val); -int spi_write_eeprom(struct rtsx_chip *chip, u16 addr, u8 val); -int spi_get_status(struct scsi_cmnd *srb, struct rtsx_chip *chip); -int spi_set_parameter(struct scsi_cmnd *srb, struct rtsx_chip *chip); -int spi_read_flash_id(struct scsi_cmnd *srb, struct rtsx_chip *chip); -int spi_read_flash(struct scsi_cmnd *srb, struct rtsx_chip *chip); -int spi_write_flash(struct scsi_cmnd *srb, struct rtsx_chip *chip); -int spi_erase_flash(struct scsi_cmnd *srb, struct rtsx_chip *chip); -int spi_write_flash_status(struct scsi_cmnd *srb, struct rtsx_chip *chip); - -#endif /* __REALTEK_RTSX_SPI_H */ diff --git a/drivers/staging/rts5208/xd.c b/drivers/staging/rts5208/xd.c deleted file mode 100644 index c0af378ada71..000000000000 --- a/drivers/staging/rts5208/xd.c +++ /dev/null @@ -1,2145 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Driver for Realtek PCI-Express card reader - * - * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. - * - * Author: - * Wei WANG (wei_wang@xxxxxxxxxxxxxx) - * Micky Ching (micky_ching@xxxxxxxxxxxxxx) - */ - -#include <linux/blkdev.h> -#include <linux/kthread.h> -#include <linux/sched.h> -#include <linux/vmalloc.h> - -#include "rtsx.h" -#include "rtsx_transport.h" -#include "rtsx_scsi.h" -#include "rtsx_card.h" -#include "xd.h" - -static int xd_build_l2p_tbl(struct rtsx_chip *chip, int zone_no); -static int xd_init_page(struct rtsx_chip *chip, u32 phy_blk, u16 logoff, - u8 start_page, u8 end_page); - -static inline void xd_set_err_code(struct rtsx_chip *chip, u8 err_code) -{ - struct xd_info *xd_card = &chip->xd_card; - - xd_card->err_code = err_code; -} - -static int xd_set_init_para(struct rtsx_chip *chip) -{ - struct xd_info *xd_card = &chip->xd_card; - int retval; - - if (chip->asic_code) - xd_card->xd_clock = 47; - else - xd_card->xd_clock = CLK_50; - - retval = switch_clock(chip, xd_card->xd_clock); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} - -static int xd_switch_clock(struct rtsx_chip *chip) -{ - struct xd_info *xd_card = &chip->xd_card; - int retval; - - retval = select_card(chip, XD_CARD); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = switch_clock(chip, xd_card->xd_clock); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} - -static int xd_read_id(struct rtsx_chip *chip, u8 id_cmd, u8 *id_buf, u8 buf_len) -{ - int retval, i; - u8 *ptr; - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_DAT, 0xFF, id_cmd); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, - XD_TRANSFER_START | XD_READ_ID); - rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, XD_TRANSFER_END, - XD_TRANSFER_END); - - for (i = 0; i < 4; i++) - rtsx_add_cmd(chip, READ_REG_CMD, (u16)(XD_ADDRESS1 + i), 0, 0); - - retval = rtsx_send_cmd(chip, XD_CARD, 20); - if (retval < 0) - return STATUS_FAIL; - - ptr = rtsx_get_cmd_data(chip) + 1; - if (id_buf && buf_len) { - if (buf_len > 4) - buf_len = 4; - memcpy(id_buf, ptr, buf_len); - } - - return STATUS_SUCCESS; -} - -static void xd_assign_phy_addr(struct rtsx_chip *chip, u32 addr, u8 mode) -{ - struct xd_info *xd_card = &chip->xd_card; - - switch (mode) { - case XD_RW_ADDR: - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS0, 0xFF, 0); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS1, 0xFF, (u8)addr); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS2, - 0xFF, (u8)(addr >> 8)); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS3, - 0xFF, (u8)(addr >> 16)); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CFG, 0xFF, - xd_card->addr_cycle | - XD_CALC_ECC | - XD_BA_NO_TRANSFORM); - break; - - case XD_ERASE_ADDR: - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS0, 0xFF, (u8)addr); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS1, - 0xFF, (u8)(addr >> 8)); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS2, - 0xFF, (u8)(addr >> 16)); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CFG, 0xFF, - (xd_card->addr_cycle - 1) | XD_CALC_ECC | - XD_BA_NO_TRANSFORM); - break; - - default: - break; - } -} - -static int xd_read_redundant(struct rtsx_chip *chip, u32 page_addr, - u8 *buf, int buf_len) -{ - int retval, i; - - rtsx_init_cmd(chip); - - xd_assign_phy_addr(chip, page_addr, XD_RW_ADDR); - - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, - 0xFF, XD_TRANSFER_START | XD_READ_REDUNDANT); - rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, - XD_TRANSFER_END, XD_TRANSFER_END); - - for (i = 0; i < 6; i++) - rtsx_add_cmd(chip, READ_REG_CMD, (u16)(XD_PAGE_STATUS + i), - 0, 0); - for (i = 0; i < 4; i++) - rtsx_add_cmd(chip, READ_REG_CMD, (u16)(XD_RESERVED0 + i), - 0, 0); - rtsx_add_cmd(chip, READ_REG_CMD, XD_PARITY, 0, 0); - - retval = rtsx_send_cmd(chip, XD_CARD, 500); - if (retval < 0) - return STATUS_FAIL; - - if (buf && buf_len) { - u8 *ptr = rtsx_get_cmd_data(chip) + 1; - - if (buf_len > 11) - buf_len = 11; - memcpy(buf, ptr, buf_len); - } - - return STATUS_SUCCESS; -} - -static int xd_read_data_from_ppb(struct rtsx_chip *chip, int offset, - u8 *buf, int buf_len) -{ - int retval, i; - - if (!buf || buf_len < 0) - return STATUS_FAIL; - - rtsx_init_cmd(chip); - - for (i = 0; i < buf_len; i++) - rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + offset + i, - 0, 0); - - retval = rtsx_send_cmd(chip, 0, 250); - if (retval < 0) { - rtsx_clear_xd_error(chip); - return STATUS_FAIL; - } - - memcpy(buf, rtsx_get_cmd_data(chip), buf_len); - - return STATUS_SUCCESS; -} - -static int xd_read_cis(struct rtsx_chip *chip, u32 page_addr, u8 *buf, - int buf_len) -{ - int retval; - u8 reg; - - if (!buf || buf_len < 10) - return STATUS_FAIL; - - rtsx_init_cmd(chip); - - xd_assign_phy_addr(chip, page_addr, XD_RW_ADDR); - - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, - 0x01, PINGPONG_BUFFER); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, 1); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CHK_DATA_STATUS, - XD_AUTO_CHK_DATA_STATUS, XD_AUTO_CHK_DATA_STATUS); - - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, - XD_TRANSFER_START | XD_READ_PAGES); - rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, XD_TRANSFER_END, - XD_TRANSFER_END); - - retval = rtsx_send_cmd(chip, XD_CARD, 250); - if (retval == -ETIMEDOUT) { - rtsx_clear_xd_error(chip); - return STATUS_FAIL; - } - - retval = rtsx_read_register(chip, XD_PAGE_STATUS, ®); - if (retval) - return retval; - if (reg != XD_GPG) { - rtsx_clear_xd_error(chip); - return STATUS_FAIL; - } - - retval = rtsx_read_register(chip, XD_CTL, ®); - if (retval) - return retval; - if (!(reg & XD_ECC1_ERROR) || !(reg & XD_ECC1_UNCORRECTABLE)) { - retval = xd_read_data_from_ppb(chip, 0, buf, buf_len); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - if (reg & XD_ECC1_ERROR) { - u8 ecc_bit, ecc_byte; - - retval = rtsx_read_register(chip, XD_ECC_BIT1, - &ecc_bit); - if (retval) - return retval; - retval = rtsx_read_register(chip, XD_ECC_BYTE1, - &ecc_byte); - if (retval) - return retval; - - dev_dbg(rtsx_dev(chip), "ECC_BIT1 = 0x%x, ECC_BYTE1 = 0x%x\n", - ecc_bit, ecc_byte); - if (ecc_byte < buf_len) { - dev_dbg(rtsx_dev(chip), "Before correct: 0x%x\n", - buf[ecc_byte]); - buf[ecc_byte] ^= (1 << ecc_bit); - dev_dbg(rtsx_dev(chip), "After correct: 0x%x\n", - buf[ecc_byte]); - } - } - } else if (!(reg & XD_ECC2_ERROR) || !(reg & XD_ECC2_UNCORRECTABLE)) { - rtsx_clear_xd_error(chip); - - retval = xd_read_data_from_ppb(chip, 256, buf, buf_len); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - if (reg & XD_ECC2_ERROR) { - u8 ecc_bit, ecc_byte; - - retval = rtsx_read_register(chip, XD_ECC_BIT2, - &ecc_bit); - if (retval) - return retval; - retval = rtsx_read_register(chip, XD_ECC_BYTE2, - &ecc_byte); - if (retval) - return retval; - - dev_dbg(rtsx_dev(chip), "ECC_BIT2 = 0x%x, ECC_BYTE2 = 0x%x\n", - ecc_bit, ecc_byte); - if (ecc_byte < buf_len) { - dev_dbg(rtsx_dev(chip), "Before correct: 0x%x\n", - buf[ecc_byte]); - buf[ecc_byte] ^= (1 << ecc_bit); - dev_dbg(rtsx_dev(chip), "After correct: 0x%x\n", - buf[ecc_byte]); - } - } - } else { - rtsx_clear_xd_error(chip); - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -static void xd_fill_pull_ctl_disable(struct rtsx_chip *chip) -{ - if (CHECK_PID(chip, 0x5208)) { - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, - XD_D3_PD | XD_D2_PD | XD_D1_PD | XD_D0_PD); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, - XD_D7_PD | XD_D6_PD | XD_D5_PD | XD_D4_PD); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, - XD_WP_PD | XD_CE_PD | XD_CLE_PD | XD_CD_PU); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, - XD_RDY_PD | XD_WE_PD | XD_RE_PD | XD_ALE_PD); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF, - MS_INS_PU | SD_WP_PD | SD_CD_PU | SD_CMD_PD); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, - MS_D5_PD | MS_D4_PD); - } else if (CHECK_PID(chip, 0x5288)) { - if (CHECK_BARO_PKG(chip, QFN)) { - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, - 0xFF, 0x55); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, - 0xFF, 0x55); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, - 0xFF, 0x4B); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, - 0xFF, 0x69); - } - } -} - -static void xd_fill_pull_ctl_stage1_barossa(struct rtsx_chip *chip) -{ - if (CHECK_BARO_PKG(chip, QFN)) { - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, 0x55); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, 0x55); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, 0x4B); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, 0x55); - } -} - -static void xd_fill_pull_ctl_enable(struct rtsx_chip *chip) -{ - if (CHECK_PID(chip, 0x5208)) { - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, - XD_D3_PD | XD_D2_PD | XD_D1_PD | XD_D0_PD); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, - XD_D7_PD | XD_D6_PD | XD_D5_PD | XD_D4_PD); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, - XD_WP_PD | XD_CE_PU | XD_CLE_PD | XD_CD_PU); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, - XD_RDY_PU | XD_WE_PU | XD_RE_PU | XD_ALE_PD); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF, - MS_INS_PU | SD_WP_PD | SD_CD_PU | SD_CMD_PD); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, - MS_D5_PD | MS_D4_PD); - } else if (CHECK_PID(chip, 0x5288)) { - if (CHECK_BARO_PKG(chip, QFN)) { - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, - 0xFF, 0x55); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, - 0xFF, 0x55); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, - 0xFF, 0x53); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, - 0xFF, 0xA9); - } - } -} - -static int xd_pull_ctl_disable(struct rtsx_chip *chip) -{ - int retval; - - if (CHECK_PID(chip, 0x5208)) { - retval = rtsx_write_register(chip, CARD_PULL_CTL1, 0xFF, - XD_D3_PD | - XD_D2_PD | - XD_D1_PD | - XD_D0_PD); - if (retval) - return retval; - retval = rtsx_write_register(chip, CARD_PULL_CTL2, 0xFF, - XD_D7_PD | - XD_D6_PD | - XD_D5_PD | - XD_D4_PD); - if (retval) - return retval; - retval = rtsx_write_register(chip, CARD_PULL_CTL3, 0xFF, - XD_WP_PD | - XD_CE_PD | - XD_CLE_PD | - XD_CD_PU); - if (retval) - return retval; - retval = rtsx_write_register(chip, CARD_PULL_CTL4, 0xFF, - XD_RDY_PD | - XD_WE_PD | - XD_RE_PD | - XD_ALE_PD); - if (retval) - return retval; - retval = rtsx_write_register(chip, CARD_PULL_CTL5, 0xFF, - MS_INS_PU | - SD_WP_PD | - SD_CD_PU | - SD_CMD_PD); - if (retval) - return retval; - retval = rtsx_write_register(chip, CARD_PULL_CTL6, 0xFF, - MS_D5_PD | MS_D4_PD); - if (retval) - return retval; - } else if (CHECK_PID(chip, 0x5288)) { - if (CHECK_BARO_PKG(chip, QFN)) { - retval = rtsx_write_register(chip, CARD_PULL_CTL1, - 0xFF, 0x55); - if (retval) - return retval; - retval = rtsx_write_register(chip, CARD_PULL_CTL2, - 0xFF, 0x55); - if (retval) - return retval; - retval = rtsx_write_register(chip, CARD_PULL_CTL3, - 0xFF, 0x4B); - if (retval) - return retval; - retval = rtsx_write_register(chip, CARD_PULL_CTL4, - 0xFF, 0x69); - if (retval) - return retval; - } - } - - return STATUS_SUCCESS; -} - -static int reset_xd(struct rtsx_chip *chip) -{ - struct xd_info *xd_card = &chip->xd_card; - int retval, i, j; - u8 *ptr, id_buf[4], redunt[11]; - - retval = select_card(chip, XD_CARD); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CHK_DATA_STATUS, 0xFF, - XD_PGSTS_NOT_FF); - if (chip->asic_code) { - if (!CHECK_PID(chip, 0x5288)) - xd_fill_pull_ctl_disable(chip); - else - xd_fill_pull_ctl_stage1_barossa(chip); - } else { - rtsx_add_cmd(chip, WRITE_REG_CMD, FPGA_PULL_CTL, 0xFF, - (FPGA_XD_PULL_CTL_EN1 & FPGA_XD_PULL_CTL_EN3) | - 0x20); - } - - if (!chip->ft2_fast_mode) - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_INIT, - XD_NO_AUTO_PWR_OFF, 0); - - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_OE, XD_OUTPUT_EN, 0); - - retval = rtsx_send_cmd(chip, XD_CARD, 100); - if (retval < 0) - return STATUS_FAIL; - - if (!chip->ft2_fast_mode) { - retval = card_power_off(chip, XD_CARD); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - wait_timeout(250); - - rtsx_init_cmd(chip); - - if (chip->asic_code) { - xd_fill_pull_ctl_enable(chip); - } else { - rtsx_add_cmd(chip, WRITE_REG_CMD, FPGA_PULL_CTL, 0xFF, - (FPGA_XD_PULL_CTL_EN1 & - FPGA_XD_PULL_CTL_EN2) | - 0x20); - } - - retval = rtsx_send_cmd(chip, XD_CARD, 100); - if (retval < 0) - return STATUS_FAIL; - - retval = card_power_on(chip, XD_CARD); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - -#ifdef SUPPORT_OCP - wait_timeout(50); - if (chip->ocp_stat & (SD_OC_NOW | SD_OC_EVER)) { - dev_dbg(rtsx_dev(chip), "Over current, OCPSTAT is 0x%x\n", - chip->ocp_stat); - return STATUS_FAIL; - } -#endif - } - - rtsx_init_cmd(chip); - - if (chip->ft2_fast_mode) { - if (chip->asic_code) { - xd_fill_pull_ctl_enable(chip); - } else { - rtsx_add_cmd(chip, WRITE_REG_CMD, FPGA_PULL_CTL, 0xFF, - (FPGA_XD_PULL_CTL_EN1 & - FPGA_XD_PULL_CTL_EN2) | - 0x20); - } - } - - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_OE, XD_OUTPUT_EN, XD_OUTPUT_EN); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CTL, XD_CE_DISEN, XD_CE_DISEN); - - retval = rtsx_send_cmd(chip, XD_CARD, 100); - if (retval < 0) - return STATUS_FAIL; - - if (!chip->ft2_fast_mode) - wait_timeout(200); - - retval = xd_set_init_para(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - /* Read ID to check if the timing setting is right */ - for (i = 0; i < 4; i++) { - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_DTCTL, 0xFF, - XD_TIME_SETUP_STEP * 3 + - XD_TIME_RW_STEP * (2 + i) + XD_TIME_RWN_STEP * i); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CATCTL, 0xFF, - XD_TIME_SETUP_STEP * 3 + - XD_TIME_RW_STEP * (4 + i) + - XD_TIME_RWN_STEP * (3 + i)); - - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, - XD_TRANSFER_START | XD_RESET); - rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, - XD_TRANSFER_END, XD_TRANSFER_END); - - rtsx_add_cmd(chip, READ_REG_CMD, XD_DAT, 0, 0); - rtsx_add_cmd(chip, READ_REG_CMD, XD_CTL, 0, 0); - - retval = rtsx_send_cmd(chip, XD_CARD, 100); - if (retval < 0) - return STATUS_FAIL; - - ptr = rtsx_get_cmd_data(chip) + 1; - - dev_dbg(rtsx_dev(chip), "XD_DAT: 0x%x, XD_CTL: 0x%x\n", - ptr[0], ptr[1]); - - if (((ptr[0] & READY_FLAG) != READY_STATE) || - !(ptr[1] & XD_RDY)) - continue; - - retval = xd_read_id(chip, READ_ID, id_buf, 4); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - dev_dbg(rtsx_dev(chip), "READ_ID: 0x%x 0x%x 0x%x 0x%x\n", - id_buf[0], id_buf[1], id_buf[2], id_buf[3]); - - xd_card->device_code = id_buf[1]; - - /* Check if the xD card is supported */ - switch (xd_card->device_code) { - case XD_4M_X8_512_1: - case XD_4M_X8_512_2: - xd_card->block_shift = 4; - xd_card->page_off = 0x0F; - xd_card->addr_cycle = 3; - xd_card->zone_cnt = 1; - xd_card->capacity = 8000; - XD_SET_4MB(xd_card); - break; - case XD_8M_X8_512: - xd_card->block_shift = 4; - xd_card->page_off = 0x0F; - xd_card->addr_cycle = 3; - xd_card->zone_cnt = 1; - xd_card->capacity = 16000; - break; - case XD_16M_X8_512: - XD_PAGE_512(xd_card); - xd_card->addr_cycle = 3; - xd_card->zone_cnt = 1; - xd_card->capacity = 32000; - break; - case XD_32M_X8_512: - XD_PAGE_512(xd_card); - xd_card->addr_cycle = 3; - xd_card->zone_cnt = 2; - xd_card->capacity = 64000; - break; - case XD_64M_X8_512: - XD_PAGE_512(xd_card); - xd_card->addr_cycle = 4; - xd_card->zone_cnt = 4; - xd_card->capacity = 128000; - break; - case XD_128M_X8_512: - XD_PAGE_512(xd_card); - xd_card->addr_cycle = 4; - xd_card->zone_cnt = 8; - xd_card->capacity = 256000; - break; - case XD_256M_X8_512: - XD_PAGE_512(xd_card); - xd_card->addr_cycle = 4; - xd_card->zone_cnt = 16; - xd_card->capacity = 512000; - break; - case XD_512M_X8: - XD_PAGE_512(xd_card); - xd_card->addr_cycle = 4; - xd_card->zone_cnt = 32; - xd_card->capacity = 1024000; - break; - case XD_1G_X8_512: - XD_PAGE_512(xd_card); - xd_card->addr_cycle = 4; - xd_card->zone_cnt = 64; - xd_card->capacity = 2048000; - break; - case XD_2G_X8_512: - XD_PAGE_512(xd_card); - xd_card->addr_cycle = 4; - xd_card->zone_cnt = 128; - xd_card->capacity = 4096000; - break; - default: - continue; - } - - /* Confirm timing setting */ - for (j = 0; j < 10; j++) { - retval = xd_read_id(chip, READ_ID, id_buf, 4); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (id_buf[1] != xd_card->device_code) - break; - } - - if (j == 10) - break; - } - - if (i == 4) { - xd_card->block_shift = 0; - xd_card->page_off = 0; - xd_card->addr_cycle = 0; - xd_card->capacity = 0; - - return STATUS_FAIL; - } - - retval = xd_read_id(chip, READ_XD_ID, id_buf, 4); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - dev_dbg(rtsx_dev(chip), "READ_XD_ID: 0x%x 0x%x 0x%x 0x%x\n", - id_buf[0], id_buf[1], id_buf[2], id_buf[3]); - if (id_buf[2] != XD_ID_CODE) - return STATUS_FAIL; - - /* Search CIS block */ - for (i = 0; i < 24; i++) { - u32 page_addr; - - if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) - return STATUS_FAIL; - - page_addr = (u32)i << xd_card->block_shift; - - for (j = 0; j < 3; j++) { - retval = xd_read_redundant(chip, page_addr, redunt, 11); - if (retval == STATUS_SUCCESS) - break; - } - if (j == 3) - continue; - - if (redunt[BLOCK_STATUS] != XD_GBLK) - continue; - - j = 0; - if (redunt[PAGE_STATUS] != XD_GPG) { - for (j = 1; j <= 8; j++) { - retval = xd_read_redundant(chip, page_addr + j, - redunt, 11); - if (retval == STATUS_SUCCESS) { - if (redunt[PAGE_STATUS] == XD_GPG) - break; - } - } - - if (j == 9) - break; - } - - /* Check CIS data */ - if (redunt[BLOCK_STATUS] == XD_GBLK && - (redunt[PARITY] & XD_BA1_ALL0)) { - u8 buf[10]; - - page_addr += j; - - retval = xd_read_cis(chip, page_addr, buf, 10); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (buf[0] == 0x01 && buf[1] == 0x03 && - buf[2] == 0xD9 && - buf[3] == 0x01 && buf[4] == 0xFF && - buf[5] == 0x18 && buf[6] == 0x02 && - buf[7] == 0xDF && buf[8] == 0x01 && - buf[9] == 0x20) { - xd_card->cis_block = (u16)i; - } - } - - break; - } - - dev_dbg(rtsx_dev(chip), "CIS block: 0x%x\n", xd_card->cis_block); - if (xd_card->cis_block == 0xFFFF) - return STATUS_FAIL; - - chip->capacity[chip->card2lun[XD_CARD]] = xd_card->capacity; - - return STATUS_SUCCESS; -} - -static int xd_check_data_blank(u8 *redunt) -{ - int i; - - for (i = 0; i < 6; i++) { - if (redunt[PAGE_STATUS + i] != 0xFF) - return 0; - } - - if ((redunt[PARITY] & (XD_ECC1_ALL1 | XD_ECC2_ALL1)) - != (XD_ECC1_ALL1 | XD_ECC2_ALL1)) - return 0; - - for (i = 0; i < 4; i++) { - if (redunt[RESERVED0 + i] != 0xFF) - return 0; - } - - return 1; -} - -static u16 xd_load_log_block_addr(u8 *redunt) -{ - u16 addr = 0xFFFF; - - if (redunt[PARITY] & XD_BA1_BA2_EQL) - addr = ((u16)redunt[BLOCK_ADDR1_H] << 8) | - redunt[BLOCK_ADDR1_L]; - else if (redunt[PARITY] & XD_BA1_VALID) - addr = ((u16)redunt[BLOCK_ADDR1_H] << 8) | - redunt[BLOCK_ADDR1_L]; - else if (redunt[PARITY] & XD_BA2_VALID) - addr = ((u16)redunt[BLOCK_ADDR2_H] << 8) | - redunt[BLOCK_ADDR2_L]; - - return addr; -} - -static int xd_init_l2p_tbl(struct rtsx_chip *chip) -{ - struct xd_info *xd_card = &chip->xd_card; - int size, i; - - dev_dbg(rtsx_dev(chip), "%s: zone_cnt = %d\n", __func__, - xd_card->zone_cnt); - - if (xd_card->zone_cnt < 1) - return STATUS_FAIL; - - size = xd_card->zone_cnt * sizeof(struct zone_entry); - dev_dbg(rtsx_dev(chip), "Buffer size for l2p table is %d\n", size); - - xd_card->zone = vmalloc(size); - if (!xd_card->zone) - return STATUS_ERROR; - - for (i = 0; i < xd_card->zone_cnt; i++) { - xd_card->zone[i].build_flag = 0; - xd_card->zone[i].l2p_table = NULL; - xd_card->zone[i].free_table = NULL; - xd_card->zone[i].get_index = 0; - xd_card->zone[i].set_index = 0; - xd_card->zone[i].unused_blk_cnt = 0; - } - - return STATUS_SUCCESS; -} - -static inline void free_zone(struct zone_entry *zone) -{ - if (!zone) - return; - - zone->build_flag = 0; - zone->set_index = 0; - zone->get_index = 0; - zone->unused_blk_cnt = 0; - vfree(zone->l2p_table); - zone->l2p_table = NULL; - vfree(zone->free_table); - zone->free_table = NULL; -} - -static void xd_set_unused_block(struct rtsx_chip *chip, u32 phy_blk) -{ - struct xd_info *xd_card = &chip->xd_card; - struct zone_entry *zone; - int zone_no; - - zone_no = (int)phy_blk >> 10; - if (zone_no >= xd_card->zone_cnt) { - dev_dbg(rtsx_dev(chip), "Set unused block to invalid zone (zone_no = %d, zone_cnt = %d)\n", - zone_no, xd_card->zone_cnt); - return; - } - zone = &xd_card->zone[zone_no]; - - if (!zone->free_table) { - if (xd_build_l2p_tbl(chip, zone_no) != STATUS_SUCCESS) - return; - } - - if (zone->set_index >= XD_FREE_TABLE_CNT || - zone->set_index < 0) { - free_zone(zone); - dev_dbg(rtsx_dev(chip), "Set unused block fail, invalid set_index\n"); - return; - } - - dev_dbg(rtsx_dev(chip), "Set unused block to index %d\n", - zone->set_index); - - zone->free_table[zone->set_index++] = (u16)(phy_blk & 0x3ff); - if (zone->set_index >= XD_FREE_TABLE_CNT) - zone->set_index = 0; - zone->unused_blk_cnt++; -} - -static u32 xd_get_unused_block(struct rtsx_chip *chip, int zone_no) -{ - struct xd_info *xd_card = &chip->xd_card; - struct zone_entry *zone; - u32 phy_blk; - - if (zone_no >= xd_card->zone_cnt) { - dev_dbg(rtsx_dev(chip), "Get unused block from invalid zone (zone_no = %d, zone_cnt = %d)\n", - zone_no, xd_card->zone_cnt); - return BLK_NOT_FOUND; - } - zone = &xd_card->zone[zone_no]; - - if (zone->unused_blk_cnt == 0 || - zone->set_index == zone->get_index) { - free_zone(zone); - dev_dbg(rtsx_dev(chip), "Get unused block fail, no unused block available\n"); - return BLK_NOT_FOUND; - } - if (zone->get_index >= XD_FREE_TABLE_CNT || zone->get_index < 0) { - free_zone(zone); - dev_dbg(rtsx_dev(chip), "Get unused block fail, invalid get_index\n"); - return BLK_NOT_FOUND; - } - - dev_dbg(rtsx_dev(chip), "Get unused block from index %d\n", - zone->get_index); - - phy_blk = zone->free_table[zone->get_index]; - zone->free_table[zone->get_index++] = 0xFFFF; - if (zone->get_index >= XD_FREE_TABLE_CNT) - zone->get_index = 0; - zone->unused_blk_cnt--; - - phy_blk += ((u32)(zone_no) << 10); - return phy_blk; -} - -static void xd_set_l2p_tbl(struct rtsx_chip *chip, - int zone_no, u16 log_off, u16 phy_off) -{ - struct xd_info *xd_card = &chip->xd_card; - struct zone_entry *zone; - - zone = &xd_card->zone[zone_no]; - zone->l2p_table[log_off] = phy_off; -} - -static u32 xd_get_l2p_tbl(struct rtsx_chip *chip, int zone_no, u16 log_off) -{ - struct xd_info *xd_card = &chip->xd_card; - struct zone_entry *zone; - int retval; - - zone = &xd_card->zone[zone_no]; - if (zone->l2p_table[log_off] == 0xFFFF) { - u32 phy_blk = 0; - int i; - -#ifdef XD_DELAY_WRITE - retval = xd_delay_write(chip); - if (retval != STATUS_SUCCESS) { - dev_dbg(rtsx_dev(chip), "In %s, delay write fail!\n", - __func__); - return BLK_NOT_FOUND; - } -#endif - - if (zone->unused_blk_cnt <= 0) { - dev_dbg(rtsx_dev(chip), "No unused block!\n"); - return BLK_NOT_FOUND; - } - - for (i = 0; i < zone->unused_blk_cnt; i++) { - phy_blk = xd_get_unused_block(chip, zone_no); - if (phy_blk == BLK_NOT_FOUND) { - dev_dbg(rtsx_dev(chip), "No unused block available!\n"); - return BLK_NOT_FOUND; - } - - retval = xd_init_page(chip, phy_blk, log_off, - 0, xd_card->page_off + 1); - if (retval == STATUS_SUCCESS) - break; - } - if (i >= zone->unused_blk_cnt) { - dev_dbg(rtsx_dev(chip), "No good unused block available!\n"); - return BLK_NOT_FOUND; - } - - xd_set_l2p_tbl(chip, zone_no, log_off, (u16)(phy_blk & 0x3FF)); - return phy_blk; - } - - return (u32)zone->l2p_table[log_off] + ((u32)(zone_no) << 10); -} - -int reset_xd_card(struct rtsx_chip *chip) -{ - struct xd_info *xd_card = &chip->xd_card; - int retval; - - memset(xd_card, 0, sizeof(struct xd_info)); - - xd_card->block_shift = 0; - xd_card->page_off = 0; - xd_card->addr_cycle = 0; - xd_card->capacity = 0; - xd_card->zone_cnt = 0; - xd_card->cis_block = 0xFFFF; - xd_card->delay_write.delay_write_flag = 0; - - retval = enable_card_clock(chip, XD_CARD); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = reset_xd(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = xd_init_l2p_tbl(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} - -static int xd_mark_bad_block(struct rtsx_chip *chip, u32 phy_blk) -{ - struct xd_info *xd_card = &chip->xd_card; - int retval; - u32 page_addr; - u8 reg = 0; - - dev_dbg(rtsx_dev(chip), "mark block 0x%x as bad block\n", phy_blk); - - if (phy_blk == BLK_NOT_FOUND) - return STATUS_FAIL; - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_STATUS, 0xFF, XD_GPG); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_STATUS, 0xFF, XD_LATER_BBLK); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR1_H, 0xFF, 0xFF); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR1_L, 0xFF, 0xFF); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR2_H, 0xFF, 0xFF); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR2_L, 0xFF, 0xFF); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_RESERVED0, 0xFF, 0xFF); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_RESERVED1, 0xFF, 0xFF); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_RESERVED2, 0xFF, 0xFF); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_RESERVED3, 0xFF, 0xFF); - - page_addr = phy_blk << xd_card->block_shift; - - xd_assign_phy_addr(chip, page_addr, XD_RW_ADDR); - - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, - xd_card->page_off + 1); - - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, - XD_TRANSFER_START | XD_WRITE_REDUNDANT); - rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, - XD_TRANSFER_END, XD_TRANSFER_END); - - retval = rtsx_send_cmd(chip, XD_CARD, 500); - if (retval < 0) { - rtsx_clear_xd_error(chip); - rtsx_read_register(chip, XD_DAT, ®); - if (reg & PROGRAM_ERROR) - xd_set_err_code(chip, XD_PRG_ERROR); - else - xd_set_err_code(chip, XD_TO_ERROR); - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -static int xd_init_page(struct rtsx_chip *chip, u32 phy_blk, - u16 logoff, u8 start_page, u8 end_page) -{ - struct xd_info *xd_card = &chip->xd_card; - int retval; - u32 page_addr; - u8 reg = 0; - - dev_dbg(rtsx_dev(chip), "Init block 0x%x\n", phy_blk); - - if (start_page > end_page) - return STATUS_FAIL; - if (phy_blk == BLK_NOT_FOUND) - return STATUS_FAIL; - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_STATUS, 0xFF, 0xFF); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_STATUS, 0xFF, 0xFF); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR1_H, - 0xFF, (u8)(logoff >> 8)); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR1_L, 0xFF, (u8)logoff); - - page_addr = (phy_blk << xd_card->block_shift) + start_page; - - xd_assign_phy_addr(chip, page_addr, XD_RW_ADDR); - - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CFG, - XD_BA_TRANSFORM, XD_BA_TRANSFORM); - - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, - 0xFF, (end_page - start_page)); - - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, - 0xFF, XD_TRANSFER_START | XD_WRITE_REDUNDANT); - rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, - XD_TRANSFER_END, XD_TRANSFER_END); - - retval = rtsx_send_cmd(chip, XD_CARD, 500); - if (retval < 0) { - rtsx_clear_xd_error(chip); - rtsx_read_register(chip, XD_DAT, ®); - if (reg & PROGRAM_ERROR) { - xd_mark_bad_block(chip, phy_blk); - xd_set_err_code(chip, XD_PRG_ERROR); - } else { - xd_set_err_code(chip, XD_TO_ERROR); - } - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -static int xd_copy_page(struct rtsx_chip *chip, u32 old_blk, u32 new_blk, - u8 start_page, u8 end_page) -{ - struct xd_info *xd_card = &chip->xd_card; - u32 old_page, new_page; - u8 i, reg = 0; - int retval; - - dev_dbg(rtsx_dev(chip), "Copy page from block 0x%x to block 0x%x\n", - old_blk, new_blk); - - if (start_page > end_page) - return STATUS_FAIL; - - if (old_blk == BLK_NOT_FOUND || new_blk == BLK_NOT_FOUND) - return STATUS_FAIL; - - old_page = (old_blk << xd_card->block_shift) + start_page; - new_page = (new_blk << xd_card->block_shift) + start_page; - - XD_CLR_BAD_NEWBLK(xd_card); - - retval = rtsx_write_register(chip, CARD_DATA_SOURCE, 0x01, - PINGPONG_BUFFER); - if (retval) - return retval; - - for (i = start_page; i < end_page; i++) { - if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) { - rtsx_clear_xd_error(chip); - xd_set_err_code(chip, XD_NO_CARD); - return STATUS_FAIL; - } - - rtsx_init_cmd(chip); - - xd_assign_phy_addr(chip, old_page, XD_RW_ADDR); - - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, 1); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CHK_DATA_STATUS, - XD_AUTO_CHK_DATA_STATUS, 0); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, - XD_TRANSFER_START | XD_READ_PAGES); - rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, - XD_TRANSFER_END, XD_TRANSFER_END); - - retval = rtsx_send_cmd(chip, XD_CARD, 500); - if (retval < 0) { - rtsx_clear_xd_error(chip); - reg = 0; - rtsx_read_register(chip, XD_CTL, ®); - if (reg & (XD_ECC1_ERROR | XD_ECC2_ERROR)) { - mdelay(100); - - if (detect_card_cd(chip, - XD_CARD) != STATUS_SUCCESS) { - xd_set_err_code(chip, XD_NO_CARD); - return STATUS_FAIL; - } - - if (((reg & XD_ECC1_ERROR) && - (reg & XD_ECC1_UNCORRECTABLE)) || - ((reg & XD_ECC2_ERROR) && - (reg & XD_ECC2_UNCORRECTABLE))) { - rtsx_write_register(chip, - XD_PAGE_STATUS, - 0xFF, - XD_BPG); - rtsx_write_register(chip, - XD_BLOCK_STATUS, - 0xFF, - XD_GBLK); - XD_SET_BAD_OLDBLK(xd_card); - dev_dbg(rtsx_dev(chip), "old block 0x%x ecc error\n", - old_blk); - } - } else { - xd_set_err_code(chip, XD_TO_ERROR); - return STATUS_FAIL; - } - } - - if (XD_CHK_BAD_OLDBLK(xd_card)) - rtsx_clear_xd_error(chip); - - rtsx_init_cmd(chip); - - xd_assign_phy_addr(chip, new_page, XD_RW_ADDR); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, 1); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, - XD_TRANSFER_START | XD_WRITE_PAGES); - rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, - XD_TRANSFER_END, XD_TRANSFER_END); - - retval = rtsx_send_cmd(chip, XD_CARD, 300); - if (retval < 0) { - rtsx_clear_xd_error(chip); - reg = 0; - rtsx_read_register(chip, XD_DAT, ®); - if (reg & PROGRAM_ERROR) { - xd_mark_bad_block(chip, new_blk); - xd_set_err_code(chip, XD_PRG_ERROR); - XD_SET_BAD_NEWBLK(xd_card); - } else { - xd_set_err_code(chip, XD_TO_ERROR); - } - return STATUS_FAIL; - } - - old_page++; - new_page++; - } - - return STATUS_SUCCESS; -} - -static int xd_reset_cmd(struct rtsx_chip *chip) -{ - int retval; - u8 *ptr; - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, - 0xFF, XD_TRANSFER_START | XD_RESET); - rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, - XD_TRANSFER_END, XD_TRANSFER_END); - rtsx_add_cmd(chip, READ_REG_CMD, XD_DAT, 0, 0); - rtsx_add_cmd(chip, READ_REG_CMD, XD_CTL, 0, 0); - - retval = rtsx_send_cmd(chip, XD_CARD, 100); - if (retval < 0) - return STATUS_FAIL; - - ptr = rtsx_get_cmd_data(chip) + 1; - if (((ptr[0] & READY_FLAG) == READY_STATE) && (ptr[1] & XD_RDY)) - return STATUS_SUCCESS; - - return STATUS_FAIL; -} - -static int xd_erase_block(struct rtsx_chip *chip, u32 phy_blk) -{ - struct xd_info *xd_card = &chip->xd_card; - u32 page_addr; - u8 reg = 0, *ptr; - int i, retval; - - if (phy_blk == BLK_NOT_FOUND) - return STATUS_FAIL; - - page_addr = phy_blk << xd_card->block_shift; - - for (i = 0; i < 3; i++) { - rtsx_init_cmd(chip); - - xd_assign_phy_addr(chip, page_addr, XD_ERASE_ADDR); - - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, - XD_TRANSFER_START | XD_ERASE); - rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, - XD_TRANSFER_END, XD_TRANSFER_END); - rtsx_add_cmd(chip, READ_REG_CMD, XD_DAT, 0, 0); - - retval = rtsx_send_cmd(chip, XD_CARD, 250); - if (retval < 0) { - rtsx_clear_xd_error(chip); - rtsx_read_register(chip, XD_DAT, ®); - if (reg & PROGRAM_ERROR) { - xd_mark_bad_block(chip, phy_blk); - xd_set_err_code(chip, XD_PRG_ERROR); - return STATUS_FAIL; - } - xd_set_err_code(chip, XD_ERASE_FAIL); - retval = xd_reset_cmd(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - continue; - } - - ptr = rtsx_get_cmd_data(chip) + 1; - if (*ptr & PROGRAM_ERROR) { - xd_mark_bad_block(chip, phy_blk); - xd_set_err_code(chip, XD_PRG_ERROR); - return STATUS_FAIL; - } - - return STATUS_SUCCESS; - } - - xd_mark_bad_block(chip, phy_blk); - xd_set_err_code(chip, XD_ERASE_FAIL); - return STATUS_FAIL; -} - -static int xd_build_l2p_tbl(struct rtsx_chip *chip, int zone_no) -{ - struct xd_info *xd_card = &chip->xd_card; - struct zone_entry *zone; - int retval; - u32 start, end, i; - u16 max_logoff, cur_fst_page_logoff; - u16 cur_lst_page_logoff, ent_lst_page_logoff; - u8 redunt[11]; - - dev_dbg(rtsx_dev(chip), "%s: %d\n", __func__, zone_no); - - if (!xd_card->zone) { - retval = xd_init_l2p_tbl(chip); - if (retval != STATUS_SUCCESS) - return retval; - } - - if (xd_card->zone[zone_no].build_flag) { - dev_dbg(rtsx_dev(chip), "l2p table of zone %d has been built\n", - zone_no); - return STATUS_SUCCESS; - } - - zone = &xd_card->zone[zone_no]; - - if (!zone->l2p_table) { - zone->l2p_table = vmalloc(2000); - if (!zone->l2p_table) - goto build_fail; - } - memset((u8 *)(zone->l2p_table), 0xff, 2000); - - if (!zone->free_table) { - zone->free_table = vmalloc(XD_FREE_TABLE_CNT * 2); - if (!zone->free_table) - goto build_fail; - } - memset((u8 *)(zone->free_table), 0xff, XD_FREE_TABLE_CNT * 2); - - if (zone_no == 0) { - if (xd_card->cis_block == 0xFFFF) - start = 0; - else - start = xd_card->cis_block + 1; - if (XD_CHK_4MB(xd_card)) { - end = 0x200; - max_logoff = 499; - } else { - end = 0x400; - max_logoff = 999; - } - } else { - start = (u32)(zone_no) << 10; - end = (u32)(zone_no + 1) << 10; - max_logoff = 999; - } - - dev_dbg(rtsx_dev(chip), "start block 0x%x, end block 0x%x\n", - start, end); - - zone->set_index = 0; - zone->get_index = 0; - zone->unused_blk_cnt = 0; - - for (i = start; i < end; i++) { - u32 page_addr = i << xd_card->block_shift; - u32 phy_block; - - retval = xd_read_redundant(chip, page_addr, redunt, 11); - if (retval != STATUS_SUCCESS) - continue; - - if (redunt[BLOCK_STATUS] != 0xFF) { - dev_dbg(rtsx_dev(chip), "bad block\n"); - continue; - } - - if (xd_check_data_blank(redunt)) { - dev_dbg(rtsx_dev(chip), "blank block\n"); - xd_set_unused_block(chip, i); - continue; - } - - cur_fst_page_logoff = xd_load_log_block_addr(redunt); - if (cur_fst_page_logoff == 0xFFFF || - cur_fst_page_logoff > max_logoff) { - retval = xd_erase_block(chip, i); - if (retval == STATUS_SUCCESS) - xd_set_unused_block(chip, i); - continue; - } - - if (zone_no == 0 && cur_fst_page_logoff == 0 && - redunt[PAGE_STATUS] != XD_GPG) - XD_SET_MBR_FAIL(xd_card); - - if (zone->l2p_table[cur_fst_page_logoff] == 0xFFFF) { - zone->l2p_table[cur_fst_page_logoff] = (u16)(i & 0x3FF); - continue; - } - - phy_block = zone->l2p_table[cur_fst_page_logoff] + - ((u32)((zone_no) << 10)); - - page_addr = ((i + 1) << xd_card->block_shift) - 1; - - retval = xd_read_redundant(chip, page_addr, redunt, 11); - if (retval != STATUS_SUCCESS) - continue; - - cur_lst_page_logoff = xd_load_log_block_addr(redunt); - if (cur_lst_page_logoff == cur_fst_page_logoff) { - int m; - - page_addr = ((phy_block + 1) << - xd_card->block_shift) - 1; - - for (m = 0; m < 3; m++) { - retval = xd_read_redundant(chip, page_addr, - redunt, 11); - if (retval == STATUS_SUCCESS) - break; - } - - if (m == 3) { - zone->l2p_table[cur_fst_page_logoff] = - (u16)(i & 0x3FF); - retval = xd_erase_block(chip, phy_block); - if (retval == STATUS_SUCCESS) - xd_set_unused_block(chip, phy_block); - continue; - } - - ent_lst_page_logoff = xd_load_log_block_addr(redunt); - if (ent_lst_page_logoff != cur_fst_page_logoff) { - zone->l2p_table[cur_fst_page_logoff] = - (u16)(i & 0x3FF); - retval = xd_erase_block(chip, phy_block); - if (retval == STATUS_SUCCESS) - xd_set_unused_block(chip, phy_block); - continue; - } else { - retval = xd_erase_block(chip, i); - if (retval == STATUS_SUCCESS) - xd_set_unused_block(chip, i); - } - } else { - retval = xd_erase_block(chip, i); - if (retval == STATUS_SUCCESS) - xd_set_unused_block(chip, i); - } - } - - if (XD_CHK_4MB(xd_card)) - end = 500; - else - end = 1000; - - i = 0; - for (start = 0; start < end; start++) { - if (zone->l2p_table[start] == 0xFFFF) - i++; - } - - dev_dbg(rtsx_dev(chip), "Block count %d, invalid L2P entry %d\n", - end, i); - dev_dbg(rtsx_dev(chip), "Total unused block: %d\n", - zone->unused_blk_cnt); - - if ((zone->unused_blk_cnt - i) < 1) - chip->card_wp |= XD_CARD; - - zone->build_flag = 1; - - return STATUS_SUCCESS; - -build_fail: - vfree(zone->l2p_table); - zone->l2p_table = NULL; - vfree(zone->free_table); - zone->free_table = NULL; - - return STATUS_FAIL; -} - -static int xd_send_cmd(struct rtsx_chip *chip, u8 cmd) -{ - int retval; - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_DAT, 0xFF, cmd); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, - XD_TRANSFER_START | XD_SET_CMD); - rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, - XD_TRANSFER_END, XD_TRANSFER_END); - - retval = rtsx_send_cmd(chip, XD_CARD, 200); - if (retval < 0) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} - -static int xd_read_multiple_pages(struct rtsx_chip *chip, u32 phy_blk, - u32 log_blk, u8 start_page, u8 end_page, - u8 *buf, unsigned int *index, - unsigned int *offset) -{ - struct xd_info *xd_card = &chip->xd_card; - u32 page_addr, new_blk; - u16 log_off; - u8 reg_val, page_cnt; - int zone_no, retval, i; - - if (start_page > end_page) - goto status_fail; - - page_cnt = end_page - start_page; - zone_no = (int)(log_blk / 1000); - log_off = (u16)(log_blk % 1000); - - if ((phy_blk & 0x3FF) == 0x3FF) { - for (i = 0; i < 256; i++) { - page_addr = ((u32)i) << xd_card->block_shift; - - retval = xd_read_redundant(chip, page_addr, NULL, 0); - if (retval == STATUS_SUCCESS) - break; - - if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) { - xd_set_err_code(chip, XD_NO_CARD); - goto status_fail; - } - } - } - - page_addr = (phy_blk << xd_card->block_shift) + start_page; - - rtsx_init_cmd(chip); - - xd_assign_phy_addr(chip, page_addr, XD_RW_ADDR); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CFG, XD_PPB_TO_SIE, XD_PPB_TO_SIE); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, page_cnt); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CHK_DATA_STATUS, - XD_AUTO_CHK_DATA_STATUS, XD_AUTO_CHK_DATA_STATUS); - - trans_dma_enable(chip->srb->sc_data_direction, chip, - page_cnt * 512, DMA_512); - - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, - XD_TRANSFER_START | XD_READ_PAGES); - rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, - XD_TRANSFER_END | XD_PPB_EMPTY, - XD_TRANSFER_END | XD_PPB_EMPTY); - - rtsx_send_cmd_no_wait(chip); - - retval = rtsx_transfer_data_partial(chip, XD_CARD, buf, page_cnt * 512, - scsi_sg_count(chip->srb), - index, offset, DMA_FROM_DEVICE, - chip->xd_timeout); - if (retval < 0) { - rtsx_clear_xd_error(chip); - - if (retval == -ETIMEDOUT) { - xd_set_err_code(chip, XD_TO_ERROR); - goto status_fail; - } else { - goto fail; - } - } - - return STATUS_SUCCESS; - -fail: - retval = rtsx_read_register(chip, XD_PAGE_STATUS, ®_val); - if (retval) - return retval; - - if (reg_val != XD_GPG) - xd_set_err_code(chip, XD_PRG_ERROR); - - retval = rtsx_read_register(chip, XD_CTL, ®_val); - if (retval) - return retval; - - if (((reg_val & (XD_ECC1_ERROR | XD_ECC1_UNCORRECTABLE)) == - (XD_ECC1_ERROR | XD_ECC1_UNCORRECTABLE)) || - ((reg_val & (XD_ECC2_ERROR | XD_ECC2_UNCORRECTABLE)) == - (XD_ECC2_ERROR | XD_ECC2_UNCORRECTABLE))) { - wait_timeout(100); - - if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) { - xd_set_err_code(chip, XD_NO_CARD); - goto status_fail; - } - - xd_set_err_code(chip, XD_ECC_ERROR); - - new_blk = xd_get_unused_block(chip, zone_no); - if (new_blk == NO_NEW_BLK) { - XD_CLR_BAD_OLDBLK(xd_card); - goto status_fail; - } - - retval = xd_copy_page(chip, phy_blk, new_blk, 0, - xd_card->page_off + 1); - if (retval != STATUS_SUCCESS) { - if (!XD_CHK_BAD_NEWBLK(xd_card)) { - retval = xd_erase_block(chip, new_blk); - if (retval == STATUS_SUCCESS) - xd_set_unused_block(chip, new_blk); - } else { - XD_CLR_BAD_NEWBLK(xd_card); - } - XD_CLR_BAD_OLDBLK(xd_card); - goto status_fail; - } - xd_set_l2p_tbl(chip, zone_no, log_off, (u16)(new_blk & 0x3FF)); - xd_erase_block(chip, phy_blk); - xd_mark_bad_block(chip, phy_blk); - XD_CLR_BAD_OLDBLK(xd_card); - } - -status_fail: - return STATUS_FAIL; -} - -static int xd_finish_write(struct rtsx_chip *chip, - u32 old_blk, u32 new_blk, u32 log_blk, u8 page_off) -{ - struct xd_info *xd_card = &chip->xd_card; - int retval, zone_no; - u16 log_off; - - dev_dbg(rtsx_dev(chip), "old_blk = 0x%x, ", old_blk); - dev_dbg(rtsx_dev(chip), "new_blk = 0x%x, ", new_blk); - dev_dbg(rtsx_dev(chip), "log_blk = 0x%x\n", log_blk); - - if (page_off > xd_card->page_off) - return STATUS_FAIL; - - zone_no = (int)(log_blk / 1000); - log_off = (u16)(log_blk % 1000); - - if (old_blk == BLK_NOT_FOUND) { - retval = xd_init_page(chip, new_blk, log_off, - page_off, xd_card->page_off + 1); - if (retval != STATUS_SUCCESS) { - retval = xd_erase_block(chip, new_blk); - if (retval == STATUS_SUCCESS) - xd_set_unused_block(chip, new_blk); - return STATUS_FAIL; - } - } else { - retval = xd_copy_page(chip, old_blk, new_blk, - page_off, xd_card->page_off + 1); - if (retval != STATUS_SUCCESS) { - if (!XD_CHK_BAD_NEWBLK(xd_card)) { - retval = xd_erase_block(chip, new_blk); - if (retval == STATUS_SUCCESS) - xd_set_unused_block(chip, new_blk); - } - XD_CLR_BAD_NEWBLK(xd_card); - return STATUS_FAIL; - } - - retval = xd_erase_block(chip, old_blk); - if (retval == STATUS_SUCCESS) { - if (XD_CHK_BAD_OLDBLK(xd_card)) { - xd_mark_bad_block(chip, old_blk); - XD_CLR_BAD_OLDBLK(xd_card); - } else { - xd_set_unused_block(chip, old_blk); - } - } else { - xd_set_err_code(chip, XD_NO_ERROR); - XD_CLR_BAD_OLDBLK(xd_card); - } - } - - xd_set_l2p_tbl(chip, zone_no, log_off, (u16)(new_blk & 0x3FF)); - - return STATUS_SUCCESS; -} - -static int xd_prepare_write(struct rtsx_chip *chip, - u32 old_blk, u32 new_blk, u32 log_blk, u8 page_off) -{ - int retval; - - dev_dbg(rtsx_dev(chip), "%s, old_blk = 0x%x, new_blk = 0x%x, log_blk = 0x%x, page_off = %d\n", - __func__, old_blk, new_blk, log_blk, (int)page_off); - - if (page_off) { - retval = xd_copy_page(chip, old_blk, new_blk, 0, page_off); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -static int xd_write_multiple_pages(struct rtsx_chip *chip, u32 old_blk, - u32 new_blk, u32 log_blk, u8 start_page, - u8 end_page, u8 *buf, unsigned int *index, - unsigned int *offset) -{ - struct xd_info *xd_card = &chip->xd_card; - u32 page_addr; - int zone_no, retval; - u16 log_off; - u8 page_cnt, reg_val; - - dev_dbg(rtsx_dev(chip), "%s, old_blk = 0x%x, new_blk = 0x%x, log_blk = 0x%x\n", - __func__, old_blk, new_blk, log_blk); - - if (start_page > end_page) - goto status_fail; - - page_cnt = end_page - start_page; - zone_no = (int)(log_blk / 1000); - log_off = (u16)(log_blk % 1000); - - page_addr = (new_blk << xd_card->block_shift) + start_page; - - retval = xd_send_cmd(chip, READ1_1); - if (retval != STATUS_SUCCESS) - goto status_fail; - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR1_H, - 0xFF, (u8)(log_off >> 8)); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR1_L, 0xFF, (u8)log_off); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_STATUS, 0xFF, XD_GBLK); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_STATUS, 0xFF, XD_GPG); - - xd_assign_phy_addr(chip, page_addr, XD_RW_ADDR); - - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CFG, XD_BA_TRANSFORM, - XD_BA_TRANSFORM); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, page_cnt); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER); - - trans_dma_enable(chip->srb->sc_data_direction, chip, - page_cnt * 512, DMA_512); - - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, - 0xFF, XD_TRANSFER_START | XD_WRITE_PAGES); - rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, - XD_TRANSFER_END, XD_TRANSFER_END); - - rtsx_send_cmd_no_wait(chip); - - retval = rtsx_transfer_data_partial(chip, XD_CARD, buf, page_cnt * 512, - scsi_sg_count(chip->srb), - index, offset, DMA_TO_DEVICE, chip->xd_timeout); - if (retval < 0) { - rtsx_clear_xd_error(chip); - - if (retval == -ETIMEDOUT) { - xd_set_err_code(chip, XD_TO_ERROR); - goto status_fail; - } else { - goto fail; - } - } - - if (end_page == (xd_card->page_off + 1)) { - xd_card->delay_write.delay_write_flag = 0; - - if (old_blk != BLK_NOT_FOUND) { - retval = xd_erase_block(chip, old_blk); - if (retval == STATUS_SUCCESS) { - if (XD_CHK_BAD_OLDBLK(xd_card)) { - xd_mark_bad_block(chip, old_blk); - XD_CLR_BAD_OLDBLK(xd_card); - } else { - xd_set_unused_block(chip, old_blk); - } - } else { - xd_set_err_code(chip, XD_NO_ERROR); - XD_CLR_BAD_OLDBLK(xd_card); - } - } - xd_set_l2p_tbl(chip, zone_no, log_off, (u16)(new_blk & 0x3FF)); - } - - return STATUS_SUCCESS; - -fail: - retval = rtsx_read_register(chip, XD_DAT, ®_val); - if (retval) - return retval; - if (reg_val & PROGRAM_ERROR) { - xd_set_err_code(chip, XD_PRG_ERROR); - xd_mark_bad_block(chip, new_blk); - } - -status_fail: - return STATUS_FAIL; -} - -#ifdef XD_DELAY_WRITE -int xd_delay_write(struct rtsx_chip *chip) -{ - struct xd_info *xd_card = &chip->xd_card; - struct xd_delay_write_tag *delay_write = &xd_card->delay_write; - int retval; - - if (delay_write->delay_write_flag) { - retval = xd_switch_clock(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - delay_write->delay_write_flag = 0; - retval = xd_finish_write(chip, - delay_write->old_phyblock, - delay_write->new_phyblock, - delay_write->logblock, - delay_write->pageoff); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} -#endif - -int xd_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, - u32 start_sector, u16 sector_cnt) -{ - struct xd_info *xd_card = &chip->xd_card; - unsigned int lun = SCSI_LUN(srb); -#ifdef XD_DELAY_WRITE - struct xd_delay_write_tag *delay_write = &xd_card->delay_write; -#endif - int retval, zone_no; - unsigned int index = 0, offset = 0; - u32 log_blk, old_blk = 0, new_blk = 0; - u16 log_off, total_sec_cnt = sector_cnt; - u8 start_page, end_page = 0, page_cnt; - u8 *ptr; - - xd_set_err_code(chip, XD_NO_ERROR); - - xd_card->cleanup_counter = 0; - - dev_dbg(rtsx_dev(chip), "%s: scsi_sg_count = %d\n", __func__, - scsi_sg_count(srb)); - - ptr = (u8 *)scsi_sglist(srb); - - retval = xd_switch_clock(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) { - chip->card_fail |= XD_CARD; - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - return STATUS_FAIL; - } - - log_blk = start_sector >> xd_card->block_shift; - start_page = (u8)start_sector & xd_card->page_off; - zone_no = (int)(log_blk / 1000); - log_off = (u16)(log_blk % 1000); - - if (xd_card->zone[zone_no].build_flag == 0) { - retval = xd_build_l2p_tbl(chip, zone_no); - if (retval != STATUS_SUCCESS) { - chip->card_fail |= XD_CARD; - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - return STATUS_FAIL; - } - } - - if (srb->sc_data_direction == DMA_TO_DEVICE) { -#ifdef XD_DELAY_WRITE - if (delay_write->delay_write_flag && - delay_write->logblock == log_blk && - start_page > delay_write->pageoff) { - delay_write->delay_write_flag = 0; - if (delay_write->old_phyblock != BLK_NOT_FOUND) { - retval = xd_copy_page(chip, - delay_write->old_phyblock, - delay_write->new_phyblock, - delay_write->pageoff, - start_page); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_WRITE_ERR); - return STATUS_FAIL; - } - } - old_blk = delay_write->old_phyblock; - new_blk = delay_write->new_phyblock; - } else if (delay_write->delay_write_flag && - (delay_write->logblock == log_blk) && - (start_page == delay_write->pageoff)) { - delay_write->delay_write_flag = 0; - old_blk = delay_write->old_phyblock; - new_blk = delay_write->new_phyblock; - } else { - retval = xd_delay_write(chip); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_WRITE_ERR); - return STATUS_FAIL; - } -#endif - old_blk = xd_get_l2p_tbl(chip, zone_no, log_off); - new_blk = xd_get_unused_block(chip, zone_no); - if (old_blk == BLK_NOT_FOUND || - new_blk == BLK_NOT_FOUND) { - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_WRITE_ERR); - return STATUS_FAIL; - } - - retval = xd_prepare_write(chip, old_blk, new_blk, - log_blk, start_page); - if (retval != STATUS_SUCCESS) { - if (detect_card_cd(chip, XD_CARD) != - STATUS_SUCCESS) { - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_NOT_PRESENT); - return STATUS_FAIL; - } - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_WRITE_ERR); - return STATUS_FAIL; - } -#ifdef XD_DELAY_WRITE - } -#endif - } else { -#ifdef XD_DELAY_WRITE - retval = xd_delay_write(chip); - if (retval != STATUS_SUCCESS) { - if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) { - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_NOT_PRESENT); - return STATUS_FAIL; - } - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - return STATUS_FAIL; - } -#endif - - old_blk = xd_get_l2p_tbl(chip, zone_no, log_off); - if (old_blk == BLK_NOT_FOUND) { - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - return STATUS_FAIL; - } - } - - dev_dbg(rtsx_dev(chip), "old_blk = 0x%x\n", old_blk); - - while (total_sec_cnt) { - if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) { - chip->card_fail |= XD_CARD; - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - return STATUS_FAIL; - } - - if ((start_page + total_sec_cnt) > (xd_card->page_off + 1)) - end_page = xd_card->page_off + 1; - else - end_page = start_page + (u8)total_sec_cnt; - - page_cnt = end_page - start_page; - if (srb->sc_data_direction == DMA_FROM_DEVICE) { - retval = xd_read_multiple_pages(chip, old_blk, log_blk, - start_page, end_page, - ptr, &index, &offset); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - return STATUS_FAIL; - } - } else { - retval = xd_write_multiple_pages(chip, old_blk, - new_blk, log_blk, - start_page, end_page, - ptr, &index, &offset); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_WRITE_ERR); - return STATUS_FAIL; - } - } - - total_sec_cnt -= page_cnt; - if (scsi_sg_count(srb) == 0) - ptr += page_cnt * 512; - - if (total_sec_cnt == 0) - break; - - log_blk++; - zone_no = (int)(log_blk / 1000); - log_off = (u16)(log_blk % 1000); - - if (xd_card->zone[zone_no].build_flag == 0) { - retval = xd_build_l2p_tbl(chip, zone_no); - if (retval != STATUS_SUCCESS) { - chip->card_fail |= XD_CARD; - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_NOT_PRESENT); - return STATUS_FAIL; - } - } - - old_blk = xd_get_l2p_tbl(chip, zone_no, log_off); - if (old_blk == BLK_NOT_FOUND) { - if (srb->sc_data_direction == DMA_FROM_DEVICE) - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - else - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_WRITE_ERR); - - return STATUS_FAIL; - } - - if (srb->sc_data_direction == DMA_TO_DEVICE) { - new_blk = xd_get_unused_block(chip, zone_no); - if (new_blk == BLK_NOT_FOUND) { - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_WRITE_ERR); - return STATUS_FAIL; - } - } - - start_page = 0; - } - - if (srb->sc_data_direction == DMA_TO_DEVICE && - (end_page != (xd_card->page_off + 1))) { -#ifdef XD_DELAY_WRITE - delay_write->delay_write_flag = 1; - delay_write->old_phyblock = old_blk; - delay_write->new_phyblock = new_blk; - delay_write->logblock = log_blk; - delay_write->pageoff = end_page; -#else - if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) { - chip->card_fail |= XD_CARD; - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - return STATUS_FAIL; - } - - retval = xd_finish_write(chip, old_blk, new_blk, - log_blk, end_page); - if (retval != STATUS_SUCCESS) { - if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) { - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_NOT_PRESENT); - return STATUS_FAIL; - } - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); - return STATUS_FAIL; - } -#endif - } - - scsi_set_resid(srb, 0); - - return STATUS_SUCCESS; -} - -void xd_free_l2p_tbl(struct rtsx_chip *chip) -{ - struct xd_info *xd_card = &chip->xd_card; - int i = 0; - - if (xd_card->zone) { - for (i = 0; i < xd_card->zone_cnt; i++) { - vfree(xd_card->zone[i].l2p_table); - xd_card->zone[i].l2p_table = NULL; - vfree(xd_card->zone[i].free_table); - xd_card->zone[i].free_table = NULL; - } - vfree(xd_card->zone); - xd_card->zone = NULL; - } -} - -void xd_cleanup_work(struct rtsx_chip *chip) -{ -#ifdef XD_DELAY_WRITE - struct xd_info *xd_card = &chip->xd_card; - - if (xd_card->delay_write.delay_write_flag) { - dev_dbg(rtsx_dev(chip), "xD: delay write\n"); - xd_delay_write(chip); - xd_card->cleanup_counter = 0; - } -#endif -} - -int xd_power_off_card3v3(struct rtsx_chip *chip) -{ - int retval; - - retval = disable_card_clock(chip, XD_CARD); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - retval = rtsx_write_register(chip, CARD_OE, XD_OUTPUT_EN, 0); - if (retval) - return retval; - - if (!chip->ft2_fast_mode) { - retval = card_power_off(chip, XD_CARD); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - wait_timeout(50); - } - - if (chip->asic_code) { - retval = xd_pull_ctl_disable(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - } else { - retval = rtsx_write_register(chip, FPGA_PULL_CTL, 0xFF, 0xDF); - if (retval) - return retval; - } - - return STATUS_SUCCESS; -} - -int release_xd_card(struct rtsx_chip *chip) -{ - struct xd_info *xd_card = &chip->xd_card; - int retval; - - chip->card_ready &= ~XD_CARD; - chip->card_fail &= ~XD_CARD; - chip->card_wp &= ~XD_CARD; - - xd_card->delay_write.delay_write_flag = 0; - - xd_free_l2p_tbl(chip); - - retval = xd_power_off_card3v3(chip); - if (retval != STATUS_SUCCESS) - return STATUS_FAIL; - - return STATUS_SUCCESS; -} diff --git a/drivers/staging/rts5208/xd.h b/drivers/staging/rts5208/xd.h deleted file mode 100644 index 98c00f268e56..000000000000 --- a/drivers/staging/rts5208/xd.h +++ /dev/null @@ -1,176 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Driver for Realtek PCI-Express card reader - * - * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. - * - * Author: - * Wei WANG (wei_wang@xxxxxxxxxxxxxx) - * Micky Ching (micky_ching@xxxxxxxxxxxxxx) - */ - -#ifndef __REALTEK_RTSX_XD_H -#define __REALTEK_RTSX_XD_H - -#define XD_DELAY_WRITE - -/* Error Codes */ -#define XD_NO_ERROR 0x00 -#define XD_NO_MEMORY 0x80 -#define XD_PRG_ERROR 0x40 -#define XD_NO_CARD 0x20 -#define XD_READ_FAIL 0x10 -#define XD_ERASE_FAIL 0x08 -#define XD_WRITE_FAIL 0x04 -#define XD_ECC_ERROR 0x02 -#define XD_TO_ERROR 0x01 - -/* XD Commands */ -#define READ1_1 0x00 -#define READ1_2 0x01 -#define READ2 0x50 -#define READ_ID 0x90 -#define RESET 0xff -#define PAGE_PRG_1 0x80 -#define PAGE_PRG_2 0x10 -#define BLK_ERASE_1 0x60 -#define BLK_ERASE_2 0xD0 -#define READ_STS 0x70 -#define READ_XD_ID 0x9A -#define COPY_BACK_512 0x8A -#define COPY_BACK_2K 0x85 -#define READ1_1_2 0x30 -#define READ1_1_3 0x35 -#define CHG_DAT_OUT_1 0x05 -#define RDM_DAT_OUT_1 0x05 -#define CHG_DAT_OUT_2 0xE0 -#define RDM_DAT_OUT_2 0xE0 -#define CHG_DAT_OUT_2 0xE0 -#define CHG_DAT_IN_1 0x85 -#define CACHE_PRG 0x15 - -/* Redundant Area Related */ -#define XD_EXTRA_SIZE 0x10 -#define XD_2K_EXTRA_SIZE 0x40 - -#define NOT_WRITE_PROTECTED 0x80 -#define READY_STATE 0x40 -#define PROGRAM_ERROR 0x01 -#define PROGRAM_ERROR_N_1 0x02 -#define INTERNAL_READY 0x20 -#define READY_FLAG 0x5F - -#define XD_8M_X8_512 0xE6 -#define XD_16M_X8_512 0x73 -#define XD_32M_X8_512 0x75 -#define XD_64M_X8_512 0x76 -#define XD_128M_X8_512 0x79 -#define XD_256M_X8_512 0x71 -#define XD_128M_X8_2048 0xF1 -#define XD_256M_X8_2048 0xDA -#define XD_512M_X8 0xDC -#define XD_128M_X16_2048 0xC1 -#define XD_4M_X8_512_1 0xE3 -#define XD_4M_X8_512_2 0xE5 -#define XD_1G_X8_512 0xD3 -#define XD_2G_X8_512 0xD5 - -#define XD_ID_CODE 0xB5 - -#define VENDOR_BLOCK 0xEFFF -#define CIS_BLOCK 0xDFFF - -#define BLK_NOT_FOUND 0xFFFFFFFF - -#define NO_NEW_BLK 0xFFFFFFFF - -#define PAGE_CORRECTABLE 0x0 -#define PAGE_NOTCORRECTABLE 0x1 - -#define NO_OFFSET 0x0 -#define WITH_OFFSET 0x1 - -#define SECT_PER_PAGE 4 -#define XD_ADDR_MODE_2C XD_ADDR_MODE_2A - -#define ZONE0_BAD_BLOCK 23 -#define NOT_ZONE0_BAD_BLOCK 24 - -#define XD_RW_ADDR 0x01 -#define XD_ERASE_ADDR 0x02 - -#define XD_PAGE_512(xd_card) \ -do { \ - (xd_card)->block_shift = 5; \ - (xd_card)->page_off = 0x1F; \ -} while (0) - -#define XD_SET_BAD_NEWBLK(xd_card) ((xd_card)->multi_flag |= 0x01) -#define XD_CLR_BAD_NEWBLK(xd_card) ((xd_card)->multi_flag &= ~0x01) -#define XD_CHK_BAD_NEWBLK(xd_card) ((xd_card)->multi_flag & 0x01) - -#define XD_SET_BAD_OLDBLK(xd_card) ((xd_card)->multi_flag |= 0x02) -#define XD_CLR_BAD_OLDBLK(xd_card) ((xd_card)->multi_flag &= ~0x02) -#define XD_CHK_BAD_OLDBLK(xd_card) ((xd_card)->multi_flag & 0x02) - -#define XD_SET_MBR_FAIL(xd_card) ((xd_card)->multi_flag |= 0x04) -#define XD_CLR_MBR_FAIL(xd_card) ((xd_card)->multi_flag &= ~0x04) -#define XD_CHK_MBR_FAIL(xd_card) ((xd_card)->multi_flag & 0x04) - -#define XD_SET_ECC_FLD_ERR(xd_card) ((xd_card)->multi_flag |= 0x08) -#define XD_CLR_ECC_FLD_ERR(xd_card) ((xd_card)->multi_flag &= ~0x08) -#define XD_CHK_ECC_FLD_ERR(xd_card) ((xd_card)->multi_flag & 0x08) - -#define XD_SET_4MB(xd_card) ((xd_card)->multi_flag |= 0x10) -#define XD_CLR_4MB(xd_card) ((xd_card)->multi_flag &= ~0x10) -#define XD_CHK_4MB(xd_card) ((xd_card)->multi_flag & 0x10) - -#define XD_SET_ECC_ERR(xd_card) ((xd_card)->multi_flag |= 0x40) -#define XD_CLR_ECC_ERR(xd_card) ((xd_card)->multi_flag &= ~0x40) -#define XD_CHK_ECC_ERR(xd_card) ((xd_card)->multi_flag & 0x40) - -#define PAGE_STATUS 0 -#define BLOCK_STATUS 1 -#define BLOCK_ADDR1_L 2 -#define BLOCK_ADDR1_H 3 -#define BLOCK_ADDR2_L 4 -#define BLOCK_ADDR2_H 5 -#define RESERVED0 6 -#define RESERVED1 7 -#define RESERVED2 8 -#define RESERVED3 9 -#define PARITY 10 - -#define CIS0_0 0 -#define CIS0_1 1 -#define CIS0_2 2 -#define CIS0_3 3 -#define CIS0_4 4 -#define CIS0_5 5 -#define CIS0_6 6 -#define CIS0_7 7 -#define CIS0_8 8 -#define CIS0_9 9 -#define CIS1_0 256 -#define CIS1_1 (256 + 1) -#define CIS1_2 (256 + 2) -#define CIS1_3 (256 + 3) -#define CIS1_4 (256 + 4) -#define CIS1_5 (256 + 5) -#define CIS1_6 (256 + 6) -#define CIS1_7 (256 + 7) -#define CIS1_8 (256 + 8) -#define CIS1_9 (256 + 9) - -int reset_xd_card(struct rtsx_chip *chip); -#ifdef XD_DELAY_WRITE -int xd_delay_write(struct rtsx_chip *chip); -#endif -int xd_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, - u32 start_sector, u16 sector_cnt); -void xd_free_l2p_tbl(struct rtsx_chip *chip); -void xd_cleanup_work(struct rtsx_chip *chip); -int xd_power_off_card3v3(struct rtsx_chip *chip); -int release_xd_card(struct rtsx_chip *chip); - -#endif /* __REALTEK_RTSX_XD_H */ -- 2.43.0